From b0419f26d0d75cf1d9b56c26142c5eb7956fef63 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 23 Aug 2004 21:53:28 +1000 Subject: - (djm) [loginrec.c] Typo and bad args in error messages; Spotted by Martin.Kraemer AT Fujitsu-Siemens.com --- loginrec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'loginrec.c') diff --git a/loginrec.c b/loginrec.c index f07f65fce..3ec378b9a 100644 --- a/loginrec.c +++ b/loginrec.c @@ -158,7 +158,7 @@ #include "log.h" #include "atomicio.h" -RCSID("$Id: loginrec.c,v 1.58 2004/08/15 09:12:52 djm Exp $"); +RCSID("$Id: loginrec.c,v 1.59 2004/08/23 11:53:28 djm Exp $"); #ifdef HAVE_UTIL_H # include @@ -832,12 +832,12 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) pos = (off_t)tty * sizeof(struct utmp); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { - logit("%s: llseek: %s", strerror(errno)); + logit("%s: lseek: %s", __func__, strerror(errno)); return (0); } if (ret != pos) { - logit("%s: Couldn't seek to tty %s slot in %s", tty, - UTMP_FILE); + logit("%s: Couldn't seek to tty %d slot in %s", + __func__, tty, UTMP_FILE); return (0); } /* @@ -853,11 +853,11 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) } if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { - logit("%s: llseek: %s", __func__, strerror(errno)); + logit("%s: lseek: %s", __func__, strerror(errno)); return (0); } if (ret != pos) { - logit("%s: Couldn't seek to tty %s slot in %s", + logit("%s: Couldn't seek to tty %d slot in %s", __func__, tty, UTMP_FILE); return (0); } -- cgit v1.2.3 From 8899ed3b6258b6943e4bf2f942a0ad7ce52303f9 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 12 Sep 2004 15:18:55 +1000 Subject: - (djm) [loginrec.c] Start KNF and tidy up of this long-neglected file. No change in resultant binary --- ChangeLog | 6 +- loginrec.c | 642 ++++++++++++++++++++++++++++++------------------------------- 2 files changed, 321 insertions(+), 327 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index 995e1bd27..8890e6235 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20040912 + - (djm) [loginrec.c] Start KNF and tidy up of this long-neglected file. + No change in resultant binary + 20040911 - (djm) [ssh-agent.c] unifdef some cygwin code; ok dtucker@ - (dtucker) [auth-pam.c auth-pam.h session.c] Bug #890: Send output from @@ -1734,4 +1738,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3547 2004/09/11 13:32:09 dtucker Exp $ +$Id: ChangeLog,v 1.3548 2004/09/12 05:23:14 djm Exp $ diff --git a/loginrec.c b/loginrec.c index 3ec378b9a..8d48fb99f 100644 --- a/loginrec.c +++ b/loginrec.c @@ -30,125 +30,99 @@ **/ /* - The new login code explained - ============================ - - This code attempts to provide a common interface to login recording - (utmp and friends) and last login time retrieval. - - Its primary means of achieving this is to use 'struct logininfo', a - union of all the useful fields in the various different types of - system login record structures one finds on UNIX variants. - - We depend on autoconf to define which recording methods are to be - used, and which fields are contained in the relevant data structures - on the local system. Many C preprocessor symbols affect which code - gets compiled here. - - The code is designed to make it easy to modify a particular - recording method, without affecting other methods nor requiring so - many nested conditional compilation blocks as were commonplace in - the old code. - - For login recording, we try to use the local system's libraries as - these are clearly most likely to work correctly. For utmp systems - this usually means login() and logout() or setutent() etc., probably - in libutil, along with logwtmp() etc. On these systems, we fall back - to writing the files directly if we have to, though this method - requires very thorough testing so we do not corrupt local auditing - information. These files and their access methods are very system - specific indeed. - - For utmpx systems, the corresponding library functions are - setutxent() etc. To the author's knowledge, all utmpx systems have - these library functions and so no direct write is attempted. If such - a system exists and needs support, direct analogues of the [uw]tmp - code should suffice. - - Retrieving the time of last login ('lastlog') is in some ways even - more problemmatic than login recording. Some systems provide a - simple table of all users which we seek based on uid and retrieve a - relatively standard structure. Others record the same information in - a directory with a separate file, and others don't record the - information separately at all. For systems in the latter category, - we look backwards in the wtmp or wtmpx file for the last login entry - for our user. Naturally this is slower and on busy systems could - incur a significant performance penalty. - - Calling the new code - -------------------- - - In OpenSSH all login recording and retrieval is performed in - login.c. Here you'll find working examples. Also, in the logintest.c - program there are more examples. - - Internal handler calling method - ------------------------------- - - When a call is made to login_login() or login_logout(), both - routines set a struct logininfo flag defining which action (log in, - or log out) is to be taken. They both then call login_write(), which - calls whichever of the many structure-specific handlers autoconf - selects for the local system. - - The handlers themselves handle system data structure specifics. Both - struct utmp and struct utmpx have utility functions (see - construct_utmp*()) to try to make it simpler to add extra systems - that introduce new features to either structure. - - While it may seem terribly wasteful to replicate so much similar - code for each method, experience has shown that maintaining code to - write both struct utmp and utmpx in one function, whilst maintaining - support for all systems whether they have library support or not, is - a difficult and time-consuming task. - - Lastlog support proceeds similarly. Functions login_get_lastlog() - (and its OpenSSH-tuned friend login_get_lastlog_time()) call - getlast_entry(), which tries one of three methods to find the last - login time. It uses local system lastlog support if it can, - otherwise it tries wtmp or wtmpx before giving up and returning 0, - meaning "tilt". - - Maintenance - ----------- - - In many cases it's possible to tweak autoconf to select the correct - methods for a particular platform, either by improving the detection - code (best), or by presetting DISABLE_ or CONF__FILE - symbols for the platform. - - Use logintest to check which symbols are defined before modifying - configure.ac and loginrec.c. (You have to build logintest yourself - with 'make logintest' as it's not built by default.) - - Otherwise, patches to the specific method(s) are very helpful! - -*/ - -/** - ** TODO: - ** homegrown ttyslot() - ** test, test, test - ** - ** Platform status: - ** ---------------- - ** - ** Known good: - ** Linux (Redhat 6.2, Debian) - ** Solaris - ** HP-UX 10.20 (gcc only) - ** IRIX - ** NeXT - M68k/HPPA/Sparc (4.2/3.3) - ** - ** Testing required: Please send reports! - ** NetBSD - ** HP-UX 11 - ** AIX - ** - ** Platforms with known problems: - ** Some variants of Slackware Linux - ** - **/ + * The new login code explained + * ============================ + * + * This code attempts to provide a common interface to login recording + * (utmp and friends) and last login time retrieval. + * + * Its primary means of achieving this is to use 'struct logininfo', a + * union of all the useful fields in the various different types of + * system login record structures one finds on UNIX variants. + * + * We depend on autoconf to define which recording methods are to be + * used, and which fields are contained in the relevant data structures + * on the local system. Many C preprocessor symbols affect which code + * gets compiled here. + * + * The code is designed to make it easy to modify a particular + * recording method, without affecting other methods nor requiring so + * many nested conditional compilation blocks as were commonplace in + * the old code. + * + * For login recording, we try to use the local system's libraries as + * these are clearly most likely to work correctly. For utmp systems + * this usually means login() and logout() or setutent() etc., probably + * in libutil, along with logwtmp() etc. On these systems, we fall back + * to writing the files directly if we have to, though this method + * requires very thorough testing so we do not corrupt local auditing + * information. These files and their access methods are very system + * specific indeed. + * + * For utmpx systems, the corresponding library functions are + * setutxent() etc. To the author's knowledge, all utmpx systems have + * these library functions and so no direct write is attempted. If such + * a system exists and needs support, direct analogues of the [uw]tmp + * code should suffice. + * + * Retrieving the time of last login ('lastlog') is in some ways even + * more problemmatic than login recording. Some systems provide a + * simple table of all users which we seek based on uid and retrieve a + * relatively standard structure. Others record the same information in + * a directory with a separate file, and others don't record the + * information separately at all. For systems in the latter category, + * we look backwards in the wtmp or wtmpx file for the last login entry + * for our user. Naturally this is slower and on busy systems could + * incur a significant performance penalty. + * + * Calling the new code + * -------------------- + * + * In OpenSSH all login recording and retrieval is performed in + * login.c. Here you'll find working examples. Also, in the logintest.c + * program there are more examples. + * + * Internal handler calling method + * ------------------------------- + * + * When a call is made to login_login() or login_logout(), both + * routines set a struct logininfo flag defining which action (log in, + * or log out) is to be taken. They both then call login_write(), which + * calls whichever of the many structure-specific handlers autoconf + * selects for the local system. + * + * The handlers themselves handle system data structure specifics. Both + * struct utmp and struct utmpx have utility functions (see + * construct_utmp*()) to try to make it simpler to add extra systems + * that introduce new features to either structure. + * + * While it may seem terribly wasteful to replicate so much similar + * code for each method, experience has shown that maintaining code to + * write both struct utmp and utmpx in one function, whilst maintaining + * support for all systems whether they have library support or not, is + * a difficult and time-consuming task. + * + * Lastlog support proceeds similarly. Functions login_get_lastlog() + * (and its OpenSSH-tuned friend login_get_lastlog_time()) call + * getlast_entry(), which tries one of three methods to find the last + * login time. It uses local system lastlog support if it can, + * otherwise it tries wtmp or wtmpx before giving up and returning 0, + * meaning "tilt". + * + * Maintenance + * ----------- + * + * In many cases it's possible to tweak autoconf to select the correct + * methods for a particular platform, either by improving the detection + * code (best), or by presetting DISABLE_ or CONF__FILE + * symbols for the platform. + * + * Use logintest to check which symbols are defined before modifying + * configure.ac and loginrec.c. (You have to build logintest yourself + * with 'make logintest' as it's not built by default.) + * + * Otherwise, patches to the specific method(s) are very helpful! + */ #include "includes.h" @@ -158,16 +132,16 @@ #include "log.h" #include "atomicio.h" -RCSID("$Id: loginrec.c,v 1.59 2004/08/23 11:53:28 djm Exp $"); - #ifdef HAVE_UTIL_H -# include +# include #endif #ifdef HAVE_LIBUTIL_H -# include +# include #endif +RCSID("$Id: loginrec.c,v 1.60 2004/09/12 05:18:55 djm Exp $"); + /** ** prototypes for helper functions in this file **/ @@ -195,13 +169,14 @@ int wtmp_get_entry(struct logininfo *li); int wtmpx_get_entry(struct logininfo *li); /* pick the shortest string */ -#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) ) +#define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2)) /** ** platform-independent login functions **/ -/* login_login(struct logininfo *) -Record a login +/* + * login_login(struct logininfo *) - Record a login * * Call with a pointer to a struct logininfo initialised with * login_init_entry() or login_alloc_entry() @@ -211,14 +186,15 @@ int wtmpx_get_entry(struct logininfo *li); * 0 on failure (will use OpenSSH's logging facilities for diagnostics) */ int -login_login (struct logininfo *li) +login_login(struct logininfo *li) { li->type = LTYPE_LOGIN; - return login_write(li); + return (login_write(li)); } -/* login_logout(struct logininfo *) - Record a logout +/* + * login_logout(struct logininfo *) - Record a logout * * Call as with login_login() * @@ -230,10 +206,11 @@ int login_logout(struct logininfo *li) { li->type = LTYPE_LOGOUT; - return login_write(li); + return (login_write(li)); } -/* login_get_lastlog_time(int) - Retrieve the last login time +/* + * login_get_lastlog_time(int) - Retrieve the last login time * * Retrieve the last login time for the given uid. Will try to use the * system lastlog facilities if they are available, but will fall back @@ -256,12 +233,13 @@ login_get_lastlog_time(const int uid) struct logininfo li; if (login_get_lastlog(&li, uid)) - return li.tv_sec; + return (li.tv_sec); else - return 0; + return (0); } -/* login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry +/* + * login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry * * Retrieve a logininfo structure populated (only partially) with * information from the system lastlog data, or from wtmp/wtmpx if no @@ -272,7 +250,6 @@ login_get_lastlog_time(const int uid) * Returns: * >0: A pointer to your struct logininfo if successful * 0 on failure (will use OpenSSH's logging facilities for diagnostics) - * */ struct logininfo * login_get_lastlog(struct logininfo *li, const int uid) @@ -292,17 +269,18 @@ login_get_lastlog(struct logininfo *li, const int uid) fatal("login_get_lastlog: Cannot find account for uid %i", uid); /* No MIN_SIZEOF here - we absolutely *must not* truncate the - * username */ + * username (XXX - so check for trunc!) */ strlcpy(li->username, pw->pw_name, sizeof(li->username)); if (getlast_entry(li)) - return li; + return (li); else - return NULL; + return (NULL); } -/* login_alloc_entry(int, char*, char*, char*) - Allocate and initialise +/* + * login_alloc_entry(int, char*, char*, char*) - Allocate and initialise * a logininfo structure * * This function creates a new struct logininfo, a data structure @@ -313,13 +291,13 @@ login_get_lastlog(struct logininfo *li, const int uid) */ struct logininfo *login_alloc_entry(int pid, const char *username, - const char *hostname, const char *line) + const char *hostname, const char *line) { struct logininfo *newli; - newli = (struct logininfo *) xmalloc (sizeof(*newli)); - (void)login_init_entry(newli, pid, username, hostname, line); - return newli; + newli = xmalloc(sizeof(*newli)); + login_init_entry(newli, pid, username, hostname, line); + return (newli); } @@ -341,7 +319,7 @@ login_free_entry(struct logininfo *li) */ int login_init_entry(struct logininfo *li, int pid, const char *username, - const char *hostname, const char *line) + const char *hostname, const char *line) { struct passwd *pw; @@ -356,18 +334,21 @@ login_init_entry(struct logininfo *li, int pid, const char *username, if (username) { strlcpy(li->username, username, sizeof(li->username)); pw = getpwnam(li->username); - if (pw == NULL) - fatal("login_init_entry: Cannot find user \"%s\"", li->username); + if (pw == NULL) { + fatal("login_init_entry: Cannot find user \"%s\"", + li->username); + } li->uid = pw->pw_uid; } if (hostname) strlcpy(li->hostname, hostname, sizeof(li->hostname)); - return 1; + return (1); } -/* login_set_current_time(struct logininfo *) - set the current time +/* + * login_set_current_time(struct logininfo *) - set the current time * * Set the current time in a logininfo structure. This function is * meant to eliminate the need to deal with system dependencies for @@ -387,7 +368,7 @@ login_set_current_time(struct logininfo *li) /* copy a sockaddr_* into our logininfo */ void login_set_addr(struct logininfo *li, const struct sockaddr *sa, - const unsigned int sa_size) + const unsigned int sa_size) { unsigned int bufsize = sa_size; @@ -395,7 +376,7 @@ login_set_addr(struct logininfo *li, const struct sockaddr *sa, if (sizeof(li->hostaddr) < sa_size) bufsize = sizeof(li->hostaddr); - memcpy((void *)&(li->hostaddr.sa), (const void *)sa, bufsize); + memcpy(&li->hostaddr.sa, sa, bufsize); } @@ -404,12 +385,12 @@ login_set_addr(struct logininfo *li, const struct sockaddr *sa, ** results **/ int -login_write (struct logininfo *li) +login_write(struct logininfo *li) { #ifndef HAVE_CYGWIN - if ((int)geteuid() != 0) { - logit("Attempt to write login records by non-root user (aborting)"); - return 1; + if (geteuid() != 0) { + logit("Attempt to write login records by non-root user (aborting)"); + return (1); } #endif @@ -419,9 +400,8 @@ login_write (struct logininfo *li) syslogin_write_entry(li); #endif #ifdef USE_LASTLOG - if (li->type == LTYPE_LOGIN) { + if (li->type == LTYPE_LOGIN) lastlog_write_entry(li); - } #endif #ifdef USE_UTMP utmp_write_entry(li); @@ -440,7 +420,7 @@ login_write (struct logininfo *li) !sys_auth_record_login(li->username,li->hostname,li->line)) logit("Writing login record failed for %s", li->username); #endif - return 0; + return (0); } #ifdef LOGIN_NEEDS_UTMPX @@ -461,7 +441,7 @@ login_utmp_only(struct logininfo *li) # ifdef USE_WTMPX wtmpx_write_entry(li); # endif - return 0; + return (0); } #endif @@ -478,25 +458,21 @@ getlast_entry(struct logininfo *li) return(lastlog_get_entry(li)); #else /* !USE_LASTLOG */ -#ifdef DISABLE_LASTLOG +#if defined(DISABLE_LASTLOG) /* On some systems we shouldn't even try to obtain last login * time, e.g. AIX */ - return 0; -# else /* DISABLE_LASTLOG */ - /* Try to retrieve the last login time from wtmp */ -# if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) + return (0); +# elif defined(USE_WTMP) && \ + (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) /* retrieve last login time from utmp */ return (wtmp_get_entry(li)); -# else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */ +# elif defined(USE_WTMPX) && \ + (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) /* If wtmp isn't available, try wtmpx */ -# if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) - /* retrieve last login time from utmpx */ return (wtmpx_get_entry(li)); -# else +# else /* Give up: No means of retrieving last login time */ - return 0; -# endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */ -# endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */ + return (0); # endif /* DISABLE_LASTLOG */ #endif /* USE_LASTLOG */ } @@ -520,19 +496,21 @@ getlast_entry(struct logininfo *li) */ -/* line_fullname(): add the leading '/dev/' if it doesn't exist make - * sure dst has enough space, if not just copy src (ugh) */ +/* + * line_fullname(): add the leading '/dev/' if it doesn't exist make + * sure dst has enough space, if not just copy src (ugh) + */ char * line_fullname(char *dst, const char *src, int dstsize) { memset(dst, '\0', dstsize); - if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) { + if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) strlcpy(dst, src, dstsize); - } else { + else { strlcpy(dst, "/dev/", dstsize); strlcat(dst, src, dstsize); } - return dst; + return (dst); } /* line_stripname(): strip the leading '/dev' if it exists, return dst */ @@ -544,15 +522,17 @@ line_stripname(char *dst, const char *src, int dstsize) strlcpy(dst, src + 5, dstsize); else strlcpy(dst, src, dstsize); - return dst; + return (dst); } -/* line_abbrevname(): Return the abbreviated (usually four-character) +/* + * line_abbrevname(): Return the abbreviated (usually four-character) * form of the line (Just use the last characters of the * full name.) * * NOTE: use strncpy because we do NOT necessarily want zero - * termination */ + * termination + */ char * line_abbrevname(char *dst, const char *src, int dstsize) { @@ -579,7 +559,7 @@ line_abbrevname(char *dst, const char *src, int dstsize) strncpy(dst, src, (size_t)dstsize); } - return dst; + return (dst); } /** @@ -595,13 +575,11 @@ line_abbrevname(char *dst, const char *src, int dstsize) void set_utmp_time(struct logininfo *li, struct utmp *ut) { -# ifdef HAVE_TV_IN_UTMP +# if defined(HAVE_TV_IN_UTMP) ut->ut_tv.tv_sec = li->tv_sec; ut->ut_tv.tv_usec = li->tv_usec; -# else -# ifdef HAVE_TIME_IN_UTMP +# elif defined(HAVE_TIME_IN_UTMP) ut->ut_time = li->tv_sec; -# endif # endif } @@ -611,7 +589,8 @@ construct_utmp(struct logininfo *li, { # ifdef HAVE_ADDR_V6_IN_UTMP struct sockaddr_in6 *sa6; -# endif +# endif + memset(ut, '\0', sizeof(*ut)); /* First fill out fields used for both logins and logouts */ @@ -647,7 +626,7 @@ construct_utmp(struct logininfo *li, /* If we're logging out, leave all other fields blank */ if (li->type == LTYPE_LOGOUT) - return; + return; /* * These fields are only used when logging in, and are blank @@ -655,9 +634,11 @@ construct_utmp(struct logininfo *li, */ /* Use strncpy because we don't necessarily want null termination */ - strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username)); + strncpy(ut->ut_name, li->username, + MIN_SIZEOF(ut->ut_name, li->username)); # ifdef HAVE_HOST_IN_UTMP - strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); + strncpy(ut->ut_host, li->hostname, + MIN_SIZEOF(ut->ut_host, li->hostname)); # endif # ifdef HAVE_ADDR_IN_UTMP /* this is just a 32-bit IP address */ @@ -692,14 +673,12 @@ construct_utmp(struct logininfo *li, void set_utmpx_time(struct logininfo *li, struct utmpx *utx) { -# ifdef HAVE_TV_IN_UTMPX +# if defined(HAVE_TV_IN_UTMPX) utx->ut_tv.tv_sec = li->tv_sec; utx->ut_tv.tv_usec = li->tv_usec; -# else /* HAVE_TV_IN_UTMPX */ -# ifdef HAVE_TIME_IN_UTMPX +# elif defined(HAVE_TIME_IN_UTMPX) utx->ut_time = li->tv_sec; -# endif /* HAVE_TIME_IN_UTMPX */ -# endif /* HAVE_TV_IN_UTMPX */ +# endif } void @@ -709,6 +688,7 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) struct sockaddr_in6 *sa6; # endif memset(utx, '\0', sizeof(*utx)); + # ifdef HAVE_ID_IN_UTMPX line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); # endif @@ -725,8 +705,10 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); set_utmpx_time(li, utx); utx->ut_pid = li->pid; + /* strncpy(): Don't necessarily want null termination */ - strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); + strncpy(utx->ut_name, li->username, + MIN_SIZEOF(utx->ut_name, li->username)); if (li->type == LTYPE_LOGOUT) return; @@ -737,7 +719,8 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) */ # ifdef HAVE_HOST_IN_UTMPX - strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); + strncpy(utx->ut_host, li->hostname, + MIN_SIZEOF(utx->ut_host, li->hostname)); # endif # ifdef HAVE_ADDR_IN_UTMPX /* this is just a 32-bit IP address */ @@ -785,16 +768,17 @@ utmp_write_library(struct logininfo *li, struct utmp *ut) { setutent(); pututline(ut); - # ifdef HAVE_ENDUTENT endutent(); # endif - return 1; + return (1); } # else /* UTMP_USE_LIBRARY */ -/* write a utmp entry direct to the file */ -/* This is a slightly modification of code in OpenBSD's login.c */ +/* + * Write a utmp entry direct to the file + * This is a slightly modification of code in OpenBSD's login.c + */ static int utmp_write_direct(struct logininfo *li, struct utmp *ut) { @@ -805,19 +789,18 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) /* FIXME: (ATL) ttyslot() needs local implementation */ #if defined(HAVE_GETTTYENT) - register struct ttyent *ty; + struct ttyent *ty; tty=0; - setttyent(); - while ((struct ttyent *)0 != (ty = getttyent())) { + while (NULL != (ty = getttyent())) { tty++; if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) break; } endttyent(); - if((struct ttyent *)0 == ty) { + if (NULL == ty) { logit("%s: tty not found", __func__); return (0); } @@ -846,11 +829,10 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) * and ut_line and ut_name match, preserve the old ut_line. */ if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && - (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && - (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && - (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { - (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); - } + (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && + (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && + (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) + memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { logit("%s: lseek: %s", __func__, strerror(errno)); @@ -861,14 +843,15 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) __func__, tty, UTMP_FILE); return (0); } - if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { logit("%s: error writing %s: %s", __func__, UTMP_FILE, strerror(errno)); + } - (void)close(fd); - return 1; + close(fd); + return (1); } else { - return 0; + return (0); } } # endif /* UTMP_USE_LIBRARY */ @@ -882,15 +865,15 @@ utmp_perform_login(struct logininfo *li) # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { logit("utmp_perform_login: utmp_write_library() failed"); - return 0; + return (0); } # else if (!utmp_write_direct(li, &ut)) { logit("utmp_perform_login: utmp_write_direct() failed"); - return 0; + return (0); } # endif - return 1; + return (1); } @@ -903,15 +886,15 @@ utmp_perform_logout(struct logininfo *li) # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { logit("utmp_perform_logout: utmp_write_library() failed"); - return 0; + return (0); } # else if (!utmp_write_direct(li, &ut)) { logit("utmp_perform_logout: utmp_write_direct() failed"); - return 0; + return (0); } # endif - return 1; + return (1); } @@ -920,14 +903,14 @@ utmp_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: - return utmp_perform_login(li); + return (utmp_perform_login(li)); case LTYPE_LOGOUT: - return utmp_perform_logout(li); + return (utmp_perform_logout(li)); default: logit("utmp_write_entry: invalid type field"); - return 0; + return (0); } } #endif /* USE_UTMP */ @@ -958,7 +941,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx) # ifdef HAVE_ENDUTXENT endutxent(); # endif - return 1; + return (1); } # else /* UTMPX_USE_LIBRARY */ @@ -968,7 +951,7 @@ static int utmpx_write_direct(struct logininfo *li, struct utmpx *utx) { logit("utmpx_write_direct: not implemented!"); - return 0; + return (0); } # endif /* UTMPX_USE_LIBRARY */ @@ -981,15 +964,15 @@ utmpx_perform_login(struct logininfo *li) # ifdef UTMPX_USE_LIBRARY if (!utmpx_write_library(li, &utx)) { logit("utmpx_perform_login: utmp_write_library() failed"); - return 0; + return (0); } # else if (!utmpx_write_direct(li, &ut)) { logit("utmpx_perform_login: utmp_write_direct() failed"); - return 0; + return (0); } # endif - return 1; + return (1); } @@ -1011,7 +994,7 @@ utmpx_perform_logout(struct logininfo *li) # else utmpx_write_direct(li, &utx); # endif - return 1; + return (1); } int @@ -1019,12 +1002,12 @@ utmpx_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: - return utmpx_perform_login(li); + return (utmpx_perform_login(li)); case LTYPE_LOGOUT: - return utmpx_perform_logout(li); + return (utmpx_perform_logout(li)); default: logit("utmpx_write_entry: invalid type field"); - return 0; + return (0); } } #endif /* USE_UTMPX */ @@ -1036,8 +1019,10 @@ utmpx_write_entry(struct logininfo *li) #ifdef USE_WTMP -/* write a wtmp entry direct to the end of the file */ -/* This is a slight modification of code in OpenBSD's logwtmp.c */ +/* + * Write a wtmp entry direct to the end of the file + * This is a slight modification of code in OpenBSD's logwtmp.c + */ static int wtmp_write(struct logininfo *li, struct utmp *ut) { @@ -1047,7 +1032,7 @@ wtmp_write(struct logininfo *li, struct utmp *ut) if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { logit("wtmp_write: problem writing %s: %s", WTMP_FILE, strerror(errno)); - return 0; + return (0); } if (fstat(fd, &buf) == 0) if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { @@ -1056,8 +1041,8 @@ wtmp_write(struct logininfo *li, struct utmp *ut) WTMP_FILE, strerror(errno)); ret = 0; } - (void)close(fd); - return ret; + close(fd); + return (ret); } static int @@ -1066,7 +1051,7 @@ wtmp_perform_login(struct logininfo *li) struct utmp ut; construct_utmp(li, &ut); - return wtmp_write(li, &ut); + return (wtmp_write(li, &ut)); } @@ -1076,7 +1061,7 @@ wtmp_perform_logout(struct logininfo *li) struct utmp ut; construct_utmp(li, &ut); - return wtmp_write(li, &ut); + return (wtmp_write(li, &ut)); } @@ -1085,17 +1070,18 @@ wtmp_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: - return wtmp_perform_login(li); + return (wtmp_perform_login(li)); case LTYPE_LOGOUT: - return wtmp_perform_logout(li); + return (wtmp_perform_logout(li)); default: logit("wtmp_write_entry: invalid type field"); - return 0; + return (0); } } -/* Notes on fetching login data from wtmp/wtmpx +/* + * Notes on fetching login data from wtmp/wtmpx * * Logouts are usually recorded with (amongst other things) a blank * username on a given tty line. However, some systems (HP-UX is one) @@ -1116,15 +1102,15 @@ static int wtmp_islogin(struct logininfo *li, struct utmp *ut) { if (strncmp(li->username, ut->ut_name, - MIN_SIZEOF(li->username, ut->ut_name)) == 0) { + MIN_SIZEOF(li->username, ut->ut_name)) == 0) { # ifdef HAVE_TYPE_IN_UTMP if (ut->ut_type & USER_PROCESS) - return 1; + return (1); # else - return 1; + return (1); # endif } - return 0; + return (0); } int @@ -1132,7 +1118,7 @@ wtmp_get_entry(struct logininfo *li) { struct stat st; struct utmp ut; - int fd, found=0; + int fd, found = 0; /* Clear the time entries in our logininfo */ li->tv_sec = li->tv_usec = 0; @@ -1140,20 +1126,20 @@ wtmp_get_entry(struct logininfo *li) if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { logit("wtmp_get_entry: problem opening %s: %s", WTMP_FILE, strerror(errno)); - return 0; + return (0); } if (fstat(fd, &st) != 0) { logit("wtmp_get_entry: couldn't stat %s: %s", WTMP_FILE, strerror(errno)); close(fd); - return 0; + return (0); } /* Seek to the start of the last struct utmp */ if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_END) == -1) { /* Looks like we've got a fresh wtmp file */ close(fd); - return 0; + return (0); } while (!found) { @@ -1161,12 +1147,14 @@ wtmp_get_entry(struct logininfo *li) logit("wtmp_get_entry: read of %s failed: %s", WTMP_FILE, strerror(errno)); close (fd); - return 0; + return (0); } if ( wtmp_islogin(li, &ut) ) { found = 1; - /* We've already checked for a time in struct - * utmp, in login_getlast(). */ + /* + * We've already checked for a time in struct + * utmp, in login_getlast() + */ # ifdef HAVE_TIME_IN_UTMP li->tv_sec = ut.ut_time; # else @@ -1175,24 +1163,24 @@ wtmp_get_entry(struct logininfo *li) # endif # endif line_fullname(li->line, ut.ut_line, - MIN_SIZEOF(li->line, ut.ut_line)); + MIN_SIZEOF(li->line, ut.ut_line)); # ifdef HAVE_HOST_IN_UTMP strlcpy(li->hostname, ut.ut_host, - MIN_SIZEOF(li->hostname, ut.ut_host)); + MIN_SIZEOF(li->hostname, ut.ut_host)); # endif continue; } /* Seek back 2 x struct utmp */ if (lseek(fd, -(off_t)(2 * sizeof(struct utmp)), SEEK_CUR) == -1) { /* We've found the start of the file, so quit */ - close (fd); - return 0; + close(fd); + return (0); } } /* We found an entry. Tidy up and return */ close(fd); - return 1; + return (1); } # endif /* USE_WTMP */ @@ -1202,8 +1190,10 @@ wtmp_get_entry(struct logininfo *li) **/ #ifdef USE_WTMPX -/* write a wtmpx entry direct to the end of the file */ -/* This is a slight modification of code in OpenBSD's logwtmp.c */ +/* + * Write a wtmpx entry direct to the end of the file + * This is a slight modification of code in OpenBSD's logwtmp.c + */ static int wtmpx_write(struct logininfo *li, struct utmpx *utx) { @@ -1214,7 +1204,7 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx) if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { logit("wtmpx_write: problem opening %s: %s", WTMPX_FILE, strerror(errno)); - return 0; + return (0); } if (fstat(fd, &buf) == 0) @@ -1224,12 +1214,12 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx) WTMPX_FILE, strerror(errno)); ret = 0; } - (void)close(fd); + close(fd); - return ret; + return (ret); #else updwtmpx(WTMPX_FILE, utx); - return 1; + return (1); #endif } @@ -1240,7 +1230,7 @@ wtmpx_perform_login(struct logininfo *li) struct utmpx utx; construct_utmpx(li, &utx); - return wtmpx_write(li, &utx); + return (wtmpx_write(li, &utx)); } @@ -1250,7 +1240,7 @@ wtmpx_perform_logout(struct logininfo *li) struct utmpx utx; construct_utmpx(li, &utx); - return wtmpx_write(li, &utx); + return (wtmpx_write(li, &utx)); } @@ -1259,12 +1249,12 @@ wtmpx_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: - return wtmpx_perform_login(li); + return (wtmpx_perform_login(li)); case LTYPE_LOGOUT: - return wtmpx_perform_logout(li); + return (wtmpx_perform_logout(li)); default: logit("wtmpx_write_entry: invalid type field"); - return 0; + return (0); } } @@ -1275,16 +1265,16 @@ wtmpx_write_entry(struct logininfo *li) static int wtmpx_islogin(struct logininfo *li, struct utmpx *utx) { - if ( strncmp(li->username, utx->ut_name, - MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { + if (strncmp(li->username, utx->ut_name, + MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { # ifdef HAVE_TYPE_IN_UTMPX if (utx->ut_type == USER_PROCESS) - return 1; + return (1); # else - return 1; + return (1); # endif } - return 0; + return (0); } @@ -1301,20 +1291,20 @@ wtmpx_get_entry(struct logininfo *li) if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { logit("wtmpx_get_entry: problem opening %s: %s", WTMPX_FILE, strerror(errno)); - return 0; + return (0); } if (fstat(fd, &st) != 0) { logit("wtmpx_get_entry: couldn't stat %s: %s", WTMPX_FILE, strerror(errno)); close(fd); - return 0; + return (0); } /* Seek to the start of the last struct utmpx */ if (lseek(fd, -(off_t)sizeof(struct utmpx), SEEK_END) == -1 ) { /* probably a newly rotated wtmpx file */ close(fd); - return 0; + return (0); } while (!found) { @@ -1322,34 +1312,34 @@ wtmpx_get_entry(struct logininfo *li) logit("wtmpx_get_entry: read of %s failed: %s", WTMPX_FILE, strerror(errno)); close (fd); - return 0; + return (0); } - /* Logouts are recorded as a blank username on a particular line. - * So, we just need to find the username in struct utmpx */ - if ( wtmpx_islogin(li, &utx) ) { + /* + * Logouts are recorded as a blank username on a particular + * line. So, we just need to find the username in struct utmpx + */ + if (wtmpx_islogin(li, &utx)) { found = 1; -# ifdef HAVE_TV_IN_UTMPX +# if defined(HAVE_TV_IN_UTMPX) li->tv_sec = utx.ut_tv.tv_sec; -# else -# ifdef HAVE_TIME_IN_UTMPX +# elif defined(HAVE_TIME_IN_UTMPX) li->tv_sec = utx.ut_time; -# endif # endif line_fullname(li->line, utx.ut_line, sizeof(li->line)); -# ifdef HAVE_HOST_IN_UTMPX +# if defined(HAVE_HOST_IN_UTMPX) strlcpy(li->hostname, utx.ut_host, - MIN_SIZEOF(li->hostname, utx.ut_host)); + MIN_SIZEOF(li->hostname, utx.ut_host)); # endif continue; } if (lseek(fd, -(off_t)(2 * sizeof(struct utmpx)), SEEK_CUR) == -1) { - close (fd); - return 0; + close(fd); + return (0); } } close(fd); - return 1; + return (1); } #endif /* USE_WTMPX */ @@ -1363,15 +1353,15 @@ syslogin_perform_login(struct logininfo *li) { struct utmp *ut; - if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) { + if ((ut = (struct utmp *)malloc(sizeof(*ut))) == NULL) { logit("syslogin_perform_login: couldn't malloc()"); - return 0; + return (0); } construct_utmp(li, ut); login(ut); free(ut); - return 1; + return (1); } static int @@ -1382,19 +1372,18 @@ syslogin_perform_logout(struct logininfo *li) (void)line_stripname(line, li->line, sizeof(line)); - if (!logout(line)) { + if (!logout(line)) logit("syslogin_perform_logout: logout() returned an error"); # ifdef HAVE_LOGWTMP - } else { + else logwtmp(line, "", ""); # endif - } /* FIXME: (ATL - if the need arises) What to do if we have * login, but no logout? what if logout but no logwtmp? All * routines are in libutil so they should all be there, * but... */ # endif - return 1; + return (1); } int @@ -1402,12 +1391,12 @@ syslogin_write_entry(struct logininfo *li) { switch (li->type) { case LTYPE_LOGIN: - return syslogin_perform_login(li); + return (syslogin_perform_login(li)); case LTYPE_LOGOUT: - return syslogin_perform_logout(li); + return (syslogin_perform_logout(li)); default: logit("syslogin_write_entry: Invalid type field"); - return 0; + return (0); } } #endif /* USE_LOGIN */ @@ -1429,7 +1418,7 @@ lastlog_construct(struct logininfo *li, struct lastlog *last) /* clear the structure */ memset(last, '\0', sizeof(*last)); - (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); + line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); strlcpy(last->ll_host, li->hostname, MIN_SIZEOF(last->ll_host, li->hostname)); last->ll_time = li->tv_sec; @@ -1441,16 +1430,16 @@ lastlog_filetype(char *filename) struct stat st; if (stat(LASTLOG_FILE, &st) != 0) { - logit("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, - strerror(errno)); - return 0; + logit("lastlog_perform_login: Couldn't stat %s: %s", + LASTLOG_FILE, strerror(errno)); + return (0); } if (S_ISDIR(st.st_mode)) - return LL_DIR; + return (LL_DIR); else if (S_ISREG(st.st_mode)) - return LL_FILE; + return (LL_FILE); else - return LL_OTHER; + return (LL_OTHER); } @@ -1464,38 +1453,39 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) type = lastlog_filetype(LASTLOG_FILE); switch (type) { - case LL_FILE: - strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); - break; - case LL_DIR: - snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", - LASTLOG_FILE, li->username); - break; - default: - logit("lastlog_openseek: %.100s is not a file or directory!", - LASTLOG_FILE); - return 0; + case LL_FILE: + strlcpy(lastlog_file, LASTLOG_FILE, + sizeof(lastlog_file)); + break; + case LL_DIR: + snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", + LASTLOG_FILE, li->username); + break; + default: + logit("lastlog_openseek: %.100s is not a file or directory!", + LASTLOG_FILE); + return (0); } *fd = open(lastlog_file, filemode, 0600); - if ( *fd < 0) { + if (*fd < 0) { debug("lastlog_openseek: Couldn't open %s: %s", lastlog_file, strerror(errno)); - return 0; + return (0); } if (type == LL_FILE) { /* find this uid's offset in the lastlog file */ offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); - if ( lseek(*fd, offset, SEEK_SET) != offset ) { + if (lseek(*fd, offset, SEEK_SET) != offset) { logit("lastlog_openseek: %s->lseek(): %s", lastlog_file, strerror(errno)); - return 0; + return (0); } } - return 1; + return (1); } static int @@ -1508,18 +1498,18 @@ lastlog_perform_login(struct logininfo *li) lastlog_construct(li, &last); if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) - return(0); + return (0); /* write the entry */ if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); logit("lastlog_write_filemode: Error writing to %s: %s", LASTLOG_FILE, strerror(errno)); - return 0; + return (0); } close(fd); - return 1; + return (1); } int @@ -1527,10 +1517,10 @@ lastlog_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: - return lastlog_perform_login(li); + return (lastlog_perform_login(li)); default: logit("lastlog_write_entry: Invalid type field"); - return 0; + return (0); } } @@ -1539,7 +1529,7 @@ lastlog_populate_entry(struct logininfo *li, struct lastlog *last) { line_fullname(li->line, last->ll_line, sizeof(li->line)); strlcpy(li->hostname, last->ll_host, - MIN_SIZEOF(li->hostname, last->ll_host)); + MIN_SIZEOF(li->hostname, last->ll_host)); li->tv_sec = last->ll_time; } -- cgit v1.2.3 From 6b0279c084f93a1e36ad648fd428297cc728cd35 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 12 Sep 2004 15:25:17 +1000 Subject: - (djm) [loginrec.c] __func__ifiy --- ChangeLog | 3 ++- loginrec.c | 68 +++++++++++++++++++++++++++++++------------------------------- 2 files changed, 36 insertions(+), 35 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index 8890e6235..bddbf611c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 20040912 - (djm) [loginrec.c] Start KNF and tidy up of this long-neglected file. No change in resultant binary + - (djm) [loginrec.c] __func__ifiy 20040911 - (djm) [ssh-agent.c] unifdef some cygwin code; ok dtucker@ @@ -1738,4 +1739,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3548 2004/09/12 05:23:14 djm Exp $ +$Id: ChangeLog,v 1.3549 2004/09/12 05:25:17 djm Exp $ diff --git a/loginrec.c b/loginrec.c index 8d48fb99f..e6b70f58c 100644 --- a/loginrec.c +++ b/loginrec.c @@ -140,7 +140,7 @@ # include #endif -RCSID("$Id: loginrec.c,v 1.60 2004/09/12 05:18:55 djm Exp $"); +RCSID("$Id: loginrec.c,v 1.61 2004/09/12 05:25:17 djm Exp $"); /** ** prototypes for helper functions in this file @@ -266,7 +266,7 @@ login_get_lastlog(struct logininfo *li, const int uid) */ pw = getpwuid(uid); if (pw == NULL) - fatal("login_get_lastlog: Cannot find account for uid %i", uid); + fatal("%s: Cannot find account for uid %i", __func__, uid); /* No MIN_SIZEOF here - we absolutely *must not* truncate the * username (XXX - so check for trunc!) */ @@ -335,7 +335,7 @@ login_init_entry(struct logininfo *li, int pid, const char *username, strlcpy(li->username, username, sizeof(li->username)); pw = getpwnam(li->username); if (pw == NULL) { - fatal("login_init_entry: Cannot find user \"%s\"", + fatal("%s: Cannot find user \"%s\"", __func__, li->username); } li->uid = pw->pw_uid; @@ -864,12 +864,12 @@ utmp_perform_login(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - logit("utmp_perform_login: utmp_write_library() failed"); + logit("%s: utmp_write_library() failed", __func__); return (0); } # else if (!utmp_write_direct(li, &ut)) { - logit("utmp_perform_login: utmp_write_direct() failed"); + logit("%s: utmp_write_direct() failed", __func__); return (0); } # endif @@ -885,12 +885,12 @@ utmp_perform_logout(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - logit("utmp_perform_logout: utmp_write_library() failed"); + logit("%s: utmp_write_library() failed", __func__); return (0); } # else if (!utmp_write_direct(li, &ut)) { - logit("utmp_perform_logout: utmp_write_direct() failed"); + logit("%s: utmp_write_direct() failed", __func__); return (0); } # endif @@ -909,7 +909,7 @@ utmp_write_entry(struct logininfo *li) return (utmp_perform_logout(li)); default: - logit("utmp_write_entry: invalid type field"); + logit("%s: invalid type field", __func__); return (0); } } @@ -950,7 +950,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx) static int utmpx_write_direct(struct logininfo *li, struct utmpx *utx) { - logit("utmpx_write_direct: not implemented!"); + logit("%s: not implemented!", __func__); return (0); } # endif /* UTMPX_USE_LIBRARY */ @@ -963,12 +963,12 @@ utmpx_perform_login(struct logininfo *li) construct_utmpx(li, &utx); # ifdef UTMPX_USE_LIBRARY if (!utmpx_write_library(li, &utx)) { - logit("utmpx_perform_login: utmp_write_library() failed"); + logit("%s: utmp_write_library() failed", __func__); return (0); } # else if (!utmpx_write_direct(li, &ut)) { - logit("utmpx_perform_login: utmp_write_direct() failed"); + logit("%s: utmp_write_direct() failed", __func__); return (0); } # endif @@ -1006,7 +1006,7 @@ utmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (utmpx_perform_logout(li)); default: - logit("utmpx_write_entry: invalid type field"); + logit("%s: invalid type field", __func__); return (0); } } @@ -1030,14 +1030,14 @@ wtmp_write(struct logininfo *li, struct utmp *ut) int fd, ret = 1; if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { - logit("wtmp_write: problem writing %s: %s", + logit("%s: problem writing %s: %s", __func__, WTMP_FILE, strerror(errno)); return (0); } if (fstat(fd, &buf) == 0) if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { ftruncate(fd, buf.st_size); - logit("wtmp_write: problem writing %s: %s", + logit("%s: problem writing %s: %s", __func__, WTMP_FILE, strerror(errno)); ret = 0; } @@ -1074,7 +1074,7 @@ wtmp_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (wtmp_perform_logout(li)); default: - logit("wtmp_write_entry: invalid type field"); + logit("%s: invalid type field", __func__); return (0); } } @@ -1124,12 +1124,12 @@ wtmp_get_entry(struct logininfo *li) li->tv_sec = li->tv_usec = 0; if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { - logit("wtmp_get_entry: problem opening %s: %s", + logit("%s: problem opening %s: %s", __func__, WTMP_FILE, strerror(errno)); return (0); } if (fstat(fd, &st) != 0) { - logit("wtmp_get_entry: couldn't stat %s: %s", + logit("%s: couldn't stat %s: %s", __func__, WTMP_FILE, strerror(errno)); close(fd); return (0); @@ -1144,7 +1144,7 @@ wtmp_get_entry(struct logininfo *li) while (!found) { if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { - logit("wtmp_get_entry: read of %s failed: %s", + logit("%s: read of %s failed: %s", __func__, WTMP_FILE, strerror(errno)); close (fd); return (0); @@ -1202,7 +1202,7 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx) int fd, ret = 1; if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { - logit("wtmpx_write: problem opening %s: %s", + logit("%s: problem opening %s: %s", __func__, WTMPX_FILE, strerror(errno)); return (0); } @@ -1210,7 +1210,7 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx) if (fstat(fd, &buf) == 0) if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) { ftruncate(fd, buf.st_size); - logit("wtmpx_write: problem writing %s: %s", + logit("%s: problem writing %s: %s", __func__, WTMPX_FILE, strerror(errno)); ret = 0; } @@ -1253,7 +1253,7 @@ wtmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (wtmpx_perform_logout(li)); default: - logit("wtmpx_write_entry: invalid type field"); + logit("%s: invalid type field", __func__); return (0); } } @@ -1289,12 +1289,12 @@ wtmpx_get_entry(struct logininfo *li) li->tv_sec = li->tv_usec = 0; if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { - logit("wtmpx_get_entry: problem opening %s: %s", + logit("%s: problem opening %s: %s", __func__, WTMPX_FILE, strerror(errno)); return (0); } if (fstat(fd, &st) != 0) { - logit("wtmpx_get_entry: couldn't stat %s: %s", + logit("%s: couldn't stat %s: %s", __func__, WTMPX_FILE, strerror(errno)); close(fd); return (0); @@ -1309,7 +1309,7 @@ wtmpx_get_entry(struct logininfo *li) while (!found) { if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { - logit("wtmpx_get_entry: read of %s failed: %s", + logit("%s: read of %s failed: %s", __func__, WTMPX_FILE, strerror(errno)); close (fd); return (0); @@ -1354,7 +1354,7 @@ syslogin_perform_login(struct logininfo *li) struct utmp *ut; if ((ut = (struct utmp *)malloc(sizeof(*ut))) == NULL) { - logit("syslogin_perform_login: couldn't malloc()"); + logit("%s: couldn't malloc()", __func__); return (0); } construct_utmp(li, ut); @@ -1373,7 +1373,7 @@ syslogin_perform_logout(struct logininfo *li) (void)line_stripname(line, li->line, sizeof(line)); if (!logout(line)) - logit("syslogin_perform_logout: logout() returned an error"); + logit("%s: logout() returned an error", __func__); # ifdef HAVE_LOGWTMP else logwtmp(line, "", ""); @@ -1395,7 +1395,7 @@ syslogin_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (syslogin_perform_logout(li)); default: - logit("syslogin_write_entry: Invalid type field"); + logit("%s: Invalid type field", __func__); return (0); } } @@ -1430,7 +1430,7 @@ lastlog_filetype(char *filename) struct stat st; if (stat(LASTLOG_FILE, &st) != 0) { - logit("lastlog_perform_login: Couldn't stat %s: %s", + logit("%s: Couldn't stat %s: %s", __func__, LASTLOG_FILE, strerror(errno)); return (0); } @@ -1462,14 +1462,14 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) LASTLOG_FILE, li->username); break; default: - logit("lastlog_openseek: %.100s is not a file or directory!", + logit("%s: %.100s is not a file or directory!", __func__, LASTLOG_FILE); return (0); } *fd = open(lastlog_file, filemode, 0600); if (*fd < 0) { - debug("lastlog_openseek: Couldn't open %s: %s", + debug("%s: Couldn't open %s: %s", __func__, lastlog_file, strerror(errno)); return (0); } @@ -1479,8 +1479,8 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); if (lseek(*fd, offset, SEEK_SET) != offset) { - logit("lastlog_openseek: %s->lseek(): %s", - lastlog_file, strerror(errno)); + logit("%s: %s->lseek(): %s", __func__, + lastlog_file, strerror(errno)); return (0); } } @@ -1503,7 +1503,7 @@ lastlog_perform_login(struct logininfo *li) /* write the entry */ if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); - logit("lastlog_write_filemode: Error writing to %s: %s", + logit("%s: Error writing to %s: %s", __func__, LASTLOG_FILE, strerror(errno)); return (0); } @@ -1519,7 +1519,7 @@ lastlog_write_entry(struct logininfo *li) case LTYPE_LOGIN: return (lastlog_perform_login(li)); default: - logit("lastlog_write_entry: Invalid type field"); + logit("%s: Invalid type field", __func__); return (0); } } -- cgit v1.2.3 From b0aae333fdecf769da6e693e63d6905713bc0fe6 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 12 Sep 2004 15:26:00 +1000 Subject: - (djm) [loginrec.c] xmalloc --- ChangeLog | 3 ++- loginrec.c | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index bddbf611c..e1cf4153f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - (djm) [loginrec.c] Start KNF and tidy up of this long-neglected file. No change in resultant binary - (djm) [loginrec.c] __func__ifiy + - (djm) [loginrec.c] xmalloc 20040911 - (djm) [ssh-agent.c] unifdef some cygwin code; ok dtucker@ @@ -1739,4 +1740,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3549 2004/09/12 05:25:17 djm Exp $ +$Id: ChangeLog,v 1.3550 2004/09/12 05:26:00 djm Exp $ diff --git a/loginrec.c b/loginrec.c index e6b70f58c..25aa29f2f 100644 --- a/loginrec.c +++ b/loginrec.c @@ -140,7 +140,7 @@ # include #endif -RCSID("$Id: loginrec.c,v 1.61 2004/09/12 05:25:17 djm Exp $"); +RCSID("$Id: loginrec.c,v 1.62 2004/09/12 05:26:01 djm Exp $"); /** ** prototypes for helper functions in this file @@ -1353,10 +1353,7 @@ syslogin_perform_login(struct logininfo *li) { struct utmp *ut; - if ((ut = (struct utmp *)malloc(sizeof(*ut))) == NULL) { - logit("%s: couldn't malloc()", __func__); - return (0); - } + ut = xmalloc(sizeof(*ut)); construct_utmp(li, ut); login(ut); free(ut); -- cgit v1.2.3 From 2fba993080eba14e339d6a6666ee79580ee20f97 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 2 Feb 2005 23:30:24 +1100 Subject: - (dtucker) [auth.c canohost.c canohost.h configure.ac defines.h loginrec.c] Bug #974: Teach sshd to write failed login records to btmp for failed auth attempts (currently only for password, kbdint and C/R, only on Linux and HP-UX), based on code from login.c from util-linux. With ashok_kovai at hotmail.com, ok djm@ --- ChangeLog | 7 +++- auth.c | 5 ++- canohost.c | 3 +- canohost.h | 2 ++ configure.ac | 5 ++- defines.h | 11 ++++++- loginrec.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 130 insertions(+), 7 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index d9670f361..07ae663d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,11 @@ the process. Since we also unset KRB5CCNAME at startup, if it's set after authentication it must have been set by the platform's native auth system. This was already done for AIX; this enables it for the general case. + - (dtucker) [auth.c canohost.c canohost.h configure.ac defines.h loginrec.c] + Bug #974: Teach sshd to write failed login records to btmp for failed auth + attempts (currently only for password, kbdint and C/R, only on Linux and + HP-UX), based on code from login.c from util-linux. With ashok_kovai at + hotmail.com, ok djm@ 20050201 - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some @@ -2063,4 +2068,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3631 2005/02/02 07:30:33 dtucker Exp $ +$Id: ChangeLog,v 1.3632 2005/02/02 12:30:24 dtucker Exp $ diff --git a/auth.c b/auth.c index dfc1be374..b6c00c12b 100644 --- a/auth.c +++ b/auth.c @@ -244,7 +244,10 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) 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 diff --git a/canohost.c b/canohost.c index 8ad684d6c..e5a6b6be3 100644 --- a/canohost.c +++ b/canohost.c @@ -20,7 +20,6 @@ RCSID("$OpenBSD: canohost.c,v 1.41 2004/07/21 11:51:29 djm Exp $"); #include "canohost.h" static void check_ip_options(int, char *); -static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); /* * Return the canonical name of the host at the other end of the socket. The @@ -166,7 +165,7 @@ check_ip_options(int sock, char *ipaddr) #endif /* IP_OPTIONS */ } -static void +void ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; diff --git a/canohost.h b/canohost.h index 4347b488a..df1f125e5 100644 --- a/canohost.h +++ b/canohost.h @@ -23,3 +23,5 @@ char *get_local_name(int); int get_remote_port(void); int get_local_port(void); + +void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff --git a/configure.ac b/configure.ac index 94d6b1e78..86b26daf9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.236 2005/02/01 23:44:00 dtucker Exp $ +# $Id: configure.ac,v 1.237 2005/02/02 12:30:25 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -219,6 +219,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(DISABLE_UTMP) AC_DEFINE(LOCKED_PASSWD_STRING, "*") AC_DEFINE(SPT_TYPE,SPT_PSTAT) + AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins]) check_for_hpux_broken_getaddrinfo=1 check_for_conflicting_getspnam=1 LIBS="$LIBS -lsec" @@ -256,6 +257,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(LOCKED_PASSWD_PREFIX, "!") AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) AC_DEFINE(LINK_OPNOTSUPP_ERRNO, EPERM) + AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts]) + AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins]) inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) diff --git a/defines.h b/defines.h index 8c1d9c409..4d59408ad 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.117 2004/06/22 03:27:16 dtucker Exp $ */ +/* $Id: defines.h,v 1.118 2005/02/02 12:30:25 dtucker Exp $ */ /* Constants */ @@ -644,6 +644,15 @@ struct winsize { # define CUSTOM_SYS_AUTH_PASSWD 1 #endif +/* HP-UX 11.11 */ +#ifdef BTMP_FILE +# define _PATH_BTMP BTMP_FILE +#endif + +#if defined(USE_BTMP) && defined(_PATH_BTMP) +# define CUSTOM_FAILED_LOGIN +#endif + /** end of login recorder definitions */ #endif /* _DEFINES_H */ diff --git a/loginrec.c b/loginrec.c index 25aa29f2f..e77318ba3 100644 --- a/loginrec.c +++ b/loginrec.c @@ -25,6 +25,27 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * The btmp logging code is derived from login.c from util-linux and is under + * the the following license: + * + * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + /** ** loginrec.c: platform-independent login recording and lastlog retrieval **/ @@ -131,6 +152,8 @@ #include "loginrec.h" #include "log.h" #include "atomicio.h" +#include "packet.h" +#include "canohost.h" #ifdef HAVE_UTIL_H # include @@ -140,7 +163,7 @@ # include #endif -RCSID("$Id: loginrec.c,v 1.62 2004/09/12 05:26:01 djm Exp $"); +RCSID("$Id: loginrec.c,v 1.63 2005/02/02 12:30:25 dtucker Exp $"); /** ** prototypes for helper functions in this file @@ -1563,3 +1586,82 @@ lastlog_get_entry(struct logininfo *li) return (0); } #endif /* USE_LASTLOG */ + +#ifdef USE_BTMP + /* + * Logs failed login attempts in _PATH_BTMP if that exists. + * The most common login failure is to give password instead of username. + * So the _PATH_BTMP file checked for the correct permission, so that + * only root can read it. + */ + +void +record_failed_login(const char *username, const char *hostname, + const char *ttyn) +{ + int fd; + struct utmp ut; + struct sockaddr_storage from; + size_t fromlen = sizeof(from); + struct sockaddr_in *a4; + struct sockaddr_in6 *a6; + time_t t; + struct stat fst; + + if (geteuid() != 0) + return; + if ((fd = open(_PATH_BTMP, O_WRONLY | O_APPEND)) < 0) { + debug("Unable to open the btmp file %s: %s", _PATH_BTMP, + strerror(errno)); + return; + } + if (fstat(fd, &fst) < 0) { + logit("%s: fstat of %s failed: %s", __func__, _PATH_BTMP, + strerror(errno)); + goto out; + } + if((fst.st_mode & (S_IRWXG | S_IRWXO)) || (fst.st_uid != 0)){ + logit("Excess permission or bad ownership on file %s", + _PATH_BTMP); + goto out; + } + + memset(&ut, 0, sizeof(ut)); + /* strncpy because we don't necessarily want nul termination */ + strncpy(ut.ut_user, username, sizeof(ut.ut_user)); + strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); + + time(&t); + ut.ut_time = t; /* ut_time is not always a time_t */ + ut.ut_type = LOGIN_PROCESS; + ut.ut_pid = getpid(); + + /* strncpy because we don't necessarily want nul termination */ + strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); + + if (packet_connection_is_on_socket() && + getpeername(packet_get_connection_in(), + (struct sockaddr *)&from, &fromlen) == 0) { + ipv64_normalise_mapped(&from, &fromlen); + if (from.ss_family == AF_INET) { + a4 = (struct sockaddr_in *)&from; + memcpy(&ut.ut_addr, &(a4->sin_addr), + MIN_SIZEOF(ut.ut_addr, a4->sin_addr)); + } +#ifdef HAVE_ADDR_V6_IN_UTMP + if (from.ss_family == AF_INET6) { + a6 = (struct sockaddr_in6 *)&from; + memcpy(&ut.ut_addr_v6, &(a6->sin6_addr), + MIN_SIZEOF(ut.ut_addr_v6, a6->sin6_addr)); + } +#endif + } + + if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut)) + error("Failed to write to %s: %s", _PATH_BTMP, + strerror(errno)); + +out: + close(fd); +} +#endif /* USE_BTMP */ -- cgit v1.2.3 From 269a1ea1c80a855d1eb74fccba6dd5c75947c5d2 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Thu, 3 Feb 2005 00:20:53 +1100 Subject: - (dtucker) [Makefile.in auth.c auth.h auth1.c auth2.c loginrec.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h session.c sshd.c] Bug #125: (first stage) Add audit instrumentation to sshd, currently disabled by default. with suggestions from and djm@ --- ChangeLog | 6 +++++- Makefile.in | 4 ++-- auth.c | 42 +++++++++++++++++++++++++++++++++++++ auth.h | 1 + auth1.c | 12 +++++++++-- auth2.c | 15 ++++++++++++-- loginrec.c | 9 +++++++- monitor.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ monitor.h | 1 + monitor_wrap.c | 30 +++++++++++++++++++++++++++ monitor_wrap.h | 6 ++++++ session.c | 16 +++++++++++++++ sshd.c | 12 +++++++++++ 13 files changed, 211 insertions(+), 8 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index 07ae663d7..e2dc30e5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,10 @@ attempts (currently only for password, kbdint and C/R, only on Linux and HP-UX), based on code from login.c from util-linux. With ashok_kovai at hotmail.com, ok djm@ + - (dtucker) [Makefile.in auth.c auth.h auth1.c auth2.c loginrec.c monitor.c + monitor.h monitor_wrap.c monitor_wrap.h session.c sshd.c] Bug #125: + (first stage) Add audit instrumentation to sshd, currently disabled by + default. with suggestions from and djm@ 20050201 - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some @@ -2068,4 +2072,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3632 2005/02/02 12:30:24 dtucker Exp $ +$Id: ChangeLog,v 1.3633 2005/02/02 13:20:53 dtucker Exp $ diff --git a/Makefile.in b/Makefile.in index 8a1c9f7c0..c6cfef11a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.267 2005/01/18 01:05:18 dtucker Exp $ +# $Id: Makefile.in,v 1.268 2005/02/02 13:20:53 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -85,7 +85,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o + loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o audit.o MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 diff --git a/auth.c b/auth.c index b6c00c12b..bbf3a54a4 100644 --- a/auth.c +++ b/auth.c @@ -51,6 +51,7 @@ RCSID("$OpenBSD: auth.c,v 1.57 2005/01/22 08:17:59 dtucker Exp $"); #include "bufaux.h" #include "packet.h" #include "loginrec.h" +#include "monitor_wrap.h" /* import */ extern ServerOptions options; @@ -251,6 +252,44 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) record_failed_login(authctxt->user, get_canonical_hostname(options.use_dns), "ssh"); #endif +#ifdef 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 AUTH_FAIL_NONE: + case AUTH_FAIL_PASSWD: + case AUTH_FAIL_KBDINT: + if (geteuid() == 0) + audit_event(event); + break; + case AUTH_FAIL_PUBKEY: + case AUTH_FAIL_HOSTBASED: + case 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); + } + } +#endif } /* @@ -476,6 +515,9 @@ getpwnamallow(const char *user) record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); #endif +#ifdef AUDIT_EVENTS + audit_event(INVALID_USER); +#endif /* AUDIT_EVENTS */ return (NULL); } if (!allowed_user(pw)) diff --git a/auth.h b/auth.h index 6c0089dc7..8d1f93403 100644 --- a/auth.h +++ b/auth.h @@ -130,6 +130,7 @@ int auth_shadow_pwexpired(Authctxt *); #endif #include "auth-pam.h" +#include "audit.h" void remove_kbdint_device(const char *); void disable_forwarding(void); diff --git a/auth1.c b/auth1.c index 2a9d18b9a..aeb5d8cb9 100644 --- a/auth1.c +++ b/auth1.c @@ -247,8 +247,12 @@ do_authloop(Authctxt *authctxt) #else /* Special handling for root */ if (authenticated && authctxt->pw->pw_uid == 0 && - !auth_root_allowed(get_authname(type))) + !auth_root_allowed(get_authname(type))) { authenticated = 0; +# ifdef AUDIT_EVENTS + PRIVSEP(audit_event(LOGIN_ROOT_DENIED)); +# endif + } #endif #ifdef USE_PAM @@ -283,8 +287,12 @@ do_authloop(Authctxt *authctxt) if (authenticated) return; - if (authctxt->failures++ > options.max_authtries) + if (authctxt->failures++ > options.max_authtries) { +#ifdef AUDIT_EVENTS + PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES)); +#endif packet_disconnect(AUTH_FAIL_MSG, authctxt->user); + } packet_start(SSH_SMSG_FAILURE); packet_send(); diff --git a/auth2.c b/auth2.c index 60e261f7f..2727e0ff5 100644 --- a/auth2.c +++ b/auth2.c @@ -166,6 +166,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(authctxt)); +#endif +#ifdef AUDIT_EVENTS + PRIVSEP(audit_event(INVALID_USER)); #endif } setproctitle("%s%s", authctxt->valid ? user : "unknown", @@ -214,8 +217,12 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) /* Special handling for root */ if (authenticated && authctxt->pw->pw_uid == 0 && - !auth_root_allowed(method)) + !auth_root_allowed(method)) { authenticated = 0; +#ifdef AUDIT_EVENTS + PRIVSEP(audit_event(LOGIN_ROOT_DENIED)); +#endif + } #ifdef USE_PAM if (options.use_pam && authenticated) { @@ -255,8 +262,12 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) /* now we can break out */ authctxt->success = 1; } else { - if (authctxt->failures++ > options.max_authtries) + if (authctxt->failures++ > options.max_authtries) { +#ifdef AUDIT_EVENTS + PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES)); +#endif packet_disconnect(AUTH_FAIL_MSG, authctxt->user); + } methods = authmethods_get(); packet_start(SSH2_MSG_USERAUTH_FAILURE); packet_put_cstring(methods); diff --git a/loginrec.c b/loginrec.c index e77318ba3..0fa9bdea7 100644 --- a/loginrec.c +++ b/loginrec.c @@ -154,6 +154,7 @@ #include "atomicio.h" #include "packet.h" #include "canohost.h" +#include "auth.h" #ifdef HAVE_UTIL_H # include @@ -163,7 +164,7 @@ # include #endif -RCSID("$Id: loginrec.c,v 1.63 2005/02/02 12:30:25 dtucker Exp $"); +RCSID("$Id: loginrec.c,v 1.64 2005/02/02 13:20:53 dtucker Exp $"); /** ** prototypes for helper functions in this file @@ -442,6 +443,12 @@ login_write(struct logininfo *li) if (li->type == LTYPE_LOGIN && !sys_auth_record_login(li->username,li->hostname,li->line)) logit("Writing login record failed for %s", li->username); +#endif +#ifdef AUDIT_EVENTS + if (li->type == LTYPE_LOGIN) + audit_session_open(li->line); + else if (li->type == LTYPE_LOGOUT) + audit_session_close(li->line); #endif return (0); } diff --git a/monitor.c b/monitor.c index 00d4a785f..ce7784aa1 100644 --- a/monitor.c +++ b/monitor.c @@ -143,6 +143,11 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); #endif +#ifdef AUDIT_EVENTS +int mm_answer_audit_event(int, Buffer *); +int mm_answer_audit_command(int, Buffer *); +#endif + static Authctxt *authctxt; static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ @@ -186,6 +191,9 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif +#ifdef AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event}, +#endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, @@ -211,6 +219,10 @@ struct mon_table mon_dispatch_postauth20[] = { {MONITOR_REQ_PTY, 0, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, +#ifdef AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, +#endif {0, 0, NULL} }; @@ -238,6 +250,9 @@ struct mon_table mon_dispatch_proto15[] = { {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, +#endif +#ifdef AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event}, #endif {0, 0, NULL} }; @@ -246,6 +261,10 @@ struct mon_table mon_dispatch_postauth15[] = { {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, +#ifdef AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, +#endif {0, 0, NULL} }; @@ -609,6 +628,9 @@ mm_answer_pwnamallow(int sock, Buffer *m) if (options.use_pam) monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif +#ifdef AUDIT_EVENTS + monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_EVENT, 1); +#endif return (0); } @@ -1491,6 +1513,49 @@ mm_answer_term(int sock, Buffer *req) exit(res); } +#ifdef AUDIT_EVENTS +/* Report that an audit event occurred */ +int +mm_answer_audit_event(int socket, Buffer *m) +{ + ssh_audit_event_t event; + + debug3("%s entering", __func__); + + event = buffer_get_int(m); + buffer_free(m); + switch(event) { + case AUTH_FAIL_PUBKEY: + case AUTH_FAIL_HOSTBASED: + case AUTH_FAIL_GSSAPI: + case LOGIN_EXCEED_MAXTRIES: + case LOGIN_ROOT_DENIED: + case CONNECTION_CLOSE: + audit_event(event); + break; + default: + fatal("Audit event type %d not permitted", event); + } + + return (0); +} + +int +mm_answer_audit_command(int socket, Buffer *m) +{ + u_int len; + char *cmd; + + debug3("%s entering", __func__); + cmd = buffer_get_string(m, &len); + /* sanity check command, if so how? */ + audit_run_command(cmd); + xfree(cmd); + buffer_free(m); + return (0); +} +#endif /* AUDIT_EVENTS */ + void monitor_apply_keystate(struct monitor *pmonitor) { diff --git a/monitor.h b/monitor.h index 621a4ad18..13ce3e1ca 100644 --- a/monitor.h +++ b/monitor.h @@ -59,6 +59,7 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX, + MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND, MONITOR_REQ_TERM }; diff --git a/monitor_wrap.c b/monitor_wrap.c index 23857639b..983b24072 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1103,6 +1103,36 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) return (success); } +#ifdef AUDIT_EVENTS +void +mm_audit_event(ssh_audit_event_t event) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + buffer_put_int(&m, event); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m); + buffer_free(&m); +} + +void +mm_audit_run_command(const char *command) +{ + Buffer m; + + debug3("%s entering command %s", __func__, command); + + buffer_init(&m); + buffer_put_cstring(&m, command); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); + buffer_free(&m); +} +#endif /* AUDIT_EVENTS */ + #ifdef GSSAPI OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) diff --git a/monitor_wrap.h b/monitor_wrap.h index e5cf5718c..7ed241aa8 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -74,6 +74,12 @@ int mm_sshpam_respond(void *, u_int, char **); void mm_sshpam_free_ctx(void *); #endif +#ifdef AUDIT_EVENTS +#include "audit.h" +void mm_audit_event(ssh_audit_event_t); +void mm_audit_run_command(const char *); +#endif + struct Session; void mm_terminate(void); int mm_pty_allocate(int *, int *, char *, int); diff --git a/session.c b/session.c index 4d7ac9de7..b645144c5 100644 --- a/session.c +++ b/session.c @@ -665,6 +665,18 @@ do_exec(Session *s, const char *command) debug("Forced command '%.900s'", command); } +#ifdef AUDIT_EVENTS + if (command != NULL) + PRIVSEP(audit_run_command(command)); + else if (s->ttyfd == -1) { + char *shell = s->pw->pw_shell; + + if (shell[0] == '\0') /* empty shell means /bin/sh */ + shell =_PATH_BSHELL; + PRIVSEP(audit_run_command(shell)); + } +#endif + #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(s->pw); @@ -2321,6 +2333,10 @@ do_cleanup(Authctxt *authctxt) } #endif +#ifdef AUDIT_EVENTS + PRIVSEP(audit_event(CONNECTION_CLOSE)); +#endif + /* remove agent socket */ auth_sock_cleanup_proc(authctxt->pw); diff --git a/sshd.c b/sshd.c index 23d6962c0..e61870ea5 100644 --- a/sshd.c +++ b/sshd.c @@ -1628,6 +1628,9 @@ main(int ac, char **av) remote_port = get_remote_port(); remote_ip = get_remote_ipaddr(); +#ifdef AUDIT_EVENTS + audit_connection_from(remote_ip, remote_port); +#endif #ifdef LIBWRAP /* Check whether logins are denied from this host. */ if (packet_connection_is_on_socket()) { @@ -1697,6 +1700,10 @@ main(int ac, char **av) } authenticated: +#ifdef AUDIT_EVENTS + audit_event(AUTH_SUCCESS); +#endif + /* * In privilege separation, we fork another child and prepare * file descriptor passing. @@ -2010,5 +2017,10 @@ cleanup_exit(int i) { if (the_authctxt) do_cleanup(the_authctxt); +#ifdef AUDIT_EVENTS + /* done after do_cleanup so it can cancel the PAM auth 'thread' */ + if (!use_privsep || mm_is_monitor()) + audit_event(CONNECTION_ABANDON); +#endif _exit(i); } -- cgit v1.2.3 From 2e0cf0dca20e56eb5d95a80ba0004769c5bc4ba7 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 8 Feb 2005 21:52:47 +1100 Subject: - (dtucker) [audit.c audit.h auth.c auth1.c auth2.c loginrec.c monitor.c monitor_wrap.c monitor_wrap.h session.c sshd.c]: Prepend all of the audit defines and enums with SSH_ to prevent namespace collisions on some platforms (eg AIX). --- ChangeLog | 6 +++++- audit.c | 56 ++++++++++++++++++++++++++++---------------------------- audit.h | 30 +++++++++++++++--------------- auth.c | 20 ++++++++++---------- auth1.c | 8 ++++---- auth2.c | 12 ++++++------ loginrec.c | 4 ++-- monitor.c | 30 +++++++++++++++--------------- monitor_wrap.c | 4 ++-- monitor_wrap.h | 2 +- session.c | 6 +++--- sshd.c | 10 +++++----- 12 files changed, 96 insertions(+), 92 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index 89424da03..60e5374ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,10 @@ regress tests so newer versions of GNU head(1) behave themselves. Patch by djm, so ok me. - (dtucker) [openbsd-compat/port-aix.c] Silence compiler warnings. + - (dtucker) [audit.c audit.h auth.c auth1.c auth2.c loginrec.c monitor.c + monitor_wrap.c monitor_wrap.h session.c sshd.c]: Prepend all of the audit + defines and enums with SSH_ to prevent namespace collisions on some + platforms (eg AIX). 20050204 - (dtucker) [monitor.c] Permit INVALID_USER audit events from slave too. @@ -2082,4 +2086,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3638 2005/02/08 10:06:55 dtucker Exp $ +$Id: ChangeLog,v 1.3639 2005/02/08 10:52:47 dtucker Exp $ diff --git a/audit.c b/audit.c index 13852a05e..18fc41047 100644 --- a/audit.c +++ b/audit.c @@ -1,4 +1,4 @@ -/* $Id: audit.c,v 1.1 2005/02/02 13:37:14 dtucker Exp $ */ +/* $Id: audit.c,v 1.2 2005/02/08 10:52:48 dtucker Exp $ */ /* * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. @@ -26,7 +26,7 @@ #include "includes.h" -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS #include "audit.h" #include "log.h" @@ -44,22 +44,22 @@ ssh_audit_event_t audit_classify_auth(const char *method) { if (strcmp(method, "none") == 0) - return AUTH_FAIL_NONE; + return SSH_AUTH_FAIL_NONE; else if (strcmp(method, "password") == 0) - return AUTH_FAIL_PASSWD; + return SSH_AUTH_FAIL_PASSWD; else if (strcmp(method, "publickey") == 0 || strcmp(method, "rsa") == 0) - return AUTH_FAIL_PUBKEY; + return SSH_AUTH_FAIL_PUBKEY; else if (strncmp(method, "keyboard-interactive", 20) == 0 || strcmp(method, "challenge-response") == 0) - return AUTH_FAIL_KBDINT; + return SSH_AUTH_FAIL_KBDINT; else if (strcmp(method, "hostbased") == 0 || strcmp(method, "rhosts-rsa") == 0) - return AUTH_FAIL_HOSTBASED; + return SSH_AUTH_FAIL_HOSTBASED; else if (strcmp(method, "gssapi-with-mic") == 0) - return AUTH_FAIL_GSSAPI; + return SSH_AUTH_FAIL_GSSAPI; else - return AUDIT_UNKNOWN; + return SSH_AUDIT_UNKNOWN; } /* helper to return supplied username */ @@ -84,32 +84,32 @@ audit_event_lookup(ssh_audit_event_t ev) ssh_audit_event_t event; const char *name; } event_lookup[] = { - {LOGIN_EXCEED_MAXTRIES, "LOGIN_EXCEED_MAXTRIES"}, - {LOGIN_ROOT_DENIED, "LOGIN_ROOT_DENIED"}, - {AUTH_SUCCESS, "AUTH_SUCCESS"}, - {AUTH_FAIL_NONE, "AUTH_FAIL_NONE"}, - {AUTH_FAIL_PASSWD, "AUTH_FAIL_PASSWD"}, - {AUTH_FAIL_KBDINT, "AUTH_FAIL_KBDINT"}, - {AUTH_FAIL_PUBKEY, "AUTH_FAIL_PUBKEY"}, - {AUTH_FAIL_HOSTBASED, "AUTH_FAIL_HOSTBASED"}, - {AUTH_FAIL_GSSAPI, "AUTH_FAIL_GSSAPI"}, - {INVALID_USER, "INVALID_USER"}, - {NOLOGIN, "NOLOGIN"}, - {CONNECTION_CLOSE, "CONNECTION_CLOSE"}, - {CONNECTION_ABANDON, "CONNECTION_ABANDON"}, - {AUDIT_UNKNOWN, "AUDIT_UNKNOWN"} + {SSH_LOGIN_EXCEED_MAXTRIES, "LOGIN_EXCEED_MAXTRIES"}, + {SSH_LOGIN_ROOT_DENIED, "LOGIN_ROOT_DENIED"}, + {SSH_AUTH_SUCCESS, "AUTH_SUCCESS"}, + {SSH_AUTH_FAIL_NONE, "AUTH_FAIL_NONE"}, + {SSH_AUTH_FAIL_PASSWD, "AUTH_FAIL_PASSWD"}, + {SSH_AUTH_FAIL_KBDINT, "AUTH_FAIL_KBDINT"}, + {SSH_AUTH_FAIL_PUBKEY, "AUTH_FAIL_PUBKEY"}, + {SSH_AUTH_FAIL_HOSTBASED, "AUTH_FAIL_HOSTBASED"}, + {SSH_AUTH_FAIL_GSSAPI, "AUTH_FAIL_GSSAPI"}, + {SSH_INVALID_USER, "INVALID_USER"}, + {SSH_NOLOGIN, "NOLOGIN"}, + {SSH_CONNECTION_CLOSE, "CONNECTION_CLOSE"}, + {SSH_CONNECTION_ABANDON, "CONNECTION_ABANDON"}, + {SSH_AUDIT_UNKNOWN, "AUDIT_UNKNOWN"} }; - for (i = 0; event_lookup[i].event != AUDIT_UNKNOWN; i++) + for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++) if (event_lookup[i].event == ev) break; return(event_lookup[i].name); } -# ifndef CUSTOM_AUDIT_EVENTS +# ifndef CUSTOM_SSH_AUDIT_EVENTS /* * Null implementations of audit functions. - * These get used if AUDIT_EVENTS is defined but no audit module is enabled. + * These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled. */ /* @@ -177,5 +177,5 @@ audit_run_command(const char *command) debug("audit run command euid %d user %s command '%.200s'", geteuid(), audit_username(), command); } -# endif /* !defined CUSTOM_AUDIT_EVENTS */ -#endif /* AUDIT_EVENTS */ +# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ +#endif /* SSH_AUDIT_EVENTS */ diff --git a/audit.h b/audit.h index 2c1437391..78e58966f 100644 --- a/audit.h +++ b/audit.h @@ -1,4 +1,4 @@ -/* $Id: audit.h,v 1.1 2005/02/02 13:37:14 dtucker Exp $ */ +/* $Id: audit.h,v 1.2 2005/02/08 10:52:48 dtucker Exp $ */ /* * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. @@ -29,20 +29,20 @@ #ifndef _SSH_AUDIT_H # define _SSH_AUDIT_H enum ssh_audit_event_type { - LOGIN_EXCEED_MAXTRIES, - LOGIN_ROOT_DENIED, - AUTH_SUCCESS, - AUTH_FAIL_NONE, - AUTH_FAIL_PASSWD, - AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */ - AUTH_FAIL_PUBKEY, /* ssh2 pubkey or ssh1 rsa */ - AUTH_FAIL_HOSTBASED, /* ssh2 hostbased or ssh1 rhostsrsa */ - AUTH_FAIL_GSSAPI, - INVALID_USER, - NOLOGIN, /* denied by /etc/nologin, not implemented */ - CONNECTION_CLOSE, /* closed after attempting auth or session */ - CONNECTION_ABANDON, /* closed without completing auth */ - AUDIT_UNKNOWN + SSH_LOGIN_EXCEED_MAXTRIES, + SSH_LOGIN_ROOT_DENIED, + SSH_AUTH_SUCCESS, + SSH_AUTH_FAIL_NONE, + SSH_AUTH_FAIL_PASSWD, + SSH_AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */ + SSH_AUTH_FAIL_PUBKEY, /* ssh2 pubkey or ssh1 rsa */ + SSH_AUTH_FAIL_HOSTBASED, /* ssh2 hostbased or ssh1 rhostsrsa */ + SSH_AUTH_FAIL_GSSAPI, + SSH_INVALID_USER, + SSH_NOLOGIN, /* denied by /etc/nologin, not implemented */ + SSH_CONNECTION_CLOSE, /* closed after attempting auth or session */ + SSH_CONNECTION_ABANDON, /* closed without completing auth */ + SSH_AUDIT_UNKNOWN }; typedef enum ssh_audit_event_type ssh_audit_event_t; diff --git a/auth.c b/auth.c index 4b62ad8f7..e6dcab209 100644 --- a/auth.c +++ b/auth.c @@ -252,7 +252,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) record_failed_login(authctxt->user, get_canonical_hostname(options.use_dns), "ssh"); #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS if (authenticated == 0 && !authctxt->postponed) { ssh_audit_event_t event; @@ -265,15 +265,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) */ event = audit_classify_auth(method); switch(event) { - case AUTH_FAIL_NONE: - case AUTH_FAIL_PASSWD: - case AUTH_FAIL_KBDINT: + case SSH_AUTH_FAIL_NONE: + case SSH_AUTH_FAIL_PASSWD: + case SSH_AUTH_FAIL_KBDINT: if (geteuid() == 0) audit_event(event); break; - case AUTH_FAIL_PUBKEY: - case AUTH_FAIL_HOSTBASED: - case AUTH_FAIL_GSSAPI: + 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 @@ -515,9 +515,9 @@ getpwnamallow(const char *user) record_failed_login(user, get_canonical_hostname(options.use_dns), "ssh"); #endif -#ifdef AUDIT_EVENTS - audit_event(INVALID_USER); -#endif /* AUDIT_EVENTS */ +#ifdef SSH_AUDIT_EVENTS + audit_event(SSH_INVALID_USER); +#endif /* SSH_AUDIT_EVENTS */ return (NULL); } if (!allowed_user(pw)) diff --git a/auth1.c b/auth1.c index aeb5d8cb9..d08928455 100644 --- a/auth1.c +++ b/auth1.c @@ -249,8 +249,8 @@ do_authloop(Authctxt *authctxt) if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed(get_authname(type))) { authenticated = 0; -# ifdef AUDIT_EVENTS - PRIVSEP(audit_event(LOGIN_ROOT_DENIED)); +# ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); # endif } #endif @@ -288,8 +288,8 @@ do_authloop(Authctxt *authctxt) return; if (authctxt->failures++ > options.max_authtries) { -#ifdef AUDIT_EVENTS - PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES)); +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); #endif packet_disconnect(AUTH_FAIL_MSG, authctxt->user); } diff --git a/auth2.c b/auth2.c index 2727e0ff5..2265d311e 100644 --- a/auth2.c +++ b/auth2.c @@ -167,8 +167,8 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) if (options.use_pam) PRIVSEP(start_pam(authctxt)); #endif -#ifdef AUDIT_EVENTS - PRIVSEP(audit_event(INVALID_USER)); +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_INVALID_USER)); #endif } setproctitle("%s%s", authctxt->valid ? user : "unknown", @@ -219,8 +219,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed(method)) { authenticated = 0; -#ifdef AUDIT_EVENTS - PRIVSEP(audit_event(LOGIN_ROOT_DENIED)); +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); #endif } @@ -263,8 +263,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) authctxt->success = 1; } else { if (authctxt->failures++ > options.max_authtries) { -#ifdef AUDIT_EVENTS - PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES)); +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); #endif packet_disconnect(AUTH_FAIL_MSG, authctxt->user); } diff --git a/loginrec.c b/loginrec.c index 0fa9bdea7..c033582ad 100644 --- a/loginrec.c +++ b/loginrec.c @@ -164,7 +164,7 @@ # include #endif -RCSID("$Id: loginrec.c,v 1.64 2005/02/02 13:20:53 dtucker Exp $"); +RCSID("$Id: loginrec.c,v 1.65 2005/02/08 10:52:48 dtucker Exp $"); /** ** prototypes for helper functions in this file @@ -444,7 +444,7 @@ login_write(struct logininfo *li) !sys_auth_record_login(li->username,li->hostname,li->line)) logit("Writing login record failed for %s", li->username); #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS if (li->type == LTYPE_LOGIN) audit_session_open(li->line); else if (li->type == LTYPE_LOGOUT) diff --git a/monitor.c b/monitor.c index 04534d759..d6df656b0 100644 --- a/monitor.c +++ b/monitor.c @@ -143,7 +143,7 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); #endif @@ -191,7 +191,7 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event}, #endif #ifdef BSD_AUTH @@ -219,7 +219,7 @@ struct mon_table mon_dispatch_postauth20[] = { {MONITOR_REQ_PTY, 0, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, #endif @@ -251,7 +251,7 @@ struct mon_table mon_dispatch_proto15[] = { {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event}, #endif {0, 0, NULL} @@ -261,7 +261,7 @@ struct mon_table mon_dispatch_postauth15[] = { {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, #endif @@ -628,7 +628,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) if (options.use_pam) monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_EVENT, 1); #endif @@ -1513,7 +1513,7 @@ mm_answer_term(int sock, Buffer *req) exit(res); } -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS /* Report that an audit event occurred */ int mm_answer_audit_event(int socket, Buffer *m) @@ -1525,13 +1525,13 @@ mm_answer_audit_event(int socket, Buffer *m) event = buffer_get_int(m); buffer_free(m); switch(event) { - case AUTH_FAIL_PUBKEY: - case AUTH_FAIL_HOSTBASED: - case AUTH_FAIL_GSSAPI: - case LOGIN_EXCEED_MAXTRIES: - case LOGIN_ROOT_DENIED: - case CONNECTION_CLOSE: - case INVALID_USER: + case SSH_AUTH_FAIL_PUBKEY: + case SSH_AUTH_FAIL_HOSTBASED: + case SSH_AUTH_FAIL_GSSAPI: + case SSH_LOGIN_EXCEED_MAXTRIES: + case SSH_LOGIN_ROOT_DENIED: + case SSH_CONNECTION_CLOSE: + case SSH_INVALID_USER: audit_event(event); break; default: @@ -1555,7 +1555,7 @@ mm_answer_audit_command(int socket, Buffer *m) buffer_free(m); return (0); } -#endif /* AUDIT_EVENTS */ +#endif /* SSH_AUDIT_EVENTS */ void monitor_apply_keystate(struct monitor *pmonitor) diff --git a/monitor_wrap.c b/monitor_wrap.c index 983b24072..e1b6512b4 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1103,7 +1103,7 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) return (success); } -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS void mm_audit_event(ssh_audit_event_t event) { @@ -1131,7 +1131,7 @@ mm_audit_run_command(const char *command) mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); buffer_free(&m); } -#endif /* AUDIT_EVENTS */ +#endif /* SSH_AUDIT_EVENTS */ #ifdef GSSAPI OM_uint32 diff --git a/monitor_wrap.h b/monitor_wrap.h index 7ed241aa8..310b42513 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -74,7 +74,7 @@ int mm_sshpam_respond(void *, u_int, char **); void mm_sshpam_free_ctx(void *); #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(ssh_audit_event_t); void mm_audit_run_command(const char *); diff --git a/session.c b/session.c index b645144c5..a50bfcff7 100644 --- a/session.c +++ b/session.c @@ -665,7 +665,7 @@ do_exec(Session *s, const char *command) debug("Forced command '%.900s'", command); } -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS if (command != NULL) PRIVSEP(audit_run_command(command)); else if (s->ttyfd == -1) { @@ -2333,8 +2333,8 @@ do_cleanup(Authctxt *authctxt) } #endif -#ifdef AUDIT_EVENTS - PRIVSEP(audit_event(CONNECTION_CLOSE)); +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); #endif /* remove agent socket */ diff --git a/sshd.c b/sshd.c index e61870ea5..6b379521b 100644 --- a/sshd.c +++ b/sshd.c @@ -1628,7 +1628,7 @@ main(int ac, char **av) remote_port = get_remote_port(); remote_ip = get_remote_ipaddr(); -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS audit_connection_from(remote_ip, remote_port); #endif #ifdef LIBWRAP @@ -1700,8 +1700,8 @@ main(int ac, char **av) } authenticated: -#ifdef AUDIT_EVENTS - audit_event(AUTH_SUCCESS); +#ifdef SSH_AUDIT_EVENTS + audit_event(SSH_AUTH_SUCCESS); #endif /* @@ -2017,10 +2017,10 @@ cleanup_exit(int i) { if (the_authctxt) do_cleanup(the_authctxt); -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ if (!use_privsep || mm_is_monitor()) - audit_event(CONNECTION_ABANDON); + audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); } -- cgit v1.2.3 From 691d5235ca9485877e8345269b1be4b2cf1be322 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 15 Feb 2005 21:45:57 +1100 Subject: - (dtucker) [README.platform auth.c configure.ac loginrec.c openbsd-compat/port-aix.c openbsd-compat/port-aix.h] Bug #835: enable IPv6 on AIX where possible (see README.platform for details) and work around a misfeature of AIX's getnameinfo. ok djm@ --- ChangeLog | 6 ++++- README.platform | 11 ++++++++- auth.c | 2 +- configure.ac | 62 +++++++++++++++++++++++++++++++++++++++++++++-- loginrec.c | 6 +++-- openbsd-compat/port-aix.c | 45 ++++++++++++++++++++++++++++------ openbsd-compat/port-aix.h | 22 ++++++++++++++--- 7 files changed, 136 insertions(+), 18 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index a55a3b3d7..9b0b3e2af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 20050215 - (dtucker) [config.sh.in] Collect oslevel -r too. + - (dtucker) [README.platform auth.c configure.ac loginrec.c + openbsd-compat/port-aix.c openbsd-compat/port-aix.h] Bug #835: enable IPv6 + on AIX where possible (see README.platform for details) and work around + a misfeature of AIX's getnameinfo. ok djm@ 20050211 - (dtucker) [configure.ac] Tidy up configure --help output. @@ -2126,4 +2130,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3651 2005/02/15 10:26:32 dtucker Exp $ +$Id: ChangeLog,v 1.3652 2005/02/15 10:45:57 dtucker Exp $ diff --git a/README.platform b/README.platform index 880b83c63..136304a8e 100644 --- a/README.platform +++ b/README.platform @@ -13,6 +13,15 @@ Accounts in this state must have their passwords reset manually by the administrator. As a precaution, it is recommended that the administrative passwords be reset before upgrading from OpenSSH <3.8. +As of OpenSSH 4.0, configure will attempt to detect if your version +and maintenance level of AIX has a working getaddrinfo, and will use it +if found. This will enable IPv6 support. If for some reason configure +gets it wrong, or if you want to build binaries to work on earlier MLs +than the build host then you can add "-DBROKEN_GETADDRINFO" to CFLAGS +to force the previous IPv4-only behaviour. + +IPv6 known to work: 5.2ML2 5.2ML5 +IPv6 known broken: 4.3.3ML11 5.1ML4 Cygwin ------ @@ -27,4 +36,4 @@ Currently, sshd does not support BSM auditting. This can show up as errors when editting cron entries via crontab. See. http://bugzilla.mindrot.org/show_bug.cgi?id=125 -$Id: README.platform,v 1.2 2004/04/23 08:57:13 dtucker Exp $ +$Id: README.platform,v 1.3 2005/02/15 10:45:57 dtucker Exp $ diff --git a/auth.c b/auth.c index e6dcab209..256807683 100644 --- a/auth.c +++ b/auth.c @@ -209,7 +209,7 @@ allowed_user(struct passwd * pw) } #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER - if (!sys_auth_allowed_user(pw)) + if (!sys_auth_allowed_user(pw, &loginmsg)) return 0; #endif diff --git a/configure.ac b/configure.ac index 2df8a5e87..b27f0cf70 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.241 2005/02/11 05:11:49 dtucker Exp $ +# $Id: configure.ac,v 1.242 2005/02/15 10:45:57 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -135,7 +135,7 @@ case "$host" in [#include ] ) AC_CHECK_FUNCS(setauthdb) - AC_DEFINE(BROKEN_GETADDRINFO) + check_for_aix_broken_getaddrinfo=1 AC_DEFINE(BROKEN_REALPATH) AC_DEFINE(SETEUID_BREAKS_SETUID) AC_DEFINE(BROKEN_SETREUID) @@ -1146,6 +1146,64 @@ main(void) ) fi +if test "x$ac_cv_func_getaddrinfo" = "xyes" -a "x$check_for_aix_broken_getaddrinfo" = "x1"; then + AC_MSG_CHECKING(if getaddrinfo seems to work) + AC_TRY_RUN( + [ +#include +#include +#include +#include +#include + +#define TEST_PORT "2222" + +int +main(void) +{ + int err, sock; + struct addrinfo *gai_ai, *ai, hints; + char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai); + if (err != 0) { + fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err)); + exit(1); + } + + for (ai = gai_ai; ai != NULL; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + + err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, + sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV); + + if (ai->ai_family == AF_INET && err != 0) { + perror("getnameinfo"); + exit(2); + } + } + exit(0); +} + ], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(AIX_GETNAMEINFO_HACK, [], +[Define if you have a getaddrinfo that fails for the all-zeros IPv6 address]) + ], + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_GETADDRINFO) + ] + ) +fi + if test "x$check_for_conflicting_getspnam" = "x1"; then AC_MSG_CHECKING(for conflicting getspnam in shadow.h) AC_COMPILE_IFELSE( diff --git a/loginrec.c b/loginrec.c index c033582ad..8f5061cdc 100644 --- a/loginrec.c +++ b/loginrec.c @@ -164,7 +164,7 @@ # include #endif -RCSID("$Id: loginrec.c,v 1.65 2005/02/08 10:52:48 dtucker Exp $"); +RCSID("$Id: loginrec.c,v 1.66 2005/02/15 10:45:57 dtucker Exp $"); /** ** prototypes for helper functions in this file @@ -192,6 +192,8 @@ int lastlog_get_entry(struct logininfo *li); int wtmp_get_entry(struct logininfo *li); int wtmpx_get_entry(struct logininfo *li); +extern Buffer loginmsg; + /* pick the shortest string */ #define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2)) @@ -441,7 +443,7 @@ login_write(struct logininfo *li) #endif #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN if (li->type == LTYPE_LOGIN && - !sys_auth_record_login(li->username,li->hostname,li->line)) + !sys_auth_record_login(li->username,li->hostname,li->line, &loginmsg)) logit("Writing login record failed for %s", li->username); #endif #ifdef SSH_AUDIT_EVENTS diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index b16988543..8ab862f98 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c @@ -34,14 +34,13 @@ #ifdef _AIX #include +#include #include "port-aix.h" /* These should be in the system headers but are not. */ int usrinfo(int, char *, int); int setauthdb(const char *, char *); -extern Buffer loginmsg; - # ifdef HAVE_SETAUTHDB static char old_registry[REGISTRY_SIZE] = ""; # endif @@ -156,7 +155,7 @@ aix_valid_authentications(const char *user) * returns 0. */ int -sys_auth_passwd(Authctxt *ctxt, const char *password) +sys_auth_passwd(Authctxt *ctxt, const char *password, Buffer *loginmsg) { char *authmsg = NULL, *msg, *name = ctxt->pw->pw_name; int authsuccess = 0, expired, reenter, result; @@ -186,7 +185,7 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) */ expired = passwdexpired(name, &msg); if (msg && *msg) { - buffer_append(&loginmsg, msg, strlen(msg)); + buffer_append(loginmsg, msg, strlen(msg)); aix_remove_embedded_newlines(msg); } debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); @@ -219,7 +218,7 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) * Returns 1 if login is allowed, 0 if not allowed. */ int -sys_auth_allowed_user(struct passwd *pw) +sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) { char *msg = NULL; int result, permitted = 0; @@ -246,7 +245,7 @@ sys_auth_allowed_user(struct passwd *pw) if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) permitted = 1; else if (msg != NULL) - buffer_append(&loginmsg, msg, strlen(msg)); + buffer_append(loginmsg, msg, strlen(msg)); if (msg == NULL) msg = xstrdup("(none)"); aix_remove_embedded_newlines(msg); @@ -259,7 +258,8 @@ sys_auth_allowed_user(struct passwd *pw) } int -sys_auth_record_login(const char *user, const char *host, const char *ttynm) +sys_auth_record_login(const char *user, const char *host, const char *ttynm, + Buffer *loginmsg) { char *msg; int success = 0; @@ -269,7 +269,7 @@ sys_auth_record_login(const char *user, const char *host, const char *ttynm) success = 1; if (msg != NULL) { debug("AIX/loginsuccess: msg %s", msg); - buffer_append(&loginmsg, msg, strlen(msg)); + buffer_append(loginmsg, msg, strlen(msg)); xfree(msg); } } @@ -349,4 +349,33 @@ aix_restoreauthdb(void) # endif /* WITH_AIXAUTHENTICATE */ +# if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) +# undef getnameinfo +/* + * For some reason, AIX's getnameinfo will refuse to resolve the all-zeros + * IPv6 address into its textual representation ("::"), so we wrap it + * with a function that will. + */ +int +sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in6 *sa6; + u_int32_t *a6; + + if (flags & (NI_NUMERICHOST|NI_NUMERICSERV) && + sa->sa_family == AF_INET6) { + sa6 = (struct sockaddr_in6 *)sa; + a6 = sa6->sin6_addr.u6_addr.u6_addr32; + + if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { + strlcpy(host, "::", hostlen); + snprintf(serv, servlen, "%d", sa6->sin6_port); + return 0; + } + } + return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); +} +# endif /* AIX_GETNAMEINFO_HACK */ + #endif /* _AIX */ diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h index 751139004..cc7c43cda 100644 --- a/openbsd-compat/port-aix.h +++ b/openbsd-compat/port-aix.h @@ -1,4 +1,4 @@ -/* $Id: port-aix.h,v 1.22 2005/02/02 06:10:11 dtucker Exp $ */ +/* $Id: port-aix.h,v 1.23 2005/02/15 10:45:58 dtucker Exp $ */ /* * @@ -27,6 +27,10 @@ #ifdef _AIX +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + #ifdef WITH_AIXAUTHENTICATE # include # include @@ -36,6 +40,8 @@ # include #endif +#include "buffer.h" + /* Some versions define r_type in the above headers, which causes a conflict */ #ifdef r_type # undef r_type @@ -64,13 +70,23 @@ void aix_usrinfo(struct passwd *); #ifdef WITH_AIXAUTHENTICATE # define CUSTOM_SYS_AUTH_PASSWD 1 # define CUSTOM_SYS_AUTH_ALLOWED_USER 1 -int sys_auth_allowed_user(struct passwd *); +int sys_auth_allowed_user(struct passwd *, Buffer *); # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 -int sys_auth_record_login(const char *, const char *, const char *); +int sys_auth_record_login(const char *, const char *, const char *, Buffer *); # define CUSTOM_FAILED_LOGIN 1 #endif void aix_setauthdb(const char *); void aix_restoreauthdb(void); void aix_remove_embedded_newlines(char *); + +#if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_GETADDRINFO) +# ifdef getnameinfo +# undef getnameinfo +# endif +int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t, + char *, size_t, int); +# define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g)) +#endif + #endif /* _AIX */ -- cgit v1.2.3 From a39f83eeee3f7bb35e86d92f5a802fe84f1b6a9d Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 15 Feb 2005 22:19:28 +1100 Subject: - (dtucker) [loginrec.c] Add missing #include. --- ChangeLog | 3 ++- loginrec.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'loginrec.c') diff --git a/ChangeLog b/ChangeLog index 9b0b3e2af..e076fc66f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ openbsd-compat/port-aix.c openbsd-compat/port-aix.h] Bug #835: enable IPv6 on AIX where possible (see README.platform for details) and work around a misfeature of AIX's getnameinfo. ok djm@ + - (dtucker) [loginrec.c] Add missing #include. 20050211 - (dtucker) [configure.ac] Tidy up configure --help output. @@ -2130,4 +2131,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3652 2005/02/15 10:45:57 dtucker Exp $ +$Id: ChangeLog,v 1.3653 2005/02/15 11:19:28 dtucker Exp $ diff --git a/loginrec.c b/loginrec.c index 8f5061cdc..361ac4cb7 100644 --- a/loginrec.c +++ b/loginrec.c @@ -155,6 +155,7 @@ #include "packet.h" #include "canohost.h" #include "auth.h" +#include "buffer.h" #ifdef HAVE_UTIL_H # include @@ -164,7 +165,7 @@ # include #endif -RCSID("$Id: loginrec.c,v 1.66 2005/02/15 10:45:57 dtucker Exp $"); +RCSID("$Id: loginrec.c,v 1.67 2005/02/15 11:19:28 dtucker Exp $"); /** ** prototypes for helper functions in this file -- cgit v1.2.3