Making SRFI-170 less of a monster hga@xxxxxx 02 Aug 2019 08:23 UTC
Amendment 1 to Making SRFI-170 less of a monster hga@xxxxxx 02 Aug 2019 12:38 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster John Cowan 02 Aug 2019 17:43 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 02 Aug 2019 18:41 UTC
(missing)
Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 02 Aug 2019 19:53 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster hga@xxxxxx 02 Aug 2019 20:00 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster John Cowan 02 Aug 2019 20:44 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster John Cowan 02 Aug 2019 21:22 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 02 Aug 2019 21:24 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster John Cowan 02 Aug 2019 21:50 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster hga@xxxxxx 02 Aug 2019 21:28 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 02 Aug 2019 22:02 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster hga@xxxxxx 09 Aug 2019 21:40 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 09 Aug 2019 22:25 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster hga@xxxxxx 09 Aug 2019 22:53 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster John Cowan 10 Aug 2019 01:33 UTC
Unix logging systems Lassi Kortela 10 Aug 2019 08:19 UTC
Re: Unix logging systems Duy Nguyen 10 Aug 2019 11:00 UTC
Re: Unix logging systems hga@xxxxxx 10 Aug 2019 11:47 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster hga@xxxxxx 02 Aug 2019 20:50 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster John Cowan 02 Aug 2019 21:39 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster hga@xxxxxx 02 Aug 2019 22:42 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 02 Aug 2019 22:55 UTC
Re: Amendment 1 to Making SRFI-170 less of a monster John Cowan 03 Aug 2019 02:51 UTC

Re: Amendment 1 to Making SRFI-170 less of a monster Lassi Kortela 02 Aug 2019 21:24 UTC

>     Oops, I left out of my first insomnia inspired message removing *all*
>     of 3.6, User and group database access, that was why I later added
>     back a direct group-info:members procedure.
>
> Still thinking about this.  I continue to think that because stat()
> exposes uids and gids, there needs to be a way to convert them to the
> strings we all know and love.

IMHO:

- include a procedure to get user info by UID (getpwuid())

- include a procedure to get group info by GID (getgrgid())

- leave out procedure to get user/group info by name (getpwnam())
   Programs should not use Unix usernames for access control.
   Sysadmins should set permissions using usernames interactively,
   but under the hood, the UIDs become the ground truth.

- leave out the procedure to enumerate all users/groups (getpwent()).
   These may involve deeply complex NIS (network user database) stuff.
   Even the getpwent() BSD manual page says:

   "NOTE that getpwent() may cause a very lengthy search for user account
   records by opendirectoryd and may result in a large number of user
   account records being cached by the calling process.  Use of this
   function is not advised."

   Getting one user/group can also invoke NIS, but doesn't need to walk
   the entire list, and most requests will probably hit the local cache.

The object returned by the getpwuid() wrapper can be an opaque object
with the pw_name (username), pw_uid, pw_gid, pw_gecos (full name) and
pw_dir (home directory) fields. Plus any optional implementation-defined
fields

The object returned by the getgrgid() wrapper should have the gr_gid and
gr_name fields, plus optional implementation-defined ones.

>     Except now that you point it out, we should also include a single
>     direct call that returns the home directory,
>
> And sets it.  Lots of programs are greatly simplified if they can set
> the working directory.

- The home directory is most reliably found out via getpwuid() as above.

- The current directory is getcwd() / chdir(). I support including both
   of these as straightforward wrappers of those Unix calls.

>     Unless any of you can think of sufficient 80/20 reasons to browse
>     other people's accounts, or find out who's in X group, etc.??
>
> Not I.

Neither do I.

>     Especially with John's suggestion to keep file-info-regular?, I'm
>     thinking of doing this in an inverse fashion, only providing
>     predicates for the file system objects that are relevant to the
>     putative user of this SRFI, i.e. regular files and directories.
>
> I think that makes sense:  regular-file? and directory?.

I'd maybe favor a single file-type procedure that returns a symbol. Ruby
has that (ftype, which returns a string). Easy to check in a case statement.

It can return 'file or 'directory or an implementation-defined value.
(It might be worth it to also standardize 'socket, as well as 'pipe
a.k.a. fifo. We could have a 'device value but as both of you pointed
out, there's little that can portably be done with devices - except
things like reading /dev/null or /dev/random where you don't have to
care it's a device.)

>     It's a *colossal* can of worms, my last Lisp project in anger, a
>     Clojure website for a non-profit I was volunteering for a few years
>     ago, had to deal with them, but only the US ones.  I haven't even
>     found a POSIX way to return the current time zone as a string,
>     although I haven't looked very hard yet.
>
> Can't be done, though /etc/timezone is an approximation.  But come to
> think of it, the *user's* notion of the current timezone is and should
> be simply the TZ variable.  So flush current-timezone.

These comments makes me think timezones should have their own SRFI. A
delightful array of historical, political, notational, scientific and
technical problems rolled into one happy bundle.

> Luckily, we can
> bootstrap a full implementation of timezones using the binary data files
> in /usr/share/zoneinfo.  It's not there on Windows, but every copy of
> Java, Ruby, Python, etc. plusave individual apps (each their own copy,
> of course, it's Windows) that don't want to expose people to the
> *severe* limitations of Windows timezones.  Or we can just have people
> download them from
> <https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz>.
> (WinZip and 7-Zip can extract tarballs.)

We could have a canonical Scheme library to parse the tzdata files and
convert to S-expressions which Scheme can easily read. Maybe there's
such a library already.

>     That's a bit messy to do portably as we're doing it now, seems the
>     strategy is to make them high numbers.  A problem this current POSIX
>     SRFI has is that it has to use the official ones, so errno-error will
>     return a sane string.
>
> I think Lassi meant that idea only for Scheme-level exceptions like
> "can't open input file" and making it possible to pull the errno out of
> that, not to *supply* arbitrary errno values to arbitrary user exceptions.

Correct. The ability for users to make new exceptions with arbitrary
errno values could come in handy too, didn't think about that.

>     But all that said, *we* can't prevent someone from setting
>     their binary set-uid root.

Luckily the problems of setuid have been publicized enough by now that
most sysadmins worth their salt are going to recoil in horror at the
suggestion to install any new setuid binaries on their premises :)

>     We *could* view giving them setuid
>     etc. calls in this base SRFI to use after doing high privilege stuff
>     as encouraging them to go down this dark path.
>
> Just so.  Flush it all.

I agree that it's best to leave those calls to some kind of security
SRFI (if Scheme should offer them at all).

It's not really a dark path - starting as root to do some initialization
and then dropping privileges is sound design. (OpenBSD's new pledge()
framework is a great case study in gradually relinquishing privileges,
and how that solves a plethora of issues in a simple way.)

But root privileges should always be dropped very early on in the
lifetime of the program, or perhaps leave just a main poll() loop
running as root and forking off unprivileged subprocesses as needed. I
agree with John that Scheme is not an ideal substrate for this kind of
work. Simplicity at the low level is key here.

The daemontools / runit uses chain-loaded shell commands to configure
and load daemons, which works brilliantly. For example, there's a
'setuidgid' program that drops to the UID and GID you want and then runs
the remainder of the command line under those credentials. Similar
chain-loading commands for setting resource limits, etc. So you write a
simple script using those commands to start the daemon that actually
stays alive to do all the complex stuff that daemons do. But by the time
that daemon starts, most of the setup has been done by the chain-loading
scripts already. It's simple and brilliant. And the chain-loading tools
are reusable and so simple that they are easy to audit.