summaryrefslogtreecommitdiff
path: root/loginrec.c
diff options
context:
space:
mode:
Diffstat (limited to 'loginrec.c')
-rw-r--r--loginrec.c139
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
1463static void
1464lastlog_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 */
1475static int 1462static int
1476lastlog_filetype(char *filename) 1463lastlog_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 */
1495static int
1496lastlog_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
1539static int 1507#ifdef LASTLOG_WRITE_PUTUTXLINE
1540lastlog_perform_login(struct logininfo *li) 1508int
1509lastlog_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 */
1563int 1520int
1564lastlog_write_entry(struct logininfo *li) 1521lastlog_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
1575static void 1555#ifdef HAVE_GETLASTLOGXBYNAME
1576lastlog_populate_entry(struct logininfo *li, struct lastlog *last) 1556int
1557lastlog_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 */
1584int 1573int
1585lastlog_get_entry(struct logininfo *li) 1574lastlog_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