The branch main has been updated by emaste:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=142b4309f42d5018a92ad5e08943fd1081a9ea57

commit 142b4309f42d5018a92ad5e08943fd1081a9ea57
Author:     Ed Maste <ema...@freebsd.org>
AuthorDate: 2025-06-06 01:27:50 +0000
Commit:     Ed Maste <ema...@freebsd.org>
CommitDate: 2025-08-19 12:48:35 +0000

    pw: Skip root check with alternate root
    
    pw may be run by an unprivileged user for creating an image or jail.
    EPERM will still be reported from the file open if the user does not
    have appropriate permission.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D50710
---
 usr.sbin/pw/pw.8      |  9 +++++++--
 usr.sbin/pw/pw.c      |  1 +
 usr.sbin/pw/pw_user.c | 18 ++++++++++++------
 usr.sbin/pw/pwupd.h   |  1 +
 4 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/usr.sbin/pw/pw.8 b/usr.sbin/pw/pw.8
index c72623ee05b3..5eae810b6732 100644
--- a/usr.sbin/pw/pw.8
+++ b/usr.sbin/pw/pw.8
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd July 29, 2024
+.Dd August 19, 2025
 .Dt PW 8
 .Os
 .Sh NAME
@@ -191,7 +191,12 @@ utility handles updating the
 .Xr master.passwd 5 ,
 .Xr group 5
 and the secure and insecure
-password database files, and must be run as root.
+password database files, and must be run as root
+.Po except when using
+.Fl R
+or
+.Fl V
+.Pc .
 .Pp
 The first one or two keywords provided to
 .Nm
diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c
index fc17f6dba022..a4c95258f3bb 100644
--- a/usr.sbin/pw/pw.c
+++ b/usr.sbin/pw/pw.c
@@ -162,6 +162,7 @@ main(int argc, char *argv[])
                                snprintf(conf.etcpath, sizeof(conf.etcpath),
                                    "%s%s", optarg, arg == 'R' ?
                                    _PATH_PWD : "");
+                               conf.altroot = true;
                        } else
                                break;
                }
diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index d9fd8c77c13e..8a9a4342f5ef 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -238,6 +238,13 @@ perform_chgpwent(const char *name, struct passwd *pwd, 
char *nispasswd)
        }
 }
 
+static void
+pw_check_root(void)
+{
+       if (!conf.altroot && geteuid() != 0)
+               errx(EX_NOPERM, "you must be root");
+}
+
 /*
  * The M_LOCK and M_UNLOCK functions simply add or remove
  * a "*LOCKED*" prefix from in front of the password to
@@ -256,8 +263,7 @@ pw_userlock(char *arg1, int mode)
        bool locked = false;
        uid_t id = (uid_t)-1;
 
-       if (geteuid() != 0)
-               errx(EX_NOPERM, "you must be root");
+       pw_check_root();
 
        if (arg1 == NULL)
                errx(EX_DATAERR, "username or id required");
@@ -1324,8 +1330,8 @@ pw_user_add(int argc, char **argv, char *arg1)
        if (argc > 0)
                usage();
 
-       if (geteuid() != 0 && ! dryrun)
-               errx(EX_NOPERM, "you must be root");
+       if (!dryrun)
+               pw_check_root();
 
        if (quiet)
                freopen(_PATH_DEVNULL, "w", stderr);
@@ -1641,8 +1647,8 @@ pw_user_mod(int argc, char **argv, char *arg1)
        if (argc > 0)
                usage();
 
-       if (geteuid() != 0 && ! dryrun)
-               errx(EX_NOPERM, "you must be root");
+       if (!dryrun)
+               pw_check_root();
 
        if (quiet)
                freopen(_PATH_DEVNULL, "w", stderr);
diff --git a/usr.sbin/pw/pwupd.h b/usr.sbin/pw/pwupd.h
index 262b044e07fc..a39a022ca309 100644
--- a/usr.sbin/pw/pwupd.h
+++ b/usr.sbin/pw/pwupd.h
@@ -78,6 +78,7 @@ struct pwconf {
        char             etcpath[MAXPATHLEN];
        int              fd;
        int              rootfd;
+       bool             altroot;
        bool             checkduplicate;
 };
 

Reply via email to