lastlog2 as Y2038 safe lastlog replacement
Hi, I don't know if anybody here did read my blogs about this, but 64bit systems using glibc have still at minimum three Y2038 problems: utmp, wtmp and lastlog. More details can be found here: https://www.thkukuk.de/blog/Y2038_glibc_utmp_64bit/ https://www.thkukuk.de/blog/Y2038_glibc_wtmp_64bit/ https://www.thkukuk.de/blog/Y2038_glibc_lastlog_64bit/ Over the weekend we activated lastlog2 as lastlog successor in Tumbleweed and MicroOS. On MicroOS we even auto-import the old lastlog file into the new lastlog2 database during the next boot, on Tumbleweed, if you want, you have to that manual: "systemctl start lastlog2-import" The old lastlog implementation will be deactivated after gdm get's submitted to Factory and somebody finally accepts openssh. Upcoming: wtmp: wtmp will be replaced with "wtmpdb". It's currently in security review and the manual pages for it are missing. This will come next. utmp: this is WIP. systemd v254 will contain the necessary additional interfaces. First upstream projects accepted already the first patches. There are currently two problems: "w" from procps and openssh... Thorsten -- Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, Germany Managing Director: Ivo Totev, Andrew Myers, Andrew McDonald, Martje Boudien Moerman (HRB 36809, AG Nürnberg)
ti., april 11 2023 at kl. 11.59 +0000 +00:00:00 skrev Thorsten Kukuk <kukuk@suse.de> følgende:
The old lastlog implementation will be deactivated after gdm get's submitted to Factory and somebody finally accepts openssh.
Are you referring to this gdm change here? $ rpm --query --changelog gdm | head -n 5 * ti. mars 28 2023 Thorsten Kukuk <kukuk@suse.com> - Create two set of pam configuration files: + *-sle.pamd are for SLES15 and older + add postlogin-* includes to the others as required by openSUSEs PAM config policy $ If yes, then I can happily report that it was ack'ed into Factory 3 days ago. /B
On Tue, Apr 11, 2023 at 7:59 AM Thorsten Kukuk <kukuk@suse.de> wrote:
Hi,
I don't know if anybody here did read my blogs about this,
Yes, unfortunately I must say.. fond of the pains of dealing with the poor abstractions of that old interfaces. And yeah, there is no better choice than sqlite for the new database, if we need something reliable and widely supported.
Hello, Am Dienstag, 11. April 2023, 13:59:27 CEST schrieb Thorsten Kukuk:
I don't know if anybody here did read my blogs about this, but 64bit systems using glibc have still at minimum three Y2038 problems: utmp, wtmp and lastlog.
More details can be found here: https://www.thkukuk.de/blog/Y2038_glibc_utmp_64bit/ https://www.thkukuk.de/blog/Y2038_glibc_wtmp_64bit/ https://www.thkukuk.de/blog/Y2038_glibc_lastlog_64bit/
# grep kukuk planet.ini # (no match) ... which leads to the question if you want your blog added on planet.opensuse.org ;-) If so, please have a look at https://github.com/openSUSE/planet-o-o/ to get added. Back to the main topic of your mail - I'm afraid you've missed a user of /var/log/wtmp: aa-notify -l reads it so that it can display AppArmor events since the last login. What is the recommended replacement for getting the date/time a user logged in last time? (Bonus points if that replacement is easily useable from python ;-) Also, is there a good / recommended way to find out if a system only has the old wtmp, or if it also (or only) has the lastlog replacement?
The old lastlog implementation will be deactivated after gdm get's submitted to Factory and somebody finally accepts openssh.
Note that openQA tests aa-notify -l, which means this step will give the tests some color - at least until I know how to implement support for the lastlog replacement. Regards, Christian Boltz -- [Windows remote herunterfahren] einfach ein Nichtgepatchtes Windows verwenden und einen der tausen Viren, die letztes Jahr die Maschinen runter gefahren haben ;) [Andreas Loesch in suse-linux]
On Tue, Apr 11, 2023 at 1:27 PM Christian Boltz <opensuse@cboltz.de> wrote:
What is the recommended replacement for getting the date/time a user logged in last time? (Bonus points if that replacement is easily useable from python ;-)
So, lastlog2 need a python binding I guess.. otherwise one needs to query the database directly, something that if history brings any lesson should be highly discouraged..
On Tue, Apr 11, Christian Boltz wrote:
Back to the main topic of your mail - I'm afraid you've missed a user of /var/log/wtmp: aa-notify -l reads it so that it can display AppArmor events since the last login.
Ah, aa-notify introduces a Y2050 problem for no good reason... And a very complicated way to find out, when the user did login :( wtmp is not a reliable way to find out when the current session started, why not using utmp? Or better logind? There is no policy, rule, best practice or whatever else when an application should create a wtmp entry and what the values should be. As result, the data of the old wtmp file is pure mess :( Beside that logrotate is regularly removing it. systemd-logind is really the best way to find out the time the current user did login.
What is the recommended replacement for getting the date/time a user logged in last time? (Bonus points if that replacement is easily useable from python ;-)
As far as I understand the code, it uses the current login time, not the last one. And the best, robust and correct source for this is systemd-logind. There are several interfaces (DBUS, libsystemd), but I don't know if there is a python interface. Or is it possible to use aa-notify -l for a different user account then the currently running one? Or if you really need to use wtmp (which is not reliable), you can use sqlite and query the wtmp.db directly. This should be a very quick and simple task in python, much easier than parsing the wtmp mess...
Also, is there a good / recommended way to find out if a system only has the old wtmp, or if it also (or only) has the lastlog replacement?
aa-notify is luckily not using lastlog. Because if it would use it, I would recommend to remove the option, the old lastlog is most of the times wrong since there are nearly no applications using it.
The old lastlog implementation will be deactivated after gdm get's submitted to Factory and somebody finally accepts openssh.
Note that openQA tests aa-notify -l, which means this step will give the tests some color - at least until I know how to implement support for the lastlog replacement.
You will need to implement a replacement for wtmp, not lastlog. So it will continue to work for now. But latest 2038 it will horrible break. I don't know the test, I hope you create fake audit entries before. Thorsten -- Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, Germany Managing Director: Ivo Totev, Andrew Myers, Andrew McDonald, Martje Boudien Moerman (HRB 36809, AG Nürnberg)
Hello, Am Dienstag, 11. April 2023, 21:46:45 CEST schrieb Thorsten Kukuk:
On Tue, Apr 11, Christian Boltz wrote:
Back to the main topic of your mail - I'm afraid you've missed a user of /var/log/wtmp: aa-notify -l reads it so that it can display AppArmor events since the last login. Ah, aa-notify introduces a Y2050 problem for no good reason...
Indeed, after it reads the last login from /var/log/wtmp (which will only work until 2038), it will run into a Y2050 problem - well, it would if /var/log/wtmp wouldn't explode in 2038 already ;-) [See non-random signature.] I introduced the Y2050 check after I found out that the wtmp file format is architecture dependent - so far, I'm aware of 3 different formats. Given that, I introduced the Y2050 check to ensure the date looks somewhat sane. (And, while on it and trying to hex-edit a wtmp file for a far-future login, I noticed the Y2038 problem in wtmp. So actually the sanity check could or even should have been 2039 instead of 2050.) Needless to say that I won't use that Y2050 check when using the new method to find out when someone logged in the last time.
And a very complicated way to find out, when the user did login :( wtmp is not a reliable way to find out when the current session started, why not using utmp? Or better logind?
My best guess is that aa-notify existed years before logind, and so far reading /var/log/wtmp worked ;-) utmp probably already existed back then, but I don't know why the original author of aa-notify decided to use wtmp instead.
There is no policy, rule, best practice or whatever else when an application should create a wtmp entry and what the values should be. As result, the data of the old wtmp file is pure mess :( Beside that logrotate is regularly removing it.
systemd-logind is really the best way to find out the time the current user did login.
OK, thanks.
What is the recommended replacement for getting the date/time a user logged in last time? (Bonus points if that replacement is easily useable from python ;-)
As far as I understand the code, it uses the current login time, not the last one. And the best, robust and correct source for this is systemd-logind. There are several interfaces (DBUS, libsystemd), but I don't know if there is a python interface.
In worst case, it shouldn't be too hard to check the output of a command if it provides json output (which systemd commands usually do). I had a look at loginctl - list-sessions looks somewhat useful, but unfortunately doesn't include the login time. user-status has a "Since:" line, but unfortunately ignores "-o json" :-( If I choose the commandline way with json output, do you have a recommendation which command I should use? With DBUS, it looks like I'll need /org/freedesktop/login1 ListSessions and/or /org/freedesktop/login1/user/_$UID Timestamp (assuming I understood man org.freedesktop.login1 right)
Or is it possible to use aa-notify -l for a different user account then the currently running one?
No, it doesn't allow to override the username for -l
Or if you really need to use wtmp (which is not reliable), you can use sqlite and query the wtmp.db directly. This should be a very quick and simple task in python, much easier than parsing the wtmp mess...
Agreed about the wtmp parsing mess. OTOH, I'm not too keen to depend on the table layout of the wtmp.db - even if I'd hope that it doesn't change too often, IIRC I've read that it's not recommended to query this database directly, and that the database layout might change.
Also, is there a good / recommended way to find out if a system only has the old wtmp, or if it also (or only) has the lastlog replacement? aa-notify is luckily not using lastlog. Because if it would use it, I would recommend to remove the option, the old lastlog is most of the times wrong since there are nearly no applications using it.
The old lastlog implementation will be deactivated after gdm get's submitted to Factory and somebody finally accepts openssh.
Note that openQA tests aa-notify -l, which means this step will give the tests some color - at least until I know how to implement support for the lastlog replacement.
You will need to implement a replacement for wtmp, not lastlog. So it
Oops, looks like I confused the various ways to find out when someone logged in...
will continue to work for now. But latest 2038 it will horrible break. I don't know the test, I hope you create fake audit entries before.
I hope that I'll have a working replacement for wtmp before 2038 ;-) (and yes, I'll create fake log entries etc. to avoid surprises) That all said - thanks for your input! Regards, Christian Boltz PS: non-random signature, as promised above --
I see no "do" in your script, so this will give you a "syntax error near unexpected token `done'" after shutdown ;-)) I've been hearing funny noises after shutdown, that must be it :-) [> Christian Boltz and Chris Maaskant in opensuse]
On Thu, Apr 13, Christian Boltz wrote:
Am Dienstag, 11. April 2023, 21:46:45 CEST schrieb Thorsten Kukuk:
And a very complicated way to find out, when the user did login :( wtmp is not a reliable way to find out when the current session started, why not using utmp? Or better logind?
My best guess is that aa-notify existed years before logind, and so far reading /var/log/wtmp worked ;-)
utmp probably already existed back then, but I don't know why the original author of aa-notify decided to use wtmp instead.
Even I'm not old enough ;) to know what was first, utmp or wtmp. But since the struct is called "utmp" and not "wtmp", I would assume that utmp is older, or they were introduced at the same time. Maybe he did not use utmp, as the entry get's removed if the user logs out, which is not the case with wtmp? But this would mean it's possible to use the "-l" option for a different user then the one calling the command?
As far as I understand the code, it uses the current login time, not the last one. And the best, robust and correct source for this is systemd-logind. There are several interfaces (DBUS, libsystemd), but I don't know if there is a python interface.
In worst case, it shouldn't be too hard to check the output of a command if it provides json output (which systemd commands usually do).
I had a look at loginctl - list-sessions looks somewhat useful, but unfortunately doesn't include the login time. user-status has a "Since:" line, but unfortunately ignores "-o json" :-(
If I choose the commandline way with json output, do you have a recommendation which command I should use?
To be honest: no idea. I'm always using libsystemd, and systemd v254 will come with a function "sd_uid_get_login_time" for me ;) I don't know if there are python bindings for libsystemd, else maybe they could be created for this function? Or write a C helper application, which does nothing else then calling this function and prints the result in the format you need?
With DBUS, it looks like I'll need /org/freedesktop/login1 ListSessions and/or /org/freedesktop/login1/user/_$UID Timestamp (assuming I understood man org.freedesktop.login1 right)
To be fair: I don't understand the DBUS API of systemd yet...
Or if you really need to use wtmp (which is not reliable), you can use sqlite and query the wtmp.db directly. This should be a very quick and simple task in python, much easier than parsing the wtmp mess...
Agreed about the wtmp parsing mess. OTOH, I'm not too keen to depend on the table layout of the wtmp.db - even if I'd hope that it doesn't change too often, IIRC I've read that it's not recommended to query this database directly, and that the database layout might change.
We could of course do the same above ideas from me for libsystemd with libwtmpdb, but in that case, I would suggest to use libsystemd, that's more reliable. Thorsten -- Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, Germany Managing Director: Ivo Totev, Andrew Myers, Andrew McDonald, Martje Boudien Moerman (HRB 36809, AG Nürnberg)
On Friday 2023-04-14 08:46, Thorsten Kukuk wrote:
On Thu, Apr 13, Christian Boltz wrote:
Even I'm not old enough ;) to know what was first, utmp or wtmp.
unix-history-repo $ git grep /.tmp init.s: sys creat; utmp; 16 / truncate /tmp/utmp init.s:utmp: </tmp/utmp\0> init.s:wtmp: </tmp/wtmp\0> unix-history-repo $ git log -1 commit c502c14c023c9c1fffe45d69b8a0ae0e85063412 (HEAD, origin/Research-V1-Snapshot-Development) Author: Ken Thompson <ken@research.uucp> Date: Tue Jun 20 05:00:00 1972 -0500
* On 4/14/23 08:46, Thorsten Kukuk wrote:
Even I'm not old enough ;) to know what was first, utmp or wtmp. But since the struct is called "utmp" and not "wtmp", I would assume that utmp is older, or they were introduced at the same time.
utmp is the database for users currently logged in to the machine (which is why it is typically never rotated - it cannot really grow too big unless you have a tremendous amount of users), wtmp is the history of logins (and logouts, which have to be deduced) and btmp is the failed login log. None of them "came first" - they are different things for different concepts. Mihai
participants (6)
-
Bjørn Lie
-
Christian Boltz
-
Cristian Rodríguez
-
Jan Engelhardt
-
Mihai Moldovan
-
Thorsten Kukuk