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;

Reply via email to