Merge branch '2020wk12' of https://github.com/kerolasa/util-linux
* '2020wk12' of https://github.com/kerolasa/util-linux: lslogins: use lastlog as wtmp fallback login: avoid lseek() with pread() and pwrite() libuuid: ensure variable is initialized [cppcheck] ctrlaltdel: display error message indicated by errno
This commit is contained in:
commit
737b972fbc
|
@ -23,7 +23,7 @@ _lslogins_module()
|
||||||
COMPREPLY=( $(compgen -W "short full iso" -- $cur) )
|
COMPREPLY=( $(compgen -W "short full iso" -- $cur) )
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
'--wtmp-file'|'--btmp-file')
|
'--wtmp-file'|'--btmp-file'|'--lastlog')
|
||||||
local IFS=$'\n'
|
local IFS=$'\n'
|
||||||
compopt -o filenames
|
compopt -o filenames
|
||||||
COMPREPLY=( $(compgen -f -- $cur) )
|
COMPREPLY=( $(compgen -f -- $cur) )
|
||||||
|
@ -69,6 +69,7 @@ _lslogins_module()
|
||||||
--print0
|
--print0
|
||||||
--wtmp-file
|
--wtmp-file
|
||||||
--btmp-file
|
--btmp-file
|
||||||
|
--lastlog
|
||||||
--help
|
--help
|
||||||
--version
|
--version
|
||||||
" -- $cur) )
|
" -- $cur) )
|
||||||
|
|
|
@ -136,7 +136,7 @@ static int get_node_id(unsigned char *node_id)
|
||||||
struct ifconf ifc;
|
struct ifconf ifc;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int n, i;
|
int n, i;
|
||||||
unsigned char *a;
|
unsigned char *a = NULL;
|
||||||
#ifdef HAVE_NET_IF_DL_H
|
#ifdef HAVE_NET_IF_DL_H
|
||||||
struct sockaddr_dl *sdlp;
|
struct sockaddr_dl *sdlp;
|
||||||
#endif
|
#endif
|
||||||
|
@ -194,7 +194,7 @@ static int get_node_id(unsigned char *node_id)
|
||||||
#endif /* HAVE_NET_IF_DL_H */
|
#endif /* HAVE_NET_IF_DL_H */
|
||||||
#endif /* SIOCGENADDR */
|
#endif /* SIOCGENADDR */
|
||||||
#endif /* SIOCGIFHWADDR */
|
#endif /* SIOCGIFHWADDR */
|
||||||
if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
|
if (a == NULL || (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]))
|
||||||
continue;
|
continue;
|
||||||
if (node_id) {
|
if (node_id) {
|
||||||
memcpy(node_id, a, 6);
|
memcpy(node_id, a, 6);
|
||||||
|
|
|
@ -498,6 +498,7 @@ static void log_lastlog(struct login_context *cxt)
|
||||||
{
|
{
|
||||||
struct sigaction sa, oldsa_xfsz;
|
struct sigaction sa, oldsa_xfsz;
|
||||||
struct lastlog ll;
|
struct lastlog ll;
|
||||||
|
off_t offset;
|
||||||
time_t t;
|
time_t t;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
@ -515,16 +516,14 @@ static void log_lastlog(struct login_context *cxt)
|
||||||
fd = open(_PATH_LASTLOG, O_RDWR, 0);
|
fd = open(_PATH_LASTLOG, O_RDWR, 0);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
offset = cxt->pwd->pw_uid * sizeof(ll);
|
||||||
if (lseek(fd, (off_t) cxt->pwd->pw_uid * sizeof(ll), SEEK_SET) == -1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print last log message.
|
* Print last log message.
|
||||||
*/
|
*/
|
||||||
if (!cxt->quiet) {
|
if (!cxt->quiet) {
|
||||||
if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
|
if ((pread(fd, (void *)&ll, sizeof(ll), offset) == sizeof(ll)) &&
|
||||||
ll.ll_time != 0) {
|
ll.ll_time != 0) {
|
||||||
char time_string[CTIME_BUFSIZ];
|
char time_string[CTIME_BUFSIZ];
|
||||||
|
|
||||||
time_t ll_time = (time_t) ll.ll_time;
|
time_t ll_time = (time_t) ll.ll_time;
|
||||||
|
@ -538,8 +537,6 @@ static void log_lastlog(struct login_context *cxt)
|
||||||
printf(_("on %.*s\n"),
|
printf(_("on %.*s\n"),
|
||||||
(int)sizeof(ll.ll_line), ll.ll_line);
|
(int)sizeof(ll.ll_line), ll.ll_line);
|
||||||
}
|
}
|
||||||
if (lseek(fd, (off_t) cxt->pwd->pw_uid * sizeof(ll), SEEK_SET) == -1)
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset((char *)&ll, 0, sizeof(ll));
|
memset((char *)&ll, 0, sizeof(ll));
|
||||||
|
@ -552,7 +549,7 @@ static void log_lastlog(struct login_context *cxt)
|
||||||
if (cxt->hostname)
|
if (cxt->hostname)
|
||||||
str2memcpy(ll.ll_host, cxt->hostname, sizeof(ll.ll_host));
|
str2memcpy(ll.ll_host, cxt->hostname, sizeof(ll.ll_host));
|
||||||
|
|
||||||
if (write_all(fd, (char *)&ll, sizeof(ll)))
|
if (pwrite(fd, (void *)&ll, sizeof(ll), offset) != sizeof(ll))
|
||||||
warn(_("write lastlog failed"));
|
warn(_("write lastlog failed"));
|
||||||
done:
|
done:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
|
|
|
@ -113,6 +113,9 @@ Display version information and exit.
|
||||||
\fB\-\-wtmp\-file \fIpath\fP
|
\fB\-\-wtmp\-file \fIpath\fP
|
||||||
Alternate path for wtmp.
|
Alternate path for wtmp.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-\-lastlog \fIpath\fP
|
||||||
|
Alternate path for lastlog.
|
||||||
|
.TP
|
||||||
\fB\-Z\fR, \fB\-\-context\fR
|
\fB\-Z\fR, \fB\-\-context\fR
|
||||||
Display the users' security context.
|
Display the users' security context.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <search.h>
|
#include <search.h>
|
||||||
|
#include <lastlog.h>
|
||||||
|
|
||||||
#include <libsmartcols.h>
|
#include <libsmartcols.h>
|
||||||
#ifdef HAVE_LIBSELINUX
|
#ifdef HAVE_LIBSELINUX
|
||||||
|
@ -95,6 +96,12 @@ enum {
|
||||||
OUT_PRETTY
|
OUT_PRETTY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LASTLOG_TIME,
|
||||||
|
LASTLOG_LINE,
|
||||||
|
LASTLOG_HOST
|
||||||
|
};
|
||||||
|
|
||||||
struct lslogins_user {
|
struct lslogins_user {
|
||||||
char *login;
|
char *login;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
@ -252,6 +259,8 @@ struct lslogins_control {
|
||||||
struct utmpx *btmp;
|
struct utmpx *btmp;
|
||||||
size_t btmp_size;
|
size_t btmp_size;
|
||||||
|
|
||||||
|
int lastlogin_fd;
|
||||||
|
|
||||||
void *usertree;
|
void *usertree;
|
||||||
|
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
@ -516,6 +525,31 @@ static int parse_btmp(struct lslogins_control *ctl, char *path)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_lastlog(struct lslogins_control *ctl, uid_t uid, void *dst, int what)
|
||||||
|
{
|
||||||
|
struct lastlog ll;
|
||||||
|
|
||||||
|
if (ctl->lastlogin_fd < 0 ||
|
||||||
|
pread(ctl->lastlogin_fd, (void *)&ll, sizeof(ll), uid * sizeof(ll)) != sizeof(ll))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (what) {
|
||||||
|
case LASTLOG_TIME: {
|
||||||
|
time_t *t = (time_t *)dst;
|
||||||
|
*t = ll.ll_time;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LASTLOG_LINE:
|
||||||
|
mem2strcpy(dst, ll.ll_line, sizeof(ll.ll_line), sizeof(ll.ll_line) + 1);
|
||||||
|
break;
|
||||||
|
case LASTLOG_HOST:
|
||||||
|
mem2strcpy(dst, ll.ll_host, sizeof(ll.ll_host), sizeof(ll.ll_host) + 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int get_sgroups(gid_t **list, size_t *len, struct passwd *pwd)
|
static int get_sgroups(gid_t **list, size_t *len, struct passwd *pwd)
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -737,23 +771,31 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c
|
||||||
if (user_wtmp) {
|
if (user_wtmp) {
|
||||||
time = user_wtmp->ut_tv.tv_sec;
|
time = user_wtmp->ut_tv.tv_sec;
|
||||||
user->last_login = make_time(ctl->time_mode, time);
|
user->last_login = make_time(ctl->time_mode, time);
|
||||||
|
} else {
|
||||||
|
time = 0;
|
||||||
|
get_lastlog(ctl, pwd->pw_uid, &time, LASTLOG_TIME);
|
||||||
|
if (time)
|
||||||
|
user->last_login = make_time(ctl->time_mode, time);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COL_LAST_TTY:
|
case COL_LAST_TTY:
|
||||||
|
user->last_tty = xcalloc(1, sizeof(user_wtmp->ut_line) + 1);
|
||||||
if (user_wtmp) {
|
if (user_wtmp) {
|
||||||
user->last_tty = xmalloc(sizeof(user_wtmp->ut_line) + 1);
|
|
||||||
mem2strcpy(user->last_tty, user_wtmp->ut_line,
|
mem2strcpy(user->last_tty, user_wtmp->ut_line,
|
||||||
sizeof(user_wtmp->ut_line),
|
sizeof(user_wtmp->ut_line),
|
||||||
sizeof(user_wtmp->ut_line) + 1);;
|
sizeof(user_wtmp->ut_line) + 1);;
|
||||||
|
} else {
|
||||||
|
get_lastlog(ctl, user->uid, user->last_tty, LASTLOG_LINE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COL_LAST_HOSTNAME:
|
case COL_LAST_HOSTNAME:
|
||||||
|
user->last_hostname = xcalloc(1, sizeof(user_wtmp->ut_host) + 1);
|
||||||
if (user_wtmp) {
|
if (user_wtmp) {
|
||||||
user->last_hostname = xmalloc(sizeof(user_wtmp->ut_host) + 1);
|
|
||||||
mem2strcpy(user->last_hostname, user_wtmp->ut_host,
|
mem2strcpy(user->last_hostname, user_wtmp->ut_host,
|
||||||
sizeof(user_wtmp->ut_host),
|
sizeof(user_wtmp->ut_host),
|
||||||
sizeof(user_wtmp->ut_host) + 1);;
|
sizeof(user_wtmp->ut_host) + 1);;
|
||||||
}
|
} else
|
||||||
|
get_lastlog(ctl, user->uid, user->last_hostname, LASTLOG_HOST);
|
||||||
break;
|
break;
|
||||||
case COL_FAILED_LOGIN:
|
case COL_FAILED_LOGIN:
|
||||||
if (user_btmp) {
|
if (user_btmp) {
|
||||||
|
@ -1363,6 +1405,7 @@ static void __attribute__((__noreturn__)) usage(void)
|
||||||
fputs(_(" -z, --print0 delimit user entries with a nul character\n"), out);
|
fputs(_(" -z, --print0 delimit user entries with a nul character\n"), out);
|
||||||
fputs(_(" --wtmp-file <path> set an alternate path for wtmp\n"), out);
|
fputs(_(" --wtmp-file <path> set an alternate path for wtmp\n"), out);
|
||||||
fputs(_(" --btmp-file <path> set an alternate path for btmp\n"), out);
|
fputs(_(" --btmp-file <path> set an alternate path for btmp\n"), out);
|
||||||
|
fputs(_(" --lastlog <path> set an alternate path for lastlog\n"), out);
|
||||||
fputs(USAGE_SEPARATOR, out);
|
fputs(USAGE_SEPARATOR, out);
|
||||||
printf(USAGE_HELP_OPTIONS(26));
|
printf(USAGE_HELP_OPTIONS(26));
|
||||||
|
|
||||||
|
@ -1379,7 +1422,7 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
char *logins = NULL, *groups = NULL, *outarg = NULL;
|
char *logins = NULL, *groups = NULL, *outarg = NULL;
|
||||||
char *path_wtmp = _PATH_WTMP, *path_btmp = _PATH_BTMP;
|
char *path_lastlog = _PATH_LASTLOG, *path_wtmp = _PATH_WTMP, *path_btmp = _PATH_BTMP;
|
||||||
struct lslogins_control *ctl = xcalloc(1, sizeof(struct lslogins_control));
|
struct lslogins_control *ctl = xcalloc(1, sizeof(struct lslogins_control));
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -1387,6 +1430,7 @@ int main(int argc, char *argv[])
|
||||||
enum {
|
enum {
|
||||||
OPT_WTMP = CHAR_MAX + 1,
|
OPT_WTMP = CHAR_MAX + 1,
|
||||||
OPT_BTMP,
|
OPT_BTMP,
|
||||||
|
OPT_LASTLOG,
|
||||||
OPT_NOTRUNC,
|
OPT_NOTRUNC,
|
||||||
OPT_NOHEAD,
|
OPT_NOHEAD,
|
||||||
OPT_TIME_FMT,
|
OPT_TIME_FMT,
|
||||||
|
@ -1417,6 +1461,7 @@ int main(int argc, char *argv[])
|
||||||
{ "print0", no_argument, 0, 'z' },
|
{ "print0", no_argument, 0, 'z' },
|
||||||
{ "wtmp-file", required_argument, 0, OPT_WTMP },
|
{ "wtmp-file", required_argument, 0, OPT_WTMP },
|
||||||
{ "btmp-file", required_argument, 0, OPT_BTMP },
|
{ "btmp-file", required_argument, 0, OPT_BTMP },
|
||||||
|
{ "lastlog-file", required_argument, 0, OPT_LASTLOG },
|
||||||
#ifdef HAVE_LIBSELINUX
|
#ifdef HAVE_LIBSELINUX
|
||||||
{ "context", no_argument, 0, 'Z' },
|
{ "context", no_argument, 0, 'Z' },
|
||||||
#endif
|
#endif
|
||||||
|
@ -1524,6 +1569,9 @@ int main(int argc, char *argv[])
|
||||||
case 'z':
|
case 'z':
|
||||||
outmode = OUT_NUL;
|
outmode = OUT_NUL;
|
||||||
break;
|
break;
|
||||||
|
case OPT_LASTLOG:
|
||||||
|
path_lastlog = optarg;
|
||||||
|
break;
|
||||||
case OPT_WTMP:
|
case OPT_WTMP:
|
||||||
path_wtmp = optarg;
|
path_wtmp = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -1591,8 +1639,10 @@ int main(int argc, char *argv[])
|
||||||
&ncolumns, column_name_to_id) < 0)
|
&ncolumns, column_name_to_id) < 0)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
if (require_wtmp())
|
if (require_wtmp()) {
|
||||||
parse_wtmp(ctl, path_wtmp);
|
parse_wtmp(ctl, path_wtmp);
|
||||||
|
ctl->lastlogin_fd = open(path_lastlog, O_RDONLY, 0);
|
||||||
|
}
|
||||||
if (require_btmp())
|
if (require_btmp())
|
||||||
parse_btmp(ctl, path_btmp);
|
parse_btmp(ctl, path_btmp);
|
||||||
|
|
||||||
|
@ -1606,6 +1656,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
scols_unref_table(tb);
|
scols_unref_table(tb);
|
||||||
tdestroy(ctl->usertree, free_user);
|
tdestroy(ctl->usertree, free_user);
|
||||||
|
close(ctl->lastlogin_fd);
|
||||||
free_ctl(ctl);
|
free_ctl(ctl);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -75,7 +75,7 @@ static int set_cad(const char *arg)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (reboot(cmd) < 0) {
|
if (reboot(cmd) < 0) {
|
||||||
warnx("reboot");
|
warn("reboot");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue