diff options
Diffstat (limited to 'patches/source/shadow')
-rw-r--r-- | patches/source/shadow/adduser | 440 | ||||
-rw-r--r-- | patches/source/shadow/doinst.sh | 17 | ||||
-rw-r--r-- | patches/source/shadow/login.defs | 387 | ||||
-rw-r--r-- | patches/source/shadow/patches/README_PATCHES | 9 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3054.diff | 27 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3055.diff | 1515 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3060.diff | 116 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3062.diff | 139 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3096.diff | 27 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3160.diff | 239 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3194.diff | 15 | ||||
-rw-r--r-- | patches/source/shadow/patches/r3299.diff | 12 | ||||
-rwxr-xr-x | patches/source/shadow/shadow.SlackBuild | 165 | ||||
-rw-r--r-- | patches/source/shadow/shadow.url | 1 | ||||
-rw-r--r-- | patches/source/shadow/slack-desc | 19 | ||||
-rw-r--r-- | patches/source/shadow/useradd | 8 |
16 files changed, 3136 insertions, 0 deletions
diff --git a/patches/source/shadow/adduser b/patches/source/shadow/adduser new file mode 100644 index 00000000..5b674a85 --- /dev/null +++ b/patches/source/shadow/adduser @@ -0,0 +1,440 @@ +#!/bin/bash +# +# Copyright 1995 Hrvoje Dogan, Croatia. +# Copyright 2002-2004, 2008, 2009, 2010 Stuart Winter, Surrey, England, UK. +# Copyright 2004, 2008-2010 Slackware Linux, Inc., Concord, CA, USA +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +########################################################################## +# Program: /usr/sbin/adduser +# Purpose: Interactive front end to /usr/sbin/useradd for Slackware Linux +# Author : Stuart Winter <mozes@slackware.com> +# Based on the original Slackware adduser by Hrvoje Dogan +# with modifications by Patrick Volkerding +# Version: 1.13 +########################################################################## +# Usage..: adduser [<new_user_name>] +########################################################################## +# History # +########### +# v1.13 - 13/01/10 +# * Fixed bug that removed underscore characters from UNIX group names. +# Thanks to mRgOBLIN for the report and Jim Hawkins for the fix. <sw> +# v1.12 - 21/07/09 +# * Adjusted the search of /etc/passwd to exclude the NIS inclusion +# string. Thanks to Dominik L. Borkowski. +# v1.11 - 04/06/09 +# * Add power and netdev to the suggested group list +# v1.10 - 24/03/08 +# * To facilitate use of the automatic mounting features of HAL, +# allow the admin to easily add users to the default groups: +# audio,cdrom,video,plugdev,floppy. +# The default is not to add new users to these groups. +# And by the way, this script is "useradd from Slackware" not +# "superadduser from Gentoo" ;-) +# v1.09 - 07/06/04 +# * Added standard Slackware script licence to the head of this file. +# v1.08 - 25/04/04 +# * Disallow user names that begin with a numeric because useradd +# (from shadow v4.03) does not allow them. <sw> +# v1.07 - 07/03/03 +# * When supplying a null string for the uid (meaning 'Choose next available'), +# if there were file names in the range 'a-z' in the pwd then the +# egrep command considered these files rather than the null string. +# The egrep expression is now in quotes. +# Reported & fixed by Vadim O. Ustiansky <sw> +# v1.06 - 31/03/03 +# * Ask to chown user.group the home directory if it already exists. +# This helps reduce later confusion when adding users whose home dir +# already exists (mounted partition for example) and is owned +# by a user other than the user to which the directory is being +# assigned as home. Default is not to chown. +# Brought to my attention by mRgOBLIN. <sw> +# v1.05 - 04/01/03 +# * Advise & prevent users from creating logins with '.' characters +# in the user name. <sw> +# * Made pending account creation info look neater <sw> +# v1.04 - 09/06/02 +# * Catered for shadow-4.0.3's 'useradd' binary that no longer +# will let you create a user that has any uppercase chars in it +# This was reported on the userlocal.org forums +# by 'xcp' - thanks. <sw,pjv> +# v1.03 - 20/05/02 +# * Support 'broken' (null lines in) /etc/passwd and +# /etc/group files <sw> +# * For recycling UIDs (default still 'off'), we now look in +# /etc/login.defs for the UID_MIN value and use it +# If not found then default to 1000 <sw> +# v1.02 - 10/04/02 +# * Fix user-specified UID bug. <pjv> +# v1.01 - 23/03/02 +# * Match Slackware indenting style, simplify. <pjv> +# v1.00 - 22/03/02 +# * Created +####################################################################### + +# Path to files +pfile=/etc/passwd +gfile=/etc/group +sfile=/etc/shells + +# Paths to binaries +useradd=/usr/sbin/useradd +chfn=/usr/bin/chfn +passwd=/usr/bin/passwd +chmod=/bin/chmod + +# Defaults +defhome=/home +defshell=/bin/bash +defchmod=711 # home dir permissions - may be preferable to use 701, however. +defgroup=users +AGID="audio cdrom floppy plugdev video power netdev" # additional groups for desktop users + +# Determine what the minimum UID is (for UID recycling) +# (we ignore it if it's not at the beginning of the line (i.e. commented out with #)) +export recycleUIDMIN="$(grep ^UID_MIN /etc/login.defs | awk '{print $2}' 2>/dev/null)" +# If we couldn't find it, set it to the default of 1000 +if [ -z "$recycleUIDMIN" ]; then + export recycleUIDMIN=1000 # this is the default from Slackware's /etc/login.defs +fi + + +# This setting enables the 'recycling' of older unused UIDs. +# When you userdel a user, it removes it from passwd and shadow but it will +# never get used again unless you specify it expliticly -- useradd (appears to) just +# look at the last line in passwd and increment the uid. I like the idea of +# recycling uids but you may have very good reasons not to (old forgotten +# confidential files still on the system could then be owned by this new user). +# We'll set this to no because this is what the original adduser shell script +# did and it's what users expect. +recycleuids=no + +# Function to read keyboard input. +# bash1 is broken (even ash will take read -ep!), so we work around +# it (even though bash1 is no longer supported on Slackware). +function get_input() { + local output + if [ "`echo $BASH_VERSION | cut -b1`" = "1" ]; then + echo -n "${1} " >&2 # fudge for use with bash v1 + read output + else # this should work with any other /bin/sh + read -ep "${1} " output + fi + echo $output +} + +# Function to display the account info +function display () { + local goose + goose="$(echo $2 | cut -d ' ' -f 2-)" # lop off the prefixed argument useradd needs + echo -n "$1 " + # If it's null then display the 'other' information + if [ -z "$goose" -a ! -z "$3" ]; then + echo "$3" + else + echo "$goose" + fi +} + +# Function to check whether groups exist in the /etc/group file +function check_group () { + local got_error group + if [ ! -z "$@" ]; then + for group in $@ ; do + local uid_not_named="" uid_not_num="" + grep -v "$^" $gfile | awk -F: '{print $1}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_named=yes + grep -v "$^" $gfile | awk -F: '{print $3}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_num=yes + if [ ! -z "$uid_not_named" -a ! -z "$uid_not_num" ]; then + echo "- Group '$group' does not exist" + got_error=yes + fi + done + fi + # Return exit code of 1 if at least one of the groups didn't exist + if [ ! -z "$got_error" ]; then + return 1 + fi +} + +#: Read the login name for the new user :# +# +# Remember that most Mail Transfer Agents are case independant, so having +# 'uSer' and 'user' may cause confusion/things to break. Because of this, +# useradd from shadow-4.0.3 no longer accepts usernames containing uppercase, +# and we must reject them, too. + +# Set the login variable to the command line param +echo +LOGIN="$1" +needinput=yes +while [ ! -z $needinput ]; do + if [ -z "$LOGIN" ]; then + while [ -z "$LOGIN" ]; do LOGIN="$(get_input "Login name for new user []:")" ; done + fi + grep "^${LOGIN}:" $pfile >/dev/null 2>&1 # ensure it's not already used + if [ $? -eq 0 ]; then + echo "- User '$LOGIN' already exists; please choose another" + unset LOGIN + elif [ ! -z "$( echo $LOGIN | grep "^[0-9]" )" ]; then + echo "- User names cannot begin with a number; please choose another" + unset LOGIN + elif [ ! "$LOGIN" = "`echo $LOGIN | tr A-Z a-z`" ]; then # useradd does not allow uppercase + echo "- User '$LOGIN' contains illegal characters (uppercase); please choose another" + unset LOGIN + elif [ ! -z "$( echo $LOGIN | grep '\.' )" ]; then + echo "- User '$LOGIN' contains illegal characters (period/dot); please choose another" + unset LOGIN + else + unset needinput + fi +done + +# Display the user name passed from the shell if it hasn't changed +if [ "$1" = "$LOGIN" ]; then + echo "Login name for new user: $LOGIN" +fi + +#: Get the UID for the user & ensure it's not already in use :# +# +# Whilst we _can_ allow users with identical UIDs, it's not a 'good thing' because +# when you change password for the uid, it finds the first match in /etc/passwd +# which isn't necessarily the correct user +# +echo +needinput=yes +while [ ! -z "$needinput" ]; do + _UID="$(get_input "User ID ('UID') [ defaults to next available ]:")" + egrep -v "^$|^\+" $pfile | awk -F: '{print $3}' | grep "^${_UID}$" >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "- That UID is already in use; please choose another" + elif [ ! -z "$(echo $_UID | egrep '[A-Za-z]')" ]; then + echo "- UIDs are numerics only" + else + unset needinput + fi +done +# If we were given a UID, then syntax up the variable to pass to useradd +if [ ! -z "$_UID" ]; then + U_ID="-u ${_UID}" +else + # Will we be recycling UIDs? + if [ "$recycleuids" = "yes" ]; then + U_ID="-u $(awk -F: '{uid[$3]=1} END { for (i=ENVIRON["recycleUIDMIN"];i in uid;i++);print i}' $pfile)" + fi +fi + +#: Get the initial group for the user & ensure it exists :# +# +# We check /etc/group for both the text version and the group ID number +echo +needinput=yes +while [ ! -z "$needinput" ]; do + GID="$(get_input "Initial group [ ${defgroup} ]:")" + check_group "$GID" + if [ $? -gt 0 ]; then + echo "- Please choose another" + else + unset needinput + fi +done +# Syntax the variable ready for useradd +if [ -z "$GID" ]; then + GID="-g ${defgroup}" +else + GID="-g ${GID}" +fi + +#: Get additional groups for the user :# +# +echo "Additional UNIX groups:" +echo +echo "Users can belong to additional UNIX groups on the system." +echo "For local users using graphical desktop login managers such" +echo "as XDM/KDM, users may need to be members of additional groups" +echo "to access the full functionality of removable media devices." +echo +echo "* Security implications *" +echo "Please be aware that by adding users to additional groups may" +echo "potentially give access to the removable media of other users." +echo +echo "If you are creating a new user for remote shell access only," +echo "users do not need to belong to any additional groups as standard," +echo "so you may press ENTER at the next prompt." +echo +needinput=yes +while [ ! -z "$needinput" ]; do + history -c + history -s "$AGID" + echo "Press ENTER to continue without adding any additional groups" + echo "Or press the UP arrow key to add/select/edit additional groups" + AGID="$(get_input ": " | sed 's/[^A-Za-z0-9 _]//g;s/ */ /g;s/^ $//g' )" + if [ ! -z "$AGID" ]; then + check_group "$AGID" # check all groups at once (treated as N # of params) + if [ $? -gt 0 ]; then + echo "- Please re-enter the group(s)" + echo + else + unset needinput # we found all groups specified + AGID="-G $(echo $AGID | tr ' ' ,)" # useradd takes comma delimited groups + fi + else + unset needinput # we don't *have* to have additional groups + fi +done + +#: Get the new user's home dir :# +# +echo +needinput=yes +while [ ! -z "$needinput" ]; do + HME="$(get_input "Home directory [ ${defhome}/${LOGIN} ]")" + if [ -z "$HME" ]; then + HME="${defhome}/${LOGIN}" + fi + # Warn the user if the home dir already exists + if [ -d "$HME" ]; then + echo "- Warning: '$HME' already exists !" + getyn="$(get_input " Do you wish to change the home directory path ? (Y/n) ")" + if [ "$(echo $getyn | grep -i "n")" ]; then + unset needinput + # You're most likely going to only do this if you have the dir *mounted* for this user's $HOME + getyn="$(get_input " Do you want to chown $LOGIN.$( echo $GID | awk '{print $2}') $HME ? (y/N) ")" + if [ "$(echo $getyn | grep -i "y")" ]; then + CHOWNHOMEDIR=$HME # set this to the home directory + fi + fi + else + unset needinput + fi +done +HME="-d ${HME}" + +#: Get the new user's shell :# +echo +needinput=yes +while [ ! -z "$needinput" ]; do + unset got_error + SHL="$(get_input "Shell [ ${defshell} ]")" + if [ -z "$SHL" ]; then + SHL="${defshell}" + fi + # Warn the user if the shell doesn't exist in /etc/shells or as a file + if [ -z "$(grep "^${SHL}$" $sfile)" ]; then + echo "- Warning: ${SHL} is not in ${sfile} (potential problem using FTP)" + got_error=yes + fi + if [ ! -f "$SHL" ]; then + echo "- Warning: ${SHL} does not exist as a file" + got_error=yes + fi + if [ ! -z "$got_error" ]; then + getyn="$(get_input " Do you wish to change the shell ? (Y/n) ")" + if [ "$(echo $getyn | grep -i "n")" ]; then + unset needinput + fi + else + unset needinput + fi +done +SHL="-s ${SHL}" + +#: Get the expiry date :# +echo +needinput=yes +while [ ! -z "$needinput" ]; do + EXP="$(get_input "Expiry date (YYYY-MM-DD) []:")" + if [ ! -z "$EXP" ]; then + # Check to see whether the expiry date is in the valid format + if [ -z "$(echo "$EXP" | grep "^[[:digit:]]\{4\}[-]\?[[:digit:]]\{2\}[-]\?[[:digit:]]\{2\}$")" ]; then + echo "- That is not a valid expiration date" + else + unset needinput + EXP="-e ${EXP}" + fi + else + unset needinput + fi +done + +# Display the info about the new impending account +echo +echo "New account will be created as follows:" +echo +echo "---------------------------------------" +display "Login name.......: " "$LOGIN" +display "UID..............: " "$_UID" "[ Next available ]" +display "Initial group....: " "$GID" +display "Additional groups: " "$AGID" "[ None ]" +display "Home directory...: " "$HME" +display "Shell............: " "$SHL" +display "Expiry date......: " "$EXP" "[ Never ]" +echo + +echo "This is it... if you want to bail out, hit Control-C. Otherwise, press" +echo "ENTER to go ahead and make the account." +read junk + +echo +echo "Creating new account..." +echo +echo + +# Add the account to the system +CMD="$useradd "$HME" -m "$EXP" "$U_ID" "$GID" "$AGID" "$SHL" "$LOGIN"" +$CMD + +if [ $? -gt 0 ]; then + echo "- Error running useradd command -- account not created!" + echo "(cmd: $CMD)" + exit 1 +fi + +# chown the home dir ? We can only do this once the useradd has +# completed otherwise the user name doesn't exist. +if [ ! -z "${CHOWNHOMEDIR}" ]; then + chown "$LOGIN"."$( echo $GID | awk '{print $2}')" "${CHOWNHOMEDIR}" +fi + +# Set the finger information +$chfn "$LOGIN" +if [ $? -gt 0 ]; then + echo "- Warning: an error occurred while setting finger information" +fi + +# Set a password +$passwd "$LOGIN" +if [ $? -gt 0 ]; then + echo "* WARNING: An error occured while setting the password for" + echo " this account. Please manually investigate this *" + exit 1 +fi + +# If it was created (it should have been!), set the permissions for that user's dir +HME="$(echo "$HME" | awk '{print $2}')" # We have to remove the -g prefix +if [ -d "$HME" ]; then + $chmod $defchmod "$HME" +fi + +echo +echo +echo "Account setup complete." +exit 0 diff --git a/patches/source/shadow/doinst.sh b/patches/source/shadow/doinst.sh new file mode 100644 index 00000000..88fefb3a --- /dev/null +++ b/patches/source/shadow/doinst.sh @@ -0,0 +1,17 @@ +config() { + NEW="$1" + OLD="$(dirname $NEW)/$(basename $NEW .new)" + # If there's no config file by that name, mv it over: + if [ ! -r $OLD ]; then + mv $NEW $OLD + elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then # toss the redundant copy + rm $NEW + fi + # Otherwise, we leave the .new copy for the admin to consider... +} + +config etc/login.access.new +config etc/login.defs.new +config var/log/faillog.new +rm -f var/log/faillog.new + diff --git a/patches/source/shadow/login.defs b/patches/source/shadow/login.defs new file mode 100644 index 00000000..dde37c97 --- /dev/null +++ b/patches/source/shadow/login.defs @@ -0,0 +1,387 @@ +# +# /etc/login.defs - Configuration control definitions for the shadow package. +# +# $Id: login.defs 3038 2009-07-23 20:41:35Z nekral-guest $ +# + +# +# Delay in seconds before being allowed another attempt after a login failure +# +FAIL_DELAY 3 + +# +# Enable logging and display of /var/log/faillog login failure info. +# +FAILLOG_ENAB yes + +# +# Enable display of unknown usernames when login failures are recorded. +# +LOG_UNKFAIL_ENAB no + +# +# Enable logging of successful logins +# +LOG_OK_LOGINS no + +# +# Enable logging and display of /var/log/lastlog login time info. +# +LASTLOG_ENAB yes + +# +# Enable checking and display of mailbox status upon login. +# +# Disable if the shell startup files already check for mail +# ("mailx -e" or equivalent). +# +MAIL_CHECK_ENAB yes + +# +# Enable additional checks upon password changes. +# +OBSCURE_CHECKS_ENAB yes + +# +# Enable checking of time restrictions specified in /etc/porttime. +# +PORTTIME_CHECKS_ENAB yes + +# +# Enable setting of ulimit, umask, and niceness from passwd gecos field. +# +QUOTAS_ENAB yes + +# +# Enable "syslog" logging of su activity - in addition to sulog file logging. +# SYSLOG_SG_ENAB does the same for newgrp and sg. +# +SYSLOG_SU_ENAB yes +SYSLOG_SG_ENAB yes + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. Root logins will be allowed only +# upon these devices. +# +CONSOLE /etc/securetty +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# If defined, all su activity is logged to this file. +# +#SULOG_FILE /var/log/sulog + +# +# If defined, ":" delimited list of "message of the day" files to +# be displayed upon login. +# +MOTD_FILE /etc/motd +#MOTD_FILE /etc/motd:/usr/lib/news/news-motd + +# +# If defined, this file will be output before each login prompt. +# +#ISSUE_FILE /etc/issue + +# +# If defined, file which maps tty line to TERM environment parameter. +# Each line of the file is in a format something like "vt100 tty01". +# +#TTYTYPE_FILE /etc/ttytype + +# +# If defined, login failures will be logged here in a utmp format. +# last, when invoked as lastb, will read /var/log/btmp, so... +# +FTMP_FILE /var/log/btmp + +# +# If defined, name of file whose presence which will inhibit non-root +# logins. The contents of this file should be a message indicating +# why logins are inhibited. +# +NOLOGINS_FILE /etc/nologin + +# +# If defined, the command name to display when running "su -". For +# example, if this is defined as "su" then a "ps" will display the +# command is "-su". If not defined, then "ps" would display the +# name of the shell actually being run, e.g. something like "-sh". +# +SU_NAME su + +# +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, MAIL_DIR takes precedence. +# +MAIL_DIR /var/spool/mail +#MAIL_FILE .mail + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# +# If defined, either a TZ environment parameter spec or the +# fully-rooted pathname of a file containing such a spec. +# +#ENV_TZ TZ=CST6CDT +#ENV_TZ /etc/tzname + +# +# If defined, an HZ environment parameter spec. +# +# for Linux/x86 +ENV_HZ HZ=100 +# For Linux/Alpha... +#ENV_HZ HZ=1024 + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin +ENV_PATH PATH=/usr/local/bin:/bin:/usr/bin + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a "write" program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP to the group number and +# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign +# TTYPERM to either 622 or 600. +# +TTYGROUP tty +TTYPERM 0620 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# ULIMIT Default "ulimit" value. +# +# The ERASECHAR and KILLCHAR are used only on System V machines. +# The ULIMIT is used only if the system supports it. +# (now it works with setrlimit too; ulimit is in 512-byte units) +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 0177 +KILLCHAR 025 +#ULIMIT 2097152 + +# Default initial "umask" value. +# UMASK is also used by useradd and newusers to set the mode of new home +# directories. +# 022 is the default value, but 027, or even 077, could be considered +# better for privacy. There is no One True Answer here: each sysadmin +# must make up her mind. +UMASK 022 + +# +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_MIN_LEN Minimum acceptable password length. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_MIN_LEN 5 +PASS_WARN_AGE 7 + +# +# If "yes", the user must be listed as a member of the first gid 0 group +# in /etc/group (called "root" on most Linux systems) to be able to "su" +# to uid 0 accounts. If the group doesn't exist or is empty, no one +# will be able to "su" to uid 0. +# +SU_WHEEL_ONLY no + +# +# If compiled with cracklib support, where are the dictionaries +# +#CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +SYS_UID_MIN 101 +SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +SYS_GID_MIN 101 +SYS_GID_MAX 999 + +# +# Max number of login retries if password is bad +# +LOGIN_RETRIES 5 + +# +# Max time in seconds for login +# +LOGIN_TIMEOUT 60 + +# +# Maximum number of attempts to change password if rejected (too easy) +# +PASS_CHANGE_TRIES 5 + +# +# Warn about weak passwords (but still allow them) if you are root. +# +PASS_ALWAYS_WARN yes + +# +# Number of significant characters in the password for crypt(). +# Default is 8, don't change unless your crypt() is better. +# Ignored if MD5_CRYPT_ENAB set to "yes". +# +#PASS_MAX_LEN 8 + +# +# Require password before chfn/chsh can make any changes. +# +CHFN_AUTH yes + +# +# Which fields may be changed by regular users using chfn - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +CHFN_RESTRICT frwh + +# +# Password prompt (%s will be replaced by user name). +# +# XXX - it doesn't work correctly yet, for now leave it commented out +# to use the default which is just "Password: ". +#LOGIN_STRING "%s's Password: " + +# +# Only works if compiled with MD5_CRYPT defined: +# If set to "yes", new passwords will be encrypted using the MD5-based +# algorithm compatible with the one used by recent releases of FreeBSD. +# It supports passwords of unlimited length and longer salt strings. +# Set to "no" if you need to copy encrypted passwords to other systems +# which don't understand the new algorithm. Default is "no". +# +# This variable is deprecated. You should use ENCRYPT_METHOD. +# +#MD5_CRYPT_ENAB no + +# +# Only works if compiled with ENCRYPTMETHOD_SELECT defined: +# If set to MD5 , MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# Overrides the MD5_CRYPT_ENAB option +# +ENCRYPT_METHOD MD5 + +# +# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute forcing the password. +# But note also that it more CPU resources will be needed to authenticate +# users. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be inside the 1000-999999999 range. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +# SHA_CRYPT_MIN_ROUNDS 5000 +# SHA_CRYPT_MAX_ROUNDS 5000 + +# +# List of groups to add to the user's supplementary group set +# when logging in on the console (as determined by the CONSOLE +# setting). Default is none. +# +# Use with caution - it is possible for users to gain permanent +# access to these groups, even when not logged in on the console. +# How to do it is left as an exercise for the reader... +# +# Most of these groups are self-explanatory. +# +# Note that users are added to these default groups only when +# logging into a shell with /bin/login, not when using a login +# manager such as kdm. In that case, users who should have +# hardware access must be added to the appropriate groups +# when the user is added with adduser or useradd, or by editing +# /etc/group directly, preferably using "vigr" +# +CONSOLE_GROUPS floppy:audio:cdrom:video:scanner + +# +# Should login be allowed if we can't cd to the home directory? +# Default in no. +# +DEFAULT_HOME yes + +# +# If this file exists and is readable, login environment will be +# read from it. Every line should be in the form name=value. +# +ENVIRON_FILE /etc/environment + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# Enable setting of the umask group bits to be the same as owner bits +# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is +# the same as gid, and username is the same as the primary group name. +# +# This also enables userdel to remove user groups if no members exist. +# +USERGROUPS_ENAB yes + +# +# If set to a non-nul number, the shadow utilities will make sure that +# groups never have more than this number of users on one line. +# This permit to support split groups (groups split into multiple lines, +# with the same group ID, to avoid limitation of the line length in the +# group file). +# +# 0 is the default value and disables this feature. +# +#MAX_MEMBERS_PER_GROUP 0 + +# +# If useradd should create home directories for users by default (non +# system users only) +# This option is overridden with the -M or -m flags on the useradd command +# line. +# +#CREATE_HOME yes + diff --git a/patches/source/shadow/patches/README_PATCHES b/patches/source/shadow/patches/README_PATCHES new file mode 100644 index 00000000..0c639d1a --- /dev/null +++ b/patches/source/shadow/patches/README_PATCHES @@ -0,0 +1,9 @@ + +r3054.diff: Fixed wrong format string +r3055.diff: Help output to stderr not stdout. +r3060.diff: Fix memory leaks +r3062.diff: Avoid memzero() on a possibly NULL pointer. +r3096.diff: Fix parsing of gshadow entries. +r3160.diff: Fixed limits support (non PAM enabled versions only) +r3194.diff: shell's name must be -su when a su fakes a login. +r3299.diff: man/ru/Makefile.am: Remove double inclusion of $(man_nopam) diff --git a/patches/source/shadow/patches/r3054.diff b/patches/source/shadow/patches/r3054.diff new file mode 100644 index 00000000..dc1eab13 --- /dev/null +++ b/patches/source/shadow/patches/r3054.diff @@ -0,0 +1,27 @@ +* src/useradd.c: Fixed wrong format string. +* lib/gshadow.c: Removed declaration of unused variable. + +=================================================================== +--- src/useradd.c (revision 3052) ++++ src/useradd.c (revision 3054) +@@ -684,7 +684,7 @@ + static void usage (void) + { + (void) fprintf (stderr, +- _("Usage: useradd [options] LOGIN\n" ++ _("Usage: %s [options] LOGIN\n" + "\n" + "Options:\n"), + Prog); + +=================================================================== +--- lib/gshadow.c (revision 3052) ++++ lib/gshadow.c (revision 3054) +@@ -216,7 +216,6 @@ + static char *buf = NULL; + + char *cp; +- struct sgrp *ret; + + if (0 == buflen) { + buf = (char *) malloc (BUFSIZ); diff --git a/patches/source/shadow/patches/r3055.diff b/patches/source/shadow/patches/r3055.diff new file mode 100644 index 00000000..a2af6f39 --- /dev/null +++ b/patches/source/shadow/patches/r3055.diff @@ -0,0 +1,1515 @@ +=================================================================== +--- src/userdel.c (revision 3054) ++++ src/userdel.c (revision 3055) +@@ -94,7 +94,7 @@ + static bool spw_locked = false; + + /* local function prototypes */ +-static void usage (void); ++static void usage (int status); + static void update_groups (void); + static void close_files (void); + static void fail_exit (int); +@@ -111,7 +111,7 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { + fputs (_("Usage: userdel [options] LOGIN\n" + "\n" +@@ -120,8 +120,8 @@ + " even if not owned by user\n" + " -h, --help display this help message and exit\n" + " -r, --remove remove home directory and mail spool\n" +- "\n"), stderr); +- exit (E_USAGE); ++ "\n"), status ? stderr : stdout); ++ exit (status); + } + + /* +@@ -774,17 +774,19 @@ + case 'f': /* force remove even if not owned by user */ + fflg = true; + break; ++ case 'h': ++ usage (E_SUCCESS); + case 'r': /* remove home dir and mailbox */ + rflg = true; + break; + default: +- usage (); ++ usage (E_USAGE); + } + } + } + + if ((optind + 1) != argc) { +- usage (); ++ usage (E_USAGE); + } + + OPENLOG ("userdel"); +Index: src/lastlog.c +=================================================================== +--- src/lastlog.c (revision 3054) ++++ src/lastlog.c (revision 3055) +@@ -71,7 +71,7 @@ + + #define NOW (time ((time_t *) 0)) + +-static void usage (void) ++static void usage (int status) + { + fputs (_("Usage: lastlog [options]\n" + "\n" +@@ -80,8 +80,8 @@ + " -h, --help display this help message and exit\n" + " -t, --time DAYS print only lastlog records more recent than DAYS\n" + " -u, --user LOGIN print lastlog record of the specified LOGIN\n" +- "\n"), stderr); +- exit (EXIT_FAILURE); ++ "\n"), status ? stderr : stdout); ++ exit (status); + } + + static void print_one (/*@null@*/const struct passwd *pw) +@@ -208,7 +208,7 @@ + NULL)) != -1) { + switch (c) { + case 'h': +- usage (); ++ usage (EXIT_SUCCESS); + break; + case 't': + { +@@ -267,7 +267,7 @@ + break; + } + default: +- usage (); ++ usage (EXIT_FAILURE); + break; + } + } +@@ -275,7 +275,7 @@ + fprintf (stderr, + _("lastlog: unexpected argument: %s\n"), + argv[optind]); +- usage(); ++ usage (EXIT_FAILURE); + } + } + +Index: src/gpasswd.c +=================================================================== +--- src/gpasswd.c (revision 3054) ++++ src/gpasswd.c (revision 3055) +@@ -94,7 +94,7 @@ + #endif + + /* local function prototypes */ +-static void usage (void); ++static void usage (int status); + static RETSIGTYPE catch_signals (int killed); + static bool is_valid_user_list (const char *users); + static void process_flags (int argc, char **argv); +@@ -128,14 +128,15 @@ + /* + * usage - display usage message + */ +-static void usage (void) ++static void usage (int status) + { +- fprintf (stderr, ++ fprintf (status ? stderr : stdout, + _("Usage: %s [option] GROUP\n" + "\n" + "Options:\n" + " -a, --add USER add USER to GROUP\n" + " -d, --delete USER remove USER from GROUP\n" ++ " -h, --help display this help message and exit\n" + " -r, --remove-password remove the GROUP's password\n" + " -R, --restrict restrict access to GROUP to its members\n" + " -M, --members USER,... set the list of members of GROUP\n" +@@ -150,7 +151,7 @@ + _("The options cannot be combined.\n") + #endif + ); +- exit (E_USAGE); ++ exit (status); + } + + /* +@@ -235,6 +236,7 @@ + static struct option long_options[] = { + {"add", required_argument, NULL, 'a'}, + {"delete", required_argument, NULL, 'd'}, ++ {"help", no_argument, NULL, 'h'}, + {"remove-password", no_argument, NULL, 'r'}, + {"restrict", no_argument, NULL, 'R'}, + {"administrators", required_argument, NULL, 'A'}, +@@ -242,7 +244,7 @@ + {NULL, 0, NULL, '\0'} + }; + +- while ((flag = getopt_long (argc, argv, "a:A:d:gM:rR", long_options, &option_index)) != -1) { ++ while ((flag = getopt_long (argc, argv, "a:A:d:ghM:rR", long_options, &option_index)) != -1) { + switch (flag) { + case 'a': /* add a user */ + aflg = true; +@@ -276,6 +278,8 @@ + break; + case 'g': /* no-op from normal password */ + break; ++ case 'h': ++ usage (E_SUCCESS); + case 'M': /* set the list of members */ + members = optarg; + if (!is_valid_user_list (members)) { +@@ -290,7 +294,7 @@ + Rflg = true; + break; + default: +- usage (); ++ usage (E_USAGE); + } + } + +@@ -325,14 +329,14 @@ + exclusive++; + } + if (exclusive > 1) { +- usage (); ++ usage (E_USAGE); + } + + /* + * Make sure one (and only one) group was provided + */ + if ((argc != (opt_index+1)) || (NULL == group)) { +- usage (); ++ usage (E_USAGE); + } + } + +Index: src/newusers.c +=================================================================== +--- src/newusers.c (revision 3054) ++++ src/newusers.c (revision 3055) +@@ -92,7 +92,7 @@ + static bool spw_locked = false; + + /* local function prototypes */ +-static void usage (void); ++static void usage (int status); + static void fail_exit (int); + static int add_group (const char *, const char *, gid_t *, gid_t); + static int get_user_id (const char *, uid_t *); +@@ -110,15 +110,16 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { +- (void) fprintf (stderr, ++ FILE *usageout = status ? stderr : stdout; ++ (void) fprintf (usageout, + _("Usage: %s [options]\n" + "\n" + "Options:\n"), + Prog); + #ifndef USE_PAM +- (void) fprintf (stderr, ++ (void) fprintf (usageout, + _(" -c, --crypt-method the crypt method (one of %s)\n"), + #ifndef USE_SHA_CRYPT + "NONE DES MD5" +@@ -127,18 +128,18 @@ + #endif /* USE_SHA_CRYPT */ + ); + #endif /* !USE_PAM */ +- (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); +- (void) fputs (_(" -r, --system create system accounts\n"), stderr); ++ (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); ++ (void) fputs (_(" -r, --system create system accounts\n"), usageout); + #ifndef USE_PAM + #ifdef USE_SHA_CRYPT + (void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n" + " crypt algorithms\n"), +- stderr); ++ usageout); + #endif /* USE_SHA_CRYPT */ + #endif /* !USE_PAM */ +- (void) fputs ("\n", stderr); ++ (void) fputs ("\n", usageout); + +- exit (EXIT_FAILURE); ++ exit (status); + } + + /* +@@ -548,7 +549,7 @@ + long_options, &option_index)) != -1) { + switch (c) { + case 'h': +- usage (); ++ usage (EXIT_SUCCESS); + break; + case 'r': + rflg = true; +@@ -565,13 +566,13 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (EXIT_FAILURE); + } + break; + #endif /* USE_SHA_CRYPT */ + #endif /* !USE_PAM */ + default: +- usage (); ++ usage (EXIT_FAILURE); + break; + } + } +@@ -602,7 +603,7 @@ + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-s", "-c"); +- usage (); ++ usage (EXIT_FAILURE); + } + #endif /* USE_SHA_CRYPT */ + +@@ -618,7 +619,7 @@ + fprintf (stderr, + _("%s: unsupported crypt method: %s\n"), + Prog, crypt_method); +- usage (); ++ usage (EXIT_FAILURE); + } + } + #endif /* !USE_PAM */ +Index: src/chpasswd.c +=================================================================== +--- src/chpasswd.c (revision 3054) ++++ src/chpasswd.c (revision 3055) +@@ -74,7 +74,7 @@ + + /* local function prototypes */ + static void fail_exit (int code); +-static void usage (void); ++static void usage (int status); + static void process_flags (int argc, char **argv); + static void check_flags (void); + static void check_perms (void); +@@ -112,15 +112,16 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { +- (void) fprintf (stderr, ++ FILE *usageout = status ? stderr : stdout; ++ (void) fprintf (usageout, + _("Usage: %s [options]\n" + "\n" + "Options:\n"), + Prog); + #ifndef USE_PAM +- (void) fprintf (stderr, ++ (void) fprintf (usageout, + _(" -c, --crypt-method the crypt method (one of %s)\n"), + #ifndef USE_SHA_CRYPT + "NONE DES MD5" +@@ -128,22 +129,22 @@ + "NONE DES MD5 SHA256 SHA512" + #endif /* USE_SHA_CRYPT */ + ); +- (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), stderr); ++ (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); + #endif /* !USE_PAM */ +- (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); ++ (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); + #ifndef USE_PAM + (void) fputs (_(" -m, --md5 encrypt the clear text password using\n" + " the MD5 algorithm\n"), +- stderr); ++ usageout); + #ifdef USE_SHA_CRYPT + (void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n" + " crypt algorithms\n"), +- stderr); ++ usageout); + #endif /* USE_SHA_CRYPT */ + #endif /* !USE_PAM */ +- (void) fputs ("\n", stderr); ++ (void) fputs ("\n", usageout); + +- exit (E_USAGE); ++ exit (status); + } + + /* +@@ -181,7 +182,7 @@ + long_options, &option_index)) != -1) { + switch (c) { + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + #ifndef USE_PAM + case 'c': +@@ -201,13 +202,13 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + #endif /* USE_SHA_CRYPT */ + #endif /* !USE_PAM */ + default: +- usage (); ++ usage (E_USAGE); + break; + } + } +@@ -229,7 +230,7 @@ + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-s", "-c"); +- usage (); ++ usage (E_USAGE); + } + #endif + +@@ -238,7 +239,7 @@ + fprintf (stderr, + _("%s: the -c, -e, and -m flags are exclusive\n"), + Prog); +- usage (); ++ usage (E_USAGE); + } + + if (cflg) { +@@ -253,7 +254,7 @@ + fprintf (stderr, + _("%s: unsupported crypt method: %s\n"), + Prog, crypt_method); +- usage (); ++ usage (E_USAGE); + } + } + #endif /* USE_PAM */ +Index: src/groupmems.c +=================================================================== +--- src/groupmems.c (revision 3054) ++++ src/groupmems.c (revision 3055) +@@ -88,7 +88,7 @@ + const struct group *grp); + static void purge_members (const struct group *grp); + static void display_members (const char *const *members); +-static void usage (void); ++static void usage (int status); + static void process_flags (int argc, char **argv); + static void check_perms (void); + static void fail_exit (int code); +@@ -361,7 +361,7 @@ + } + } + +-static void usage (void) ++static void usage (int status) + { + (void) fputs (_("Usage: groupmems [options] [action]\n" + "\n" +@@ -372,10 +372,11 @@ + "Actions:\n" + " -a, --add username add username to the members of the group\n" + " -d, --delete username remove username from the members of the group\n" ++ " -h, --help display this help message and exit\n" + " -p, --purge purge all members from the group\n" + " -l, --list list the members of the group\n" +- "\n"), stderr); +- fail_exit (EXIT_USAGE); ++ "\n"), status ? stderr : stdout); ++ fail_exit (status); + } + + /* +@@ -389,12 +390,13 @@ + {"add", required_argument, NULL, 'a'}, + {"delete", required_argument, NULL, 'd'}, + {"group", required_argument, NULL, 'g'}, ++ {"help", no_argument, NULL, 'h'}, + {"list", no_argument, NULL, 'l'}, + {"purge", no_argument, NULL, 'p'}, + {NULL, 0, NULL, '\0'} + }; + +- while ((arg = getopt_long (argc, argv, "a:d:g:lp", long_options, ++ while ((arg = getopt_long (argc, argv, "a:d:g:hlp", long_options, + &option_index)) != EOF) { + switch (arg) { + case 'a': +@@ -408,6 +410,8 @@ + case 'g': + thisgroup = xstrdup (optarg); + break; ++ case 'h': ++ usage (EXIT_SUCCESS); + case 'l': + list = true; + ++exclusive; +@@ -417,12 +421,12 @@ + ++exclusive; + break; + default: +- usage (); ++ usage (EXIT_USAGE); + } + } + + if ((exclusive > 1) || (optind < argc)) { +- usage (); ++ usage (EXIT_USAGE); + } + + /* local, no need for xgetpwnam */ +Index: src/usermod.c +=================================================================== +--- src/usermod.c (revision 3054) ++++ src/usermod.c (revision 3055) +@@ -149,7 +149,7 @@ + static void date_to_str (char *buf, size_t maxsize, + long int date, const char *negativ); + static int get_groups (char *); +-static void usage (void); ++static void usage (int status); + static void new_pwent (struct passwd *); + #ifdef WITH_SELINUX + static void selinux_update_mapping (void); +@@ -300,9 +300,9 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { +- fprintf (stderr, ++ fprintf (status ? stderr : stdout, + _("Usage: usermod [options] LOGIN\n" + "\n" + "Options:\n" +@@ -334,7 +334,7 @@ + "" + #endif + ); +- exit (E_USAGE); ++ exit (status); + } + + /* +@@ -815,7 +815,7 @@ + bool anyflag = false; + + if ((1 == argc) || ('-' == argv[argc - 1][0])) { +- usage (); ++ usage (E_USAGE); + } + + { +@@ -955,7 +955,7 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + fflg = true; + break; +@@ -976,6 +976,8 @@ + } + Gflg = true; + break; ++ case 'h': ++ usage (E_SUCCESS); + case 'l': + if (!is_valid_user_name (optarg)) { + fprintf (stderr, +@@ -1036,7 +1038,7 @@ + break; + #endif + default: +- usage (); ++ usage (E_USAGE); + } + anyflag = true; + } +@@ -1092,14 +1094,14 @@ + } + + if (optind != argc - 1) { +- usage (); ++ usage (E_USAGE); + } + + if (aflg && (!Gflg)) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-a", "-G"); +- usage (); ++ usage (E_USAGE); + exit (E_USAGE); + } + +@@ -1107,7 +1109,7 @@ + fprintf (stderr, + _("%s: the -L, -p, and -U flags are exclusive\n"), + Prog); +- usage (); ++ usage (E_USAGE); + exit (E_USAGE); + } + +@@ -1115,7 +1117,7 @@ + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-o", "-u"); +- usage (); ++ usage (E_USAGE); + exit (E_USAGE); + } + +@@ -1123,7 +1125,7 @@ + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-m", "-d"); +- usage (); ++ usage (E_USAGE); + exit (E_USAGE); + } + +Index: src/chgpasswd.c +=================================================================== +--- src/chgpasswd.c (revision 3054) ++++ src/chgpasswd.c (revision 3055) +@@ -78,7 +78,7 @@ + + /* local function prototypes */ + static void fail_exit (int code); +-static void usage (void); ++static void usage (int status); + static void process_flags (int argc, char **argv); + static void check_flags (void); + static void check_perms (void); +@@ -114,9 +114,10 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { +- fprintf (stderr, _("Usage: %s [options]\n" ++ fprintf (status ? stderr : stdout, ++ _("Usage: %s [options]\n" + "\n" + "Options:\n" + " -c, --crypt-method the crypt method (one of %s)\n" +@@ -135,7 +136,7 @@ + " crypt algorithms\n") + #endif + ); +- exit (E_USAGE); ++ exit (status); + } + + /* +@@ -174,7 +175,7 @@ + eflg = true; + break; + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 'm': + md5flg = true; +@@ -186,12 +187,12 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + #endif + default: +- usage (); ++ usage (E_USAGE); + break; + } + } +@@ -212,7 +213,7 @@ + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-s", "-c"); +- usage (); ++ usage (E_USAGE); + } + #endif + +@@ -221,7 +222,7 @@ + fprintf (stderr, + _("%s: the -c, -e, and -m flags are exclusive\n"), + Prog); +- usage (); ++ usage (E_USAGE); + } + + if (cflg) { +@@ -236,7 +237,7 @@ + fprintf (stderr, + _("%s: unsupported crypt method: %s\n"), + Prog, crypt_method); +- usage (); ++ usage (E_USAGE); + } + } + } +Index: src/vipw.c +=================================================================== +--- src/vipw.c (revision 3054) ++++ src/vipw.c (revision 3055) +@@ -1,7 +1,7 @@ + /* + vipw, vigr edit the password or group file + with -s will edit shadow or gshadow file +- ++ + Copyright (c) 1997 , Guy Maor <maor@ece.utexas.edu> + Copyright (c) 1999 - 2000, Marek Michałkiewicz + Copyright (c) 2002 - 2006, Tomasz Kłoczko +@@ -29,8 +29,8 @@ + + #include <errno.h> + #include <getopt.h> +-#ifdef WITH_SELINUX +-#include <selinux/selinux.h> ++#ifdef WITH_SELINUX ++#include <selinux/selinux.h> + #endif + #include <signal.h> + #include <stdio.h> +@@ -64,7 +64,7 @@ + static bool quiet = false; + + /* local function prototypes */ +-static void usage (void); ++static void usage (int status); + static int create_backup_file (FILE *, const char *, struct stat *); + static void vipwexit (const char *msg, int syserr, int ret); + static void vipwedit (const char *, int (*)(void), int (*)(void)); +@@ -72,9 +72,9 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { +- (void) ++ (void) + fputs (_("Usage: vipw [options]\n" + "\n" + "Options:\n" +@@ -83,8 +83,8 @@ + " -p, --passwd edit passwd database\n" + " -q, --quiet quiet mode\n" + " -s, --shadow edit shadow or gshadow database\n" +- "\n"), stderr); +- exit (E_USAGE); ++ "\n"), status ? stderr : stdout); ++ exit (status); + } + + /* +@@ -285,8 +285,8 @@ + if (st1.st_mtime == st2.st_mtime) { + vipwexit (0, 0, 0); + } +-#ifdef WITH_SELINUX +- /* unset the fscreatecon */ ++#ifdef WITH_SELINUX ++ /* unset the fscreatecon */ + if (is_selinux_enabled ()) { + if (setfscreatecon (NULL)) { + vipwexit (_("setfscreatecon () failed"), errno, 1); +@@ -353,7 +353,7 @@ + do_vipw = false; + break; + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 'p': + do_vipw = true; +@@ -365,7 +365,7 @@ + editshadow = true; + break; + default: +- usage (); ++ usage (E_USAGE); + } + } + } +Index: src/useradd.c +=================================================================== +--- src/useradd.c (revision 3054) ++++ src/useradd.c (revision 3055) +@@ -179,7 +179,7 @@ + static void show_defaults (void); + static int set_defaults (void); + static int get_groups (char *); +-static void usage (void); ++static void usage (int status); + static void new_pwent (struct passwd *); + #ifdef WITH_SELINUX + static void selinux_update_mapping (void); +@@ -681,45 +681,46 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { +- (void) fprintf (stderr, ++ FILE *usageout = status ? stderr : stdout; ++ (void) fprintf (usageout, + _("Usage: %s [options] LOGIN\n" + "\n" + "Options:\n"), + Prog); + (void) fputs (_(" -b, --base-dir BASE_DIR base directory for the home directory of the\n" +- " new account\n"), stderr); +- (void) fputs (_(" -c, --comment COMMENT GECOS field of the new account\n"), stderr); +- (void) fputs (_(" -d, --home-dir HOME_DIR home directory of the new account\n"), stderr); +- (void) fputs (_(" -D, --defaults print or change default useradd configuration\n"), stderr); +- (void) fputs (_(" -e, --expiredate EXPIRE_DATE expiration date of the new account\n"), stderr); +- (void) fputs (_(" -f, --inactive INACTIVE password inactivity period of the new account\n"), stderr); ++ " new account\n"), usageout); ++ (void) fputs (_(" -c, --comment COMMENT GECOS field of the new account\n"), usageout); ++ (void) fputs (_(" -d, --home-dir HOME_DIR home directory of the new account\n"), usageout); ++ (void) fputs (_(" -D, --defaults print or change default useradd configuration\n"), usageout); ++ (void) fputs (_(" -e, --expiredate EXPIRE_DATE expiration date of the new account\n"), usageout); ++ (void) fputs (_(" -f, --inactive INACTIVE password inactivity period of the new account\n"), usageout); + (void) fputs (_(" -g, --gid GROUP name or ID of the primary group of the new\n" +- " account\n"), stderr); ++ " account\n"), usageout); + (void) fputs (_(" -G, --groups GROUPS list of supplementary groups of the new\n" +- " account\n"), stderr); +- (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); +- (void) fputs (_(" -k, --skel SKEL_DIR use this alternative skeleton directory\n"), stderr); +- (void) fputs (_(" -K, --key KEY=VALUE override /etc/login.defs defaults\n"), stderr); ++ " account\n"), usageout); ++ (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); ++ (void) fputs (_(" -k, --skel SKEL_DIR use this alternative skeleton directory\n"), usageout); ++ (void) fputs (_(" -K, --key KEY=VALUE override /etc/login.defs defaults\n"), usageout); + (void) fputs (_(" -l, --no-log-init do not add the user to the lastlog and\n" +- " faillog databases\n"), stderr); +- (void) fputs (_(" -m, --create-home create the user's home directory\n"), stderr); +- (void) fputs (_(" -M, --no-create-home do not create the user's home directory\n"), stderr); ++ " faillog databases\n"), usageout); ++ (void) fputs (_(" -m, --create-home create the user's home directory\n"), usageout); ++ (void) fputs (_(" -M, --no-create-home do not create the user's home directory\n"), usageout); + (void) fputs (_(" -N, --no-user-group do not create a group with the same name as\n" +- " the user\n"), stderr); ++ " the user\n"), usageout); + (void) fputs (_(" -o, --non-unique allow to create users with duplicate\n" +- " (non-unique) UID\n"), stderr); +- (void) fputs (_(" -p, --password PASSWORD encrypted password of the new account\n"), stderr); +- (void) fputs (_(" -r, --system create a system account\n"), stderr); +- (void) fputs (_(" -s, --shell SHELL login shell of the new account\n"), stderr); +- (void) fputs (_(" -u, --uid UID user ID of the new account\n"), stderr); +- (void) fputs (_(" -U, --user-group create a group with the same name as the user\n"), stderr); ++ " (non-unique) UID\n"), usageout); ++ (void) fputs (_(" -p, --password PASSWORD encrypted password of the new account\n"), usageout); ++ (void) fputs (_(" -r, --system create a system account\n"), usageout); ++ (void) fputs (_(" -s, --shell SHELL login shell of the new account\n"), usageout); ++ (void) fputs (_(" -u, --uid UID user ID of the new account\n"), usageout); ++ (void) fputs (_(" -U, --user-group create a group with the same name as the user\n"), usageout); + #ifdef WITH_SELINUX +- (void) fputs (_(" -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user mapping\n"), stderr); ++ (void) fputs (_(" -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user mapping\n"), usageout); + #endif +- (void) fputs ("\n", stderr); +- exit (E_USAGE); ++ (void) fputs ("\n", usageout); ++ exit (status); + } + + /* +@@ -989,9 +990,9 @@ + }; + while ((c = getopt_long (argc, argv, + #ifdef WITH_SELINUX +- "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:UZ:", ++ "b:c:d:De:f:g:G:hk:K:lmMNop:rs:u:UZ:", + #else +- "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:U", ++ "b:c:d:De:f:g:G:hk:K:lmMNop:rs:u:U", + #endif + long_options, NULL)) != -1) { + switch (c) { +@@ -1029,7 +1030,7 @@ + break; + case 'D': + if (anyflag) { +- usage (); ++ usage (E_USAGE); + } + Dflg = true; + break; +@@ -1066,7 +1067,7 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + /* + * -f -1 is allowed +@@ -1106,7 +1107,7 @@ + Gflg = true; + break; + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 'k': + def_template = optarg; +@@ -1201,7 +1202,7 @@ + break; + #endif + default: +- usage (); ++ usage (E_USAGE); + } + anyflag = true; + } +@@ -1220,31 +1221,31 @@ + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-o", "-u"); +- usage (); ++ usage (E_USAGE); + } + if (kflg && !mflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-k", "-m"); +- usage (); ++ usage (E_USAGE); + } + if (Uflg && gflg) { + fprintf (stderr, + _("%s: options %s and %s conflict\n"), + Prog, "-U", "-g"); +- usage (); ++ usage (E_USAGE); + } + if (Uflg && Nflg) { + fprintf (stderr, + _("%s: options %s and %s conflict\n"), + Prog, "-U", "-N"); +- usage (); ++ usage (E_USAGE); + } + if (mflg && Mflg) { + fprintf (stderr, + _("%s: options %s and %s conflict\n"), + Prog, "-m", "-M"); +- usage (); ++ usage (E_USAGE); + } + + /* +@@ -1253,15 +1254,15 @@ + */ + if (Dflg) { + if (optind != argc) { +- usage (); ++ usage (E_USAGE); + } + + if (uflg || oflg || Gflg || dflg || cflg || mflg) { +- usage (); ++ usage (E_USAGE); + } + } else { + if (optind != argc - 1) { +- usage (); ++ usage (E_USAGE); + } + + user_name = argv[optind]; +Index: src/su.c +=================================================================== +--- src/su.c (revision 3054) ++++ src/su.c (revision 3055) +@@ -323,7 +323,7 @@ + /* + * usage - print command line syntax and exit + */ +-static void usage (void) ++static void usage (int status) + { + fputs (_("Usage: su [options] [LOGIN]\n" + "\n" +@@ -335,8 +335,8 @@ + " --preserve-environment do not reset environment variables, and\n" + " keep the same shell\n" + " -s, --shell SHELL use SHELL instead of the default in passwd\n" +- "\n"), stderr); +- exit (E_USAGE); ++ "\n"), status ? stderr : stdout); ++ exit (status); + } + + /* +@@ -421,7 +421,7 @@ + command = optarg; + break; + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 'l': + fakelogin = true; +@@ -438,7 +438,7 @@ + shellstr = optarg; + break; + default: +- usage (); /* NOT REACHED */ ++ usage (E_USAGE); /* NOT REACHED */ + } + } + +Index: src/groupmod.c +=================================================================== +--- src/groupmod.c (revision 3054) ++++ src/groupmod.c (revision 3055) +@@ -93,7 +93,7 @@ + pflg = false; /* new encrypted password */ + + /* local function prototypes */ +-static void usage (void); ++static void usage (int status); + static void new_grent (struct group *); + + #ifdef SHADOWGRP +@@ -113,21 +113,22 @@ + * usage - display usage message and exit + */ + +-static void usage (void) ++static void usage (int status) + { +- (void) fprintf (stderr, ++ FILE *usageout = status ? stderr : stdout; ++ (void) fprintf (usageout, + _("Usage: %s [options] GROUP\n" + "\n" + "Options:\n"), + Prog); +- (void) fputs (_(" -g, --gid GID change the group ID to GID\n"), stderr); +- (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); +- (void) fputs (_(" -n, --new-name NEW_GROUP change the name to NEW_GROUP\n"), stderr); +- (void) fputs (_(" -o, --non-unique allow to use a duplicate (non-unique) GID\n"), stderr); ++ (void) fputs (_(" -g, --gid GID change the group ID to GID\n"), usageout); ++ (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); ++ (void) fputs (_(" -n, --new-name NEW_GROUP change the name to NEW_GROUP\n"), usageout); ++ (void) fputs (_(" -o, --non-unique allow to use a duplicate (non-unique) GID\n"), usageout); + (void) fputs (_(" -p, --password PASSWORD change the password to this (encrypted)\n" +- " PASSWORD\n"), stderr); +- (void) fputs ("\n", stderr); +- exit (E_USAGE); ++ " PASSWORD\n"), usageout); ++ (void) fputs ("\n", usageout); ++ exit (status); + } + + /* +@@ -362,6 +363,8 @@ + exit (E_BAD_ARG); + } + break; ++ case 'h': ++ usage (E_SUCCESS); + case 'n': + nflg = true; + group_newname = optarg; +@@ -374,16 +377,16 @@ + pflg = true; + break; + default: +- usage (); ++ usage (E_USAGE); + } + } + + if (oflg && !gflg) { +- usage (); ++ usage (E_USAGE); + } + + if (optind != (argc - 1)) { +- usage (); ++ usage (E_USAGE); + } + + group_name = argv[argc - 1]; +Index: src/passwd.c +=================================================================== +--- src/passwd.c (revision 3054) ++++ src/passwd.c (revision 3055) +@@ -180,7 +180,7 @@ + " -w, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n" + " -x, --maxdays MAX_DAYS set maximum number of days before password\n" + " change to MAX_DAYS\n" +- "\n"), stderr); ++ "\n"), status ? stderr : stdout); + exit (status); + } + +@@ -811,7 +811,7 @@ + {NULL, 0, NULL, '\0'} + }; + +- while ((c = getopt_long (argc, argv, "adei:kln:qr:Suw:x:", ++ while ((c = getopt_long (argc, argv, "adehi:kln:qr:Suw:x:", + long_options, &option_index)) != -1) { + switch (c) { + case 'a': +@@ -897,6 +897,8 @@ + xflg = true; + anyflag = true; + break; ++ case 'h': ++ usage (E_SUCCESS); + default: + usage (E_BAD_ARG); + } +Index: src/groupadd.c +=================================================================== +--- src/groupadd.c (revision 3054) ++++ src/groupadd.c (revision 3055) +@@ -88,7 +88,7 @@ + #endif + + /* local function prototypes */ +-static void usage (void); ++static void usage (int status); + static void new_grent (struct group *grent); + + #ifdef SHADOWGRP +@@ -105,24 +105,25 @@ + /* + * usage - display usage message and exit + */ +-static void usage (void) ++static void usage (int status) + { +- (void) fprintf (stderr, ++ FILE *usageout = status ? stderr : stdout; ++ (void) fprintf (usageout, + _("Usage: %s [options] GROUP\n" + "\n" + "Options:\n"), + Prog); + (void) fputs (_(" -f, --force exit successfully if the group already exists,\n" +- " and cancel -g if the GID is already used\n"), stderr); +- (void) fputs (_(" -g, --gid GID use GID for the new group\n"), stderr); +- (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); +- (void) fputs (_(" -K, --key KEY=VALUE override /etc/login.defs defaults\n"), stderr); ++ " and cancel -g if the GID is already used\n"), usageout); ++ (void) fputs (_(" -g, --gid GID use GID for the new group\n"), usageout); ++ (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); ++ (void) fputs (_(" -K, --key KEY=VALUE override /etc/login.defs defaults\n"), usageout); + (void) fputs (_(" -o, --non-unique allow to create groups with duplicate\n" +- " (non-unique) GID\n"), stderr); +- (void) fputs (_(" -p, --password PASSWORD use this encrypted password for the new group\n"), stderr); +- (void) fputs (_(" -r, --system create a system account\n"), stderr); +- (void) fputs ("\n", stderr); +- exit (E_USAGE); ++ " (non-unique) GID\n"), usageout); ++ (void) fputs (_(" -p, --password PASSWORD use this encrypted password for the new group\n"), usageout); ++ (void) fputs (_(" -r, --system create a system account\n"), usageout); ++ (void) fputs ("\n", usageout); ++ exit (status); + } + + /* +@@ -412,7 +413,7 @@ + } + break; + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 'K': + /* +@@ -444,7 +445,7 @@ + rflg = true; + break; + default: +- usage (); ++ usage (E_USAGE); + } + } + +@@ -452,7 +453,7 @@ + * Check the flags consistency + */ + if (optind != argc - 1) { +- usage (); ++ usage (E_USAGE); + } + group_name = argv[optind]; + +@@ -468,7 +469,7 @@ + { + /* -o does not make sense without -g */ + if (oflg && !gflg) { +- usage (); ++ usage (E_USAGE); + } + + check_new_name (); +Index: src/chage.c +=================================================================== +--- src/chage.c (revision 3054) ++++ src/chage.c (revision 3055) +@@ -91,7 +91,7 @@ + + /* local function prototypes */ + static bool isnum (const char *s); +-static void usage (void); ++static void usage (int status); + static void date_to_str (char *buf, size_t maxsize, time_t date); + static int new_fields (void); + static void print_date (time_t date); +@@ -152,7 +152,7 @@ + /* + * usage - print command line syntax and exit + */ +-static void usage (void) ++static void usage (int status) + { + fputs (_("Usage: chage [options] [LOGIN]\n" + "\n" +@@ -168,8 +168,8 @@ + " -M, --maxdays MAX_DAYS set maximim number of days before password\n" + " change to MAX_DAYS\n" + " -W, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n" +- "\n"), stderr); +- exit (E_USAGE); ++ "\n"), status ? stderr : stdout); ++ exit (status); + } + + static void date_to_str (char *buf, size_t maxsize, time_t date) +@@ -413,7 +413,7 @@ + fprintf (stderr, + _("%s: invalid date '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + case 'E': +@@ -425,11 +425,11 @@ + fprintf (stderr, + _("%s: invalid date '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 'I': + Iflg = true; +@@ -438,7 +438,7 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + case 'l': +@@ -451,7 +451,7 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + case 'M': +@@ -461,7 +461,7 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + case 'W': +@@ -471,11 +471,11 @@ + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), + Prog, optarg); +- usage (); ++ usage (E_USAGE); + } + break; + default: +- usage (); ++ usage (E_USAGE); + } + } + +@@ -495,14 +495,14 @@ + */ + + if (argc != opt_index + 1) { +- usage (); ++ usage (E_USAGE); + } + + if (lflg && (mflg || Mflg || dflg || Wflg || Iflg || Eflg)) { + fprintf (stderr, + _("%s: do not include \"l\" with other flags\n"), + Prog); +- usage (); ++ usage (E_USAGE); + } + } + +Index: src/faillog.c +=================================================================== +--- src/faillog.c (revision 3054) ++++ src/faillog.c (revision 3055) +@@ -47,6 +47,17 @@ + /*@-exitarg@*/ + #include "exitcodes.h" + ++/* local function prototypes */ ++static void usage (int status); ++static void print_one (/*@null@*/const struct passwd *pw, bool force); ++static void set_locktime (long locktime); ++static bool set_locktime_one (uid_t uid, long locktime); ++static void setmax (int max); ++static bool setmax_one (uid_t uid, int max); ++static void print (void); ++static bool reset_one (uid_t uid); ++static void reset (void); ++ + /* + * Global variables + */ +@@ -69,24 +80,25 @@ + + #define NOW (time((time_t *) 0)) + +-static void usage (void) ++static void usage (int status) + { +- (void) fprintf (stderr, ++ FILE *usageout = status ? stderr : stdout; ++ (void) fprintf (usageout, + _("Usage: %s [options]\n" + "\n" + "Options:\n"), + "faillog"); +- (void) fputs (_(" -a, --all display faillog records for all users\n"), stderr); +- (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); +- (void) fputs (_(" -l, --lock-time SEC after failed login lock account for SEC seconds\n"), stderr); +- (void) fputs (_(" -m, --maximum MAX set maximum failed login counters to MAX\n"), stderr); +- (void) fputs (_(" -r, --reset reset the counters of login failures\n"), stderr); +- (void) fputs (_(" -t, --time DAYS display faillog records more recent than DAYS\n"), stderr); ++ (void) fputs (_(" -a, --all display faillog records for all users\n"), usageout); ++ (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); ++ (void) fputs (_(" -l, --lock-time SEC after failed login lock account for SEC seconds\n"), usageout); ++ (void) fputs (_(" -m, --maximum MAX set maximum failed login counters to MAX\n"), usageout); ++ (void) fputs (_(" -r, --reset reset the counters of login failures\n"), usageout); ++ (void) fputs (_(" -t, --time DAYS display faillog records more recent than DAYS\n"), usageout); + (void) fputs (_(" -u, --user LOGIN/RANGE display faillog record or maintains failure\n" + " counters and limits (if used with -r, -m,\n" +- " or -l) only for the specified LOGIN(s)\n"), stderr); +- (void) fputs ("\n", stderr); +- exit (E_USAGE); ++ " or -l) only for the specified LOGIN(s)\n"), usageout); ++ (void) fputs ("\n", usageout); ++ exit (status); + } + + static void print_one (/*@null@*/const struct passwd *pw, bool force) +@@ -495,7 +507,7 @@ + aflg = true; + break; + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 'l': + if (getlong (optarg, &fail_locktime) == 0) { +@@ -561,16 +573,16 @@ + break; + } + default: +- usage (); ++ usage (E_USAGE); + } + } + } + + if (aflg && uflg) { +- usage (); ++ usage (E_USAGE); + } + if (tflg && (lflg || mflg || rflg)) { +- usage (); ++ usage (E_USAGE); + } + + /* Open the faillog database */ +Index: src/chsh.c +=================================================================== +--- src/chsh.c (revision 3054) ++++ src/chsh.c (revision 3055) +@@ -72,7 +72,7 @@ + + /* local function prototypes */ + static void fail_exit (int code); +-static void usage (void); ++static void usage (int status); + static void new_fields (void); + static bool shell_is_listed (const char *); + static bool is_restricted_shell (const char *); +@@ -101,15 +101,15 @@ + /* + * usage - print command line syntax and exit + */ +-static void usage (void) ++static void usage (int status) + { + fputs (_("Usage: chsh [options] [LOGIN]\n" + "\n" + "Options:\n" + " -h, --help display this help message and exit\n" + " -s, --shell SHELL new login shell for the user account\n" +- "\n"), stderr); +- exit (E_USAGE); ++ "\n"), status ? stderr : stdout); ++ exit (status); + } + + /* +@@ -217,14 +217,14 @@ + &option_index)) != -1) { + switch (c) { + case 'h': +- usage (); ++ usage (E_SUCCESS); + break; + case 's': + sflg = true; + STRFCPY (loginsh, optarg); + break; + default: +- usage (); ++ usage (E_USAGE); + } + } + +@@ -233,7 +233,7 @@ + * be the user's name. + */ + if (argc > (optind + 1)) { +- usage (); ++ usage (E_USAGE); + } + } + +Index: man/groupmems.8.xml +=================================================================== +--- man/groupmems.8.xml (revision 3054) ++++ man/groupmems.8.xml (revision 3055) +@@ -114,6 +114,12 @@ + </listitem> + </varlistentry> + <varlistentry> ++ <term><option>-h</option>, <option>--help</option></term> ++ <listitem> ++ <para>Display help message and exit.</para> ++ </listitem> ++ </varlistentry> ++ <varlistentry> + <term><option>-l</option>, <option>--list</option></term> + <listitem> + <para>List the group membership list.</para> +Index: man/gpasswd.1.xml +=================================================================== +--- man/gpasswd.1.xml (revision 3054) ++++ man/gpasswd.1.xml (revision 3055) +@@ -1,7 +1,7 @@ + <?xml version="1.0" encoding="UTF-8"?> + <!-- + Copyright (c) 1996 , Rafal Maszkowski +- Copyright (c) 2007 - 2008, Nicolas François ++ Copyright (c) 2007 - 2009, Nicolas François + All rights reserved. + + Redistribution and use in source and binary forms, with or without +@@ -148,6 +148,14 @@ + </variablelist> + <variablelist remap='IP'> + <varlistentry> ++ <term><option>-h</option>, <option>--help</option></term> ++ <listitem> ++ <para>Display help message and exit.</para> ++ </listitem> ++ </varlistentry> ++ </variablelist> ++ <variablelist remap='IP'> ++ <varlistentry> + <term> + <option>-r</option>, <option>--remove-password</option> + </term> +Index: NEWS +=================================================================== +--- NEWS (revision 3054) ++++ NEWS (revision 3055) +@@ -1,5 +1,11 @@ + $Id$ + ++shadow-4.1.4.1 -> shadow-4.1.4.2 UNRELEASED ++ ++- general ++ * report usage error to stderr, but report usage help to stdout (and return ++ zero) when explicitly requested (e.g. with --help). ++ + shadow-4.1.4.1 -> shadow-4.1.4.2 2009-07-24 + + - general diff --git a/patches/source/shadow/patches/r3060.diff b/patches/source/shadow/patches/r3060.diff new file mode 100644 index 00000000..8ece6430 --- /dev/null +++ b/patches/source/shadow/patches/r3060.diff @@ -0,0 +1,116 @@ +* libmisc/copydir.c, lib/shadowmem.c, lib/groupmem.c, lib/pwmem.c: +Fix some memory leaks. + +Index: libmisc/copydir.c +=================================================================== +--- libmisc/copydir.c (revision 3059) ++++ libmisc/copydir.c (revision 3060) +@@ -443,6 +443,7 @@ + nchars = readlink (filename, buffer, size); + + if (nchars < 0) { ++ free(buffer); + return NULL; + } + + +Index: lib/shadowmem.c +=================================================================== +--- lib/shadowmem.c (revision 3059) ++++ lib/shadowmem.c (revision 3060) +@@ -52,10 +52,13 @@ + *sp = *spent; + sp->sp_namp = strdup (spent->sp_namp); + if (NULL == sp->sp_namp) { ++ free(sp); + return NULL; + } + sp->sp_pwdp = strdup (spent->sp_pwdp); + if (NULL == sp->sp_pwdp) { ++ free(sp->sp_namp); ++ free(sp); + return NULL; + } + +Index: lib/groupmem.c +=================================================================== +--- lib/groupmem.c (revision 3059) ++++ lib/groupmem.c (revision 3060) +@@ -51,10 +51,13 @@ + *gr = *grent; + gr->gr_name = strdup (grent->gr_name); + if (NULL == gr->gr_name) { ++ free(gr); + return NULL; + } + gr->gr_passwd = strdup (grent->gr_passwd); + if (NULL == gr->gr_passwd) { ++ free(gr->gr_name); ++ free(gr); + return NULL; + } + +@@ -62,11 +65,21 @@ + + gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *)); + if (NULL == gr->gr_mem) { ++ free(gr->gr_passwd); ++ free(gr->gr_name); ++ free(gr); + return NULL; + } + for (i = 0; grent->gr_mem[i]; i++) { + gr->gr_mem[i] = strdup (grent->gr_mem[i]); + if (NULL == gr->gr_mem[i]) { ++ int j; ++ for (j=0; j<i; j++) ++ free(gr->gr_mem[j]); ++ free(gr->gr_mem); ++ free(gr->gr_passwd); ++ free(gr->gr_name); ++ free(gr); + return NULL; + } + } +Index: lib/pwmem.c +=================================================================== +--- lib/pwmem.c (revision 3059) ++++ lib/pwmem.c (revision 3060) +@@ -51,22 +51,37 @@ + *pw = *pwent; + pw->pw_name = strdup (pwent->pw_name); + if (NULL == pw->pw_name) { ++ free(pw); + return NULL; + } + pw->pw_passwd = strdup (pwent->pw_passwd); + if (NULL == pw->pw_passwd) { ++ free(pw->pw_name); ++ free(pw); + return NULL; + } + pw->pw_gecos = strdup (pwent->pw_gecos); + if (NULL == pw->pw_gecos) { ++ free(pw->pw_passwd); ++ free(pw->pw_name); ++ free(pw); + return NULL; + } + pw->pw_dir = strdup (pwent->pw_dir); + if (NULL == pw->pw_dir) { ++ free(pw->pw_gecos); ++ free(pw->pw_passwd); ++ free(pw->pw_name); ++ free(pw); + return NULL; + } + pw->pw_shell = strdup (pwent->pw_shell); + if (NULL == pw->pw_shell) { ++ free(pw->pw_dir); ++ free(pw->pw_gecos); ++ free(pw->pw_passwd); ++ free(pw->pw_name); ++ free(pw); + return NULL; + } + diff --git a/patches/source/shadow/patches/r3062.diff b/patches/source/shadow/patches/r3062.diff new file mode 100644 index 00000000..00d9ba3a --- /dev/null +++ b/patches/source/shadow/patches/r3062.diff @@ -0,0 +1,139 @@ +Index: lib/shadowmem.c +=================================================================== +--- lib/shadowmem.c (revision 3061) ++++ lib/shadowmem.c (revision 3062) +@@ -49,8 +49,14 @@ + if (NULL == sp) { + return NULL; + } +- *sp = *spent; +- sp->sp_namp = strdup (spent->sp_namp); ++ sp->sp_lstchg = spent->sp_lstchg; ++ sp->sp_min = spent->sp_min; ++ sp->sp_max = spent->sp_max; ++ sp->sp_warn = spent->sp_warn; ++ sp->sp_inact = spent->sp_inact; ++ sp->sp_expire = spent->sp_expire; ++ sp->sp_flag = spent->sp_flag; ++ sp->sp_namp = strdup (spent->sp_namp); + if (NULL == sp->sp_namp) { + free(sp); + return NULL; +@@ -68,8 +74,10 @@ + void spw_free (/*@out@*/ /*@only@*/struct spwd *spent) + { + free (spent->sp_namp); +- memzero (spent->sp_pwdp, strlen (spent->sp_pwdp)); +- free (spent->sp_pwdp); ++ if (NULL != spent->sp_pwdp) { ++ memzero (spent->sp_pwdp, strlen (spent->sp_pwdp)); ++ free (spent->sp_pwdp); ++ } + free (spent); + } + +Index: lib/groupmem.c +=================================================================== +--- lib/groupmem.c (revision 3061) ++++ lib/groupmem.c (revision 3062) +@@ -48,7 +48,7 @@ + if (NULL == gr) { + return NULL; + } +- *gr = *grent; ++ gr->gr_gid = grent->gr_gid; + gr->gr_name = strdup (grent->gr_name); + if (NULL == gr->gr_name) { + free(gr); +@@ -90,13 +90,18 @@ + + void gr_free (/*@out@*/ /*@only@*/struct group *grent) + { ++ size_t i; + free (grent->gr_name); +- memzero (grent->gr_passwd, strlen (grent->gr_passwd)); +- free (grent->gr_passwd); +- while (*(grent->gr_mem)) { +- free (*(grent->gr_mem)); +- grent->gr_mem++; ++ if (NULL != grent->gr_passwd) { ++ memzero (grent->gr_passwd, strlen (grent->gr_passwd)); ++ free (grent->gr_passwd); + } ++ if (NULL != grent->gr_mem) { ++ for (i = 0; NULL != grent->gr_mem[i]; i++) { ++ free (grent->gr_mem[i]); ++ } ++ free (grent->gr_mem); ++ } + free (grent); + } + +Index: lib/sgroupio.c +=================================================================== +--- lib/sgroupio.c (revision 3061) ++++ lib/sgroupio.c (revision 3062) +@@ -51,7 +51,6 @@ + if (NULL == sg) { + return NULL; + } +- *sg = *sgent; + sg->sg_name = strdup (sgent->sg_name); + if (NULL == sg->sg_name) { + free (sg); +@@ -137,17 +136,20 @@ + + void sgr_free (/*@out@*/ /*@only@*/struct sgrp *sgent) + { ++ size_t i; + free (sgent->sg_name); +- memzero (sgent->sg_passwd, strlen (sgent->sg_passwd)); +- free (sgent->sg_passwd); +- while (NULL != *(sgent->sg_adm)) { +- free (*(sgent->sg_adm)); +- sgent->sg_adm++; ++ if (NULL != sgent->sg_passwd) { ++ memzero (sgent->sg_passwd, strlen (sgent->sg_passwd)); ++ free (sgent->sg_passwd); + } +- while (NULL != *(sgent->sg_mem)) { +- free (*(sgent->sg_mem)); +- sgent->sg_mem++; ++ for (i = 0; NULL != sgent->sg_adm[i]; i++) { ++ free (sgent->sg_adm[i]); + } ++ free (sgent->sg_adm); ++ for (i = 0; NULL != sgent->sg_mem[i]; i++) { ++ free (sgent->sg_mem[i]); ++ } ++ free (sgent->sg_mem); + free (sgent); + } + +Index: lib/pwmem.c +=================================================================== +--- lib/pwmem.c (revision 3061) ++++ lib/pwmem.c (revision 3062) +@@ -48,7 +48,8 @@ + if (NULL == pw) { + return NULL; + } +- *pw = *pwent; ++ pw->pw_uid = pwent->pw_uid; ++ pw->pw_gid = pwent->pw_gid; + pw->pw_name = strdup (pwent->pw_name); + if (NULL == pw->pw_name) { + free(pw); +@@ -91,8 +92,10 @@ + void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent) + { + free (pwent->pw_name); +- memzero (pwent->pw_passwd, strlen (pwent->pw_passwd)); +- free (pwent->pw_passwd); ++ if (pwent->pw_passwd) { ++ memzero (pwent->pw_passwd, strlen (pwent->pw_passwd)); ++ free (pwent->pw_passwd); ++ } + free (pwent->pw_gecos); + free (pwent->pw_dir); + free (pwent->pw_shell); diff --git a/patches/source/shadow/patches/r3096.diff b/patches/source/shadow/patches/r3096.diff new file mode 100644 index 00000000..0e77ce6f --- /dev/null +++ b/patches/source/shadow/patches/r3096.diff @@ -0,0 +1,27 @@ + +* lib/gshadow.c: Fix parsing of gshadow entries. + +Index: lib/gshadow.c +=================================================================== +--- lib/gshadow.c (revision 3095) ++++ lib/gshadow.c (revision 3096) +@@ -222,6 +222,7 @@ + if (NULL == buf) { + return NULL; + } ++ buflen = BUFSIZ; + } + + if (NULL == fp) { +@@ -229,9 +230,9 @@ + } + + #ifdef USE_NIS +- while (fgetsx (buf, (int) sizeof buf, fp) == buf) ++ while (fgetsx (buf, (int) buflen, fp) == buf) + #else +- if (fgetsx (buf, (int) sizeof buf, fp) == buf) ++ if (fgetsx (buf, (int) buflen, fp) == buf) + #endif + { + while ( ((cp = strrchr (buf, '\n')) == NULL) diff --git a/patches/source/shadow/patches/r3160.diff b/patches/source/shadow/patches/r3160.diff new file mode 100644 index 00000000..5aabbaa9 --- /dev/null +++ b/patches/source/shadow/patches/r3160.diff @@ -0,0 +1,239 @@ +Index: libmisc/limits.c +=================================================================== +--- libmisc/limits.c (revision 3159) ++++ libmisc/limits.c (revision 3160) +@@ -33,6 +33,7 @@ + /* + * Separated from setup.c. --marekm + * Resource limits thanks to Cristian Gafton. ++ * Enhancements of resource limit code by Thomas Orgis <thomas@orgis.org> ("thor"). + */ + + #include <config.h> +@@ -44,6 +45,7 @@ + #include <sys/types.h> + #include <sys/stat.h> + #include <stdio.h> ++#include <ctype.h> + #include "prototypes.h" + #include "defines.h" + #include <pwd.h> +@@ -69,17 +71,37 @@ + unsigned int multiplier) + { + struct rlimit rlim; +- long limit; ++ rlim_t limit; + +- if (getlong (value, &limit) == 0) { +- return 0; ++ /* The "-" is special, not belonging to a strange negative limit. ++ It is infinity, in a controlled way. --thor */ ++ if(value[0] == '-') { ++ limit = RLIM_INFINITY; + } +- limit *= multiplier; +- if (limit != (rlim_t) limit) { +- return 0; ++ else { ++ /* We cannot use getlong here because it fails when there ++ is more to the value than just this number! ++ Also, we are limited to base 10 here (hex numbers will not ++ work with the limit string parser as is anyway) --thor */ ++ char *endptr; ++ long longlimit = strtol(value, &endptr, 10); ++ if ((0 == longlimit) && (value == endptr)) { ++ /* No argument at all. No-op. ++ We could instead throw an error, though. --thor */ ++ return 0; ++ } ++ longlimit *= multiplier; ++ limit = (rlim_t)longlimit; ++ if(longlimit != limit) ++ { ++ /* Again, silent error handling... I left it that way. ++ Wouldn't screaming make more sense? --thor */ ++ return 0; ++ } + } +- rlim.rlim_cur = (rlim_t) limit; +- rlim.rlim_max = (rlim_t) limit; ++ ++ rlim.rlim_cur = limit; ++ rlim.rlim_max = limit; + if (setrlimit (resource, &rlim) != 0) { + return LOGIN_ERROR_RLIMIT; + } +@@ -199,6 +221,9 @@ + * [Ii]: i = RLIMIT_NICE max nice value (0..39 translates to 20..-19) + * [Oo]: o = RLIMIT_RTPRIO max real time priority (linux/sched.h 0..MAX_RT_PRIO) + * ++ * Remember to extend the "no-limits" string below when adding a new limit... ++ * --thor ++ * + * Return value: + * 0 = okay, of course + * LOGIN_ERROR_RLIMIT = error setting some RLIMIT +@@ -214,7 +239,20 @@ + bool reported = false; + + pp = buf; ++ /* Skip leading whitespace. --thor */ ++ while(*pp == ' ' || *pp == '\t') ++pp; + ++ /* The special limit string "-" results in no limit for all known limits. ++ We achieve that by parsing a full limit string, parts of it being ignored ++ if a limit type is not known to the system. ++ Though, there will be complaining for unknown limit types. --thor */ ++ if(strcmp(pp, "-") == 0) { ++ /* Remember to extend this, too, when adding new limits! ++ Oh... but "unlimited" does not make sense for umask, or does it? ++ --thor */ ++ pp = "A- C- D- F- M- N- R- S- T- P- I- O-"; ++ } ++ + while ('\0' != *pp) { + switch (*pp++) { + #ifdef RLIMIT_AS +@@ -316,6 +354,10 @@ + break; + default: + /* Only report invalid strings once */ ++ /* Note: A string can be invalid just because a specific (theoretically ++ valid) setting is not supported by this build. ++ It is just a warning in syslog anyway. The line is still processed ++ --thor */ + if (!reported) { + SYSLOG ((LOG_WARN, + "Invalid limit string: '%s'", +@@ -324,13 +366,51 @@ + retval |= LOGIN_ERROR_RLIMIT; + } + } ++ /* After parsing one limit setting (or just complaining about it), ++ one still needs to skip its argument to prevent a bogus warning on ++ trying to parse that as limit specification. ++ So, let's skip all digits, "-" and our limited set of whitespace. ++ --thor */ ++ while(isdigit(*pp) || *pp == '-' || *pp == ' ' || *pp == '\t') { ++ ++pp; ++ } + } + return retval; + } + ++/* Check if user uname is in the group gname. ++ * Can I be sure that gr_mem contains no UID as string? ++ * Returns true when user is in the group, false when not. ++ * Any error is treated as false. --thor ++ */ ++static bool user_in_group (const char *uname, const char *gname) ++{ ++ struct group *groupdata; ++ char **member; ++ if(uname == NULL || gname == NULL){ ++ return false; ++ } ++ /* We are not claiming to be re-entrant! ++ * In case of paranoia or a multithreaded login program, ++ * one needs to add some mess for getgrnam_r. */ ++ groupdata = getgrnam(gname); ++ if(groupdata == NULL) { ++ SYSLOG ((LOG_WARN, "Nonexisting group `%s' in limits file.", gname)); ++ return false; ++ } ++ /* Now look for our user in the list of members. */ ++ member = groupdata->gr_mem; ++ while(*member != NULL) { ++ if(strcmp(*member, uname) == 0) { ++ return true; ++ } ++ ++member; ++ } ++ return false; ++} ++ + static int setup_user_limits (const char *uname) + { +- /* TODO: allow and use @group syntax --cristiang */ + FILE *fil; + char buf[1024]; + char name[1024]; +@@ -352,7 +432,7 @@ + } + /* The limits file have the following format: + * - '#' (comment) chars only as first chars on a line; +- * - username must start on first column ++ * - username must start on first column (or *, or @group --thor) + * A better (smarter) checking should be done --cristiang */ + while (fgets (buf, 1024, fil) != NULL) { + if (('#' == buf[0]) || ('\n' == buf[0])) { +@@ -367,6 +447,13 @@ + * Imposing a limit should be done with care, so a wrong + * entry means no care anyway :-). A '-' as a limits + * strings means no limits --cristiang */ ++ /* In addition to the handling of * as name which was alrady present, ++ I added handling of the @group syntax. ++ To clarify: The first entry with matching user name rules, ++ everything after it is ignored. If there is no user entry, ++ the last encountered entry for a matching group rules. ++ If there is no matching group entry, the default limits rule. ++ --thor. */ + if (sscanf (buf, "%s%[ACDFMNRSTULPIOacdfmnrstulpio0-9 \t-]", + name, tempbuf) == 2) { + if (strcmp (name, uname) == 0) { +@@ -374,6 +461,12 @@ + break; + } else if (strcmp (name, "*") == 0) { + strcpy (deflimits, tempbuf); ++ } else if (name[0] == '@') { ++ /* If the user is in the group, the group limits apply unless ++ later a line for the specific user is found. --thor */ ++ if(user_in_group(uname, name+1)) { ++ strcpy (limits, tempbuf); ++ } + } + } + } +Index: man/limits.5.xml +=================================================================== +--- man/limits.5.xml (revision 3159) ++++ man/limits.5.xml (revision 3160) +@@ -64,7 +64,13 @@ + <emphasis remap='I'>user LIMITS_STRING</emphasis> + </para> + ++ <para>or in the form:</para> ++ + <para> ++ <emphasis remap='I'>@group LIMITS_STRING</emphasis> ++ </para> ++ ++ <para> + The <emphasis>LIMITS_STRING</emphasis> is a string of a concatenated + list of resource limits. Each limit consists of a letter identifier + followed by a numerical limit. +@@ -125,11 +131,23 @@ + </para> + + <para> ++ The limits specified in the form "<replaceable>@group</replaceable>" ++ apply to the members of the specified ++ <replaceable>group</replaceable>. ++ </para> ++ ++ <para> + To completely disable limits for a user, a single dash + "<emphasis>-</emphasis>" will do. + </para> + + <para> ++ To disable a limit for a user, a single dash ++ "<replaceable>-</replaceable>" can be used instead of the numerical ++ value for this limit. ++ </para> ++ ++ <para> + Also, please note that all limit settings are set PER LOGIN. They are + not global, nor are they permanent. Perhaps global limits will come, + but for now this will have to do ;) diff --git a/patches/source/shadow/patches/r3194.diff b/patches/source/shadow/patches/r3194.diff new file mode 100644 index 00000000..0eff631b --- /dev/null +++ b/patches/source/shadow/patches/r3194.diff @@ -0,0 +1,15 @@ +* src/su.c: shell's name must be -su when a su fakes a login. + +=================================================================== +--- src/su.c (revision 3193) ++++ src/su.c (revision 3194) +@@ -1021,7 +1021,7 @@ + * Use the shell and create an argv + * with the rest of the command line included. + */ +- argv[-1] = shellstr; ++ argv[-1] = cp; + #ifndef USE_PAM + execve_shell (shellstr, &argv[-1], environ); + err = errno; + diff --git a/patches/source/shadow/patches/r3299.diff b/patches/source/shadow/patches/r3299.diff new file mode 100644 index 00000000..a46b18f0 --- /dev/null +++ b/patches/source/shadow/patches/r3299.diff @@ -0,0 +1,12 @@ +Index: man/ru/Makefile.am +=================================================================== +--- man/ru/Makefile.am (revision 3298) ++++ man/ru/Makefile.am (revision 3299) +@@ -1,7 +1,6 @@ + mandir = @mandir@/ru + + man_MANS = \ +- $(man_nopam) \ + chage.1 \ + chfn.1 \ + chgpasswd.8 \ diff --git a/patches/source/shadow/shadow.SlackBuild b/patches/source/shadow/shadow.SlackBuild new file mode 100755 index 00000000..84f790e2 --- /dev/null +++ b/patches/source/shadow/shadow.SlackBuild @@ -0,0 +1,165 @@ +#!/bin/sh + +# Copyright 2005-2011 Patrick J. Volkerding, Sebeka, Minnesota, USA +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +PKGNAM=shadow +VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z* | rev | cut -f 3- -d . | cut -f 1 -d - | rev)} +BUILD=${BUILD:-2_slack13.1} + +# Automatically determine the architecture we're building on: +if [ -z "$ARCH" ]; then + case "$( uname -m )" in + i?86) export ARCH=i486 ;; + arm*) export ARCH=arm ;; + # Unless $ARCH is already set, use uname -m for all other archs: + *) export ARCH=$( uname -m ) ;; + esac +fi + +NUMJOBS=${NUMJOBS:--j6} + +CWD=$(pwd) +TMP=${TMP:-/tmp} +PKG=$TMP/package-shadow + +if [ "$ARCH" = "i486" ]; then + SLKCFLAGS="-O2 -march=i486 -mtune=i686" +elif [ "$ARCH" = "s390" ]; then + SLKCFLAGS="-O2" +elif [ "$ARCH" = "x86_64" ]; then + SLKCFLAGS="-O2 -fPIC" +else + SLKCFLAGS="-O2" +fi + +rm -rf $PKG +mkdir -p $TMP $PKG +cd $TMP +rm -rf shadow-$VERSION +tar xvf $CWD/shadow-$VERSION.tar.?z* || exit 1 +cd shadow-$VERSION + +# Apply some patches taken from the svn trunk that +# fix some of the more serious bugs in 4.1.4.3: +for patch in $CWD/patches/*.diff.gz ; do + zcat $patch | patch -p0 --verbose || exit 1 +done + +# Re-run automake because of r3299 patch to man/ru/Makefile.am: +automake -f + +chown -R root:root . +find . \ + \( -perm 777 -o -perm 775 -o -perm 711 -o -perm 555 -o -perm 511 \) \ + -exec chmod 755 {} \; -o \ + \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \ + -exec chmod 644 {} \; + +CFLAGS="$SLKCFLAGS" \ +./configure \ + --prefix=/usr \ + --sysconfdir=/etc \ + --mandir=/usr/man \ + --docdir=/usr/doc/shadow-$VERSION \ + --disable-shared \ + --without-libcrack \ + --build=$ARCH-slackware-linux + +# --enable-utmpx # defaults to 'no' + +make $NUMJOBS || make || exit 1 +make install DESTDIR=$PKG || exit 1 + +# Fix user group = 100: +zcat $CWD/useradd.gz > $PKG/etc/default/useradd + +# /bin/groups is provided by coreutils. +rm -f $PKG/bin/groups +find $PKG -name groups.1 -exec rm {} \; + +# Install a login.defs with unsurprising defaults: +rm -f $PKG/etc/login.defs +zcat $CWD/login.defs.gz > $PKG/etc/login.defs.new + +mv $PKG/etc/login.access $PKG/etc/login.access.new + +# I don't think this works well enough to recommend it. +#mv $PKG/etc/limits $PKG/etc/limits.new +rm -f $PKG/etc/limits + +# Add the friendly 'adduser' script: +cat $CWD/adduser > $PKG/usr/sbin/adduser +chmod 0755 $PKG/usr/sbin/adduser + +# Add sulogin to the package: +cp -a src/sulogin $PKG/sbin +( cd $PKG/bin ; ln -s ../sbin/sulogin ) + +# Add the empty faillog log file: +mkdir -p $PKG/var/log +touch $PKG/var/log/faillog.new + +# Put some stuff back in "old" locations and make symlinks for compat +( cd $PKG/usr/bin + mv faillog ../sbin + mv lastlog ../sbin + ln -s ../sbin/faillog + ln -s ../sbin/lastlog +) + +# Use 4711 rather than 4755 permissions where setuid root is required: +find $PKG -type f -perm 4755 -exec chmod 4711 "{}" \; + +# Compress and if needed symlink the man pages: +if [ -d $PKG/usr/man ]; then + ( cd $PKG/usr/man + for manpagedir in $(find . -type d -name "man*") ; do + ( cd $manpagedir + for eachpage in $( find . -type l -maxdepth 1) ; do + ln -s $( readlink $eachpage ).gz $eachpage.gz + rm $eachpage + done + gzip -9 *.? + ) + done + ) +fi + +mkdir -p $PKG/usr/doc/shadow-$VERSION +cp -a \ + COPYING* NEWS README* TODO doc/{README*,HOWTO,WISHLIST,*.txt} \ + $PKG/usr/doc/shadow-$VERSION + +# If there's a ChangeLog, installing at least part of the recent history +# is useful, but don't let it get totally out of control: +if [ -r ChangeLog ]; then + DOCSDIR=$(echo $PKG/usr/doc/${PKGNAM}-$VERSION) + cat ChangeLog | head -n 1000 > $DOCSDIR/ChangeLog + touch -r ChangeLog $DOCSDIR/ChangeLog +fi + +mkdir -p $PKG/install +cat $CWD/slack-desc > $PKG/install/slack-desc +zcat $CWD/doinst.sh.gz > $PKG/install/doinst.sh + +cd $PKG +/sbin/makepkg -l y -c n $TMP/shadow-$VERSION-$ARCH-$BUILD.txz + diff --git a/patches/source/shadow/shadow.url b/patches/source/shadow/shadow.url new file mode 100644 index 00000000..b18864a8 --- /dev/null +++ b/patches/source/shadow/shadow.url @@ -0,0 +1 @@ +ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow diff --git a/patches/source/shadow/slack-desc b/patches/source/shadow/slack-desc new file mode 100644 index 00000000..57749146 --- /dev/null +++ b/patches/source/shadow/slack-desc @@ -0,0 +1,19 @@ +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. Line +# up the first '|' above the ':' following the base package name, and the '|' +# on the right side marks the last column you can put a character in. You must +# make exactly 11 lines for the formatting to be correct. It's also +# customary to leave one space after the ':'. + + |-----handy-ruler------------------------------------------------------| +shadow: shadow (shadow password suite) +shadow: +shadow: This set of login related programs utilizes an alternate, non-readable +shadow: file to contain the actual encrypted passwords. This is presumed to +shadow: increase system security by increasing the difficulty with which +shadow: system crackers obtain encrypted passwords. It was written by +shadow: Julianne Frances Haugh and the Linux port is maintained by Tomasz +shadow: Kloczko. +shadow: +shadow: This package provides 'login', which is needed to log into the system. +shadow: diff --git a/patches/source/shadow/useradd b/patches/source/shadow/useradd new file mode 100644 index 00000000..f3205e49 --- /dev/null +++ b/patches/source/shadow/useradd @@ -0,0 +1,8 @@ +# useradd defaults file +GROUP=100 +HOME=/home +INACTIVE=-1 +EXPIRE= +SHELL=/bin/bash +SKEL=/etc/skel +CREATE_MAIL_SPOOL=yes |