Index: usr.bin/last/last.c =================================================================== --- usr.bin/last/last.c +++ usr.bin/last/last.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include @@ -47,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -117,12 +119,18 @@ int main(int argc, char *argv[]) { + cap_rights_t rights; int ch; char *p; (void) setlocale(LC_TIME, ""); d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); + /* + * Cache UTX database fds. + */ + setutxent(); + maxrec = -1; snaptime = 0; while ((ch = getopt(argc, argv, "0123456789d:f:h:n:st:wy")) != -1) @@ -147,6 +155,8 @@ break; case 'f': file = optarg; + if (setutxdb(UTXDB_LOG, file) != 0) + err(1, "%s", file); break; case 'h': hostconv(optarg); @@ -176,6 +186,24 @@ usage(); } + cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_READ, CAP_WRITE); + if ((cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) || + (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) || + (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)) + err(1, "can't limit stdio rights"); + + /* + * Cache NLS data, for strerror, for err(3), before entering capability + * mode. + */ + (void)catopen("libc", NL_CAT_LOCALE); + + /* Cache timezone. */ + tzset(); + + if (cap_enter() < 0 && errno != ENOSYS) + err(1, "cap_enter"); + if (sflag && width == 8) usage(); if (argc) { @@ -213,8 +241,6 @@ (void)time(&t); /* Load the last entries from the file. */ - if (setutxdb(UTXDB_LOG, file) != 0) - err(1, "%s", file); while ((ut = getutxent()) != NULL) { if (amount % 128 == 0) { buf = realloc(buf, (amount + 128) * sizeof *ut);