Package: shadow
Severity: normal
Tags: patch

Hi,

[a-z] may not represent all 26 ASCII lowercase letters in regular
expressions, eg. Estonian collation sorts z between s and t:
  $ echo rstuvwxyz | LC_ALL=en_US.UTF-8 sed -e 's/[a-z]//g'

  $ echo rstuvwxyz | LC_ALL=et_EE.UTF-8 sed -e 's/[a-z]//g'
  tuvwxy
As shown above, this applies to sed, but also awk, grep, expr
  $ echo tuv | LC_ALL=et_EE.UTF-8 awk '/[a-z]/ {print}'
  $ echo tuv | LC_ALL=et_EE.UTF-8 grep [a-z]
  $ LC_ALL=et_EE.UTF-8 expr tuv : [a-z]
  $
and many more.
On the other hand, some commands always work with C collation rules,
most notably tr:
  $ echo 1rstuvwxyz2 | LC_ALL=et_EE.UTF-8 tr -d a-z
  12
or perl and python if they are not told to switch to user's locale.

One must then switch to C locale to avoid those collation issues,
see attached patch.  I also added switches to 'tr' even if it is not
needed for now because documentation tells that 'tr' may get fixed.

Thanks

Denis
diff -ur debian.orig/passwd.config debian/passwd.config
--- debian.orig/passwd.config   2005-12-16 13:10:49.000000000 +0100
+++ debian/passwd.config        2005-12-16 13:19:56.000000000 +0100
@@ -225,11 +225,11 @@
                                        userdefault="tbm"
                                    ;;
                                    *)
-                                       userdefault=`echo $RET | sed 's/ .*//' 
| tr A-Z a-z`
+                                       userdefault=`echo $RET | sed 's/ .*//' 
| LC_ALL=C tr A-Z a-z`
                                    ;;
                                esac
                                if test -n "$userdefault" && \
-                                  expr "$userdefault" : '[a-z][-a-z0-9]*$' 
>/dev/null; then
+                                  LC_ALL=C expr "$userdefault" : 
'[a-z][-a-z0-9]*$' >/dev/null; then
                                        db_set passwd/username "$userdefault"
                                fi
                        fi
@@ -243,7 +243,7 @@
                        # Verify the user name, loop with message if bad.
                        db_get passwd/username
                        USER="$RET"
-                       if ! expr "$USER" : '[a-z][-a-z0-9]*$' >/dev/null; then
+                       if ! LC_ALL=C expr "$USER" : '[a-z][-a-z0-9]*$' 
>/dev/null; then
                                db_fset passwd/username seen false
                                db_fset passwd/username-bad seen false
                                db_input critical passwd/username-bad

Reply via email to