Jeremie Courreges-Anglas <[email protected]> wrote: |So here's the update to s-nail-14.8.3.
No maintainer could do that any better! We yearn for someone like you! (I think we don't pine, though.) |This release brings an additional executable to perform dot-locking |against mailboxes. Since by default on OpenBSD /var/mail belongs to |root:wheel, mode 755 there is no way for that (setgid) executable to |work, so I removed it from the build (WANT_PRIVSEP=0). You and William could also use the attached patch, feel free and use any possible combination of PRIVSEP_USER= and PRIVSEP_GROUP=, e.g., you may do WANT_PRIVSEP=yes PRIVSEP_USER=root PRIVSEP_GROUP= It is on the [master] branch now. Ciao, and thanks again! --steffen
commit 8296012 Author: Steffen (Daode) Nurpmeso <[email protected]> Date: 2015-07-07 00:56:08 +0200 WANT_PRIVSEP: add optional PRIVSEP_USER, try setuid(2) if given --- make.rc | 5 +++++ mk-mk.in | 15 +++++++++++++-- privsep.c | 42 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/make.rc b/make.rc index 130f333..da31ccf 100644 --- a/make.rc +++ b/make.rc @@ -205,8 +205,13 @@ WANT_COLOUR=yes # SETGID that has the sole purpose and functionality of managing this dotlock. # WANT_PRIVSEP enables this mini dotlock program, which will be installed in # LIBEXECDIR SETGID to the group PRIVSEP_GROUP. +# If you set PRIVSEP_USER to any value then the binary will be installed +# SETUID and will try to change user identity. +# You can define _GROUP and _USER and have it installed SETUID *and* SETGID. +# But note nothing prevents you from giving two empty values. WANT_PRIVSEP=yes PRIVSEP_GROUP=mail +PRIVSEP_USER= ## PATHS AND PROGRAMS ## diff --git a/mk-mk.in b/mk-mk.in index 4fb6537..3fe411b 100644 --- a/mk-mk.in +++ b/mk-mk.in @@ -220,8 +220,19 @@ install: _install_echoes mk.mk mkman.1 mkrc.rc if [ -n "$(OPTIONAL_PRIVSEP)" ]; then \ __mkdir "$(DESTDIR)$(LIBEXECDIR)";\ __stripfile "$(PRIVSEP)";\ - __copychownfile 2555 ":$(PRIVSEP_GROUP)" "$(PRIVSEP)" \ - "$(DESTDIR)$(LIBEXECDIR)/$(PRIVSEP)";\ + m='o=rx' o=;\ + if [ -n "$(PRIVSEP_GROUP)" ]; then \ + m="g=rxs,$${m}" o=":$(PRIVSEP_GROUP)";\ + else \ + m="g=rx,$${m}";\ + fi;\ + if [ -n "$(PRIVSEP_USER)" ]; then \ + m="u=rxs,$${m}" o="$(PRIVSEP_USER)$${o}";\ + else \ + m="u=rx,$${m}";\ + fi;\ + __copychownfile "$${m}" "$${o}" "$(PRIVSEP)" \ + "$(DESTDIR)$(LIBEXECDIR)/$(PRIVSEP)";\ fi;\ __mkdir "$(DESTDIR)$(MANDIR)/man1";\ __copyfile 0444 ./mkman.1 "$(DESTDIR)$(MANDIR)/man1/$(UAGENT).1";\ diff --git a/privsep.c b/privsep.c index fb1e47c..83ebf97 100644 --- a/privsep.c +++ b/privsep.c @@ -34,9 +34,6 @@ _ign_signal(int signum) nact.sa_handler = SIG_IGN; sigemptyset(&nact.sa_mask); nact.sa_flags = 0; -#ifdef SA_RESTART - nact.sa_flags |= SA_RESTART; -#endif sigaction(signum, &nact, &oact); } @@ -47,7 +44,7 @@ main(int argc, char **argv) char const *name, *hostname, *randstr; size_t pollmsecs; enum dotlock_state dls; - gid_t gid, egid; + bool_t anyid; /* We're a dumb helper, ensure as much as we can noone else uses us */ if (argc != 10 || @@ -74,11 +71,40 @@ main(int argc, char **argv) randstr = argv[7]; pollmsecs = (size_t)strtoul(argv[9], NULL, 10); - /* Try to change our group identity; to catch faulty installations etc. + /* Try to change our identity; to catch faulty installations etc. + * don't baild if UID==EUID or setuid() fails, but simply continue, * don't baild if GID==EGID or setgid() fails, but simply continue */ - gid = getgid(); - egid = getegid(); - if (gid == egid || setgid(egid)) { + anyid = FAL0; + + if (PRIVSEP_USER[0] != '\0') { + uid_t uid = getuid(), euid = geteuid(); + + if (uid != euid) { + if (setuid(euid)) { + dls = DLS_PRIVFAILED; + if (UICMP(z, write(STDOUT_FILENO, &dls, sizeof dls), !=, + sizeof dls)) + goto jerr; + } + anyid = TRU1; + } + } + + if (PRIVSEP_GROUP[0] != '\0') { + gid_t gid = getgid(), egid = getegid(); + + if (gid != egid) { + if (setgid(egid)) { + dls = DLS_PRIVFAILED; + if (UICMP(z, write(STDOUT_FILENO, &dls, sizeof dls), !=, + sizeof dls)) + goto jerr; + } + anyid = TRU1; + } + } + + if (!anyid) { dls = DLS_PRIVFAILED; if (UICMP(z, write(STDOUT_FILENO, &dls, sizeof dls), !=, sizeof dls)) goto jerr;
