diff options
Diffstat (limited to 'loginrec.c')
-rw-r--r-- | loginrec.c | 139 |
1 files changed, 66 insertions, 73 deletions
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 |