From 2f6a0ad191af2e0e67c66bdc5dfc84d9a97bf12c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 31 May 2000 11:20:11 +1000 Subject: [PATCH] - Cleanup of auth.c, login.c and fake-* - Cleanup of auth-pam.c, save and print "account expired" error messages --- ChangeLog | 4 ++ auth-pam.c | 113 ++++++++++++++++++------------ auth.c | 8 +-- fake-getaddrinfo.c | 171 ++++++++++++++++++++++----------------------- fake-getnameinfo.c | 76 +++++++++----------- fake-getnameinfo.h | 1 + fake-socket.h | 10 +-- login.c | 137 +++++++++++++++++++----------------- 8 files changed, 274 insertions(+), 246 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0fb51014f..2899a4c4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20000531 + - Cleanup of auth.c, login.c and fake-* + - Cleanup of auth-pam.c, save and print "account expired" error messages + 20000530 - Define atexit for old Solaris - Fix buffer overrun in login.c for systems which use syslen in utmpx. diff --git a/auth-pam.c b/auth-pam.c index e3f4c4252..174d289f3 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -13,12 +13,16 @@ #include "xmalloc.h" #include "servconf.h" -RCSID("$Id: auth-pam.c,v 1.4 2000/04/29 14:47:29 damien Exp $"); +RCSID("$Id: auth-pam.c,v 1.5 2000/05/31 01:20:12 damien Exp $"); + +#define NEW_AUTHTOK_MSG \ + "Warning: You password has expired, please change it now" /* Callbacks */ static int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); void pam_cleanup_proc(void *context); +void pam_msg_cat(const char *msg); /* module-local variables */ static struct pam_conv conv = { @@ -27,7 +31,7 @@ static struct pam_conv conv = { }; static struct pam_handle_t *pamh = NULL; static const char *pampasswd = NULL; -static char *pamconv_msg = NULL; +static char *pam_msg = NULL; /* PAM conversation function. This is really a kludge to get the password */ /* into PAM and to pick up any messages generated by PAM into pamconv_msg */ @@ -36,8 +40,6 @@ static int pamconv(int num_msg, const struct pam_message **msg, { struct pam_response *reply; int count; - size_t msg_len; - char *p; /* PAM will free this later */ reply = malloc(num_msg * sizeof(*reply)); @@ -54,31 +56,14 @@ static int pamconv(int num_msg, const struct pam_message **msg, reply[count].resp_retcode = PAM_SUCCESS; reply[count].resp = xstrdup(pampasswd); break; - case PAM_TEXT_INFO: reply[count].resp_retcode = PAM_SUCCESS; reply[count].resp = xstrdup(""); - if (msg[count]->msg == NULL) - break; + if (msg[count]->msg != NULL) + pam_msg_cat(msg[count]->msg); - debug("Adding PAM message: %s", msg[count]->msg); - - msg_len = strlen(msg[count]->msg); - if (pamconv_msg) { - size_t n = strlen(pamconv_msg); - pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2); - p = pamconv_msg + n; - } else { - pamconv_msg = p = xmalloc(msg_len + 2); - } - memcpy(p, msg[count]->msg, msg_len); - p[msg_len] = '\n'; - p[msg_len + 1] = '\0'; break; - - case PAM_PROMPT_ECHO_ON: - case PAM_ERROR_MSG: default: free(reply); return PAM_CONV_ERR; @@ -100,19 +85,19 @@ void pam_cleanup_proc(void *context) pam_retval = pam_close_session((pam_handle_t *)pamh, 0); if (pam_retval != PAM_SUCCESS) { log("Cannot close PAM session: %.200s", - PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); } pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED); if (pam_retval != PAM_SUCCESS) { log("Cannot delete credentials: %.200s", - PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); } pam_retval = pam_end((pam_handle_t *)pamh, pam_retval); if (pam_retval != PAM_SUCCESS) { log("Cannot release PAM authentication: %.200s", - PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); } } } @@ -135,7 +120,8 @@ int auth_pam_password(struct passwd *pw, const char *password) pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); if (pam_retval == PAM_SUCCESS) { - debug("PAM Password authentication accepted for user \"%.100s\"", pw->pw_name); + debug("PAM Password authentication accepted for user \"%.100s\"", + pw->pw_name); return 1; } else { debug("PAM Password authentication for \"%.100s\" failed: %s", @@ -148,26 +134,36 @@ int auth_pam_password(struct passwd *pw, const char *password) int do_pam_account(char *username, char *remote_user) { int pam_retval; - + debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname()); pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, get_canonical_hostname()); if (pam_retval != PAM_SUCCESS) { - fatal("PAM set rhost failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + fatal("PAM set rhost failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); } if (remote_user != NULL) { debug("PAM setting ruser to \"%.200s\"", remote_user); pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user); if (pam_retval != PAM_SUCCESS) { - fatal("PAM set ruser failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + fatal("PAM set ruser failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); } } pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0); - if (pam_retval != PAM_SUCCESS) { - log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); - return(0); + switch (pam_retval) { + case PAM_SUCCESS: + /* This is what we want */ + break; + case PAM_NEW_AUTHTOK_REQD: + pam_msg_cat(NEW_AUTHTOK_MSG); + break; + default: + log("PAM rejected by account configuration: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + return(0); } return(1); @@ -181,13 +177,17 @@ void do_pam_session(char *username, const char *ttyname) if (ttyname != NULL) { debug("PAM setting tty to \"%.200s\"", ttyname); pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set tty failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } } pam_retval = pam_open_session((pam_handle_t *)pamh, 0); - if (pam_retval != PAM_SUCCESS) - fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM session setup failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } } /* Set PAM credentials */ @@ -197,8 +197,10 @@ void do_pam_setcred() debug("PAM establishing creds"); pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED); - if (pam_retval != PAM_SUCCESS) - fatal("PAM setcred failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM setcred failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } } /* Cleanly shutdown PAM */ @@ -217,9 +219,12 @@ void start_pam(struct passwd *pw) pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, (pam_handle_t**)&pamh); - if (pam_retval != PAM_SUCCESS) - fatal("PAM initialisation failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM initialisation failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + fatal_add_cleanup(&pam_cleanup_proc, NULL); } @@ -237,8 +242,30 @@ char **fetch_pam_environment(void) /* or account checking to stderr */ void print_pam_messages(void) { - if (pamconv_msg != NULL) - fprintf(stderr, pamconv_msg); + if (pam_msg != NULL) + fprintf(stderr, pam_msg); +} + +/* Append a message to the PAM message buffer */ +void pam_msg_cat(const char *msg) +{ + char *p; + size_t new_msg_len; + size_t pam_msg_len; + + new_msg_len = strlen(msg); + + if (pam_msg) { + pam_msg_len = strlen(pam_msg); + pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2); + p = pam_msg + pam_msg_len; + } else { + pam_msg = p = xmalloc(new_msg_len + 2); + } + + memcpy(p, msg, new_msg_len); + p[new_msg_len] = '\n'; + p[new_msg_len + 1] = '\0'; } #endif /* USE_PAM */ diff --git a/auth.c b/auth.c index 0a58df58b..685b8bb35 100644 --- a/auth.c +++ b/auth.c @@ -121,17 +121,17 @@ allowed_user(struct passwd * pw) } #ifdef WITH_AIXAUTHENTICATE - if (loginrestrictions(pw->pw_name,S_RLOGIN,NULL,&loginmsg) != 0) { + if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { if (loginmsg && *loginmsg) { /* Remove embedded newlines (if any) */ char *p; - for (p = loginmsg; *p; p++) + for (p = loginmsg; *p; p++) { if (*p == '\n') *p = ' '; + } /* Remove trailing newline */ *--p = '\0'; - log("Login restricted for %s: %.100s", - pw->pw_name, loginmsg); + log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); } return 0; } diff --git a/fake-getaddrinfo.c b/fake-getaddrinfo.c index 456c41e58..b3af4aa2e 100644 --- a/fake-getaddrinfo.c +++ b/fake-getaddrinfo.c @@ -7,113 +7,112 @@ * But these functions are not implemented correctly. The minimum subset * is implemented for ssh use only. For exapmle, this routine assumes * that ai_family is AF_INET. Don't use it for another purpose. - * - * In the case not using 'configure --enable-ipv6', this getaddrinfo.c - * will be used if you have broken getaddrinfo or no getaddrinfo. */ #include "includes.h" #include "ssh.h" #ifndef HAVE_GAI_STRERROR -char * -gai_strerror(ecode) -int ecode; +char *gai_strerror(int ecode) { - switch (ecode) { - case EAI_NODATA: - return "no address associated with hostname."; - case EAI_MEMORY: - return "memory allocation failure."; - default: - return "unknown error."; - } + switch (ecode) { + case EAI_NODATA: + return "no address associated with hostname."; + case EAI_MEMORY: + return "memory allocation failure."; + default: + return "unknown error."; + } } #endif /* !HAVE_GAI_STRERROR */ #ifndef HAVE_FREEADDRINFO -void -freeaddrinfo(ai) -struct addrinfo *ai; +void freeaddrinfo(struct addrinfo *ai) { - struct addrinfo *next; - - do { - next = ai->ai_next; - free(ai); - } while (NULL != (ai = next)); + struct addrinfo *next; + + do { + next = ai->ai_next; + free(ai); + } while (NULL != (ai = next)); } #endif /* !HAVE_FREEADDRINFO */ #ifndef HAVE_GETADDRINFO -static struct addrinfo * -malloc_ai(port, addr) -int port; -u_long addr; +static struct addrinfo *malloc_ai(int port, u_long addr) { - struct addrinfo *ai; + struct addrinfo *ai; - if (NULL != (ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + - sizeof(struct sockaddr_in)))) { - memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); - ai->ai_addr = (struct sockaddr *)(ai + 1); - /* XXX -- ssh doesn't use sa_len */ - ai->ai_addrlen = sizeof(struct sockaddr_in); - ai->ai_addr->sa_family = ai->ai_family = AF_INET; - ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; - ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; - return ai; - } else { - return NULL; - } + ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + if (ai == NULL) + return(NULL); + + memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + return(ai); } -int -getaddrinfo(hostname, servname, hints, res) -const char *hostname, *servname; -const struct addrinfo *hints; -struct addrinfo **res; +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) { - struct addrinfo *cur, *prev = NULL; - struct hostent *hp; - int i, port; - - if (servname) - port = htons(atoi(servname)); - else - port = 0; - if (hints && hints->ai_flags & AI_PASSIVE) - if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) - return 0; - else - return EAI_MEMORY; - if (!hostname) - if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) - return 0; - else - return EAI_MEMORY; - if (inet_addr(hostname) != -1) - if (NULL != (*res = malloc_ai(port, inet_addr(hostname)))) - return 0; - else - return EAI_MEMORY; - if ((hp = gethostbyname(hostname)) && - hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { - for (i = 0; hp->h_addr_list[i]; i++) - if (NULL != (cur = malloc_ai(port, - ((struct in_addr *)hp->h_addr_list[i])->s_addr))) { - if (prev) - prev->ai_next = cur; + struct addrinfo *cur, *prev = NULL; + struct hostent *hp; + int i, port; + + if (servname) + port = htons(atoi(servname)); else - *res = cur; - prev = cur; - } else { - if (*res) - freeaddrinfo(*res); - return EAI_MEMORY; - } - return 0; - } - return EAI_NODATA; + port = 0; + + if (hints && hints->ai_flags & AI_PASSIVE) { + if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) + return 0; + else + return EAI_MEMORY; + } + + if (!hostname) { + if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) + return 0; + else + return EAI_MEMORY; + } + + if (inet_addr(hostname) != -1) { + if (NULL != (*res = malloc_ai(port, inet_addr(hostname)))) + return 0; + else + return EAI_MEMORY; + } + + hp = gethostbyname(hostname); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + for (i = 0; hp->h_addr_list[i]; i++) { + cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); + if (cur == NULL) { + if (*res) + freeaddrinfo(*res); + return EAI_MEMORY; + } + + if (prev) + prev->ai_next = cur; + else + *res = cur; + + prev = cur; + } + return 0; + } + + return EAI_NODATA; } #endif /* !HAVE_GETADDRINFO */ diff --git a/fake-getnameinfo.c b/fake-getnameinfo.c index f74f3128f..867cf90b5 100644 --- a/fake-getnameinfo.c +++ b/fake-getnameinfo.c @@ -7,55 +7,47 @@ * But these functions are not implemented correctly. The minimum subset * is implemented for ssh use only. For exapmle, this routine assumes * that ai_family is AF_INET. Don't use it for another purpose. - * - * In the case not using 'configure --enable-ipv6', this getnameinfo.c - * will be used if you have broken getnameinfo or no getnameinfo. */ #include "includes.h" #include "ssh.h" #ifndef HAVE_GETNAMEINFO -int -getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) -const struct sockaddr *sa; -size_t salen; -char *host; -size_t hostlen; -char *serv; -size_t servlen; -int flags; +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - struct hostent *hp; - char tmpserv[16]; - - if (serv) { - sprintf(tmpserv, "%d", ntohs(sin->sin_port)); - if (strlen(tmpserv) > servlen) - return EAI_MEMORY; - else - strcpy(serv, tmpserv); - } - if (host) - if (flags & NI_NUMERICHOST) - if (strlen(inet_ntoa(sin->sin_addr)) > hostlen) - return EAI_MEMORY; - else { - strcpy(host, inet_ntoa(sin->sin_addr)); - return 0; - } - else - if (NULL != (hp = gethostbyaddr((char *)&sin->sin_addr, - sizeof(struct in_addr), AF_INET))) - if (strlen(hp->h_name) > hostlen) - return EAI_MEMORY; - else { - strcpy(host, hp->h_name); - return 0; + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (serv) { + snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); + if (strlen(tmpserv) > servlen) + return EAI_MEMORY; + else + strcpy(serv, tmpserv); } - else - return EAI_NODATA; - return 0; + + if (host) { + if (flags & NI_NUMERICHOST) { + if (strlen(inet_ntoa(sin->sin_addr)) > hostlen) + return EAI_MEMORY; + + strcpy(host, inet_ntoa(sin->sin_addr)); + return 0; + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp == NULL) + return EAI_NODATA; + + if (strlen(hp->h_name) > hostlen) + return EAI_MEMORY; + + strcpy(host, hp->h_name); + return 0; + } + } + return 0; } #endif /* !HAVE_GETNAMEINFO */ diff --git a/fake-getnameinfo.h b/fake-getnameinfo.h index ecf0df2cf..0d25f4270 100644 --- a/fake-getnameinfo.h +++ b/fake-getnameinfo.h @@ -2,6 +2,7 @@ #define _FAKE_GETNAMEINFO_H #include "config.h" + #ifndef HAVE_GETNAMEINFO int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); diff --git a/fake-socket.h b/fake-socket.h index e11ad44e0..0e1624d11 100644 --- a/fake-socket.h +++ b/fake-socket.h @@ -5,10 +5,10 @@ #include "sys/types.h" #ifndef HAVE_STRUCT_SOCKADDR_STORAGE -#define _SS_MAXSIZE 128 /* Implementation specific max size */ -#define _SS_ALIGNSIZE (sizeof(int)) -#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_short)) -#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(u_short) + \ +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_ALIGNSIZE (sizeof(int)) +# define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_short)) +# define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(u_short) + \ _SS_PAD1SIZE + _SS_ALIGNSIZE)) struct sockaddr_storage { @@ -20,7 +20,7 @@ struct sockaddr_storage { #endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ #ifndef IN6_IS_ADDR_LOOPBACK -#define IN6_IS_ADDR_LOOPBACK(a) \ +# define IN6_IS_ADDR_LOOPBACK(a) \ (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) #endif /* !IN6_IS_ADDR_LOOPBACK */ diff --git a/login.c b/login.c index 6749a1556..6fdc71e68 100644 --- a/login.c +++ b/login.c @@ -18,7 +18,7 @@ */ #include "includes.h" -RCSID("$Id: login.c,v 1.28 2000/05/30 03:12:46 damien Exp $"); +RCSID("$Id: login.c,v 1.29 2000/05/31 01:20:12 damien Exp $"); #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) # include @@ -38,6 +38,11 @@ RCSID("$Id: login.c,v 1.28 2000/05/30 03:12:46 damien Exp $"); # include #endif +#ifdef WITH_AIXAUTHENTICATE +/* This is done in do_authentication */ +# define DISABLE_LASTLOG +#endif /* WITH_AIXAUTHENTICATE */ + /* * Returns the time when the user last logged in. Returns 0 if the * information is not available. This must be called before record_login. @@ -53,58 +58,50 @@ unsigned long get_last_login_time(uid_t uid, const char *logname, char *buf, unsigned int bufsize) { -#if defined(WITH_AIXAUTHENTICATE) - /* This is done in do_authentication */ - return (unsigned long) 0; -#else #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) struct lastlog ll; - char *lastlog; int fd; -#ifdef LASTLOG_IS_DIR +# ifdef LASTLOG_IS_DIR char lbuf[1024]; -#endif /* LASTLOG_IS_DIR */ - lastlog = _PATH_LASTLOG; + snprintf(lbuf, sizeof(buf), "%s/%s", _PATH_LASTLOG, logname); + if ((fd = open(lbuf, O_RDONLY)) < 0) + return 0; +# else /* LASTLOG_IS_DIR */ buf[0] = '\0'; -#ifndef LASTLOG_IS_DIR - fd = open(lastlog, O_RDONLY); - if (fd < 0) + if ((fd = open(_PATH_LASTLOG, O_RDONLY)) < 0) return 0; + lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); -#else /* LASTLOG_IS_DIR */ - snprintf(lbuf, sizeof(buf), "%s/%s", lastlog, logname); - fd = open(lbuf, O_RDONLY); - if (fd < 0) - return 0; -#endif /* LASTLOG_IS_DIR */ +# endif /* LASTLOG_IS_DIR */ if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { close(fd); return 0; } + close(fd); + if (bufsize > sizeof(ll.ll_host) + 1) bufsize = sizeof(ll.ll_host) + 1; strncpy(buf, ll.ll_host, bufsize - 1); buf[bufsize - 1] = 0; - return ll.ll_time; + return ll.ll_time; #else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ # ifdef HAVE_TYPE_IN_UTMP /* Look in wtmp for the last login */ struct utmp wt; - char *wt_file = _PATH_WTMP; - int fd1; + int fd1; unsigned long t = 0; - if ( (fd1 = open(wt_file, O_RDONLY)) < 0 ) { - error("Couldn't open %.100s to find last login time.", wt_file); + if ((fd1 = open(_PATH_WTMP, O_RDONLY)) < 0) { + error("Couldn't open %.100s to find last login time.", _PATH_WTMP); return 0; } /* seek to last record of file */ - lseek(fd1, (off_t)(0-sizeof(struct utmp)), SEEK_END); + lseek(fd1, (off_t)(0 - sizeof(struct utmp)), SEEK_END); /* loop through wtmp for our last user login record */ do { @@ -113,47 +110,44 @@ get_last_login_time(uid_t uid, const char *logname, return 0; } - if ( wt.ut_type == USER_PROCESS) { - if ( !strncmp(logname, wt.ut_user, 8) ) { - t = (unsigned long) wt.ut_time; -# ifdef HAVE_HOST_IN_UTMP + if (wt.ut_type == USER_PROCESS) { + if (!strncmp(logname, wt.ut_user, 8)) { + t = (unsigned long)wt.ut_time; +# ifdef HAVE_HOST_IN_UTMP if (bufsize > sizeof(wt.ut_host) + 1) - bufsize = sizeof(wt.ut_host) + 1; + bufsize = sizeof(wt.ut_host) + 1; strncpy(buf, wt.ut_host, bufsize - 1); buf[bufsize - 1] = 0; -# else /* HAVE_HOST_IN_UTMP */ +# else /* HAVE_HOST_IN_UTMP */ buf[0] = 0; -# endif /* HAVE_HOST_IN_UTMP */ +# endif /* HAVE_HOST_IN_UTMP */ } } - if (lseek(fd1, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1) + if (lseek(fd1, (off_t)(0 - (2 * sizeof(struct utmp))), SEEK_CUR) < 0) break; } while (t == 0); return t; -# else +# else /* HAVE_TYPE_IN_UTMP */ return 0; # endif /* HAVE_TYPE_IN_UTMP */ #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ -#endif /* defined(WITH_AIXAUTHENTICATE) */ } /* - * Records that the user has logged in. I these parts of operating systems - * were more standardized. + * Records that the user has logged in. I wish these parts of operating + * systems were more standardized. */ - void record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, const char *host, struct sockaddr * addr) { #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) struct lastlog ll; - char *lastlog; -#ifdef LASTLOG_IS_DIR +# ifdef LASTLOG_IS_DIR char buf[1024]; -#endif /* LASTLOG_IS_DIR */ +# endif /* LASTLOG_IS_DIR */ #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ struct utmp u; #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) @@ -163,28 +157,35 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, /* Construct an utmp/wtmp entry. */ memset(&u, 0, sizeof(u)); strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); + #if defined(HAVE_ID_IN_UTMP) -#ifdef _AIX +# ifdef _AIX strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id)); -#else /* !AIX */ +# else /* !AIX */ strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id)); -#endif +# endif #endif /* defined(HAVE_ID_IN_UTMP) */ + strncpy(u.ut_name, user, sizeof(u.ut_name)); + #if defined(HAVE_TV_IN_UTMP) (void)gettimeofday(&u.ut_tv, NULL); #else /* defined(HAVE_TV_IN_UTMP) */ u.ut_time = time(NULL); #endif /* defined(HAVE_TV_IN_UTMP) */ + #if defined(HAVE_PID_IN_UTMP) u.ut_pid = (pid_t)pid; #endif /* HAVE_PID_IN_UTMP */ + #if defined(HAVE_TYPE_IN_UTMP) u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; #endif /* HAVE_TYPE_IN_UTMP */ + #if defined(HAVE_HOST_IN_UTMP) strncpy(u.ut_host, host, sizeof(u.ut_host)); #endif + #if defined(HAVE_ADDR_IN_UTMP) if (addr) { switch (addr->sa_family) { @@ -193,26 +194,29 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); break; } -#if defined(HAVE_ADDR_V6_IN_UTMP) +# if defined(HAVE_ADDR_V6_IN_UTMP) case AF_INET6: { struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); break; } -#endif +# endif /* defined(HAVE_ADDR_V6_IN_UTMP) */ default: break; } } -#endif +#endif /* defined(HAVE_ADDR_IN_UTMP) */ #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) memset(&utx, 0, sizeof(utx)); + strncpy(utx.ut_user, user, sizeof(utx.ut_name)); strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line)); strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id)); + utx.ut_pid = (pid_t)pid; (void)gettimeofday(&utx.ut_tv, NULL); + utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; # ifdef HAVE_HOST_IN_UTMPX # ifdef HAVE_SYSLEN_IN_UTMPX @@ -225,7 +229,8 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, # endif /* HAVE_SYSLEN_IN_UTMPX */ utx.ut_host[sizeof(utx.ut_host)-1] = '\0'; # endif -#if defined(HAVE_ADDR_IN_UTMPX) + +# if defined(HAVE_ADDR_IN_UTMPX) if (addr) { switch (addr->sa_family) { case AF_INET: { @@ -233,31 +238,27 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); break; } -#if defined(HAVE_ADDR_V6_IN_UTMPX) +# if defined(HAVE_ADDR_V6_IN_UTMPX) case AF_INET6: { struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); break; } -#endif +# endif /* defined(HAVE_ADDR_V6_IN_UTMPX) */ default: break; } } -#endif +# endif /* defined(HAVE_ADDR_IN_UTMPX) */ #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ -/*#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) && !defined(HAVE_LOGIN)*/ #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) login(&u, &utx); #else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ login(&u); #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ -#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE) - /* AIX does this in do_authentication */ - lastlog = _PATH_LASTLOG; - +#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) /* Update lastlog unless actually recording a logout. */ if (strcmp(user, "") != 0) { int fd; @@ -271,21 +272,25 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, ll.ll_time = time(NULL); strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); strncpy(ll.ll_host, host, sizeof(ll.ll_host)); -#ifdef LASTLOG_IS_DIR - snprintf(buf, sizeof(buf), "%s/%s", lastlog, user); - fd = open(buf, O_RDWR); - if (fd >= 0) { -#else /* LASTLOG_IS_DIR */ - fd = open(lastlog, O_RDWR); - if (fd >= 0) { - lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); -#endif /* LASTLOG_IS_DIR */ +# ifdef LASTLOG_IS_DIR + snprintf(buf, sizeof(buf), "%s/%s", _PATH_LASTLOG, user); + if ((fd = open(buf, O_RDWR)) >= 0) { if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) - log("Could not write %.100s: %.100s", lastlog, strerror(errno)); + log("Could not write %.100s: %.100s", buf, strerror(errno)); close(fd); } +# else /* LASTLOG_IS_DIR */ + if ((fd = open(_PATH_LASTLOG, O_RDWR)) >= 0) { + lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); + if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) { + log("Could not write %.100s: %.100s", _PATH_LASTLOG, + strerror(errno)); + } + close(fd); + } +# endif /* LASTLOG_IS_DIR */ } -#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE) */ +#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ } /* Records that the user has logged out. */