Password aging
HP-UX, SunOS4.1, System-V, and some other derivatives (see SVID2 and XPG2
specifications) use a password aging scheme which causes glibc-based
programs to fail to match passwords in shared password files and NIS maps.
Debian 2.0 and 2.1 Linux, e.g., libc-2.0.7t, have this problem for example.
These password files encode
password aging information in the encrypted password field of
the file, separated from the encrypted password by a comma. You can
search AltaVista for +"/etc/passwd" +aging -shadow +comma
to find out more than you want to know about it.
I've attached a simple and probably over-cautous patch to ignore
the password aging stuff in the guilty password files and NIS/YP maps.
Currently the struct passwd, returned by getpwent() for example,
populated by glibc, contains everything up to the following colon,
which causes the password matching algorithm to fail. With this patch,
only the field up to the comma (if present) is returned in the passwd
struct. The simple test program 'gp.c' can be used to verify the
before/after behavior of this patch.
I'd appreciate knowing if this is a feature you'd prefer to leave out of
glibc so I can find another way to solve people's problems.
Thanks!
-Paul Bame
bame@sde.hp.com
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Paul Bame <bame@bame> on Thu Apr 22 16:59:19 1999
#
# This archive contains:
# glibc-2.0.7-pwaging.diff gp.c
#
LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH
echo x - glibc-2.0.7-pwaging.diff
cat >glibc-2.0.7-pwaging.diff <<'@EOF'
*** glibc-2.0.7t/pwd/fgetpwent_r.c.orig Fri Feb 12 09:07:03 1999
--- glibc-2.0.7t/pwd/fgetpwent_r.c Fri Feb 12 10:30:33 1999
***************
*** 46,52 ****
--- 46,57 ----
}
else
{
+ char *comma;
STRING_FIELD (result->pw_passwd, ISCOLON, 0);
+ /* Truncate encrypted password at ',' in case it contains aging info */
+ if (result->pw_passwd != NULL
+ && (comma = strchr(result->pw_passwd, ',')) != NULL)
+ *comma = '\0';
if (result->pw_name[0] == '+' || result->pw_name[0] == '-')
{
INT_FIELD_MAYBE_NULL (result->pw_uid, ISCOLON, 0, 10, , 0)
@EOF
chmod 644 glibc-2.0.7-pwaging.diff
echo x - gp.c
cat >gp.c <<'@EOF'
#include <stdio.h>
#include <pwd.h>
#include <sys/types.h>
int
main(int argc, char *argv[])
{
struct passwd *pw;
if (argc != 2)
{
fprintf(stderr, "Usage: %s user-name\n", argv[0]);
return 2;
}
setpwent();
while ((pw = getpwent()) != NULL)
{
if (strcmp(pw->pw_name, argv[1]) == 0)
{
printf("pw_name: '%s'\n", pw->pw_name);
printf("pw_passwd: '%s'\n", pw->pw_passwd);
printf("pw_uid: '%d'\n", pw->pw_uid);
printf("pw_gid: '%d'\n", pw->pw_gid);
printf("pw_gecos: '%s'\n", pw->pw_gecos);
printf("pw_dir: '%s'\n", pw->pw_dir);
printf("pw_shell: '%s'\n", pw->pw_shell);
return 0;
}
}
endpwent();
return 3;
}
@EOF
chmod 644 gp.c
exit 0
Reply to: