diff --git a/chkname-regex.patch b/chkname-regex.patch index c27e7a5..9fc4c27 100644 --- a/chkname-regex.patch +++ b/chkname-regex.patch @@ -1,3 +1,19 @@ +Index: etc/login.defs +=================================================================== +--- etc/login.defs.orig ++++ etc/login.defs +@@ -274,3 +274,11 @@ USERGROUPS_ENAB yes + # missing. + # + #FORCE_SHADOW yes ++ ++# ++# User/group names must match the following regex expression. ++# The default is [A-Za-z_][A-Za-z0-9_.-]*[A-Za-z0-9_.$-]\?, ++# but be aware that the result could depend on the locale settings. ++# ++#CHARACTER_CLASS [A-Za-z_][A-Za-z0-9_.-]*[A-Za-z0-9_.$-]\? ++CHARACTER_CLASS [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_][ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-]*[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.$-]\? Index: lib/getdef.c =================================================================== --- lib/getdef.c.orig diff --git a/encryption_method_nis.patch b/encryption_method_nis.patch index 47f6ab3..8235523 100644 --- a/encryption_method_nis.patch +++ b/encryption_method_nis.patch @@ -1,10 +1,32 @@ ---- lib/getdef.c +Add support for ENCRYPT_METHOD_NIS used by pam: modules/pam_unix/pam_unix_passwd.c. + +Index: lib/getdef.c +=================================================================== +--- lib/getdef.c.orig +++ lib/getdef.c -@@ -58,6 +58,7 @@ static struct itemdef def_table[] = { +@@ -85,6 +85,7 @@ static struct itemdef def_table[] = { {"CREATE_HOME", NULL}, {"DEFAULT_HOME", NULL}, {"ENCRYPT_METHOD", NULL}, + {"ENCRYPT_METHOD_NIS", NULL}, {"ENV_PATH", NULL}, + {"ENV_ROOTPATH", NULL}, {"ENV_SUPATH", NULL}, - {"ERASECHAR", NULL}, +Index: etc/login.defs +=================================================================== +--- etc/login.defs.orig ++++ etc/login.defs +@@ -187,10 +187,13 @@ CHFN_RESTRICT rwh + # If set to DES, DES-based algorithm will be used for encrypting password (default) + # Overrides the MD5_CRYPT_ENAB option + # ++# ENCRYPT_METHOD_NIS is used by pam_unix_passwd.so. ++# + # Note: If you use PAM, it is recommended to use a value consistent with + # the PAM modules configuration. + # + #ENCRYPT_METHOD DES ++#ENCRYPT_METHOD_NIS DES + + # + # Only works if ENCRYPT_METHOD is set to SHA256 or SHA512. diff --git a/getdef-new-defs.patch b/getdef-new-defs.patch deleted file mode 100644 index 0c5dd41..0000000 --- a/getdef-new-defs.patch +++ /dev/null @@ -1,34 +0,0 @@ -Index: lib/getdef.c -=================================================================== ---- lib/getdef.c.orig -+++ lib/getdef.c -@@ -91,6 +91,7 @@ static struct itemdef def_table[] = { - {"FAKE_SHELL", NULL}, - {"GID_MAX", NULL}, - {"GID_MIN", NULL}, -+ {"GROUPADD_CMD", NULL}, - {"HUSHLOGIN_FILE", NULL}, - {"KILLCHAR", NULL}, - {"LOGIN_RETRIES", NULL}, -@@ -126,7 +127,10 @@ static struct itemdef def_table[] = { - {"UID_MAX", NULL}, - {"UID_MIN", NULL}, - {"UMASK", NULL}, -+ {"USERADD_CMD", NULL}, - {"USERDEL_CMD", NULL}, -+ {"USERDEL_PRECMD", NULL}, -+ {"USERDEL_POSTCMD", NULL}, - {"USERGROUPS_ENAB", NULL}, - #ifndef USE_PAM - PAMDEFS -@@ -149,6 +153,10 @@ static struct itemdef knowndef_table[] = - #ifdef USE_PAM - PAMDEFS - #endif -+ /* Used by /bin/login */ -+ {"MOTD_FILE", NULL}, -+ {"ENV_PATH", NULL}, -+ {"ENV_ROOTPATH", NULL}, - {NULL, NULL} - }; - diff --git a/shadow-login_defs-check.sh b/shadow-login_defs-check.sh new file mode 100644 index 0000000..2b4fa26 --- /dev/null +++ b/shadow-login_defs-check.sh @@ -0,0 +1,256 @@ +#!/bin/bash + +# login.defs and lib/getdef.c contain support for third party variables. +# It also contains support for variables that are unusable in installations with PAM support enabled. +# This script generates a list of used and unused variables in login.defs +# with respect to the current configuration. +# Arguments: arguments of osc build +# If the shadow-login_defs-check-unused.lst is generated, you should +# update login.defs. + +set -o errexit + +echo "Preparing..." + +# Check for required commands +which quilt >/dev/null +which osc >/dev/null + +# login.defs is shared with util-linux login, su and runuser. +# Extract list of referenced variables. +if ! test -f openSUSE:Factory/util-linux/BUILD/*/configure.ac ; then + echo "Checking out util-linux..." + osc co openSUSE:Factory util-linux + cd openSUSE:Factory/util-linux + quilt setup -d BUILD util-linux.spec + cd BUILD/* + quilt push -a + cd ../../../.. +fi + +echo "Extracting variables from util-linux..." +cd openSUSE:Factory/util-linux/BUILD/* +( + grep -rh getlogindefs . | + sed -n 's/^.*getlogindefs[a-z_]*("\([A-Z0-9_]*\)".*$/\1/p' + grep -rh logindefs_setenv . | + sed -n 's/^.*logindefs_setenv*("[A-Z0-9_]*", "\([A-Z0-9_]*\)".*$/\1/p' +) | + LC_ALL=C sort -u >../../../../shadow-login_defs-check-util-linux.lst +cd ../../../.. + +# login.defs is shared pam_unix*.so, pam_faildelay.so and pam_umask.so. +# Extract list of referenced variables. +if ! test -f openSUSE:Factory/pam/BUILD/*/configure.ac ; then + echo "Checking out pam..." + osc co openSUSE:Factory pam + cd openSUSE:Factory/pam + quilt setup -d BUILD pam.spec + cd BUILD/* + quilt push -a + cd ../../../.. +fi + +echo "Extracting variables from pam..." +cd openSUSE:Factory/pam/BUILD/* +grep -rh LOGIN_DEFS . | + sed -n 's/^.*search_key *("\([A-Z0-9_]*\)", *LOGIN_DEFS).*$/\1/p' | + LC_ALL=C sort -u >../../../../shadow-login_defs-check-pam.lst +cd ../../../.. + +if ! test -f shadow-login_defs-check-build/stamp ; then + echo "Performing preprocessing of shadow by osc..." + if ! test -f shadow.spec.shadow-login_defs-check-save ; then + cp -a shadow.spec shadow.spec.shadow-login_defs-check-save + +# In case of shadow, variables extraction is more complicated. The list +# depends on configure options, so we have to perform a fake build and +# extract variables from prepreocessed sources. + patch <shadow-login_defs-check-deleted.lst + +# The build above is optional only for case of failure or edits in the +# code below. If any other build was performed, don't expect correct +# results. + +cd shadow-login_defs-check-build/shadow-* + +echo "Extracting variables from etc/login.defs..." +# Extract variables referenced in login.defs, both active and commented out. +sed -n "s/^#//;s/\([A-Z0-9_]*\)[[:space:]].*$/\1/p" ../../shadow-login_defs-check-login_defs.lst +LC_ALL=C sort -u ../../shadow-login_defs-check-login_defs.lst >../../shadow-login_defs-check-login_defs-sorted.lst + +echo "Extracting variables from lib/getdef.c..." +# Extract variables referenced in lib/getdef.c using current defines. +sed -n 's/^\(},\|\) {"\([A-Z0-9_]*\)", /\2/p' ../../shadow-login_defs-check-getdef.lst +LC_ALL=C sort -u ../../shadow-login_defs-check-getdef.lst >../../shadow-login_defs-check-getdef-sorted.lst + +echo "Extracting variables from shadow..." +# Extract variables referenced in preprocessed files. +grep -r '\(getdef[a-z_]*\|call_script\|is_listed\) *( *"[A-Za-z0-9_]*"' | + grep '[^ ]*\.o:' >../../shadow-login_defs-check-shadow.log + +cd ../.. + +export RC=0 +echo "" +echo "" +echo "Performing checks..." + +sed ' + s/^.*\(getdef[a-z_]*\|call_script\|is_listed*\) *( *"\([A-Za-z0-9_]*\)".*$/\2/ +' ../../shadow-login_defs-check-shadow-all.lst + +sed 's%^\(.*\)%/^.*\\\/\1\.o:/d%' shadow-login_defs-check-deleted.sed +sed -f shadow-login_defs-check-deleted.sed shadow-login_defs-check-shadow-used.lst + +if ! test -s shadow-login_defs-check-deleted.sed ; then + echo " BUG: Empty shadow-login_defs-check-deleted.sed Results will be unreliable!" + if test $RC -le 4 ; then export RC=4 ; fi +fi + +echo "" +echo "Checking that variables in login.defs are referred only once..." +if test $(wc -l shadow-login_defs-check-login_defs.lst | sed 's/ .*//') != $(wc -l shadow-login_defs-check-login_defs-sorted.lst | sed 's/ .*//') ; then + echo " ERROR: Some variable referred at more places of login.defs!" + LC_ALL=C sort shadow-login_defs-check-login_defs.lst >shadow-login_defs-check-login_defs-sorted-nu.lst + diff shadow-login_defs-check-login_defs-sorted-nu.lst shadow-login_defs-check-login_defs-sorted.lst + if test $RC -le 3 ; then export RC=3 ; fi +fi + +echo "" +echo "Checking that variables in lib/getdef.c are referred only once..." +if test $(wc -l shadow-login_defs-check-getdef.lst | sed 's/ .*//') != $(wc -l shadow-login_defs-check-getdef-sorted.lst | sed 's/ .*//') ; then + echo " ERROR: Some variable referred at more places of lib/getdef.c!" + LC_ALL=C sort shadow-login_defs-check-getdef.lst >shadow-login_defs-check-getdef-sorted-nu.lst + diff shadow-login_defs-check-getdef-sorted-nu.lst shadow-login_defs-check-getdef-sorted.lst + if test $RC -le 3 ; then export RC=3 ; fi +fi + +cat shadow-login_defs-check-shadow-used.lst shadow-login_defs-check-util-linux.lst shadow-login_defs-check-pam.lst | LC_ALL=C sort -u >shadow-login_defs-check-all-used.lst +# RC inside pipe cannot be read directly. Use 3 for a real stdout inside the pipe, and use stdout for RC. +exec 3>&1 +function report_packages() { + echo -n " (" + grep -l $1 shadow-login_defs-check-{shadow-used,util-linux,pam}.lst | + sed 's/shadow-login_defs-check-//;s/\.lst//;s/-used//;s/$/, /;$s/, $//' | + tr -d '\n' + echo -n ")" +} + +# Extracting variables from shadow is not capable to identify compiled-but-unused library code. +# This function will identify known false matches. +function falsematch() { + case "$1" in +# MAIL_* used by library call mailcheck() used only by login.c that is deleted in the spec. + MAIL_* ) return 0 ;; +# FTMP_FILE used by library call failtmp() used only by login.c that is deleted in the spec. + FTMP_FILE ) return 0 ;; +# ISSUE_FILE used by library call login_prompt() used only by login.c that is deleted in the spec. + ISSUE_FILE ) return 0 ;; + * ) return 1 ;; + esac +} + +echo "" +echo "Checking that all used variables are covered by login.defs..." +RC=$(cat shadow-login_defs-check-all-used.lst | ( + while read ; do + if falsematch "$REPLY" ; then + echo " FALSE MATCH: Variable $REPLY is not present in login.defs$(report_packages $REPLY)" >&3 + continue + fi + if ! grep -q -x "$REPLY" shadow-login_defs-check-login_defs-sorted.lst ; then + echo " NOTICE: Variable $REPLY is not present in login.defs$(report_packages $REPLY)" >&3 + if test $RC -le 2 ; then RC=2 ; fi + fi + done + echo $RC +) ) + +echo "" +echo "Checking that all used variables are covered by lib/getdef.c..." +RC=$(cat shadow-login_defs-check-all-used.lst | ( + while read ; do + if falsematch "$REPLY" ; then continue ; fi + if ! grep -q -x "$REPLY" shadow-login_defs-check-getdef.lst ; then + echo " ERROR: Variable $REPLY is missing in the parser$(report_packages $REPLY)" >&3 + if test $RC -le 3 ; then RC=3 ; fi + fi + done + echo $RC +) ) + +echo "" +echo "Checking that all used variables referred in login.defs are valid..." +RC=$(cat shadow-login_defs-check-login_defs.lst | ( + while read ; do + if ! grep -q -x "$REPLY" shadow-login_defs-check-all-used.lst ; then + echo " ERROR: Failed to find reference for $REPLY" >&3 + if test $RC -le 3 ; then RC=3 ; fi + fi + if ! grep -q -x "$REPLY" shadow-login_defs-check-getdef.lst ; then + echo " BUG: Parser does not contain reference for $REPLY" >&3 + if test $RC -le 4 ; then RC=4 ; fi + fi + done + echo $RC +) ) + + +echo "" +echo "" +echo "All checks finished." +echo -n "Result: " +case $RC in +0) echo "OK." ;; +1) echo "Notices only. Action is optional." ;; +2) echo "Warnings only. Evaluation is needed." ;; +3) echo "Errors found. Fix is recommended." ;; +4) echo "Fatal error. Fix has to be done." ;; +esac + +if test $RC -ge 1 ; then + exit 1 +fi + +echo " +If you ported shadow-util-linux.patch to the new util-linux version, +please submit these updates: +Change in util-linux.spec:" +sed -n 's/^Version:[[:space:]]*/Requires: login_defs-support-for-util-linux >= /p' = /p' 2.3 BuildRequires: autoconf @@ -62,6 +81,13 @@ Requires(pre): user(root) PreReq: permissions Provides: pwdutils = 3.2.20 Obsoletes: pwdutils <= 3.2.19 +# Virtual provides for supported variables in login.defs. +# It prevents references to unknown variables. +# Upgrade them only if shadow-util-linux.patch or +# encryption_method_nis.patch has to be ported! +# Call shadow-login_defs-check.sh before! +Provides: login_defs-support-for-pam = 1.3.1 +Provides: login_defs-support-for-util-linux = 2.33.1 %description This package includes the necessary programs for converting plain @@ -71,7 +97,7 @@ group accounts. %prep %setup -q -a 1 %patch0 -%patch1 -p1 +%patch1 %patch2 %patch3 %patch4 @@ -81,6 +107,8 @@ group accounts. %patch10 %patch11 -p1 %patch12 -p1 +%patch13 +%patch14 %if 0%{?suse_version} < 1330 %patch20 -p1 %endif diff --git a/useradd-script.patch b/useradd-script.patch index 22f99e2..880c142 100644 --- a/useradd-script.patch +++ b/useradd-script.patch @@ -1,6 +1,38 @@ ---- src/useradd.c +Index: etc/login.defs +=================================================================== +--- etc/login.defs.orig ++++ etc/login.defs +@@ -212,6 +212,13 @@ CHFN_RESTRICT rwh + DEFAULT_HOME yes + + # ++# If defined, this command is run when adding a user. ++# It should rebuild any NIS database etc. to add the ++# new created account. ++# ++USERADD_CMD /usr/sbin/useradd.local ++ ++# + # 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). +Index: lib/getdef.c +=================================================================== +--- lib/getdef.c.orig ++++ lib/getdef.c +@@ -125,6 +125,7 @@ static struct itemdef def_table[] = { + {"UID_MAX", NULL}, + {"UID_MIN", NULL}, + {"UMASK", NULL}, ++ {"USERADD_CMD", NULL}, + {"USERDEL_CMD", NULL}, + {"USERDEL_PRECMD", NULL}, + {"USERDEL_POSTCMD", NULL}, +Index: src/useradd.c +=================================================================== +--- src/useradd.c.orig +++ src/useradd.c -@@ -1982,6 +1982,30 @@ static void create_mail (void) +@@ -2115,6 +2115,30 @@ static void create_mail (void) } /* @@ -31,7 +63,7 @@ * main - useradd command */ int main (int argc, char **argv) -@@ -2242,6 +2266,7 @@ int main (int argc, char **argv) +@@ -2390,6 +2414,7 @@ int main (int argc, char **argv) nscd_flush_cache ("passwd"); nscd_flush_cache ("group"); diff --git a/userdel-script.patch b/userdel-script.patch index 1aae489..e4b93a0 100644 --- a/userdel-script.patch +++ b/userdel-script.patch @@ -1,7 +1,51 @@ -diff -urEbwB shadow-4.6/src/userdel.c shadow-4.6.new/src/userdel.c ---- shadow-4.6/src/userdel.c 2018-04-29 18:42:37.000000000 +0200 -+++ shadow-4.6.new/src/userdel.c 2018-05-14 16:13:43.996280216 +0200 -@@ -125,7 +125,7 @@ +Index: lib/getdef.c +=================================================================== +--- lib/getdef.c.orig ++++ lib/getdef.c +@@ -126,6 +126,8 @@ static struct itemdef def_table[] = { + {"UID_MIN", NULL}, + {"UMASK", NULL}, + {"USERDEL_CMD", NULL}, ++ {"USERDEL_PRECMD", NULL}, ++ {"USERDEL_POSTCMD", NULL}, + {"USERGROUPS_ENAB", NULL}, + #ifndef USE_PAM + PAMDEFS +Index: etc/login.defs +=================================================================== +--- etc/login.defs.orig ++++ etc/login.defs +@@ -216,9 +216,25 @@ DEFAULT_HOME yes + # It should remove any at/cron/print jobs etc. owned by + # the user to be removed (passed as the first argument). + # ++# See also USERDEL_PRECMD and USERDEL_POSTCMD below. ++# + #USERDEL_CMD /usr/sbin/userdel_local + + # ++# If defined, this command is run before removing a user. ++# It should remove any at/cron/print jobs etc. owned by ++# the user to be removed. ++# ++USERDEL_PRECMD /usr/sbin/userdel-pre.local ++ ++# ++# If defined, this command is run after removing a user. ++# It should rebuild any NIS database etc. to remove the ++# account from it. ++# ++USERDEL_POSTCMD /usr/sbin/userdel-post.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. +Index: src/userdel.c +=================================================================== +--- src/userdel.c.orig ++++ src/userdel.c +@@ -125,7 +125,7 @@ static void close_files (void); static void fail_exit (int); static void open_files (void); static void update_user (void); @@ -10,7 +54,7 @@ diff -urEbwB shadow-4.6/src/userdel.c shadow-4.6.new/src/userdel.c #ifdef EXTRA_CHECK_HOME_DIR static bool path_prefix (const char *, const char *); -@@ -767,13 +767,13 @@ +@@ -767,13 +767,13 @@ static void update_user (void) * cron, at, or print jobs. */ @@ -26,7 +70,7 @@ diff -urEbwB shadow-4.6/src/userdel.c shadow-4.6.new/src/userdel.c if (NULL == cmd) { return; } -@@ -1213,9 +1213,10 @@ +@@ -1213,9 +1213,10 @@ int main (int argc, char **argv) } /* @@ -35,20 +79,20 @@ diff -urEbwB shadow-4.6/src/userdel.c shadow-4.6.new/src/userdel.c + * Do the hard stuff - open the files, remove the user entries, + * remove the home directory, then close and update the files. */ -+ call_script ("USERDEL_PRECMD", user_name); ++ call_script ("USERDEL_PRECMD", user_name); open_files (); update_user (); update_groups (); -@@ -1319,7 +1320,7 @@ +@@ -1319,7 +1320,7 @@ int main (int argc, char **argv) * the entry from /etc/passwd. */ if(prefix[0] == '\0') - user_cancel (user_name); -+ call_script ("USERDEL_CMD", user_name); ++ call_script ("USERDEL_CMD", user_name); close_files (); #ifdef WITH_TCB -@@ -1329,6 +1330,9 @@ +@@ -1329,6 +1330,9 @@ int main (int argc, char **argv) nscd_flush_cache ("passwd"); nscd_flush_cache ("group");