8.37. Shadow-4.17.3

The Shadow package contains programs for handling passwords in a secure way.

Approximate build time: 0.1 SBU
Required disk space: 114 MB

8.37.1. Installation of Shadow

Create the PKGBUILD for the Shadow package with the following commands:

mkdir /sources/shadow
cd /sources/shadow
cat > PKGBUILD << "REALEOF"
# Maintainer: Linux From Scratch <lfs-dev@lists.linuxfromscratch.org>

pkgname="shadow"
pkgver="4.17.3"
pkgrel="1"
pkgdesc="The Shadow package contains programs for handling passwords in a secure way."
arch=('x86'
      'x86_64')
url="https://github.com/shadow-maint/shadow/"
license=('BSD3C')
groups=('core')
depends=('glibc'
         'libxcrypt'
         'linux-pam')
makedepends=('acl'
             'attr'
             'bash'
             'binutils'
             'coreutils'
             'diffutils'
             'findutils'
             'gawk'
             'gcc'
             'gettext'
             'grep'
             'libcap'
             'make'
             'sed')
source=('https://github.com/shadow-maint/shadow/releases/download/4.17.3/shadow-4.17.3.tar.xz')
md5sums=('0da190e53ecee76237e4c8f3f39531ed')
backup=('etc/default/useradd'
        'etc/login.defs'
        'etc/pam.d/login'
        'etc/pam.d/passwd'
        'etc/pam.d/su'
        'etc/pam.d/chage'
        'etc/pam.d/chfn'
        'etc/pam.d/chgpasswd'
        'etc/pam.d/chpasswd'
        'etc/pam.d/chsh'
        'etc/pam.d/groupadd'
        'etc/pam.d/groupdel'
        'etc/pam.d/groupmems'
        'etc/pam.d/groupmod'
        'etc/pam.d/newusers'
        'etc/pam.d/useradd'
        'etc/pam.d/userdel'
        'etc/pam.d/usermod')

prepare() {
  cd "${pkgname}-${pkgver}"

  # Don't install groups utility (use Coreutils version)
  sed -i 's/groups$(EXEEXT) //' src/Makefile.in

  # Don't install groups man-page either
  find man -name Makefile.in -exec sed -i 's/groups\.1 / /'   {} \;

  # Don't install these as man-pages version is better
  find man -name Makefile.in -exec sed -i 's/getspnam\.3 / /' {} \;
  find man -name Makefile.in -exec sed -i 's/passwd\.5 / /'   {} \;

  # Use YESCRYPT instead of MD5, correct mail spool dir, and correct
  # duplicate PATH entries due to merged /usr
  sed -e 's@#ENCRYPT_METHOD DES@ENCRYPT_METHOD YESCRYPT@' \
      -e 's@/var/spool/mail@/var/mail@'                   \
      -e '/PATH=/{s@/sbin:@@;s@/bin:@@}'                  \
      -i etc/login.defs
}

build() {
  cd "${pkgname}-${pkgver}"
  ./configure --sysconfdir=/etc   \
              --disable-static    \
              --without-libbsd    \
              --with-{b,yes}crypt
  make
}

package() {
  cd "${pkgname}-${pkgver}"
  make DESTDIR="${pkgdir}" exec_prefix=/usr pamddir= install
  make DESTDIR="${pkgdir}" -C man install-man

  # Disable login.defs functions that are hanled by Linud-PAM
  for FUNCTION in FAIL_DELAY               \
                  FAILLOG_ENAB             \
                  LASTLOG_ENAB             \
                  MAIL_CHECK_ENAB          \
                  OBSCURE_CHECKS_ENAB      \
                  PORTTIME_CHECKS_ENAB     \
                  QUOTAS_ENAB              \
                  CONSOLE MOTD_FILE        \
                  FTMP_FILE NOLOGINS_FILE  \
                  ENV_HZ PASS_MIN_LEN      \
                  SU_WHEEL_ONLY            \
                  CRACKLIB_DICTPATH        \
                  PASS_CHANGE_TRIES        \
                  PASS_ALWAYS_WARN         \
                  CHFN_AUTH ENCRYPT_METHOD \
                  ENVIRON_FILE
  do
    sed -i "s/^${FUNCTION}/# &/" "${pkgdir}/etc/login.defs"
  done

  install -vdm755 "${pkgdir}/etc/pam.d"

  # login
  cat > "${pkgdir}/etc/pam.d/login" << "EOF"
# Begin /etc/pam.d/login

# Set failure delay before next prompt to 3 seconds
auth      optional    pam_faildelay.so  delay=3000000

# Check to make sure that the user is allowed to login
auth      requisite   pam_nologin.so

# Check to make sure that root is allowed to login
# Disabled by default. You will need to create /etc/securetty
# file for this module to function. See man 5 securetty.
#auth      required    pam_securetty.so

# Additional group memberships - disabled by default
#auth      optional    pam_group.so

# include system auth settings
auth      include     system-auth

# check access for the user
account   required    pam_access.so

# include system account settings
account   include     system-account

# Set default environment variables for the user
session   required    pam_env.so

# Set resource limits for the user
session   required    pam_limits.so

# Display the message of the day - Disabled by default
#session   optional    pam_motd.so

# Check user's mail - Disabled by default
#session   optional    pam_mail.so      standard quiet

# include system session and password settings
session   include     system-session
password  include     system-password

# End /etc/pam.d/login
EOF

  # passwd
  cat > "${pkgdir}/etc/pam.d/passwd" << "EOF"
# Begin /etc/pam.d/passwd

password  include     system-password

# End /etc/pam.d/passwd
EOF

  # su
  cat > "${pkgdir}/etc/pam.d/su" << "EOF"
# Begin /etc/pam.d/su

# always allow root
auth      sufficient  pam_rootok.so

# Allow users in the wheel group to execute su without a password
# disabled by default
#auth      sufficient  pam_wheel.so trust use_uid

# include system auth settings
auth      include     system-auth

# limit su to users in the wheel group
# disabled by default
#auth      required    pam_wheel.so use_uid

# include system account settings
account   include     system-account

# Set default environment variables for the service user
session   required    pam_env.so

# include system session settings
session   include     system-session

# End /etc/pam.d/su
EOF

  # chpasswd and newusers
  cat > "${pkgdir}/etc/pam.d/chpasswd" << "EOF"
# Begin /etc/pam.d/chpasswd

# always allow root
auth      sufficient  pam_rootok.so

# include system auth and account settings
auth      include     system-auth
account   include     system-account
password  include     system-password

# End /etc/pam.d/chpasswd
EOF
  sed -e s/chpasswd/newusers/ \
      "${pkgdir}/etc/pam.d/chpasswd" > \
      "${pkgdir}/etc/pam.d/newusers"

  # chage
  cat > "${pkgdir}/etc/pam.d/chage" << "EOF"
# Begin /etc/pam.d/chage

# always allow root
auth      sufficient  pam_rootok.so

# include system auth and account settings
auth      include     system-auth
account   include     system-account

# End /etc/pam.d/chage
EOF

  # chfn chgpasswd chsh groupadd groupdel
  # groupmems groupmod useradd userdel usermod
  for PROGRAM in chfn chgpasswd chsh groupadd groupdel \
                 groupmems groupmod useradd userdel usermod
  do
    install -v -m644 "${pkgdir}/etc/pam.d/chage" \
                     "${pkgdir}/etc/pam.d/${PROGRAM}"
    sed -i "s/chage/${PROGRAM}/" "${pkgdir}/etc/pam.d/${PROGRAM}"
  done

  install -vdm755 "${pkgdir}/etc/default"
  cat > "${pkgdir}/etc/default/useradd" << "EOF"
# useradd defaults file
GROUP=999
GROUPS=
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
USRSKEL=/usr/etc/skel
CREATE_MAIL_SPOOL=no
LOG_INIT=yes
EOF

  # remove /etc/login.access and /etc/limits as they are not used
  rm -fv "${pkgdir}"/etc/{login.access,limits}

  # Install the Linux-PAM file here too
  cat > /etc/pam.d/system-account << "EOF"
# Begin /etc/pam.d/system-account

account   required    pam_unix.so

# End /etc/pam.d/system-account
EOF

  cat > /etc/pam.d/system-auth << "EOF"
# Begin /etc/pam.d/system-auth

auth      optional    pam_cap.so
auth      required    pam_unix.so

# End /etc/pam.d/system-auth
EOF

  cat > /etc/pam.d/system-session << "EOF"
# Begin /etc/pam.d/system-session

session   required    pam_unix.so

# End /etc/pam.d/system-session
EOF

  cat > /etc/pam.d/system-password << "EOF"
# Begin /etc/pam.d/system-password

# check new passwords for strength (man pam_pwquality)
password  required    pam_pwquality.so   authtok_type=UNIX retry=1 difok=1 \
                                         minlen=8 dcredit=0 ucredit=0 \
                                         lcredit=0 ocredit=0 minclass=1 \
                                         maxrepeat=0 maxsequence=0 \
                                         maxclassrepeat=0 gecoscheck=0 \
                                         dictcheck=1 usercheck=1 \
                                         enforcing=1 badwords="" \
                                         dictpath=/usr/lib/cracklib/pw_dict

# use yescrypt hash for encryption, use shadow, and try to use any
# previously defined authentication token (chosen password) set by any
# prior module.
password  required    pam_unix.so        yescrypt shadow try_first_pass

# End /etc/pam.d/system-password
EOF

  cat > /etc/pam.d/other << "EOF"
# Begin /etc/pam.d/other

auth        required        pam_warn.so
auth        required        pam_deny.so
account     required        pam_warn.so
account     required        pam_deny.so
password    required        pam_warn.so
password    required        pam_deny.so
session     required        pam_warn.so
session     required        pam_deny.so

# End /etc/pam.d/other
EOF

  # Ensure minimum group warning is below 1000 (system groups)
  install -vdm755 ${pkgdir}/etc/default/
  echo "GROUPS=999" > ${pkgdir}/etc/default/useradd
}
REALEOF

The meaning of the new configure options and configuration changes:

touch /usr/bin/passwd

The file /usr/bin/passwd needs to exist because its location is hardcoded in some programs; if it does not already exist, the installation script will create it in the wrong place.

--with-{b,yes}crypt

The shell expands this to two switches, --with-bcrypt and --with-yescrypt. They allow shadow to use the Bcrypt and Yescrypt algorithms implemented by Libxcrypt for hashing passwords. These algorithms are more secure (in particular, much more resistant to GPU-based attacks) than the traditional SHA algorithms.

--with-group-name-max-length=32

The longest permissible user name is 32 characters. Make the maximum length of a group name the same.

--without-libbsd

Do not use the readpassphrase function from libbsd which is not in LFS. Use the internal copy instead.

GROUP=999

This parameter sets the beginning of the group numbers used in the /etc/group file. The particular value 999 comes from the --gid parameter above. You may set it to any desired value. Note that useradd will never reuse a UID or GID. If the number identified in this parameter is used, it will use the next available number. Note also that if you don't have a group with an ID equal to this number on your system, then the first time you use useradd without the -g parameter, an error message will be generated—useradd: unknown GID 999, even though the account has been created correctly. That is why we created the group users with this group ID in Section 7.6, “Creating Essential Files and Symlinks.”

CREATE_MAIL_SPOOL=yes

This parameter causes useradd to create a mailbox file for each new user. useradd will assign the group ownership of this file to the mail group with 0660 permissions. If you would rather not create these files, issue the following command:

sed -i '/MAIL/s/yes/no/' /etc/default/useradd

Prepare the build directory for the pacman user and build the package:

chown -R root:pacman .
chmod 2775 .
chmod 664 PKGBUILD
su pacman -c 'makepkg -L --nodeps'

Add the newly created package to the central package repository:

cp shadow-4.17.3-1-$(uname -m).pkg.tar.xz \
   /srv/pacman/repos/LFS/
repo-add /srv/pacman/repos/LFS/LFS.db.tar.xz \
         /srv/pacman/repos/LFS/shadow-4.17.3-1-$(uname -m).pkg.tar.xz

Update the local cache and install the Shadow package:

pacman -Syu
pacman -S shadow - -overwrite \* -dd - -noconfirm

Finally, copy the source files into the source repository and clean up the build directory:

mkdir /srv/pacman/source/LFS/shadow
cp PKGBUILD /srv/pacman/source/LFS/shadow
cd /sources
rm -rf shadow

8.37.2. Contents of Shadow

Installed programs: chage, chfn, chgpasswd, chpasswd, chsh, expiry, faillog, getsubids, gpasswd, groupadd, groupdel, groupmems, groupmod, grpck, grpconv, grpunconv, login, logoutd, newgidmap, newgrp, newuidmap, newusers, nologin, passwd, pwck, pwconv, pwunconv, sg (link to newgrp), su, useradd, userdel, usermod, vigr (link to vipw), and vipw
Installed directories: /etc/default and /usr/include/shadow
Installed libraries: libsubid.so

Short Descriptions

chage

Used to change the maximum number of days between obligatory password changes

chfn

Used to change a user's full name and other information

chgpasswd

Used to update group passwords in batch mode

chpasswd

Used to update user passwords in batch mode

chsh

Used to change a user's default login shell

expiry

Checks and enforces the current password expiration policy

faillog

Is used to examine the log of login failures, to set a maximum number of failures before an account is blocked, and to reset the failure count

getsubids

Is used to list the subordinate id ranges for a user

gpasswd

Is used to add and delete members and administrators to groups

groupadd

Creates a group with the given name

groupdel

Deletes the group with the given name

groupmems

Allows a user to administer his/her own group membership list without the requirement of super user privileges.

groupmod

Is used to modify the given group's name or GID

grpck

Verifies the integrity of the group files /etc/group and /etc/gshadow

grpconv

Creates or updates the shadow group file from the normal group file

grpunconv

Updates /etc/group from /etc/gshadow and then deletes the latter

login

Is used by the system to let users sign on

logoutd

Is a daemon used to enforce restrictions on log-on time and ports

newgidmap

Is used to set the gid mapping of a user namespace

newgrp

Is used to change the current GID during a login session

newuidmap

Is used to set the uid mapping of a user namespace

newusers

Is used to create or update an entire series of user accounts

nologin

Displays a message saying an account is not available; it is designed to be used as the default shell for disabled accounts

passwd

Is used to change the password for a user or group account

pwck

Verifies the integrity of the password files /etc/passwd and /etc/shadow

pwconv

Creates or updates the shadow password file from the normal password file

pwunconv

Updates /etc/passwd from /etc/shadow and then deletes the latter

sg

Executes a given command while the user's GID is set to that of the given group

su

Runs a shell with substitute user and group IDs

useradd

Creates a new user with the given name, or updates the default new-user information

userdel

Deletes the specified user account

usermod

Is used to modify the given user's login name, user identification (UID), shell, initial group, home directory, etc.

vigr

Edits the /etc/group or /etc/gshadow files

vipw

Edits the /etc/passwd or /etc/shadow files

libsubid

library to handle subordinate id ranges for users and groups