Duncaen / OpenDoas

A portable fork of the OpenBSD `doas` command
Other
623 stars 35 forks source link

Provide a fallback for setresuid(2). #38

Closed snimmagadda closed 3 years ago

snimmagadda commented 3 years ago

On platforms(NetBSD, MacOS) missing setresuid(2), fallback to setuid(2)/setgid(2).

Duncaen commented 3 years ago

It might make sense to switch back to setusercontext, setresuid etc was a fallback for when its not available.

Duncaen commented 3 years ago

This should improve NetBSD support, for MacOS I guess something like the current patch would work.

From 603c0f9283193edc3fffe8931a05a8af837c0a37 Mon Sep 17 00:00:00 2001
From: Duncan Overbruck <mail@duncano.de>
Date: Thu, 5 Nov 2020 21:00:16 +0100
Subject: [PATCH] check for login_cap.h and use setusercontext if available

---
 configure | 10 ++++++++++
 doas.c    | 10 ++++++++++
 2 files changed, 20 insertions(+)

diff --git a/configure b/configure
index 4ae9b69..a9b37bd 100755
--- a/configure
+++ b/configure
@@ -451,6 +451,16 @@ int main(void) {
 }'
 check_func "ndir_h" "$src"

+#
+# Check for login_cap.h.
+#
+src='
+#include <login_cap.h>
+int main(void) {
+   return 0;
+}'
+check_func "login_cap_h" "$src"
+
 #
 #
 #
diff --git a/doas.c b/doas.c
index dea68f8..33ccd9d 100644
--- a/doas.c
+++ b/doas.c
@@ -20,6 +20,9 @@
 #include <sys/ioctl.h>

 #include <limits.h>
+#ifdef HAVE_LOGIN_CAP_H
+#include <login_cap.h>
+#endif
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -379,12 +382,19 @@ main(int argc, char **argv)
        rule->options & PERSIST);
 #endif

+#ifdef HAVE_LOGIN_CAP_H
+   if (setusercontext(NULL, pw, target, LOGIN_SETGROUP |
+       LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK |
+       LOGIN_SETUSER) != 0)
+       errx(1, "failed to set user context for target");
+#else
    if (setresgid(targpw->pw_gid, targpw->pw_gid, targpw->pw_gid) != 0)
        err(1, "setresgid");
    if (initgroups(targpw->pw_name, targpw->pw_gid) != 0)
        err(1, "initgroups");
    if (setresuid(target, target, target) != 0)
        err(1, "setresuid");
+#endif

    if (getcwd(cwdpath, sizeof(cwdpath)) == NULL)
        cwd = "(failed)";
-- 
2.29.2
snimmagadda commented 3 years ago

This should improve NetBSD support, for MacOS I guess something like the current patch would work.

Thanks, a few comments...

diff --git a/configure b/configure index 4ae9b69..a9b37bd 100755 --- a/configure +++ b/configure @@ -451,6 +451,16 @@ int main(void) { }' check_func "ndir_h" "$src"

+# +# Check for login_cap.h. +# +src=' +#include +int main(void) {

  • return 0; +}' +check_func "login_cap_h" "$src"

Perhaps add '#include <sys/types.h>', otherwise check_func ignores warnings and... Checking for login_cap_h ... no.

Still need this hunk to let configure proceed...

-check_func "setresuid" "$src" || die "system has no setresuid(2): not supported" +check_func "setresuid" "$src"

@@ -379,12 +382,19 @@ main(int argc, char **argv) rule->options & PERSIST);

endif

+#ifdef HAVE_LOGIN_CAP_H

  • if (setusercontext(NULL, pw, target, LOGIN_SETGROUP |

Should the second arg be targpw? Fails to compile.

  • LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK |
  • LOGIN_SETUSER) != 0)
  • errx(1, "failed to set user context for target"); +#else if (setresgid(targpw->pw_gid, targpw->pw_gid, targpw->pw_gid) != 0) err(1, "setresgid"); if (initgroups(targpw->pw_name, targpw->pw_gid) != 0) err(1, "initgroups"); if (setresuid(target, target, target) != 0) err(1, "setresuid"); +#endif

    if (getcwd(cwdpath, sizeof(cwdpath)) == NULL) cwd = "(failed)";

Also, another setresuid(2) in checkconfig() requires this HAVE_LOGIN_CAP_H guard.

snimmagadda commented 3 years ago

While this is under review, I looked around how openssh-portable handles setresuid(2) and adapted it for opendoas in PR #40.

snimmagadda commented 3 years ago

Thanks, closing these PRs.