Re: utmps: database cursor position and pututxline(3)
I'm lamenting the sorry state of basic user administration and security software on Linux. You and me both. ;) I think the communities around my software and related software such as musl are made of individuals who recognize that there's huge room for improvement in that area, and try to make it better, step by step. Better software need to exist, and then it needs to acquire traction. It's slow, really slow, but we're working on it. musl today is a lot more popular than it was 5 years ago. In the same time frame, s6 has become relatively popular in Docker containers. Progress happens. A better model for user authentication and sign-in across services is something I've never really spent time thinking about, because it's basically related to networking, and networking is *hard*, and I'm still not done with improvements on the local machine. Let's talk about it again in 10 years. ;) -- Laurent
Re: utmps: database cursor position and pututxline(3)
Thanks for sharing your thoughts - I appreciate, and learn from, your input. Again I didn't mean to belittle or devalue your work, quite the opposite. I'm disappointed and underwhelmed by the interface and its usage, not by the implementation. Also referring to the s6 as an "ecosystem" was silly, sorry. The s6 infrastructure would be more appropriate. On Mon, Apr 12, 2021 at 1:14 PM Laurent Bercot wrote: > > I have exactly zero doubt that any attempt at designing a "modern" > framework for user accounting would manage to do worse than utmp. > systemd has done exactly that. Other attempts would be similar. > People who would actually take time and energy to do this right are > not interested in doing it, because user accounting is 1. ultimately > user snooping, and 2. becoming useless by the day with the way Unix > is used now. > > As you said, it's best to let it die - not because utmp is bad, but > because *the concept of user accounting* is bad. > It's true that the old days of time-sharing and university servers with dozens of users are long gone and in that light full user accounting is pretty useless and privacy-invading. But the basic feature of reliably and trustingly keeping track of which users are connected to the system at any given time remains essential. And it would be nice if it were done across services (e.g. mail, smb, web, etc.), not just terminal logins, without having to run a dozen different tools or consult a dozen different logs. Some kind of self-hosted Kerberos, if you will, although it's not the correct analogy since Kerberos is only concerned about authentication, but hopefully you get the idea, with the accompanying reporting tools. Which could be extended and upscaled to a centralized client/server model if needed with a choice of back-ends. I'm lamenting the sorry state of basic user administration and security software on Linux. We have antiquated tools such as shadow-utils, util-linux, which code is laden with legacy stuff and burdened with hooks to linux-pam, SElinux, libaudit, utmp, and whatnot. Then there are the services, which are more or less equally afflicted. It looks like a big ol' mess to me. On one side we have bare-bones embedded Linux systems powering IoT devices which are woefully insecure, constantly hacked and participating in botnets. On another side we have Red Hat (aka IBM) bloated monsters. There is no "modern" middle-ground that I'm aware of.
Re: utmps: database cursor position and pututxline(3)
I only did some ad-hoc testing with the only 2 programs that both read and write to utmp and that I have integrated with utmps: util-linux login and OpenSSH. And I used the simple tests I attached earlier. All good. Cool, thanks. I'll still give it some more thought. The fact that my earlier modification is broken is exactly why I didn't do it in the first place, and I'm an idiot for having changed it without thinking, and that's what happens when I'm looking at those things during the week-end while doing something else. :P So now I'm going to think it through and find the correct way of implementing that change. It may be your patch; it may be different. And let me mention once more that I hate vague specifications that sound simple but have hidden complexity like this. I will also use the opportunity to understand what's going on with the ut_id field. Now that that's done, I'm having second-thoughts about this whole utmp/wtmp endeavor and wondering if it's worth the efforts. Don't get me wrong, I think your implementation fulfills its premises of security and robustness quite well, and I like how it fits within the s6 "ecosystem". But the POSIX API and data structures feel clunky and archaic. Take for example the id field, which is an arbitrary 4-character string used to uniquely identify an entry in the database. That doesn't strike me as very robust nor secure, given that there is no mechanism to prevent id collisions. Well yes, it's not a secret that utmp sucks. Rich Felker may have made the right choice in leaving it on the cutting floor and expecting that no-one would miss it. Perhaps we should just let it die. Users want 'who' to work. musl-based distributions can't make 'who' work. Users blame the lack of 'who' on musl and stop using musl-based distributions. Having a working utmp implementation makes users happy and helps with musl adoption. The reason why Rich didn't implement utmp in musl is not that the API and data structures are bad. There is *plenty* of suckage in the POSIX standard - starting with something everyone uses: stdio! - and he happily implemented 99% of it. The reason is that utmp is not implementable in a libc without requiring suid/sgid binaries to modify the database, see https://wiki.musl-libc.org/faq.html#Q:-Why-is-the-utmp/wtmp-functionality-only-implemented-as-stubs? So it's not "the APIs suck", it's "it's a security risk". utmps is the only existing *secure* utmp implementation, because it relies on daemons and kernel-verified client credentials to actually access the database, and removes the need for suid/sgid. The "needs daemons to work securely" part is why it can't be done inside of a libc; you could consider utmps as a companion package to musl for a complete implementation of the standard. Isn't there a modern framework equivalent for user accounting on *nix-like systems? I mean beside systemd of course :) I have exactly zero doubt that any attempt at designing a "modern" framework for user accounting would manage to do worse than utmp. systemd has done exactly that. Other attempts would be similar. People who would actually take time and energy to do this right are not interested in doing it, because user accounting is 1. ultimately user snooping, and 2. becoming useless by the day with the way Unix is used now. As you said, it's best to let it die - not because utmp is bad, but because *the concept of user accounting* is bad. I'm just providing a utmp implementation that is as secure as possible for existing programs that use it, because people want those programs to work; but if you like user accounting, then you'll have to deal with all the flaws of utmp. :P -- Laurent
Re: utmps: database cursor position and pututxline(3)
Attached is a patch for the approach I suggested previously. I only did some ad-hoc testing with the only 2 programs that both read and write to utmp and that I have integrated with utmps: util-linux login and OpenSSH. And I used the simple tests I attached earlier. All good. login is happy, OpenSSH is happy. I'm happy. That's good enough for me. I re-read the POSIX doc and it doesn't seem there is any egregious violation. YMMV. If you'd like to incorporate the patch, you're welcome to do so. I tried to follow your coding style but please feel free to rewrite to match your coding standards as you see fit :) Now that that's done, I'm having second-thoughts about this whole utmp/wtmp endeavor and wondering if it's worth the efforts. Don't get me wrong, I think your implementation fulfills its premises of security and robustness quite well, and I like how it fits within the s6 "ecosystem". But the POSIX API and data structures feel clunky and archaic. Take for example the id field, which is an arbitrary 4-character string used to uniquely identify an entry in the database. That doesn't strike me as very robust nor secure, given that there is no mechanism to prevent id collisions. Rich Felker may have made the right choice in leaving it on the cutting floor and expecting that no-one would miss it. Perhaps we should just let it die. Isn't there a modern framework equivalent for user accounting on *nix-like systems? I mean beside systemd of course :)
Re: utmps: database cursor position and pututxline(3)
On Sun, Apr 11, 2021 at 2:31 PM Laurent Bercot wrote: > > Fixed in git, please try it and tell me if it works for you. > (I simply made the getutx*() functions stay on the current record on > success, instead of pointing to the next record.) > Thanks for the quick changes. So the good news is that putuxline() following getuxid() or getuxline() correctly overwrites the matched record. The bad news is that getutxent() is suffering from a self-inflicted DoS :) setutxent(); while (getutxent()); will give you an infinite loop (reading the first record over and over again). I'd suggest another approach that should work better, at least on paper: instead of doing onestepback() at the end of each do_getutx*(), revert those changes and do onestepback() in do_putline() before entering the idmatch() loop - taking care to ignore the failure (EINVAL) of onestepback() if we're at the start of database. There may be scenarios where this may not be correct. I haven't thought it through properly. Unless you have other ideas you'd rather try, I'll experiment with this approach a bit and let you know the results. In the meantime you may want to back out your commit because it's pretty broken right now unfortunately.
Re: utmps: database cursor position and pututxline(3)
Fixed in git, please try it and tell me if it works for you. (I simply made the getutx*() functions stay on the current record on success, instead of pointing to the next record.) -- Laurent
Re: utmps: database cursor position and pututxline(3)
What's your take on this? My interpretation of the POSIX doc is that pututxline(3) should start searching from the last entry found/read, not from the next entry after it. Well, yes, as you said, the spec is unclear, but the login(1) and glibc interpretation makes sense: after a getutxline() you kinda want to be able to directly pututxline() on the same record. In any case utmps should align on existing behaviour, even when it contradicts the spec - it already does that for record selection, for instance: glibc's getutxid() is not quite compliant (I forget the exact details but a strictly compliant utmps-utmpd would not work and I had to modify its id matching). So yes, I'll change the record-reading routines so they stop on the current record on success. I'll also add WTMPX_FILE because it doesn't harm anything - it treads on namespace a bit, but glibc's already does. Thanks for the reports. -- Laurent