diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | loginrec.c | 139 |
3 files changed, 79 insertions, 77 deletions
@@ -1,6 +1,11 @@ | |||
1 | 20090212 | 1 | 20090205 |
2 | - (djm) [sshpty.c] bz#1419: OSX uses cloning ptys that automagically | 2 | - (djm) [sshpty.c] bz#1419: OSX uses cloning ptys that automagically |
3 | set ownership and modes, so avoid explicitly setting them | 3 | set ownership and modes, so avoid explicitly setting them |
4 | - (djm) [configure.ac loginrec.c] bz#1421: fix lastlog support for OSX. | ||
5 | OSX provides a getlastlogxbyname function that automates the reading of | ||
6 | a lastlog file. Also, the pututxline function will update lastlog so | ||
7 | there is no need for loginrec.c to do it explicitly. Collapse some | ||
8 | overly verbose code while I'm in there. | ||
4 | 9 | ||
5 | 20090201 | 10 | 20090201 |
6 | - (dtucker) [defines.h sshconnect.c] INET6_ADDRSTRLEN is now needed in | 11 | - (dtucker) [defines.h sshconnect.c] INET6_ADDRSTRLEN is now needed in |
@@ -5118,5 +5123,5 @@ | |||
5118 | OpenServer 6 and add osr5bigcrypt support so when someone migrates | 5123 | OpenServer 6 and add osr5bigcrypt support so when someone migrates |
5119 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ | 5124 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ |
5120 | 5125 | ||
5121 | $Id: ChangeLog,v 1.5184 2009/02/12 01:19:20 djm Exp $ | 5126 | $Id: ChangeLog,v 1.5185 2009/02/12 02:12:21 djm Exp $ |
5122 | 5127 | ||
diff --git a/configure.ac b/configure.ac index 94589ddc7..242dea0dc 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: configure.ac,v 1.413 2009/01/08 04:50:09 tim Exp $ | 1 | # $Id: configure.ac,v 1.414 2009/02/12 02:12:22 djm Exp $ |
2 | # | 2 | # |
3 | # Copyright (c) 1999-2004 Damien Miller | 3 | # Copyright (c) 1999-2004 Damien Miller |
4 | # | 4 | # |
@@ -15,7 +15,7 @@ | |||
15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | 16 | ||
17 | AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) | 17 | AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) |
18 | AC_REVISION($Revision: 1.413 $) | 18 | AC_REVISION($Revision: 1.414 $) |
19 | AC_CONFIG_SRCDIR([ssh.c]) | 19 | AC_CONFIG_SRCDIR([ssh.c]) |
20 | 20 | ||
21 | AC_CONFIG_HEADER(config.h) | 21 | AC_CONFIG_HEADER(config.h) |
@@ -477,6 +477,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) | |||
477 | AC_CHECK_DECL(AU_IPv4, [], | 477 | AC_CHECK_DECL(AU_IPv4, [], |
478 | AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records]) | 478 | AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records]) |
479 | [#include <bsm/audit.h>] | 479 | [#include <bsm/audit.h>] |
480 | AC_DEFINE(LASTLOG_WRITE_PUTUTXLINE, 1, | ||
481 | [Define if pututxline updates lastlog too]) | ||
480 | ) | 482 | ) |
481 | ;; | 483 | ;; |
482 | *-*-dragonfly*) | 484 | *-*-dragonfly*) |
@@ -1508,6 +1510,8 @@ AC_CHECK_FUNCS(utmpname) | |||
1508 | dnl Checks for utmpx functions | 1510 | dnl Checks for utmpx functions |
1509 | AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline ) | 1511 | AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline ) |
1510 | AC_CHECK_FUNCS(setutxent utmpxname) | 1512 | AC_CHECK_FUNCS(setutxent utmpxname) |
1513 | dnl Checks for lastlog functions | ||
1514 | AC_CHECK_FUNCS(getlastlogxbyname) | ||
1511 | 1515 | ||
1512 | AC_CHECK_FUNC(daemon, | 1516 | AC_CHECK_FUNC(daemon, |
1513 | [AC_DEFINE(HAVE_DAEMON, 1, [Define if your libraries define daemon()])], | 1517 | [AC_DEFINE(HAVE_DAEMON, 1, [Define if your libraries define daemon()])], |
diff --git a/loginrec.c b/loginrec.c index b41114198..f4af06736 100644 --- a/loginrec.c +++ b/loginrec.c | |||
@@ -1456,25 +1456,14 @@ syslogin_write_entry(struct logininfo *li) | |||
1456 | **/ | 1456 | **/ |
1457 | 1457 | ||
1458 | #ifdef USE_LASTLOG | 1458 | #ifdef USE_LASTLOG |
1459 | #define LL_FILE 1 | ||
1460 | #define LL_DIR 2 | ||
1461 | #define LL_OTHER 3 | ||
1462 | |||
1463 | static void | ||
1464 | lastlog_construct(struct logininfo *li, struct lastlog *last) | ||
1465 | { | ||
1466 | /* clear the structure */ | ||
1467 | memset(last, '\0', sizeof(*last)); | ||
1468 | |||
1469 | line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); | ||
1470 | strlcpy(last->ll_host, li->hostname, | ||
1471 | MIN_SIZEOF(last->ll_host, li->hostname)); | ||
1472 | last->ll_time = li->tv_sec; | ||
1473 | } | ||
1474 | 1459 | ||
1460 | #if !defined(LASTLOG_WRITE_PUTUTXLINE) || !defined(HAVE_GETLASTLOGXBYNAME) | ||
1461 | /* open the file (using filemode) and seek to the login entry */ | ||
1475 | static int | 1462 | static int |
1476 | lastlog_filetype(char *filename) | 1463 | lastlog_openseek(struct logininfo *li, int *fd, int filemode) |
1477 | { | 1464 | { |
1465 | off_t offset; | ||
1466 | char lastlog_file[1024]; | ||
1478 | struct stat st; | 1467 | struct stat st; |
1479 | 1468 | ||
1480 | if (stat(LASTLOG_FILE, &st) != 0) { | 1469 | if (stat(LASTLOG_FILE, &st) != 0) { |
@@ -1482,34 +1471,12 @@ lastlog_filetype(char *filename) | |||
1482 | LASTLOG_FILE, strerror(errno)); | 1471 | LASTLOG_FILE, strerror(errno)); |
1483 | return (0); | 1472 | return (0); |
1484 | } | 1473 | } |
1485 | if (S_ISDIR(st.st_mode)) | 1474 | if (S_ISDIR(st.st_mode)) { |
1486 | return (LL_DIR); | ||
1487 | else if (S_ISREG(st.st_mode)) | ||
1488 | return (LL_FILE); | ||
1489 | else | ||
1490 | return (LL_OTHER); | ||
1491 | } | ||
1492 | |||
1493 | |||
1494 | /* open the file (using filemode) and seek to the login entry */ | ||
1495 | static int | ||
1496 | lastlog_openseek(struct logininfo *li, int *fd, int filemode) | ||
1497 | { | ||
1498 | off_t offset; | ||
1499 | int type; | ||
1500 | char lastlog_file[1024]; | ||
1501 | |||
1502 | type = lastlog_filetype(LASTLOG_FILE); | ||
1503 | switch (type) { | ||
1504 | case LL_FILE: | ||
1505 | strlcpy(lastlog_file, LASTLOG_FILE, | ||
1506 | sizeof(lastlog_file)); | ||
1507 | break; | ||
1508 | case LL_DIR: | ||
1509 | snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", | 1475 | snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", |
1510 | LASTLOG_FILE, li->username); | 1476 | LASTLOG_FILE, li->username); |
1511 | break; | 1477 | } else if (S_ISREG(st.st_mode)) { |
1512 | default: | 1478 | strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); |
1479 | } else { | ||
1513 | logit("%s: %.100s is not a file or directory!", __func__, | 1480 | logit("%s: %.100s is not a file or directory!", __func__, |
1514 | LASTLOG_FILE); | 1481 | LASTLOG_FILE); |
1515 | return (0); | 1482 | return (0); |
@@ -1522,7 +1489,7 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) | |||
1522 | return (0); | 1489 | return (0); |
1523 | } | 1490 | } |
1524 | 1491 | ||
1525 | if (type == LL_FILE) { | 1492 | if (S_ISREG(st.st_mode)) { |
1526 | /* find this uid's offset in the lastlog file */ | 1493 | /* find this uid's offset in the lastlog file */ |
1527 | offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); | 1494 | offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); |
1528 | 1495 | ||
@@ -1535,52 +1502,74 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) | |||
1535 | 1502 | ||
1536 | return (1); | 1503 | return (1); |
1537 | } | 1504 | } |
1505 | #endif /* !LASTLOG_WRITE_PUTUTXLINE || !HAVE_GETLASTLOGXBYNAME */ | ||
1538 | 1506 | ||
1539 | static int | 1507 | #ifdef LASTLOG_WRITE_PUTUTXLINE |
1540 | lastlog_perform_login(struct logininfo *li) | 1508 | int |
1509 | lastlog_write_entry(struct logininfo *li) | ||
1541 | { | 1510 | { |
1542 | struct lastlog last; | 1511 | switch(li->type) { |
1543 | int fd; | 1512 | case LTYPE_LOGIN: |
1544 | 1513 | return 1; /* lastlog written by pututxline */ | |
1545 | /* create our struct lastlog */ | 1514 | default: |
1546 | lastlog_construct(li, &last); | 1515 | logit("lastlog_write_entry: Invalid type field"); |
1547 | 1516 | return 0; | |
1548 | if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) | ||
1549 | return (0); | ||
1550 | |||
1551 | /* write the entry */ | ||
1552 | if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { | ||
1553 | close(fd); | ||
1554 | logit("%s: Error writing to %s: %s", __func__, | ||
1555 | LASTLOG_FILE, strerror(errno)); | ||
1556 | return (0); | ||
1557 | } | 1517 | } |
1558 | |||
1559 | close(fd); | ||
1560 | return (1); | ||
1561 | } | 1518 | } |
1562 | 1519 | #else /* LASTLOG_WRITE_PUTUTXLINE */ | |
1563 | int | 1520 | int |
1564 | lastlog_write_entry(struct logininfo *li) | 1521 | lastlog_write_entry(struct logininfo *li) |
1565 | { | 1522 | { |
1523 | struct lastlog last; | ||
1524 | int fd; | ||
1525 | |||
1566 | switch(li->type) { | 1526 | switch(li->type) { |
1567 | case LTYPE_LOGIN: | 1527 | case LTYPE_LOGIN: |
1568 | return (lastlog_perform_login(li)); | 1528 | /* create our struct lastlog */ |
1529 | memset(&last, '\0', sizeof(last)); | ||
1530 | line_stripname(last.ll_line, li->line, sizeof(last.ll_line)); | ||
1531 | strlcpy(last.ll_host, li->hostname, | ||
1532 | MIN_SIZEOF(last.ll_host, li->hostname)); | ||
1533 | last.ll_time = li->tv_sec; | ||
1534 | |||
1535 | if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) | ||
1536 | return (0); | ||
1537 | |||
1538 | /* write the entry */ | ||
1539 | if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { | ||
1540 | close(fd); | ||
1541 | logit("%s: Error writing to %s: %s", __func__, | ||
1542 | LASTLOG_FILE, strerror(errno)); | ||
1543 | return (0); | ||
1544 | } | ||
1545 | |||
1546 | close(fd); | ||
1547 | return (1); | ||
1569 | default: | 1548 | default: |
1570 | logit("%s: Invalid type field", __func__); | 1549 | logit("%s: Invalid type field", __func__); |
1571 | return (0); | 1550 | return (0); |
1572 | } | 1551 | } |
1573 | } | 1552 | } |
1553 | #endif /* LASTLOG_WRITE_PUTUTXLINE */ | ||
1574 | 1554 | ||
1575 | static void | 1555 | #ifdef HAVE_GETLASTLOGXBYNAME |
1576 | lastlog_populate_entry(struct logininfo *li, struct lastlog *last) | 1556 | int |
1557 | lastlog_get_entry(struct logininfo *li) | ||
1577 | { | 1558 | { |
1578 | line_fullname(li->line, last->ll_line, sizeof(li->line)); | 1559 | struct lastlogx l, *ll; |
1579 | strlcpy(li->hostname, last->ll_host, | ||
1580 | MIN_SIZEOF(li->hostname, last->ll_host)); | ||
1581 | li->tv_sec = last->ll_time; | ||
1582 | } | ||
1583 | 1560 | ||
1561 | if ((ll = getlastlogxbyname(li->username, &l)) == NULL) { | ||
1562 | memset(&l, '\0', sizeof(l)); | ||
1563 | ll = &l; | ||
1564 | } | ||
1565 | line_fullname(li->line, ll->ll_line, sizeof(li->line)); | ||
1566 | strlcpy(li->hostname, ll->ll_host, | ||
1567 | MIN_SIZEOF(li->hostname, ll->ll_host)); | ||
1568 | li->tv_sec = ll->ll_tv.tv_sec; | ||
1569 | li->tv_usec = ll->ll_tv.tv_usec; | ||
1570 | return (1); | ||
1571 | } | ||
1572 | #else /* HAVE_GETLASTLOGXBYNAME */ | ||
1584 | int | 1573 | int |
1585 | lastlog_get_entry(struct logininfo *li) | 1574 | lastlog_get_entry(struct logininfo *li) |
1586 | { | 1575 | { |
@@ -1598,7 +1587,10 @@ lastlog_get_entry(struct logininfo *li) | |||
1598 | memset(&last, '\0', sizeof(last)); | 1587 | memset(&last, '\0', sizeof(last)); |
1599 | /* FALLTHRU */ | 1588 | /* FALLTHRU */ |
1600 | case sizeof(last): | 1589 | case sizeof(last): |
1601 | lastlog_populate_entry(li, &last); | 1590 | line_fullname(li->line, last.ll_line, sizeof(li->line)); |
1591 | strlcpy(li->hostname, last.ll_host, | ||
1592 | MIN_SIZEOF(li->hostname, last.ll_host)); | ||
1593 | li->tv_sec = last.ll_time; | ||
1602 | return (1); | 1594 | return (1); |
1603 | case -1: | 1595 | case -1: |
1604 | error("%s: Error reading from %s: %s", __func__, | 1596 | error("%s: Error reading from %s: %s", __func__, |
@@ -1613,6 +1605,7 @@ lastlog_get_entry(struct logininfo *li) | |||
1613 | /* NOTREACHED */ | 1605 | /* NOTREACHED */ |
1614 | return (0); | 1606 | return (0); |
1615 | } | 1607 | } |
1608 | #endif /* HAVE_GETLASTLOGXBYNAME */ | ||
1616 | #endif /* USE_LASTLOG */ | 1609 | #endif /* USE_LASTLOG */ |
1617 | 1610 | ||
1618 | #ifdef USE_BTMP | 1611 | #ifdef USE_BTMP |