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; };