The branch stable/14 has been updated by kevans:

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

commit b50d2127d9718e54b68ffead90e9de8b5cee72f5
Author:     Kyle Evans <[email protected]>
AuthorDate: 2024-12-01 19:05:57 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2024-12-10 23:05:51 +0000

    pw: set the user's home directory mode if it existed
    
    The adduser(8) prompt allows one to set the mode of a new home
    directory, but pw(8) doesn't honor the -M mode if the home directory
    already exists at creation time.  It doesn't seem to make sense to
    ignore the mode (which may lead to a security issue on the system being
    configured) when we'll happily chown an existing directory, so fix the
    inconsistency.
    
    PR:             280099
    Reviewed by:    des, jlduran (previous version)
    
    (cherry picked from commit 6a7238fd7c60f35191eadaa026d3d395c6140c47)
---
 usr.sbin/adduser/adduser.8 |  6 ++++--
 usr.sbin/pw/cpdir.c        | 27 +++++++++++++++++++++------
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/usr.sbin/adduser/adduser.8 b/usr.sbin/adduser/adduser.8
index 8ba623fedd9d..e21a7653f250 100644
--- a/usr.sbin/adduser/adduser.8
+++ b/usr.sbin/adduser/adduser.8
@@ -27,7 +27,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 11, 2024
+.Dd December 1, 2024
 .Dt ADDUSER 8
 .Os
 .Sh NAME
@@ -246,7 +246,9 @@ file can reference the internal variables of the
 script.
 .It Fl M Ar mode
 Create the home directory with permissions set to
-.Ar mode .
+.Ar mode ,
+modified by the current
+.Xr umask 2 .
 .It Fl N
 Do not read the default configuration file.
 .It Fl q
diff --git a/usr.sbin/pw/cpdir.c b/usr.sbin/pw/cpdir.c
index 504933ab88af..3dee8f7c43ac 100644
--- a/usr.sbin/pw/cpdir.c
+++ b/usr.sbin/pw/cpdir.c
@@ -49,13 +49,28 @@ copymkdir(int rootfd, char const * dir, int skelfd, mode_t 
mode, uid_t uid,
        if (*dir == '/')
                dir++;
 
-       if (mkdirat(rootfd, dir, mode) != 0 && errno != EEXIST) {
-               warn("mkdir(%s)", dir);
-               return;
+       if (mkdirat(rootfd, dir, mode) != 0) {
+               mode_t pumask;
+
+               if (errno != EEXIST) {
+                       warn("mkdir(%s)", dir);
+                       return;
+               }
+
+               pumask = umask(0);
+               umask(pumask);
+
+               if (fchmodat(rootfd, dir, mode & ~pumask,
+                   AT_SYMLINK_NOFOLLOW) == -1)
+                       warn("chmod(%s)", dir);
        }
-       fchownat(rootfd, dir, uid, gid, AT_SYMLINK_NOFOLLOW);
-       if (flags > 0)
-               chflagsat(rootfd, dir, flags, AT_SYMLINK_NOFOLLOW);
+
+       if (fchownat(rootfd, dir, uid, gid, AT_SYMLINK_NOFOLLOW) == -1)
+               warn("chown(%s)", dir);
+
+       if (flags > 0 && chflagsat(rootfd, dir, flags,
+           AT_SYMLINK_NOFOLLOW) == -1)
+               warn("chflags(%s)", dir);
 
        if (skelfd == -1)
                return;

Reply via email to