From 653831d0e66104c8934f42dfd5232515d70637f4 Mon Sep 17 00:00:00 2001 From: nekral-guest Date: Sun, 7 Oct 2007 11:44:33 +0000 Subject: [PATCH] [svn-upgrade] Tagging new upstream version, shadow (20000902) --- current/ABOUT-NLS | 226 + current/Makefile.am | 6 + current/Makefile.in | 391 ++ current/acconfig.h | 151 + current/aclocal.m4 | 1027 ++++ current/config.guess | 1087 ++++ current/config.h.in | 460 ++ current/config.sub | 1215 ++++ current/configure | 6803 +++++++++++++++++++++ current/configure.in | 311 + current/contrib/Makefile.am | 6 + current/contrib/Makefile.in | 212 + current/contrib/README | 10 + current/contrib/adduser-old.c | 300 + current/contrib/adduser.c | 502 ++ current/contrib/adduser.sh | 90 + current/contrib/adduser2.sh | 743 +++ current/contrib/atudel | 85 + current/contrib/groupmems.shar | 546 ++ current/contrib/pwdauth.c | 308 + current/contrib/rpasswd.c | 591 ++ current/contrib/shadow-anonftp.patch | 147 + current/contrib/udbachk.v012.tgz | Bin 0 -> 20228 bytes current/debian/FILES | 70 + current/debian/Makefile.am | 9 + current/debian/Makefile.in | 212 + current/debian/changelog | 175 + current/debian/checksums | 7 + current/debian/control | 41 + current/debian/control.gnu | 16 + current/debian/control.linux | 41 + current/debian/login.conffiles | 6 + current/debian/login.copyright | 76 + current/debian/login.postinst | 42 + current/debian/login.postrm | 6 + current/debian/login.preinst | 4 + current/debian/login.prerm | 8 + current/debian/logoutd.init | 36 + current/debian/passwd.conffiles | 3 + current/debian/passwd.copyright | 55 + current/debian/passwd.cron | 8 + current/debian/passwd.init | 25 + current/debian/passwd.postinst | 41 + current/debian/passwd.postrm | 6 + current/debian/porttime | 8 + current/debian/rules | 159 + current/debian/secure-su.README | 4 + current/debian/secure-su.conffiles | 1 + current/debian/secure-su.copyright | 54 + current/debian/secure-su.postrm | 12 + current/debian/secure-su.preinst | 14 + current/debian/securetty | 14 + current/debian/tar.c | 409 ++ current/doc/ANNOUNCE | 48 + current/doc/CHANGES | 694 +++ current/doc/HOWTO | 1918 ++++++ current/doc/INSTALL | 176 + current/doc/LICENSE | 118 + current/doc/LSM | 20 + current/doc/Makefile.am | 7 + current/doc/Makefile.in | 212 + current/doc/README | 253 + current/doc/README.debian | 68 + current/doc/README.limits | 66 + current/doc/README.linux | 166 + current/doc/README.mirrors | 60 + current/doc/README.nls | 30 + current/doc/README.pam | 35 + current/doc/README.platforms | 33 + current/doc/README.shadow-paper | 25 + current/doc/README.sun4 | 39 + current/doc/WISHLIST | 53 + current/doc/console.c.spec.txt | 36 + current/doc/cracklib26.diff | 340 + current/etc/Makefile.am | 7 + current/etc/Makefile.in | 318 + current/etc/limits | 28 + current/etc/login.access | 54 + current/etc/login.defs | 214 + current/etc/login.defs.hurd | 143 + current/etc/login.defs.linux | 370 ++ current/etc/pam.d/Makefile.am | 4 + current/etc/pam.d/Makefile.in | 211 + current/etc/pam.d/passwd | 5 + current/etc/pam.d/su | 7 + current/etc/shells | 10 + current/etc/suauth | 4 + current/install-sh | 251 + current/intl/ChangeLog | 1086 ++++ current/intl/Makefile.in | 214 + current/intl/VERSION | 1 + current/intl/bindtextdom.c | 203 + current/intl/cat-compat.c | 262 + current/intl/dcgettext.c | 655 ++ current/intl/dgettext.c | 59 + current/intl/explodename.c | 197 + current/intl/finddomain.c | 216 + current/intl/gettext.c | 70 + current/intl/gettext.h | 105 + current/intl/gettextP.h | 89 + current/intl/hash-string.h | 59 + current/intl/intl-compat.c | 76 + current/intl/l10nflist.c | 411 ++ current/intl/libgettext.h | 182 + current/intl/linux-msg.sed | 100 + current/intl/loadinfo.h | 78 + current/intl/loadmsgcat.c | 220 + current/intl/localealias.c | 438 ++ current/intl/po2tbl.sed.in | 102 + current/intl/textdomain.c | 108 + current/intl/xopen-msg.sed | 104 + current/lib/Makefile.am | 57 + current/lib/Makefile.in | 448 ++ current/lib/commonio.c | 803 +++ current/lib/commonio.h | 100 + current/lib/defines.h | 348 ++ current/lib/dialchk.c | 77 + current/lib/dialchk.h | 16 + current/lib/dialup.c | 169 + current/lib/dialup.h | 66 + current/lib/encrypt.c | 123 + current/lib/faillog.h | 55 + current/lib/fputsx.c | 80 + current/lib/getdef.c | 406 ++ current/lib/getdef.h | 11 + current/lib/getpass.c | 296 + current/lib/grdbm.c | 211 + current/lib/groupio.c | 184 + current/lib/groupio.h | 12 + current/lib/grpack.c | 95 + current/lib/gsdbm.c | 167 + current/lib/gshadow.c | 528 ++ current/lib/gshadow_.h | 71 + current/lib/gspack.c | 150 + current/lib/lastlog_.h | 50 + current/lib/lockpw.c | 114 + current/lib/md5.c | 261 + current/lib/md5.h | 27 + current/lib/md5crypt.c | 151 + current/lib/mkdir.c | 60 + current/lib/pam_defs.h | 21 + current/lib/port.c | 439 ++ current/lib/port.h | 81 + current/lib/prototypes.h | 228 + current/lib/putgrent.c | 75 + current/lib/putpwent.c | 72 + current/lib/putspent.c | 103 + current/lib/pwauth.c | 578 ++ current/lib/pwauth.h | 60 + current/lib/pwdbm.c | 143 + current/lib/pwio.c | 186 + current/lib/pwio.h | 12 + current/lib/pwpack.c | 163 + current/lib/rad64.c | 126 + current/lib/rcsid.h | 22 + current/lib/rename.c | 91 + current/lib/rmdir.c | 59 + current/lib/sgetgrent.c | 140 + current/lib/sgetpwent.c | 136 + current/lib/sgetspent.c | 198 + current/lib/sgroupio.c | 212 + current/lib/sgroupio.h | 13 + current/lib/shadow.c | 592 ++ current/lib/shadow_.h | 89 + current/lib/shadowio.c | 171 + current/lib/shadowio.h | 13 + current/lib/snprintf.c | 320 + current/lib/snprintf.h | 51 + current/lib/spdbm.c | 116 + current/lib/sppack.c | 113 + current/lib/strcasecmp.c | 25 + current/lib/strdup.c | 16 + current/lib/strerror.c | 23 + current/lib/strstr.c | 55 + current/lib/tcfsio.c | 90 + current/lib/tcfsio.h | 14 + current/lib/utent.c | 114 + current/libmisc/Makefile.am | 20 + current/libmisc/Makefile.in | 435 ++ current/libmisc/addgrps.c | 89 + current/libmisc/age.c | 235 + current/libmisc/basename.c | 22 + current/libmisc/chkname.c | 73 + current/libmisc/chkname.h | 15 + current/libmisc/chkshell.c | 98 + current/libmisc/chowndir.c | 132 + current/libmisc/chowntty.c | 127 + current/libmisc/console.c | 115 + current/libmisc/copydir.c | 403 ++ current/libmisc/entry.c | 99 + current/libmisc/env.c | 250 + current/libmisc/failure.c | 278 + current/libmisc/failure.h | 44 + current/libmisc/fields.c | 104 + current/libmisc/getdate.c | 2006 ++++++ current/libmisc/getdate.h | 8 + current/libmisc/getdate.y | 1024 ++++ current/libmisc/hushed.c | 90 + current/libmisc/isexpired.c | 173 + current/libmisc/limits.c | 426 ++ current/libmisc/list.c | 234 + current/libmisc/log.c | 100 + current/libmisc/login_access.c | 340 + current/libmisc/login_desrpc.c | 77 + current/libmisc/login_krb.c | 61 + current/libmisc/loginprompt.c | 165 + current/libmisc/mail.c | 79 + current/libmisc/motd.c | 69 + current/libmisc/myname.c | 41 + current/libmisc/obscure.c | 286 + current/libmisc/pam_pass.c | 58 + current/libmisc/pwd2spwd.c | 103 + current/libmisc/pwd_init.c | 73 + current/libmisc/pwdcheck.c | 69 + current/libmisc/rlogin.c | 171 + current/libmisc/salt.c | 70 + current/libmisc/setugid.c | 134 + current/libmisc/setup.c | 72 + current/libmisc/setupenv.c | 292 + current/libmisc/shell.c | 126 + current/libmisc/strtoday.c | 207 + current/libmisc/suauth.c | 201 + current/libmisc/sub.c | 78 + current/libmisc/sulog.c | 74 + current/libmisc/ttytype.c | 89 + current/libmisc/tz.c | 67 + current/libmisc/ulimit.c | 34 + current/libmisc/utmp.c | 478 ++ current/libmisc/valid.c | 101 + current/libmisc/xmalloc.c | 38 + current/ltconfig | 3017 +++++++++ current/ltmain.sh | 3975 ++++++++++++ current/man/Makefile.am | 21 + current/man/Makefile.in | 471 ++ current/man/chage.1 | 109 + current/man/chfn.1 | 66 + current/man/chpasswd.8 | 62 + current/man/chsh.1 | 66 + current/man/dialups.5 | 22 + current/man/dpasswd.8 | 55 + current/man/faillog.5 | 59 + current/man/faillog.8 | 100 + current/man/gpasswd.1 | 73 + current/man/groupadd.8 | 64 + current/man/groupdel.8 | 60 + current/man/groupmod.8 | 66 + current/man/groups.1 | 57 + current/man/grpck.8 | 101 + current/man/id.1 | 54 + current/man/lastlog.8 | 63 + current/man/limits.5 | 76 + current/man/login.1 | 155 + current/man/login.access.5 | 52 + current/man/login.defs.5 | 573 ++ current/man/logoutd.8 | 51 + current/man/mkpasswd.8 | 81 + current/man/newgrp.1 | 80 + current/man/newusers.8 | 68 + current/man/passwd.1 | 190 + current/man/passwd.5 | 111 + current/man/pl/Makefile.am | 60 + current/man/pl/Makefile.in | 316 + current/man/pl/chage.1 | 110 + current/man/pl/chfn.1 | 77 + current/man/pl/chpasswd.8 | 62 + current/man/pl/chsh.1 | 70 + current/man/pl/d_passwd.5 | 30 + current/man/pl/dialups.5 | 24 + current/man/pl/dpasswd.8 | 56 + current/man/pl/faillog.5 | 59 + current/man/pl/faillog.8 | 95 + current/man/pl/gpasswd.1 | 65 + current/man/pl/groupadd.8 | 72 + current/man/pl/groupdel.8 | 68 + current/man/pl/groupmod.8 | 77 + current/man/pl/groups.1 | 61 + current/man/pl/grpck.8 | 103 + current/man/pl/id.1 | 57 + current/man/pl/lastlog.8 | 64 + current/man/pl/limits.5 | 79 + current/man/pl/login.1 | 134 + current/man/pl/login.access.5 | 54 + current/man/pl/login.defs.5 | 557 ++ current/man/pl/logoutd.8 | 50 + current/man/pl/mkpasswd.8 | 80 + current/man/pl/newgrp.1 | 87 + current/man/pl/newusers.8 | 69 + current/man/pl/passwd.1 | 201 + current/man/pl/passwd.5 | 88 + current/man/pl/porttime.5 | 81 + current/man/pl/pw_auth.3 | 152 + current/man/pl/pwauth.8 | 65 + current/man/pl/pwck.8 | 109 + current/man/pl/pwconv.8 | 66 + current/man/pl/shadow.3 | 148 + current/man/pl/shadow.5 | 92 + current/man/pl/shadowconfig.8 | 27 + current/man/pl/su.1 | 87 + current/man/pl/suauth.5 | 115 + current/man/pl/sulogin.8 | 94 + current/man/porttime.5 | 84 + current/man/pw_auth.3 | 159 + current/man/pwauth.8 | 67 + current/man/pwck.8 | 107 + current/man/pwconv.8 | 63 + current/man/shadow.3 | 148 + current/man/shadow.5 | 99 + current/man/shadowconfig.8 | 24 + current/man/su.1 | 87 + current/man/suauth.5 | 112 + current/man/sulogin.8 | 88 + current/man/useradd.8 | 197 + current/man/userdel.8 | 69 + current/man/usermod.8 | 162 + current/man/vipw.8 | 29 + current/missing | 190 + current/mkinstalldirs | 40 + current/po/ChangeLog | 0 current/po/Makefile.in.in | 248 + current/po/POTFILES.in | 123 + current/po/cat-id-tbl.c | 504 ++ current/po/el.gmo | Bin 0 -> 41822 bytes current/po/el.po | 2459 ++++++++ current/po/fr.gmo | Bin 0 -> 40067 bytes current/po/fr.po | 2417 ++++++++ current/po/pl.gmo | Bin 0 -> 40513 bytes current/po/pl.po | 2414 ++++++++ current/po/shadow.pot | 2368 +++++++ current/po/stamp-cat-id | 1 + current/po/sv.gmo | Bin 0 -> 39254 bytes current/po/sv.po | 2406 ++++++++ current/redhat/Makefile.am | 8 + current/redhat/Makefile.in | 214 + current/redhat/README | 29 + current/redhat/shadow-970616-fix.patch | 256 + current/redhat/shadow-970616-glibc.patch | 11 + current/redhat/shadow-970616-rh.patch | 1242 ++++ current/redhat/shadow-970616-utuser.patch | 12 + current/redhat/shadow-970616.login.defs | 57 + current/redhat/shadow-970616.useradd | 7 + current/redhat/shadow-utils-970616.spec | 137 + current/redhat/shadow-utils.spec.in | 154 + current/src/Makefile.am | 90 + current/src/Makefile.in | 895 +++ current/src/chage.c | 841 +++ current/src/chfn.c | 600 ++ current/src/chpasswd.c | 288 + current/src/chsh.c | 437 ++ current/src/dpasswd.c | 259 + current/src/expiry.c | 210 + current/src/faillog.c | 379 ++ current/src/gpasswd.c | 661 ++ current/src/groupadd.c | 537 ++ current/src/groupdel.c | 351 ++ current/src/groupmod.c | 548 ++ current/src/groups.c | 183 + current/src/grpck.c | 649 ++ current/src/grpconv.c | 173 + current/src/grpunconv.c | 131 + current/src/id.c | 187 + current/src/lastlog.c | 192 + current/src/login.c | 1314 ++++ current/src/logoutd.c | 308 + current/src/mkpasswd.c | 394 ++ current/src/newgrp.c | 499 ++ current/src/newusers.c | 568 ++ current/src/passwd.c | 1415 +++++ current/src/patchlevel.h | 58 + current/src/pwck.c | 616 ++ current/src/pwconv.c | 187 + current/src/pwunconv.c | 196 + current/src/shadowconfig.sh | 67 + current/src/su.c | 637 ++ current/src/sulogin.c | 273 + current/src/useradd.c | 1746 ++++++ current/src/userdel.c | 846 +++ current/src/usermod.c | 1705 ++++++ current/src/vipw.c | 252 + current/stamp-h.in | 1 + 379 files changed, 97630 insertions(+) create mode 100644 current/ABOUT-NLS create mode 100644 current/Makefile.am create mode 100644 current/Makefile.in create mode 100644 current/acconfig.h create mode 100644 current/aclocal.m4 create mode 100755 current/config.guess create mode 100644 current/config.h.in create mode 100755 current/config.sub create mode 100755 current/configure create mode 100644 current/configure.in create mode 100644 current/contrib/Makefile.am create mode 100644 current/contrib/Makefile.in create mode 100644 current/contrib/README create mode 100644 current/contrib/adduser-old.c create mode 100644 current/contrib/adduser.c create mode 100755 current/contrib/adduser.sh create mode 100755 current/contrib/adduser2.sh create mode 100755 current/contrib/atudel create mode 100644 current/contrib/groupmems.shar create mode 100644 current/contrib/pwdauth.c create mode 100644 current/contrib/rpasswd.c create mode 100644 current/contrib/shadow-anonftp.patch create mode 100644 current/contrib/udbachk.v012.tgz create mode 100644 current/debian/FILES create mode 100644 current/debian/Makefile.am create mode 100644 current/debian/Makefile.in create mode 100644 current/debian/changelog create mode 100755 current/debian/checksums create mode 100644 current/debian/control create mode 100644 current/debian/control.gnu create mode 100644 current/debian/control.linux create mode 100644 current/debian/login.conffiles create mode 100644 current/debian/login.copyright create mode 100644 current/debian/login.postinst create mode 100644 current/debian/login.postrm create mode 100644 current/debian/login.preinst create mode 100644 current/debian/login.prerm create mode 100644 current/debian/logoutd.init create mode 100644 current/debian/passwd.conffiles create mode 100644 current/debian/passwd.copyright create mode 100644 current/debian/passwd.cron create mode 100755 current/debian/passwd.init create mode 100644 current/debian/passwd.postinst create mode 100644 current/debian/passwd.postrm create mode 100644 current/debian/porttime create mode 100755 current/debian/rules create mode 100644 current/debian/secure-su.README create mode 100644 current/debian/secure-su.conffiles create mode 100644 current/debian/secure-su.copyright create mode 100644 current/debian/secure-su.postrm create mode 100644 current/debian/secure-su.preinst create mode 100644 current/debian/securetty create mode 100644 current/debian/tar.c create mode 100644 current/doc/ANNOUNCE create mode 100644 current/doc/CHANGES create mode 100644 current/doc/HOWTO create mode 100644 current/doc/INSTALL create mode 100644 current/doc/LICENSE create mode 100644 current/doc/LSM create mode 100644 current/doc/Makefile.am create mode 100644 current/doc/Makefile.in create mode 100644 current/doc/README create mode 100644 current/doc/README.debian create mode 100644 current/doc/README.limits create mode 100644 current/doc/README.linux create mode 100644 current/doc/README.mirrors create mode 100644 current/doc/README.nls create mode 100644 current/doc/README.pam create mode 100644 current/doc/README.platforms create mode 100644 current/doc/README.shadow-paper create mode 100644 current/doc/README.sun4 create mode 100644 current/doc/WISHLIST create mode 100644 current/doc/console.c.spec.txt create mode 100644 current/doc/cracklib26.diff create mode 100644 current/etc/Makefile.am create mode 100644 current/etc/Makefile.in create mode 100644 current/etc/limits create mode 100644 current/etc/login.access create mode 100644 current/etc/login.defs create mode 100644 current/etc/login.defs.hurd create mode 100644 current/etc/login.defs.linux create mode 100644 current/etc/pam.d/Makefile.am create mode 100644 current/etc/pam.d/Makefile.in create mode 100644 current/etc/pam.d/passwd create mode 100644 current/etc/pam.d/su create mode 100644 current/etc/shells create mode 100644 current/etc/suauth create mode 100755 current/install-sh create mode 100644 current/intl/ChangeLog create mode 100644 current/intl/Makefile.in create mode 100644 current/intl/VERSION create mode 100644 current/intl/bindtextdom.c create mode 100644 current/intl/cat-compat.c create mode 100644 current/intl/dcgettext.c create mode 100644 current/intl/dgettext.c create mode 100644 current/intl/explodename.c create mode 100644 current/intl/finddomain.c create mode 100644 current/intl/gettext.c create mode 100644 current/intl/gettext.h create mode 100644 current/intl/gettextP.h create mode 100644 current/intl/hash-string.h create mode 100644 current/intl/intl-compat.c create mode 100644 current/intl/l10nflist.c create mode 100644 current/intl/libgettext.h create mode 100644 current/intl/linux-msg.sed create mode 100644 current/intl/loadinfo.h create mode 100644 current/intl/loadmsgcat.c create mode 100644 current/intl/localealias.c create mode 100644 current/intl/po2tbl.sed.in create mode 100644 current/intl/textdomain.c create mode 100644 current/intl/xopen-msg.sed create mode 100644 current/lib/Makefile.am create mode 100644 current/lib/Makefile.in create mode 100644 current/lib/commonio.c create mode 100644 current/lib/commonio.h create mode 100644 current/lib/defines.h create mode 100644 current/lib/dialchk.c create mode 100644 current/lib/dialchk.h create mode 100644 current/lib/dialup.c create mode 100644 current/lib/dialup.h create mode 100644 current/lib/encrypt.c create mode 100644 current/lib/faillog.h create mode 100644 current/lib/fputsx.c create mode 100644 current/lib/getdef.c create mode 100644 current/lib/getdef.h create mode 100644 current/lib/getpass.c create mode 100644 current/lib/grdbm.c create mode 100644 current/lib/groupio.c create mode 100644 current/lib/groupio.h create mode 100644 current/lib/grpack.c create mode 100644 current/lib/gsdbm.c create mode 100644 current/lib/gshadow.c create mode 100644 current/lib/gshadow_.h create mode 100644 current/lib/gspack.c create mode 100644 current/lib/lastlog_.h create mode 100644 current/lib/lockpw.c create mode 100644 current/lib/md5.c create mode 100644 current/lib/md5.h create mode 100644 current/lib/md5crypt.c create mode 100644 current/lib/mkdir.c create mode 100644 current/lib/pam_defs.h create mode 100644 current/lib/port.c create mode 100644 current/lib/port.h create mode 100644 current/lib/prototypes.h create mode 100644 current/lib/putgrent.c create mode 100644 current/lib/putpwent.c create mode 100644 current/lib/putspent.c create mode 100644 current/lib/pwauth.c create mode 100644 current/lib/pwauth.h create mode 100644 current/lib/pwdbm.c create mode 100644 current/lib/pwio.c create mode 100644 current/lib/pwio.h create mode 100644 current/lib/pwpack.c create mode 100644 current/lib/rad64.c create mode 100644 current/lib/rcsid.h create mode 100644 current/lib/rename.c create mode 100644 current/lib/rmdir.c create mode 100644 current/lib/sgetgrent.c create mode 100644 current/lib/sgetpwent.c create mode 100644 current/lib/sgetspent.c create mode 100644 current/lib/sgroupio.c create mode 100644 current/lib/sgroupio.h create mode 100644 current/lib/shadow.c create mode 100644 current/lib/shadow_.h create mode 100644 current/lib/shadowio.c create mode 100644 current/lib/shadowio.h create mode 100644 current/lib/snprintf.c create mode 100644 current/lib/snprintf.h create mode 100644 current/lib/spdbm.c create mode 100644 current/lib/sppack.c create mode 100644 current/lib/strcasecmp.c create mode 100644 current/lib/strdup.c create mode 100644 current/lib/strerror.c create mode 100644 current/lib/strstr.c create mode 100644 current/lib/tcfsio.c create mode 100644 current/lib/tcfsio.h create mode 100644 current/lib/utent.c create mode 100644 current/libmisc/Makefile.am create mode 100644 current/libmisc/Makefile.in create mode 100644 current/libmisc/addgrps.c create mode 100644 current/libmisc/age.c create mode 100644 current/libmisc/basename.c create mode 100644 current/libmisc/chkname.c create mode 100644 current/libmisc/chkname.h create mode 100644 current/libmisc/chkshell.c create mode 100644 current/libmisc/chowndir.c create mode 100644 current/libmisc/chowntty.c create mode 100644 current/libmisc/console.c create mode 100644 current/libmisc/copydir.c create mode 100644 current/libmisc/entry.c create mode 100644 current/libmisc/env.c create mode 100644 current/libmisc/failure.c create mode 100644 current/libmisc/failure.h create mode 100644 current/libmisc/fields.c create mode 100644 current/libmisc/getdate.c create mode 100644 current/libmisc/getdate.h create mode 100644 current/libmisc/getdate.y create mode 100644 current/libmisc/hushed.c create mode 100644 current/libmisc/isexpired.c create mode 100644 current/libmisc/limits.c create mode 100644 current/libmisc/list.c create mode 100644 current/libmisc/log.c create mode 100644 current/libmisc/login_access.c create mode 100644 current/libmisc/login_desrpc.c create mode 100644 current/libmisc/login_krb.c create mode 100644 current/libmisc/loginprompt.c create mode 100644 current/libmisc/mail.c create mode 100644 current/libmisc/motd.c create mode 100644 current/libmisc/myname.c create mode 100644 current/libmisc/obscure.c create mode 100644 current/libmisc/pam_pass.c create mode 100644 current/libmisc/pwd2spwd.c create mode 100644 current/libmisc/pwd_init.c create mode 100644 current/libmisc/pwdcheck.c create mode 100644 current/libmisc/rlogin.c create mode 100644 current/libmisc/salt.c create mode 100644 current/libmisc/setugid.c create mode 100644 current/libmisc/setup.c create mode 100644 current/libmisc/setupenv.c create mode 100644 current/libmisc/shell.c create mode 100644 current/libmisc/strtoday.c create mode 100644 current/libmisc/suauth.c create mode 100644 current/libmisc/sub.c create mode 100644 current/libmisc/sulog.c create mode 100644 current/libmisc/ttytype.c create mode 100644 current/libmisc/tz.c create mode 100644 current/libmisc/ulimit.c create mode 100644 current/libmisc/utmp.c create mode 100644 current/libmisc/valid.c create mode 100644 current/libmisc/xmalloc.c create mode 100755 current/ltconfig create mode 100644 current/ltmain.sh create mode 100644 current/man/Makefile.am create mode 100644 current/man/Makefile.in create mode 100644 current/man/chage.1 create mode 100644 current/man/chfn.1 create mode 100644 current/man/chpasswd.8 create mode 100644 current/man/chsh.1 create mode 100644 current/man/dialups.5 create mode 100644 current/man/dpasswd.8 create mode 100644 current/man/faillog.5 create mode 100644 current/man/faillog.8 create mode 100644 current/man/gpasswd.1 create mode 100644 current/man/groupadd.8 create mode 100644 current/man/groupdel.8 create mode 100644 current/man/groupmod.8 create mode 100644 current/man/groups.1 create mode 100644 current/man/grpck.8 create mode 100644 current/man/id.1 create mode 100644 current/man/lastlog.8 create mode 100644 current/man/limits.5 create mode 100644 current/man/login.1 create mode 100644 current/man/login.access.5 create mode 100644 current/man/login.defs.5 create mode 100644 current/man/logoutd.8 create mode 100644 current/man/mkpasswd.8 create mode 100644 current/man/newgrp.1 create mode 100644 current/man/newusers.8 create mode 100644 current/man/passwd.1 create mode 100644 current/man/passwd.5 create mode 100644 current/man/pl/Makefile.am create mode 100644 current/man/pl/Makefile.in create mode 100644 current/man/pl/chage.1 create mode 100644 current/man/pl/chfn.1 create mode 100644 current/man/pl/chpasswd.8 create mode 100644 current/man/pl/chsh.1 create mode 100644 current/man/pl/d_passwd.5 create mode 100644 current/man/pl/dialups.5 create mode 100644 current/man/pl/dpasswd.8 create mode 100644 current/man/pl/faillog.5 create mode 100644 current/man/pl/faillog.8 create mode 100644 current/man/pl/gpasswd.1 create mode 100644 current/man/pl/groupadd.8 create mode 100644 current/man/pl/groupdel.8 create mode 100644 current/man/pl/groupmod.8 create mode 100644 current/man/pl/groups.1 create mode 100644 current/man/pl/grpck.8 create mode 100644 current/man/pl/id.1 create mode 100644 current/man/pl/lastlog.8 create mode 100644 current/man/pl/limits.5 create mode 100644 current/man/pl/login.1 create mode 100644 current/man/pl/login.access.5 create mode 100644 current/man/pl/login.defs.5 create mode 100644 current/man/pl/logoutd.8 create mode 100644 current/man/pl/mkpasswd.8 create mode 100644 current/man/pl/newgrp.1 create mode 100644 current/man/pl/newusers.8 create mode 100644 current/man/pl/passwd.1 create mode 100644 current/man/pl/passwd.5 create mode 100644 current/man/pl/porttime.5 create mode 100644 current/man/pl/pw_auth.3 create mode 100644 current/man/pl/pwauth.8 create mode 100644 current/man/pl/pwck.8 create mode 100644 current/man/pl/pwconv.8 create mode 100644 current/man/pl/shadow.3 create mode 100644 current/man/pl/shadow.5 create mode 100644 current/man/pl/shadowconfig.8 create mode 100644 current/man/pl/su.1 create mode 100644 current/man/pl/suauth.5 create mode 100644 current/man/pl/sulogin.8 create mode 100644 current/man/porttime.5 create mode 100644 current/man/pw_auth.3 create mode 100644 current/man/pwauth.8 create mode 100644 current/man/pwck.8 create mode 100644 current/man/pwconv.8 create mode 100644 current/man/shadow.3 create mode 100644 current/man/shadow.5 create mode 100644 current/man/shadowconfig.8 create mode 100644 current/man/su.1 create mode 100644 current/man/suauth.5 create mode 100644 current/man/sulogin.8 create mode 100644 current/man/useradd.8 create mode 100644 current/man/userdel.8 create mode 100644 current/man/usermod.8 create mode 100644 current/man/vipw.8 create mode 100755 current/missing create mode 100755 current/mkinstalldirs create mode 100644 current/po/ChangeLog create mode 100644 current/po/Makefile.in.in create mode 100644 current/po/POTFILES.in create mode 100644 current/po/cat-id-tbl.c create mode 100644 current/po/el.gmo create mode 100644 current/po/el.po create mode 100644 current/po/fr.gmo create mode 100644 current/po/fr.po create mode 100644 current/po/pl.gmo create mode 100644 current/po/pl.po create mode 100644 current/po/shadow.pot create mode 100644 current/po/stamp-cat-id create mode 100644 current/po/sv.gmo create mode 100644 current/po/sv.po create mode 100644 current/redhat/Makefile.am create mode 100644 current/redhat/Makefile.in create mode 100644 current/redhat/README create mode 100644 current/redhat/shadow-970616-fix.patch create mode 100644 current/redhat/shadow-970616-glibc.patch create mode 100644 current/redhat/shadow-970616-rh.patch create mode 100644 current/redhat/shadow-970616-utuser.patch create mode 100644 current/redhat/shadow-970616.login.defs create mode 100644 current/redhat/shadow-970616.useradd create mode 100644 current/redhat/shadow-utils-970616.spec create mode 100644 current/redhat/shadow-utils.spec.in create mode 100644 current/src/Makefile.am create mode 100644 current/src/Makefile.in create mode 100644 current/src/chage.c create mode 100644 current/src/chfn.c create mode 100644 current/src/chpasswd.c create mode 100644 current/src/chsh.c create mode 100644 current/src/dpasswd.c create mode 100644 current/src/expiry.c create mode 100644 current/src/faillog.c create mode 100644 current/src/gpasswd.c create mode 100644 current/src/groupadd.c create mode 100644 current/src/groupdel.c create mode 100644 current/src/groupmod.c create mode 100644 current/src/groups.c create mode 100644 current/src/grpck.c create mode 100644 current/src/grpconv.c create mode 100644 current/src/grpunconv.c create mode 100644 current/src/id.c create mode 100644 current/src/lastlog.c create mode 100644 current/src/login.c create mode 100644 current/src/logoutd.c create mode 100644 current/src/mkpasswd.c create mode 100644 current/src/newgrp.c create mode 100644 current/src/newusers.c create mode 100644 current/src/passwd.c create mode 100644 current/src/patchlevel.h create mode 100644 current/src/pwck.c create mode 100644 current/src/pwconv.c create mode 100644 current/src/pwunconv.c create mode 100755 current/src/shadowconfig.sh create mode 100644 current/src/su.c create mode 100644 current/src/sulogin.c create mode 100644 current/src/useradd.c create mode 100644 current/src/userdel.c create mode 100644 current/src/usermod.c create mode 100644 current/src/vipw.c create mode 100644 current/stamp-h.in diff --git a/current/ABOUT-NLS b/current/ABOUT-NLS new file mode 100644 index 00000000..28d38c76 --- /dev/null +++ b/current/ABOUT-NLS @@ -0,0 +1,226 @@ +Notes on the Free Translation Project +************************************* + + Free software is going international! The Free Translation Project +is a way to get maintainers of free software, translators, and users all +together, so that will gradually become able to speak many languages. +A few packages already provide translations for their messages. + + If you found this `ABOUT-NLS' file inside a distribution, you may +assume that the distributed package does use GNU `gettext' internally, +itself available at your nearest GNU archive site. But you do *not* +need to install GNU `gettext' prior to configuring, installing or using +this package with messages translated. + + Installers will find here some useful hints. These notes also +explain how users should proceed for getting the programs to use the +available translations. They tell how people wanting to contribute and +work at translations should contact the appropriate team. + + When reporting bugs in the `intl/' directory or bugs which may be +related to internationalization, you should tell about the version of +`gettext' which is used. The information can be found in the +`intl/VERSION' file, in internationalized packages. + +One advise in advance +===================== + + If you want to exploit the full power of internationalization, you +should configure it using + + ./configure --with-included-gettext + +to force usage of internationalizing routines provided within this +package, despite the existence of internationalizing capabilities in the +operating system where this package is being installed. So far, only +the `gettext' implementation in the GNU C library version 2 provides as +many features (such as locale alias or message inheritance) as the +implementation here. It is also not possible to offer this additional +functionality on top of a `catgets' implementation. Future versions of +GNU `gettext' will very likely convey even more functionality. So it +might be a good idea to change to GNU `gettext' as soon as possible. + + So you need not provide this option if you are using GNU libc 2 or +you have installed a recent copy of the GNU gettext package with the +included `libintl'. + +INSTALL Matters +=============== + + Some packages are "localizable" when properly installed; the +programs they contain can be made to speak your own native language. +Most such packages use GNU `gettext'. Other packages have their own +ways to internationalization, predating GNU `gettext'. + + By default, this package will be installed to allow translation of +messages. It will automatically detect whether the system provides +usable `catgets' (if using this is selected by the installer) or +`gettext' functions. If neither is available, the GNU `gettext' own +library will be used. This library is wholly contained within this +package, usually in the `intl/' subdirectory, so prior installation of +the GNU `gettext' package is *not* required. Installers may use +special options at configuration time for changing the default +behaviour. The commands: + + ./configure --with-included-gettext + ./configure --with-catgets + ./configure --disable-nls + +will respectively bypass any pre-existing `catgets' or `gettext' to use +the internationalizing routines provided within this package, enable +the use of the `catgets' functions (if found on the locale system), or +else, *totally* disable translation of messages. + + When you already have GNU `gettext' installed on your system and run +configure without an option for your new package, `configure' will +probably detect the previously built and installed `libintl.a' file and +will decide to use this. This might be not what is desirable. You +should use the more recent version of the GNU `gettext' library. I.e. +if the file `intl/VERSION' shows that the library which comes with this +package is more recent, you should use + + ./configure --with-included-gettext + +to prevent auto-detection. + + By default the configuration process will not test for the `catgets' +function and therefore they will not be used. The reasons are already +given above: the emulation on top of `catgets' cannot provide all the +extensions provided by the GNU `gettext' library. If you nevertheless +want to use the `catgets' functions use + + ./configure --with-catgets + +to enable the test for `catgets' (this causes no harm if `catgets' is +not available on your system). If you really select this option we +would like to hear about the reasons because we cannot think of any +good one ourself. + + Internationalized packages have usually many `po/LL.po' files, where +LL gives an ISO 639 two-letter code identifying the language. Unless +translations have been forbidden at `configure' time by using the +`--disable-nls' switch, all available translations are installed +together with the package. However, the environment variable `LINGUAS' +may be set, prior to configuration, to limit the installed set. +`LINGUAS' should then contain a space separated list of two-letter +codes, stating which languages are allowed. + +Using This Package +================== + + As a user, if your language has been installed for this package, you +only have to set the `LANG' environment variable to the appropriate +ISO 639 `LL' two-letter code prior to using the programs in the +package. For example, let's suppose that you speak German. At the +shell prompt, merely execute `setenv LANG de' (in `csh'), +`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This +can be done from your `.login' or `.profile' file, once and for all. + + An operating system might already offer message localization for +many of its programs, while other programs have been installed locally +with the full capabilities of GNU `gettext'. Just using `gettext' +extended syntax for `LANG' would break proper localization of already +available operating system programs. In this case, users should set +both `LANGUAGE' and `LANG' variables in their environment, as programs +using GNU `gettext' give preference to `LANGUAGE'. For example, some +Swedish users would rather read translations in German than English for +when Swedish is not available. This is easily accomplished by setting +`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'. + +Translating Teams +================= + + For the Free Translation Project to be a success, we need interested +people who like their own language and write it well, and who are also +able to synergize with other translators speaking the same language. +Each translation team has its own mailing list, courtesy of Linux +International. You may reach your translation team at the address +`LL@li.org', replacing LL by the two-letter ISO 639 code for your +language. Language codes are *not* the same as the country codes given +in ISO 3166. The following translation teams exist, as of December +1997: + + Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en', + Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian + `hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja', + Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish + `pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es', + Swedish `sv', and Turkish `tr'. + +For example, you may reach the Chinese translation team by writing to +`zh@li.org'. + + If you'd like to volunteer to *work* at translating messages, you +should become a member of the translating team for your own language. +The subscribing address is *not* the same as the list itself, it has +`-request' appended. For example, speakers of Swedish can send a +message to `sv-request@li.org', having this message body: + + subscribe + + Keep in mind that team members are expected to participate +*actively* in translations, or at solving translational difficulties, +rather than merely lurking around. If your team does not exist yet and +you want to start one, or if you are unsure about what to do or how to +get started, please write to `translation@iro.umontreal.ca' to reach the +coordinator for all translator teams. + + The English team is special. It works at improving and uniformizing +the terminology in use. Proven linguistic skill are praised more than +programming skill, here. + +Available Packages +================== + + Languages are not equally supported in all packages. The following +matrix shows the current state of internationalization, as of December +1997. The matrix shows, in regard of each package, for which languages +PO files have been submitted to translation coordination. + + Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv + .----------------------------------------------------. + bash | [] [] [] | 3 + bison | [] [] [] | 3 + clisp | [] [] [] [] | 4 + cpio | [] [] [] [] [] [] | 6 + diffutils | [] [] [] [] [] | 5 + enscript | [] [] [] [] [] [] | 6 + fileutils | [] [] [] [] [] [] [] [] [] [] | 10 + findutils | [] [] [] [] [] [] [] [] [] | 9 + flex | [] [] [] [] | 4 + gcal | [] [] [] [] [] | 5 + gettext | [] [] [] [] [] [] [] [] [] [] [] | 12 + grep | [] [] [] [] [] [] [] [] [] [] | 10 + hello | [] [] [] [] [] [] [] [] [] [] [] | 11 + id-utils | [] [] [] | 3 + indent | [] [] [] [] [] | 5 + libc | [] [] [] [] [] [] [] | 7 + m4 | [] [] [] [] [] [] | 6 + make | [] [] [] [] [] [] | 6 + music | [] [] | 2 + ptx | [] [] [] [] [] [] [] [] | 8 + recode | [] [] [] [] [] [] [] [] [] | 9 + sh-utils | [] [] [] [] [] [] [] [] | 8 + sharutils | [] [] [] [] [] [] | 6 + tar | [] [] [] [] [] [] [] [] [] [] [] | 11 + texinfo | [] [] [] | 3 + textutils | [] [] [] [] [] [] [] [] [] | 9 + wdiff | [] [] [] [] [] [] [] [] | 8 + `----------------------------------------------------' + 17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv + 27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179 + + Some counters in the preceding matrix are higher than the number of +visible blocks let us expect. This is because a few extra PO files are +used for implementing regional variants of languages, or language +dialects. + + For a PO file in the matrix above to be effective, the package to +which it applies should also have been internationalized and +distributed as such by its maintainer. There might be an observable +lag between the mere existence a PO file and its wide availability in a +distribution. + + If December 1997 seems to be old, you may fetch a more recent copy +of this `ABOUT-NLS' file on most GNU archive sites. + diff --git a/current/Makefile.am b/current/Makefile.am new file mode 100644 index 00000000..36b1db1e --- /dev/null +++ b/current/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = 1.0 foreign + +SUBDIRS = intl po man lib libmisc src \ + contrib debian doc etc redhat # old diff --git a/current/Makefile.in b/current/Makefile.in new file mode 100644 index 00000000..b608fad7 --- /dev/null +++ b/current/Makefile.in @@ -0,0 +1,391 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +SUBDIRS = intl po man lib libmisc src contrib debian doc etc redhat # old + +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ./stamp-h.in ABOUT-NLS Makefile.am Makefile.in acconfig.h \ +aclocal.m4 config.guess config.h.in config.sub configure configure.in \ +install-sh ltconfig ltmain.sh missing mkinstalldirs + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.h.in: $(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile config.h +all-redirect: all-recursive-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-hdr clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-hdr distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +install-data-recursive uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/acconfig.h b/current/acconfig.h new file mode 100644 index 00000000..7fce8825 --- /dev/null +++ b/current/acconfig.h @@ -0,0 +1,151 @@ +/* $Id: acconfig.h,v 1.13 1999/08/27 19:02:50 marekm Exp $ */ + + + +/* Define to enable password aging. */ +#undef AGING + +/* Define if struct passwd has pw_age. */ +#undef ATT_AGE + +/* Define if struct passwd has pw_comment. */ +#undef ATT_COMMENT + +/* Define to support JFH's auth. methods. UNTESTED. */ +#undef AUTH_METHODS + +/* Define if struct passwd has pw_quota. */ +#undef BSD_QUOTA + +/* Define if you have secure RPC. */ +#undef DES_RPC + +/* Define to support 16-character passwords. */ +#undef DOUBLESIZE + +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Path for faillog file. */ +#undef FAILLOG_FILE + +/* Define if you want my getgrent routines. */ +#undef GETGRENT + +/* Define to libshadow_getpass to use our own version of getpass(). */ +#undef getpass + +/* Define if you want my getpwent routines. */ +#undef GETPWENT + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Defined if you have libcrack. */ +#undef HAVE_LIBCRACK + +/* Defined if you have the ts&szs cracklib. */ +#undef HAVE_LIBCRACK_HIST + +/* Defined if it includes *Pw functions. */ +#undef HAVE_LIBCRACK_PW + +/* Defined if you have libcrypt. */ +#undef HAVE_LIBCRYPT + +/* Define if struct lastlog has ll_host */ +#undef HAVE_LL_HOST + +/* Working shadow group support in libc? */ +#undef HAVE_SHADOWGRP + +/* Define to 1 if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define to support TCFS. */ +#undef HAVE_TCFS + +/* Path for lastlog file. */ +#undef LASTLOG_FILE + +/* Define to support /etc/login.access login access control. */ +#undef LOGIN_ACCESS + +/* Location of system mail spool directory. */ +#undef MAIL_SPOOL_DIR + +/* Name of user's mail spool file if stored in user's home directory. */ +#undef MAIL_SPOOL_FILE + +/* Define to support the MD5-based password hashing algorithm. */ +#undef MD5_CRYPT + +/* Define to use ndbm. */ +#undef NDBM + +/* Define to support OPIE one-time password logins. */ +#undef OPIE + +/* Package name. */ +#undef PACKAGE + +/* Define if pam_strerror() needs two arguments (Linux-PAM 0.59+). */ +#undef PAM_STRERROR_NEEDS_TWO_ARGS + +/* Path to passwd program. */ +#undef PASSWD_PROGRAM + +/* Define if the compiler understands function prototypes. */ +#undef PROTOTYPES + +/* Define if login should support the -r flag for rlogind. */ +#undef RLOGIN + +/* Define to the ruserok() "success" return value (0 or 1). */ +#undef RUSEROK + +/* Define to support the shadow group file. */ +#undef SHADOWGRP + +/* Define to support the shadow password file. */ +#undef SHADOWPWD + +/* Define to support S/Key logins. */ +#undef SKEY + +/* Define to support /etc/suauth su access control. */ +#undef SU_ACCESS + +/* Define to support SecureWare(tm) long passwords. */ +#undef SW_CRYPT + +/* Define if you want gdbm for TCFS. */ +#undef TCFS_GDBM_SUPPORT + +/* Define to support Pluggable Authentication Modules. */ +#undef USE_PAM + +/* Define to use syslog(). */ +#undef USE_SYSLOG + +/* Define if you have ut_host in struct utmp. */ +#undef UT_HOST + +/* Path for utmp file. */ +#undef _UTMP_FILE + +/* Define to ut_name if struct utmp has ut_name (not ut_user). */ +#undef ut_user + +/* Version. */ +#undef VERSION + +/* Path for wtmp file. */ +#undef _WTMP_FILE + diff --git a/current/aclocal.m4 b/current/aclocal.m4 new file mode 100644 index 00000000..7f119fd2 --- /dev/null +++ b/current/aclocal.m4 @@ -0,0 +1,1027 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN(AM_CONFIG_HEADER, +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + + +# serial 1 + +AC_DEFUN(AM_C_PROTOTYPES, +[AC_REQUIRE([AM_PROG_CC_STDC]) +AC_REQUIRE([AC_PROG_CPP]) +AC_MSG_CHECKING([for function prototypes]) +if test "$am_cv_prog_cc_stdc" != no; then + AC_MSG_RESULT(yes) + AC_DEFINE(PROTOTYPES,1,[Define if compiler has function prototypes]) + U= ANSI2KNR= +else + AC_MSG_RESULT(no) + U=_ ANSI2KNR=./ansi2knr + # Ensure some checks needed by ansi2knr itself. + AC_HEADER_STDC + AC_CHECK_HEADERS(string.h) +fi +AC_SUBST(U)dnl +AC_SUBST(ANSI2KNR)dnl +]) + + +# serial 1 + +# @defmac AC_PROG_CC_STDC +# @maindex PROG_CC_STDC +# @ovindex CC +# If the C compiler in not in ANSI C mode by default, try to add an option +# to output variable @code{CC} to make it so. This macro tries various +# options that select ANSI C on some system or another. It considers the +# compiler to be in ANSI C mode if it handles function prototypes correctly. +# +# If you use this macro, you should check after calling it whether the C +# compiler has been set to accept ANSI C; if not, the shell variable +# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source +# code in ANSI C, you can make an un-ANSIfied copy of it by using the +# program @code{ansi2knr}, which comes with Ghostscript. +# @end defmac + +AC_DEFUN(AM_PROG_CC_STDC, +[AC_REQUIRE([AC_PROG_CC]) +AC_BEFORE([$0], [AC_C_INLINE]) +AC_BEFORE([$0], [AC_C_CONST]) +dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require +dnl a magic option to avoid problems with ANSI preprocessor commands +dnl like #elif. +dnl FIXME: can't do this because then AC_AIX won't work due to a +dnl circular dependency. +dnl AC_BEFORE([$0], [AC_PROG_CPP]) +AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) +AC_CACHE_VAL(am_cv_prog_cc_stdc, +[am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + AC_TRY_COMPILE( +[#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +], [ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +], +[am_cv_prog_cc_stdc="$ac_arg"; break]) +done +CC="$ac_save_CC" +]) +if test -z "$am_cv_prog_cc_stdc"; then + AC_MSG_RESULT([none needed]) +else + AC_MSG_RESULT($am_cv_prog_cc_stdc) +fi +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac +]) + + +# serial 40 AC_PROG_LIBTOOL +AC_DEFUN(AC_PROG_LIBTOOL, +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN(AC_LIBTOOL_SETUP, +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_SHARED, [dnl +define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_STATIC, [dnl +define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl +define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AC_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. +changequote(,)dnl + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' +changequote([,])dnl + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_SUBST(LD) +AC_PROG_LD_GNU +]) + +AC_DEFUN(AC_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AC_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +AC_SUBST(NM) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN(AC_CHECK_LIBM, +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case "$host" in +*-*-beos* | *-*-cygwin*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library, adds --enable-ltdl-convenience to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case "$enable_ltdl_convenience" in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la + INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library, and adds --enable-ltdl-install to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la + INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +dnl old names +AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl +AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl +AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl +AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl +AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl +AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl +AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl + +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 5 + +AC_DEFUN(AM_WITH_NLS, + [AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + USE_INCLUDED_LIBINTL=no + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + AC_DEFINE(ENABLE_NLS) + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, + [AC_TRY_LINK([#include ], [return (int) gettext ("")], + gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) + + if test "$gt_cv_func_gettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for gettext in libintl], + gt_cv_func_gettext_libintl, + [AC_CHECK_LIB(intl, gettext, + gt_cv_func_gettext_libintl=yes, + gt_cv_func_gettext_libintl=no)], + gt_cv_func_gettext_libintl=no)]) + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + ]) + + if test "$CATOBJEXT" = "NONE"; then + AC_MSG_CHECKING([whether catgets can be used]) + AC_ARG_WITH(catgets, + [ --with-catgets use catgets functions if available], + nls_cv_use_catgets=$withval, nls_cv_use_catgets=no) + AC_MSG_RESULT($nls_cv_use_catgets) + + if test "$nls_cv_use_catgets" = "yes"; then + dnl No gettext in C library. Try catgets next. + AC_CHECK_LIB(i, main) + AC_CHECK_FUNC(catgets, + [AC_DEFINE(HAVE_CATGETS) + INTLOBJS="\$(CATOBJS)" + AC_PATH_PROG(GENCAT, gencat, no)dnl + if test "$GENCAT" != "no"; then + AC_PATH_PROG(GMSGFMT, gmsgfmt, no) + if test "$GMSGFMT" = "no"; then + AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no) + fi + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.cat + INSTOBJEXT=.cat + DATADIRNAME=lib + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi]) + fi + fi + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_SUBST(MSGFMT) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl) + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac]) + + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN(AM_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h sys/param.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ +strdup __argz_count __argz_stringify __argz_next]) + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + AC_CHECK_FUNCS(stpcpy) + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + AC_DEFINE(HAVE_STPCPY) + fi + + AM_LC_MESSAGES + AM_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl The reference to in the installed file + dnl must be resolved because we cannot expect the users of this + dnl to define HAVE_LOCALE_H. + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include " + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header . Take care yourself. */" + fi + AC_SUBST(INCLUDE_LOCALE_H) + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux libc-5 and the normal X/Open format + test -d intl || mkdir intl + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed + fi + dnl po2tbl.sed is always needed. + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed + + dnl In the intl/Makefile.in we have a special dependency which makes + dnl only sense for gettext. We comment this out for non-gettext + dnl packages. + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + AC_SUBST(GT_NO) + AC_SUBST(GT_YES) + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) + + dnl *** For now the libtool support in intl/Makefile is not for real. + l= + AC_SUBST(l) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + +# Search path for a program which passes the given test. +# Ulrich Drepper , 1996. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN(AM_PATH_PROG_WITH_TEST, +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# Check whether LC_MESSAGES is available in . +# Ulrich Drepper , 1995. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +AC_DEFUN(AM_LC_MESSAGES, + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES) + fi + fi]) + diff --git a/current/config.guess b/current/config.guess new file mode 100755 index 00000000..6cb567b8 --- /dev/null +++ b/current/config.guess @@ -0,0 +1,1087 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 +# Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to the Autoconf mailing list . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + macppc:NetBSD:*:*) + echo powerpc-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + ($CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*T3E:*:*:*) + echo t3e-cray-unicosmk${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + if test -x /usr/bin/objformat; then + if test "elf" = "`/usr/bin/objformat`"; then + echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` + exit 0 + fi + fi + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # uname on the ARM produces all sorts of strangeness, and we need to + # filter it out. + case "$UNAME_MACHINE" in + armv*) UNAME_MACHINE=$UNAME_MACHINE ;; + arm* | sa110*) UNAME_MACHINE="arm" ;; + esac + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32ppc) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <$dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:5:7*) + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) && UNAME_MACHINE=i585 + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE} + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/current/config.h.in b/current/config.h.in new file mode 100644 index 00000000..716b7583 --- /dev/null +++ b/current/config.h.in @@ -0,0 +1,460 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if using alloca.c. */ +#undef C_ALLOCA + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +#undef GETGROUPS_T + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if your struct stat has st_rdev. */ +#undef HAVE_ST_RDEV + +/* Define if you have the strftime function. */ +#undef HAVE_STRFTIME + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define if utime(file, NULL) sets file's timestamp to the present. */ +#undef HAVE_UTIME_NULL + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `int' if doesn't define. */ +#undef mode_t + +/* Define to `long' if doesn't define. */ +#undef off_t + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define if the `setpgrp' function takes no argument. */ +#undef SETPGRP_VOID + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#undef STACK_DIRECTION + +/* Define if the `S_IS*' macros in do not work properly. */ +#undef STAT_MACROS_BROKEN + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define if your declares struct tm. */ +#undef TM_IN_SYS_TIME + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* Define if you do not have , index, bzero, etc.. */ +#undef USG + +/* Define to enable password aging. */ +#undef AGING + +/* Define if struct passwd has pw_age. */ +#undef ATT_AGE + +/* Define if struct passwd has pw_comment. */ +#undef ATT_COMMENT + +/* Define if struct passwd has pw_quota. */ +#undef BSD_QUOTA + +/* Define if you have secure RPC. */ +#undef DES_RPC + +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Path for faillog file. */ +#undef FAILLOG_FILE + +/* Define to libshadow_getpass to use our own version of getpass(). */ +#undef getpass + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Defined if you have libcrack. */ +#undef HAVE_LIBCRACK + +/* Defined if you have the ts&szs cracklib. */ +#undef HAVE_LIBCRACK_HIST + +/* Defined if it includes *Pw functions. */ +#undef HAVE_LIBCRACK_PW + +/* Defined if you have libcrypt. */ +#undef HAVE_LIBCRYPT + +/* Define if struct lastlog has ll_host */ +#undef HAVE_LL_HOST + +/* Working shadow group support in libc? */ +#undef HAVE_SHADOWGRP + +/* Define to 1 if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define to support TCFS. */ +#undef HAVE_TCFS + +/* Path for lastlog file. */ +#undef LASTLOG_FILE + +/* Define to support /etc/login.access login access control. */ +#undef LOGIN_ACCESS + +/* Location of system mail spool directory. */ +#undef MAIL_SPOOL_DIR + +/* Name of user's mail spool file if stored in user's home directory. */ +#undef MAIL_SPOOL_FILE + +/* Define to support the MD5-based password hashing algorithm. */ +#undef MD5_CRYPT + +/* Define to support OPIE one-time password logins. */ +#undef OPIE + +/* Define if pam_strerror() needs two arguments (Linux-PAM 0.59+). */ +#undef PAM_STRERROR_NEEDS_TWO_ARGS + +/* Path to passwd program. */ +#undef PASSWD_PROGRAM + +/* Define if login should support the -r flag for rlogind. */ +#undef RLOGIN + +/* Define to the ruserok() "success" return value (0 or 1). */ +#undef RUSEROK + +/* Define to support the shadow group file. */ +#undef SHADOWGRP + +/* Define to support the shadow password file. */ +#undef SHADOWPWD + +/* Define to support S/Key logins. */ +#undef SKEY + +/* Define to support /etc/suauth su access control. */ +#undef SU_ACCESS + +/* Define if you want gdbm for TCFS. */ +#undef TCFS_GDBM_SUPPORT + +/* Define to support Pluggable Authentication Modules. */ +#undef USE_PAM + +/* Define to use syslog(). */ +#undef USE_SYSLOG + +/* Define if you have ut_host in struct utmp. */ +#undef UT_HOST + +/* Path for utmp file. */ +#undef _UTMP_FILE + +/* Define to ut_name if struct utmp has ut_name (not ut_user). */ +#undef ut_user + +/* Path for wtmp file. */ +#undef _WTMP_FILE + +/* Define if you have the __argz_count function. */ +#undef HAVE___ARGZ_COUNT + +/* Define if you have the __argz_next function. */ +#undef HAVE___ARGZ_NEXT + +/* Define if you have the __argz_stringify function. */ +#undef HAVE___ARGZ_STRINGIFY + +/* Define if you have the a64l function. */ +#undef HAVE_A64L + +/* Define if you have the dcgettext function. */ +#undef HAVE_DCGETTEXT + +/* Define if you have the fchmod function. */ +#undef HAVE_FCHMOD + +/* Define if you have the fchown function. */ +#undef HAVE_FCHOWN + +/* Define if you have the fsync function. */ +#undef HAVE_FSYNC + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getgroups function. */ +#undef HAVE_GETGROUPS + +/* Define if you have the gethostname function. */ +#undef HAVE_GETHOSTNAME + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the getspnam function. */ +#undef HAVE_GETSPNAM + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the getusershell function. */ +#undef HAVE_GETUSERSHELL + +/* Define if you have the getutent function. */ +#undef HAVE_GETUTENT + +/* Define if you have the initgroups function. */ +#undef HAVE_INITGROUPS + +/* Define if you have the lchown function. */ +#undef HAVE_LCHOWN + +/* Define if you have the lckpwdf function. */ +#undef HAVE_LCKPWDF + +/* Define if you have the lstat function. */ +#undef HAVE_LSTAT + +/* Define if you have the memcpy function. */ +#undef HAVE_MEMCPY + +/* Define if you have the memset function. */ +#undef HAVE_MEMSET + +/* Define if you have the mkdir function. */ +#undef HAVE_MKDIR + +/* Define if you have the munmap function. */ +#undef HAVE_MUNMAP + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the putgrent function. */ +#undef HAVE_PUTGRENT + +/* Define if you have the putpwent function. */ +#undef HAVE_PUTPWENT + +/* Define if you have the putspent function. */ +#undef HAVE_PUTSPENT + +/* Define if you have the rename function. */ +#undef HAVE_RENAME + +/* Define if you have the rmdir function. */ +#undef HAVE_RMDIR + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the setgroups function. */ +#undef HAVE_SETGROUPS + +/* Define if you have the setlocale function. */ +#undef HAVE_SETLOCALE + +/* Define if you have the sgetgrent function. */ +#undef HAVE_SGETGRENT + +/* Define if you have the sgetpwent function. */ +#undef HAVE_SGETPWENT + +/* Define if you have the sgetspent function. */ +#undef HAVE_SGETSPENT + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the snprintf function. */ +#undef HAVE_SNPRINTF + +/* Define if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the strchr function. */ +#undef HAVE_STRCHR + +/* Define if you have the strdup function. */ +#undef HAVE_STRDUP + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR + +/* Define if you have the strstr function. */ +#undef HAVE_STRSTR + +/* Define if you have the updwtmp function. */ +#undef HAVE_UPDWTMP + +/* Define if you have the updwtmpx function. */ +#undef HAVE_UPDWTMPX + +/* Define if you have the header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GSHADOW_H + +/* Define if you have the header file. */ +#undef HAVE_LASTLOG_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#undef HAVE_NDIR_H + +/* Define if you have the header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_PATHS_H + +/* Define if you have the header file. */ +#undef HAVE_RPC_KEY_PROT_H + +/* Define if you have the header file. */ +#undef HAVE_SGTTY_H + +/* Define if you have the header file. */ +#undef HAVE_SHADOW_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_DIR_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_NDIR_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define if you have the header file. */ +#undef HAVE_ULIMIT_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_USERSEC_H + +/* Define if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define if you have the header file. */ +#undef HAVE_UTMP_H + +/* Define if you have the header file. */ +#undef HAVE_UTMPX_H + +/* Define if you have the i library (-li). */ +#undef HAVE_LIBI + +/* Define if you have the inet library (-linet). */ +#undef HAVE_LIBINET + +/* Define if you have the nsl library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define if you have the socket library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + +/* Define if compiler has function prototypes */ +#undef PROTOTYPES + diff --git a/current/config.sub b/current/config.sub new file mode 100755 index 00000000..2436b453 --- /dev/null +++ b/current/config.sub @@ -0,0 +1,1215 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v) + basic_machine=$basic_machine-unknown + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \ + | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* \ + | f301-* | armv*-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* ) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | *MiNT) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-corel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-corel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/current/configure b/current/configure new file mode 100755 index 00000000..8de554bb --- /dev/null +++ b/current/configure @@ -0,0 +1,6803 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --enable-desrpc try to use secure RPC in login (default if found)" +ac_help="$ac_help + --enable-shadowgrp enable shadow group support [default=yes]" +ac_help="$ac_help + --with-libcrack try to use libcrack (default if found)" +ac_help="$ac_help + --with-libcrypt try to use libcrypt (default if found)" +ac_help="$ac_help + --with-libopie use libopie for OPIE support" +ac_help="$ac_help + --with-libpam use libpam for PAM support" +ac_help="$ac_help + --with-libskey use libskey for S/Key support" +ac_help="$ac_help + --with-libtcfs use libtcfs for TCFS support" +ac_help="$ac_help + --disable-nls do not use Native Language Support" +ac_help="$ac_help + --with-included-gettext use the GNU gettext library included here" +ac_help="$ac_help + --with-catgets use catgets functions if available" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=lib/dialchk.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:588: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:641: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:698: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=shadow + +VERSION=20000902 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <> confdefs.h <&6 +echo "configure:744: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:757: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:770: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:783: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:796: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + + + + +test "$prefix" = "NONE" && prefix="/usr" +test "$prefix" = "/usr" && exec_prefix="" +test "$CFLAGS" = "" && CFLAGS="-O2 -Wall" +test "$LDFLAGS" = "" && LDFLAGS="-s" + +ALL_LINGUAS="el fr pl sv" + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:823: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:853: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:904: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:936: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 947 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:952: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:978: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:983: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1011: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 +echo "configure:1043: checking for POSIXized ISC" >&5 +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + echo "$ac_t""yes" 1>&6 + ISC=yes # If later tests want to check for ISC. + cat >> confdefs.h <<\EOF +#define _POSIX_SOURCE 1 +EOF + + if test "$GCC" = yes; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +else + echo "$ac_t""no" 1>&6 + ISC= +fi + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1064: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +for ac_prog in 'bison -y' byacc +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1089: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_YACC="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +YACC="$ac_cv_prog_YACC" +if test -n "$YACC"; then + echo "$ac_t""$YACC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + + + + +echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6 +echo "configure:1123: checking for ${CC-cc} option to accept ANSI C" >&5 +if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + cat > conftest.$ac_ext < +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; + +int main() { + +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + +; return 0; } +EOF +if { (eval echo configure:1176: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + am_cv_prog_cc_stdc="$ac_arg"; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done +CC="$ac_save_CC" + +fi + +if test -z "$am_cv_prog_cc_stdc"; then + echo "$ac_t""none needed" 1>&6 +else + echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6 +fi +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1200: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1255: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + + +echo $ac_n "checking for function prototypes""... $ac_c" 1>&6 +echo "configure:1282: checking for function prototypes" >&5 +if test "$am_cv_prog_cc_stdc" != no; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define PROTOTYPES 1 +EOF + + U= ANSI2KNR= +else + echo "$ac_t""no" 1>&6 + U=_ ANSI2KNR=./ansi2knr + # Ensure some checks needed by ansi2knr itself. + echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1295: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1308: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + + for ac_hdr in string.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1402: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1412: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +fi + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:1516: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:1537: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1557: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:1596: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:1620: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:1623: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$ac_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } + +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1659: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 + + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1675: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi +fi + +NM="$ac_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 1735 "configure"' > conftest.$ac_ext + if { (eval echo configure:1736: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:1757: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 +echo "configure:1877: checking for $ac_hdr that defines DIR" >&5 +if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include <$ac_hdr> +int main() { +DIR *dirp = 0; +; return 0; } +EOF +if { (eval echo configure:1890: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then +echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 +echo "configure:1915: checking for opendir in -ldir" >&5 +ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldir $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ldir" +else + echo "$ac_t""no" 1>&6 +fi + +else +echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 +echo "configure:1956: checking for opendir in -lx" >&5 +ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lx $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lx" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1998: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2011: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:2078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 +echo "configure:2102: checking for sys/wait.h that is POSIX.1 compatible" >&5 +if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#ifndef WEXITSTATUS +#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif +int main() { +int s; +wait (&s); +s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; +; return 0; } +EOF +if { (eval echo configure:2123: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_header_sys_wait_h=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_sys_wait_h=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 +if test $ac_cv_header_sys_wait_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_WAIT_H 1 +EOF + +fi + +for ac_hdr in fcntl.h limits.h unistd.h sys/time.h utmp.h utmpx.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2147: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_hdr in termios.h termio.h sgtty.h sys/ioctl.h syslog.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2187: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_hdr in paths.h usersec.h utime.h ulimit.h sys/resource.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2227: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2237: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_hdr in gshadow.h shadow.h lastlog.h rpc/key_prot.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2267: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2277: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:2305: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:2359: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 +echo "configure:2380: checking for uid_t in sys/types.h" >&5 +if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "uid_t" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_uid_t=yes +else + rm -rf conftest* + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_type_uid_t" 1>&6 +if test $ac_cv_type_uid_t = no; then + cat >> confdefs.h <<\EOF +#define uid_t int +EOF + + cat >> confdefs.h <<\EOF +#define gid_t int +EOF + +fi + +echo $ac_n "checking for off_t""... $ac_c" 1>&6 +echo "configure:2414: checking for off_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_off_t=yes +else + rm -rf conftest* + ac_cv_type_off_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_off_t" 1>&6 +if test $ac_cv_type_off_t = no; then + cat >> confdefs.h <<\EOF +#define off_t long +EOF + +fi + +echo $ac_n "checking for pid_t""... $ac_c" 1>&6 +echo "configure:2447: checking for pid_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_pid_t=yes +else + rm -rf conftest* + ac_cv_type_pid_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_pid_t" 1>&6 +if test $ac_cv_type_pid_t = no; then + cat >> confdefs.h <<\EOF +#define pid_t int +EOF + +fi + +echo $ac_n "checking for mode_t""... $ac_c" 1>&6 +echo "configure:2480: checking for mode_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_mode_t=yes +else + rm -rf conftest* + ac_cv_type_mode_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_mode_t" 1>&6 +if test $ac_cv_type_mode_t = no; then + cat >> confdefs.h <<\EOF +#define mode_t int +EOF + +fi + +echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 +echo "configure:2513: checking for st_rdev in struct stat" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +int main() { +struct stat s; s.st_rdev; +; return 0; } +EOF +if { (eval echo configure:2526: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_st_rdev=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_st_rdev=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_st_rdev" 1>&6 +if test $ac_cv_struct_st_rdev = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ST_RDEV 1 +EOF + +fi + +echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 +echo "configure:2547: checking whether stat file-mode macros are broken" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include + +#if defined(S_ISBLK) && defined(S_IFDIR) +# if S_ISBLK (S_IFDIR) +You lose. +# endif +#endif + +#if defined(S_ISBLK) && defined(S_IFCHR) +# if S_ISBLK (S_IFCHR) +You lose. +# endif +#endif + +#if defined(S_ISLNK) && defined(S_IFREG) +# if S_ISLNK (S_IFREG) +You lose. +# endif +#endif + +#if defined(S_ISSOCK) && defined(S_IFREG) +# if S_ISSOCK (S_IFREG) +You lose. +# endif +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "You lose" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_header_stat_broken=yes +else + rm -rf conftest* + ac_cv_header_stat_broken=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_header_stat_broken" 1>&6 +if test $ac_cv_header_stat_broken = yes; then + cat >> confdefs.h <<\EOF +#define STAT_MACROS_BROKEN 1 +EOF + +fi + +echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 +echo "configure:2603: checking whether time.h and sys/time.h may both be included" >&5 +if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +int main() { +struct tm *tp; +; return 0; } +EOF +if { (eval echo configure:2617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_header_time=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_time=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_time" 1>&6 +if test $ac_cv_header_time = yes; then + cat >> confdefs.h <<\EOF +#define TIME_WITH_SYS_TIME 1 +EOF + +fi + +echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 +echo "configure:2638: checking whether struct tm is in sys/time.h or time.h" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +int main() { +struct tm *tp; tp->tm_sec; +; return 0; } +EOF +if { (eval echo configure:2651: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_tm=time.h +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_tm=sys/time.h +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_tm" 1>&6 +if test $ac_cv_struct_tm = sys/time.h; then + cat >> confdefs.h <<\EOF +#define TM_IN_SYS_TIME 1 +EOF + +fi + + +echo $ac_n "checking for pw_age in struct passwd""... $ac_c" 1>&6 +echo "configure:2673: checking for pw_age in struct passwd" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_passwd_pw_age'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { + struct passwd pw; pw.pw_age = ""; +; return 0; } +EOF +if { (eval echo configure:2685: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_passwd_pw_age=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_passwd_pw_age=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_passwd_pw_age" 1>&6 + +if test "$ac_cv_struct_passwd_pw_age" = "yes"; then + cat >> confdefs.h <<\EOF +#define ATT_AGE 1 +EOF + +fi + +echo $ac_n "checking for pw_comment in struct passwd""... $ac_c" 1>&6 +echo "configure:2707: checking for pw_comment in struct passwd" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_passwd_pw_comment'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { + struct passwd pw; pw.pw_comment = ""; +; return 0; } +EOF +if { (eval echo configure:2719: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_passwd_pw_comment=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_passwd_pw_comment=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_passwd_pw_comment" 1>&6 + +if test "$ac_cv_struct_passwd_pw_comment" = "yes"; then + cat >> confdefs.h <<\EOF +#define ATT_COMMENT 1 +EOF + +fi + +echo $ac_n "checking for pw_quota in struct passwd""... $ac_c" 1>&6 +echo "configure:2741: checking for pw_quota in struct passwd" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_passwd_pw_quota'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { + struct passwd pw; pw.pw_quota = 0; +; return 0; } +EOF +if { (eval echo configure:2753: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_passwd_pw_quota=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_passwd_pw_quota=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_passwd_pw_quota" 1>&6 + +if test "$ac_cv_struct_passwd_pw_quota" = "yes"; then + cat >> confdefs.h <<\EOF +#define BSD_QUOTA 1 +EOF + +fi + +if test "$ac_cv_header_utmp_h" = "yes"; then + echo $ac_n "checking for ut_host in struct utmp""... $ac_c" 1>&6 +echo "configure:2776: checking for ut_host in struct utmp" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_utmp_ut_host'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { + struct utmp ut; char *cp = ut.ut_host; +; return 0; } +EOF +if { (eval echo configure:2788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_utmp_ut_host=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_utmp_ut_host=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_utmp_ut_host" 1>&6 + + if test "$ac_cv_struct_utmp_ut_host" = "yes"; then + cat >> confdefs.h <<\EOF +#define UT_HOST 1 +EOF + + fi + + echo $ac_n "checking for ut_user in struct utmp""... $ac_c" 1>&6 +echo "configure:2810: checking for ut_user in struct utmp" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_utmp_ut_user'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { + struct utmp ut; char *cp = ut.ut_user; +; return 0; } +EOF +if { (eval echo configure:2822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_utmp_ut_user=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_utmp_ut_user=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_utmp_ut_user" 1>&6 + + if test "$ac_cv_struct_utmp_ut_user" = "no"; then + cat >> confdefs.h <<\EOF +#define ut_user ut_name +EOF + + fi +fi + +if test "$ac_cv_header_lastlog_h" = "yes"; then + echo $ac_n "checking for ll_host in struct lastlog""... $ac_c" 1>&6 +echo "configure:2846: checking for ll_host in struct lastlog" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_lastlog_ll_host'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { + struct lastlog ll; char *cp = ll.ll_host; +; return 0; } +EOF +if { (eval echo configure:2858: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_lastlog_ll_host=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_lastlog_ll_host=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_lastlog_ll_host" 1>&6 + + if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_LL_HOST 1 +EOF + + fi +fi + +echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6 +echo "configure:2881: checking type of array argument to getgroups" >&5 +if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_type_getgroups=cross +else + cat > conftest.$ac_ext < +#define NGID 256 +#undef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +main() +{ + gid_t gidset[NGID]; + int i, n; + union { gid_t gval; long lval; } val; + + val.lval = -1; + for (i = 0; i < NGID; i++) + gidset[i] = val.gval; + n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1, + gidset); + /* Exit non-zero if getgroups seems to require an array of ints. This + happens when gid_t is short but getgroups modifies an array of ints. */ + exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0); +} + +EOF +if { (eval echo configure:2914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_type_getgroups=gid_t +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_type_getgroups=int +fi +rm -fr conftest* +fi + +if test $ac_cv_type_getgroups = cross; then + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_getgroups=gid_t +else + rm -rf conftest* + ac_cv_type_getgroups=int +fi +rm -f conftest* + +fi +fi + +echo "$ac_t""$ac_cv_type_getgroups" 1>&6 +cat >> confdefs.h <&6 +echo "configure:2953: checking whether ${CC-cc} needs -traditional" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_pattern="Autoconf.*'x'" + cat > conftest.$ac_ext < +Autoconf TIOCGETP +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +else + rm -rf conftest* + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat > conftest.$ac_ext < +Autoconf TCGETA +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi + +echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +echo "configure:2999: checking return type of signal handlers" >&5 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { +int i; +; return 0; } +EOF +if { (eval echo configure:3021: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3040: checking whether utime accepts a null argument" >&5 +if eval "test \"`echo '$''{'ac_cv_func_utime_null'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata; > conftestdata +# Sequent interprets utime(file, 0) to mean use start of epoch. Wrong. +if test "$cross_compiling" = yes; then + ac_cv_func_utime_null=no +else + cat > conftest.$ac_ext < +#include +main() { +struct stat s, t; +exit(!(stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0 +&& stat("conftestdata", &t) == 0 && t.st_mtime >= s.st_mtime +&& t.st_mtime - s.st_mtime < 120)); +} +EOF +if { (eval echo configure:3061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_utime_null=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_utime_null=no +fi +rm -fr conftest* +fi + +rm -f core core.* *.core +fi + +echo "$ac_t""$ac_cv_func_utime_null" 1>&6 +if test $ac_cv_func_utime_null = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_UTIME_NULL 1 +EOF + +fi + +echo $ac_n "checking for strftime""... $ac_c" 1>&6 +echo "configure:3085: checking for strftime" >&5 +if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strftime(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strftime) || defined (__stub___strftime) +choke me +#else +strftime(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_strftime=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_strftime=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_STRFTIME 1 +EOF + +else + echo "$ac_t""no" 1>&6 +# strftime is in -lintl on SCO UNIX. +echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 +echo "configure:3135: checking for strftime in -lintl" >&5 +ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_STRFTIME 1 +EOF + +LIBS="-lintl $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +for ac_func in a64l fchmod fchown fsync getgroups gethostname getspnam +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3183: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in gettimeofday getusershell getutent initgroups lchown lckpwdf +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3238: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in lstat memcpy memset setgroups sigaction strchr updwtmp updwtmpx +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3293: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + +for ac_func in mkdir putgrent putpwent putspent rename rmdir +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3349: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}" +fi +done + + +for ac_func in sgetgrent sgetpwent sgetspent +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3406: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}" +fi +done + + +for ac_func in snprintf strcasecmp strdup strerror strstr +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3463: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}" +fi +done + + + +echo $ac_n "checking for setpgrp""... $ac_c" 1>&6 +echo "configure:3519: checking for setpgrp" >&5 +if eval "test \"`echo '$''{'ac_cv_func_setpgrp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char setpgrp(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_setpgrp) || defined (__stub___setpgrp) +choke me +#else +setpgrp(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_setpgrp=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_setpgrp=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'setpgrp`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6 +echo "configure:3567: checking whether setpgrp takes no argument" >&5 +if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#endif + +/* + * If this system has a BSD-style setpgrp, which takes arguments, exit + * successfully. + */ +main() +{ + if (setpgrp(1,1) == -1) + exit(0); + else + exit(1); +} + +EOF +if { (eval echo configure:3595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_setpgrp_void=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_setpgrp_void=yes +fi +rm -fr conftest* +fi + + +fi + +echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6 +if test $ac_cv_func_setpgrp_void = yes; then + cat >> confdefs.h <<\EOF +#define SETPGRP_VOID 1 +EOF + +fi + + +if test "$ac_cv_header_shadow_h" = "yes"; then +echo $ac_n "checking for working shadow group support""... $ac_c" 1>&6 +echo "configure:3621: checking for working shadow group support" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_shadowgrp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_libc_shadowgrp=no +else + cat > conftest.$ac_ext < +main() +{ + struct sgrp *sg = sgetsgent("test:x::"); + /* NYS libc on Red Hat 3.0.3 has broken shadow group support */ + return !sg || !sg->sg_adm || !sg->sg_mem; +} + +EOF +if { (eval echo configure:3641: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_libc_shadowgrp=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_libc_shadowgrp=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_libc_shadowgrp" 1>&6 + +if test "$ac_cv_libc_shadowgrp" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SHADOWGRP 1 +EOF + +fi +fi + +echo $ac_n "checking location of shared mail directory""... $ac_c" 1>&6 +echo "configure:3666: checking location of shared mail directory" >&5 +for maildir in /var/spool/mail /var/mail /usr/spool/mail /usr/mail NONE; do + if test "$maildir" = "NONE"; then + echo "$ac_t""None" 1>&6 + elif test -d $maildir; then + cat >> confdefs.h <&6 + break + fi +done + +echo $ac_n "checking location of user mail file""... $ac_c" 1>&6 +echo "configure:3681: checking location of user mail file" >&5 +for mailfile in Mailbox mailbox Mail mail .mail NONE; do + if test "$mailfile" = "NONE"; then + echo "$ac_t""None" 1>&6 + elif test -f $HOME/$mailfile; then + cat >> confdefs.h <&6 + break + fi +done + +echo $ac_n "checking location of utmp""... $ac_c" 1>&6 +echo "configure:3696: checking location of utmp" >&5 +for utmpdir in /var/run /var/adm /usr/adm /etc NONE; do + if test "$utmpdir" = "NONE"; then + echo "configure: warning: utmp file not found" 1>&2 + elif test -f $utmpdir/utmp; then + cat >> confdefs.h <&6 + break + fi +done + +echo $ac_n "checking location of faillog/lastlog/wtmp""... $ac_c" 1>&6 +echo "configure:3711: checking location of faillog/lastlog/wtmp" >&5 +for logdir in /var/log /var/adm /usr/adm /etc; do + if test -d $logdir; then + cat >> confdefs.h <> confdefs.h <> confdefs.h <&6 + break + fi +done + +echo $ac_n "checking location of the passwd program""... $ac_c" 1>&6 +echo "configure:3732: checking location of the passwd program" >&5 +if test -f /usr/bin/passwd; then + passwd_dir=/usr/bin +else + passwd_dir=/bin +fi +cat >> confdefs.h <&6 + +cat >> confdefs.h <<\EOF +#define SHADOWPWD 1 +EOF + +cat >> confdefs.h <<\EOF +#define USG 1 +EOF + +cat >> confdefs.h <<\EOF +#define AGING 1 +EOF + +cat >> confdefs.h <<\EOF +#define USE_SYSLOG 1 +EOF + +cat >> confdefs.h <<\EOF +#define RLOGIN 1 +EOF + +cat >> confdefs.h <<\EOF +#define RUSEROK 0 +EOF + +cat >> confdefs.h <<\EOF +#define LOGIN_ACCESS 1 +EOF + +cat >> confdefs.h <<\EOF +#define SU_ACCESS 1 +EOF + + +cat >> confdefs.h <<\EOF +#define getpass libshadow_getpass +EOF + + +# Check whether --enable-desrpc or --disable-desrpc was given. +if test "${enable_desrpc+set}" = set; then + enableval="$enable_desrpc" + : +fi + +# Check whether --enable-shadowgrp or --disable-shadowgrp was given. +if test "${enable_shadowgrp+set}" = set; then + enableval="$enable_shadowgrp" + : +fi + + +# Check whether --with-libcrack or --without-libcrack was given. +if test "${with_libcrack+set}" = set; then + withval="$with_libcrack" + : +fi + +# Check whether --with-libcrypt or --without-libcrypt was given. +if test "${with_libcrypt+set}" = set; then + withval="$with_libcrypt" + : +fi + +# Check whether --with-libopie or --without-libopie was given. +if test "${with_libopie+set}" = set; then + withval="$with_libopie" + : +fi + +# Check whether --with-libpam or --without-libpam was given. +if test "${with_libpam+set}" = set; then + withval="$with_libpam" + : +fi + +# Check whether --with-libskey or --without-libskey was given. +if test "${with_libskey+set}" = set; then + withval="$with_libskey" + : +fi + +# Check whether --with-libtcfs or --without-libtcfs was given. +if test "${with_libtcfs+set}" = set; then + withval="$with_libtcfs" + : +fi + + + +echo $ac_n "checking for inet_ntoa""... $ac_c" 1>&6 +echo "configure:3834: checking for inet_ntoa" >&5 +if eval "test \"`echo '$''{'ac_cv_func_inet_ntoa'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char inet_ntoa(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_inet_ntoa) || defined (__stub___inet_ntoa) +choke me +#else +inet_ntoa(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3862: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_inet_ntoa=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_inet_ntoa=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'inet_ntoa`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for inet_ntoa in -linet""... $ac_c" 1>&6 +echo "configure:3880: checking for inet_ntoa in -linet" >&5 +ac_lib_var=`echo inet'_'inet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-linet $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + +echo $ac_n "checking for socket""... $ac_c" 1>&6 +echo "configure:3929: checking for socket" >&5 +if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_socket) || defined (__stub___socket) +choke me +#else +socket(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_socket=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_socket=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:3975: checking for socket in -lsocket" >&5 +ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + +echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +echo "configure:4024: checking for gethostbyname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +gethostbyname(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gethostbyname=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:4070: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + + + +if test "$enable_desrpc" != "no" -a "$ac_cv_header_rpc_key_prot_h" = "yes" ; then + echo $ac_n "checking for getsecretkey""... $ac_c" 1>&6 +echo "configure:4122: checking for getsecretkey" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getsecretkey'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getsecretkey(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getsecretkey) || defined (__stub___getsecretkey) +choke me +#else +getsecretkey(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getsecretkey=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getsecretkey=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getsecretkey`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define DES_RPC 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getsecretkey in -lrpcsvc""... $ac_c" 1>&6 +echo "configure:4171: checking for getsecretkey in -lrpcsvc" >&5 +ac_lib_var=`echo rpcsvc'_'getsecretkey | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lrpcsvc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define DES_RPC 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + +if test "$enable_shadowgrp" != "no"; then + cat >> confdefs.h <<\EOF +#define SHADOWGRP 1 +EOF + +fi + + +if test "$with_libcrypt" != "no"; then + echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 +echo "configure:4227: checking for crypt in -lcrypt" >&5 +ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrypt $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBCRYPT 1 +EOF + LIBCRYPT=-lcrypt +else + echo "$ac_t""no" 1>&6 +fi + +fi + +if test "$enable_md5crypt" = "yes"; then + LIBOBJS="$LIBOBJS md5.o md5crypt.o" + cat >> confdefs.h <<\EOF +#define MD5_CRYPT 1 +EOF + +fi + + +if test "$with_libcrack" != "no"; then + echo "checking cracklib flavour, don't be surprised by the results" + echo $ac_n "checking for FascistCheck in -lcrack""... $ac_c" 1>&6 +echo "configure:4283: checking for FascistCheck in -lcrack" >&5 +ac_lib_var=`echo crack'_'FascistCheck | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrack $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBCRACK 1 +EOF + LIBCRACK=-lcrack +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for FascistHistory in -lcrack""... $ac_c" 1>&6 +echo "configure:4326: checking for FascistHistory in -lcrack" >&5 +ac_lib_var=`echo crack'_'FascistHistory | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrack $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBCRACK_HIST 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for FascistHistoryPw in -lcrack""... $ac_c" 1>&6 +echo "configure:4369: checking for FascistHistoryPw in -lcrack" >&5 +ac_lib_var=`echo crack'_'FascistHistoryPw | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrack $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBCRACK_PW 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +fi + + + +if test "$with_libskey" = "yes"; then + echo $ac_n "checking for MD5Init in -lmd""... $ac_c" 1>&6 +echo "configure:4417: checking for MD5Init in -lmd" >&5 +ac_lib_var=`echo md'_'MD5Init | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lmd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBMD=-lmd +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for skeychallenge in -lskey""... $ac_c" 1>&6 +echo "configure:4457: checking for skeychallenge in -lskey" >&5 +ac_lib_var=`echo skey'_'skeychallenge | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lskey $LIBMD $LIBCRYPT $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define SKEY 1 +EOF + LIBSKEY=-lskey +else + echo "$ac_t""no" 1>&6 +fi + +elif test "$with_libopie" = "yes"; then + echo $ac_n "checking for opiechallenge in -lopie""... $ac_c" 1>&6 +echo "configure:4501: checking for opiechallenge in -lopie" >&5 +ac_lib_var=`echo opie'_'opiechallenge | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lopie $LIBCRYPT $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define OPIE 1 +EOF + LIBSKEY=-lopie +else + echo "$ac_t""no" 1>&6 +fi + +fi + + +if test "$with_libtcfs" = "yes"; then + echo $ac_n "checking for tcfs_encrypt_key in -ltcfs""... $ac_c" 1>&6 +echo "configure:4548: checking for tcfs_encrypt_key in -ltcfs" >&5 +ac_lib_var=`echo tcfs'_'tcfs_encrypt_key | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ltcfs -lgdbm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_TCFS 1 +EOF + cat >> confdefs.h <<\EOF +#define TCFS_GDBM_SUPPORT 1 +EOF + LIBTCFS="-ltcfs -lgdbm" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + +if test "$with_libpam" = "yes"; then + LIBPAM="-lpam -lpam_misc -ldl" + cat >> confdefs.h <<\EOF +#define USE_PAM 1 +EOF + + echo $ac_n "checking whether pam_strerror needs two arguments""... $ac_c" 1>&6 +echo "configure:4603: checking whether pam_strerror needs two arguments" >&5 +if eval "test \"`echo '$''{'ac_cv_pam_strerror_needs_two_args'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { + pam_handle_t *pamh; pam_strerror(pamh, PAM_SUCCESS); +; return 0; } +EOF +if { (eval echo configure:4615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_pam_strerror_needs_two_args=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_pam_strerror_needs_two_args=no + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_pam_strerror_needs_two_args" 1>&6 + if test "$ac_cv_pam_strerror_needs_two_args" = "yes"; then + cat >> confdefs.h <<\EOF +#define PAM_STRERROR_NEEDS_TWO_ARGS 1 +EOF + + fi +fi + +LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.o/.lo/g'` + + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:4642: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <&6 +echo "configure:4682: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 +echo "configure:4717: checking for working alloca.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { +char *p = alloca(2 * sizeof(int)); +; return 0; } +EOF +if { (eval echo configure:4729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_header_alloca_h=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_alloca_h=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 +if test $ac_cv_header_alloca_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA_H 1 +EOF + +fi + +echo $ac_n "checking for alloca""... $ac_c" 1>&6 +echo "configure:4750: checking for alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int main() { +char *p = (char *) alloca(1); +; return 0; } +EOF +if { (eval echo configure:4783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_func_alloca_works=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_func_alloca_works=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 +if test $ac_cv_func_alloca_works = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA 1 +EOF + +fi + +if test $ac_cv_func_alloca_works = no; then + # The SVR3 libPW and SVR4 libucb both contain incompatible functions + # that cause trouble. Some versions do not even contain alloca or + # contain a buggy version. If you still want to use their alloca, + # use ar to extract alloca.o from them instead of compiling alloca.c. + ALLOCA=alloca.${ac_objext} + cat >> confdefs.h <<\EOF +#define C_ALLOCA 1 +EOF + + +echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 +echo "configure:4815: checking whether alloca needs Cray hooks" >&5 +if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5 | + egrep "webecray" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_os_cray=yes +else + rm -rf conftest* + ac_cv_os_cray=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_os_cray" 1>&6 +if test $ac_cv_os_cray = yes; then +for ac_func in _getb67 GETB67 getb67; do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4845: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <&6 +fi + +done +fi + +echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 +echo "configure:4900: checking stack direction for C alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat > conftest.$ac_ext < addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +if { (eval echo configure:4927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_stack_direction=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_stack_direction=-1 +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 +cat >> confdefs.h <&6 +echo "configure:4952: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4962: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4991: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:5044: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext < +#include +#include + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:5192: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + + + for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h sys/param.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:5220: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:5230: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ +strdup __argz_count __argz_stringify __argz_next +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5260: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + for ac_func in stpcpy +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5317: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_STPCPY 1 +EOF + + fi + + if test $ac_cv_header_locale_h = yes; then + echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 +echo "configure:5379: checking for LC_MESSAGES" >&5 +if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { +return LC_MESSAGES +; return 0; } +EOF +if { (eval echo configure:5391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + am_cv_val_LC_MESSAGES=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + am_cv_val_LC_MESSAGES=no +fi +rm -f conftest* +fi + +echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6 + if test $am_cv_val_LC_MESSAGES = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_LC_MESSAGES 1 +EOF + + fi + fi + echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 +echo "configure:5412: checking whether NLS is requested" >&5 + # Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + USE_NLS=$enableval +else + USE_NLS=yes +fi + + echo "$ac_t""$USE_NLS" 1>&6 + + + USE_INCLUDED_LIBINTL=no + + if test "$USE_NLS" = "yes"; then + cat >> confdefs.h <<\EOF +#define ENABLE_NLS 1 +EOF + + echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 +echo "configure:5432: checking whether included gettext is requested" >&5 + # Check whether --with-included-gettext or --without-included-gettext was given. +if test "${with_included_gettext+set}" = set; then + withval="$with_included_gettext" + nls_cv_force_use_gnu_gettext=$withval +else + nls_cv_force_use_gnu_gettext=no +fi + + echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6 + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 +echo "configure:5451: checking for libintl.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:5461: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 +echo "configure:5478: checking for gettext in libc" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:5490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libc=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libc=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 + + if test "$gt_cv_func_gettext_libc" != "yes"; then + echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 +echo "configure:5506: checking for bindtextdomain in -lintl" >&5 +ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 +echo "configure:5541: checking for gettext in libintl" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 +echo "configure:5546: checking for gettext in -lintl" >&5 +ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + gt_cv_func_gettext_libintl=yes +else + echo "$ac_t""no" 1>&6 +gt_cv_func_gettext_libintl=no +fi + +fi + +echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_GETTEXT 1 +EOF + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5604: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + if test "$MSGFMT" != "no"; then + for ac_func in dcgettext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5638: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5693: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5729: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f conftest* + INSTOBJEXT=.mo + fi + fi + +else + echo "$ac_t""no" 1>&6 +fi + + + if test "$CATOBJEXT" = "NONE"; then + echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6 +echo "configure:5792: checking whether catgets can be used" >&5 + # Check whether --with-catgets or --without-catgets was given. +if test "${with_catgets+set}" = set; then + withval="$with_catgets" + nls_cv_use_catgets=$withval +else + nls_cv_use_catgets=no +fi + + echo "$ac_t""$nls_cv_use_catgets" 1>&6 + + if test "$nls_cv_use_catgets" = "yes"; then + echo $ac_n "checking for main in -li""... $ac_c" 1>&6 +echo "configure:5805: checking for main in -li" >&5 +ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-li $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo i | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + echo $ac_n "checking for catgets""... $ac_c" 1>&6 +echo "configure:5848: checking for catgets" >&5 +if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char catgets(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_catgets) || defined (__stub___catgets) +choke me +#else +catgets(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_catgets=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_catgets=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'catgets`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_CATGETS 1 +EOF + + INTLOBJS="\$(CATOBJS)" + # Extract the first word of "gencat", so it can be a program name with args. +set dummy gencat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5898: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GENCAT" in + /*) + ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GENCAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no" + ;; +esac +fi +GENCAT="$ac_cv_path_GENCAT" +if test -n "$GENCAT"; then + echo "$ac_t""$GENCAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + if test "$GENCAT" != "no"; then + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5934: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test "$GMSGFMT" = "no"; then + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5971: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + fi + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6006: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.cat + INSTOBJEXT=.cat + DATADIRNAME=lib + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi +else + echo "$ac_t""no" 1>&6 +fi + + fi + fi + + if test "$CATOBJEXT" = "NONE"; then + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + INTLOBJS="\$(GETTOBJS)" + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6064: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6098: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6134: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6 + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + + + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + + + + + + + + + + + + + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 +echo "configure:6227: checking for catalogs to be installed" >&5 + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + echo "$ac_t""$LINGUAS" 1>&6 + fi + + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include " + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header . Take care yourself. */" + fi + + + test -d intl || mkdir intl + if test "$CATOBJEXT" = ".cat"; then + ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 +echo "configure:6255: checking for linux/version.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6265: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + msgformat=linux +else + echo "$ac_t""no" 1>&6 +msgformat=xopen +fi + + + sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed + fi + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed + + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + + + + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + + + l= + + + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "libmisc/Makefile man/Makefile man/pl/Makefile + lib/Makefile src/Makefile Makefile + contrib/Makefile debian/Makefile doc/Makefile etc/Makefile + intl/Makefile intl/po2tbl.sed po/Makefile.in + etc/pam.d/Makefile old/Makefile + redhat/Makefile redhat/shadow-utils.spec config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@LN_S@%$LN_S%g +s%@YACC@%$YACC%g +s%@CPP@%$CPP%g +s%@U@%$U%g +s%@ANSI2KNR@%$ANSI2KNR%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@RANLIB@%$RANLIB%g +s%@LD@%$LD%g +s%@NM@%$NM%g +s%@LIBTOOL@%$LIBTOOL%g +s%@LIBOBJS@%$LIBOBJS%g +s%@LIBCRYPT@%$LIBCRYPT%g +s%@LIBCRACK@%$LIBCRACK%g +s%@LIBSKEY@%$LIBSKEY%g +s%@LIBMD@%$LIBMD%g +s%@LIBTCFS@%$LIBTCFS%g +s%@LIBPAM@%$LIBPAM%g +s%@LTLIBOBJS@%$LTLIBOBJS%g +s%@ALLOCA@%$ALLOCA%g +s%@USE_NLS@%$USE_NLS%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@GENCAT@%$GENCAT%g +s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g +s%@CATALOGS@%$CATALOGS%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@DATADIRNAME@%$DATADIRNAME%g +s%@GMOFILES@%$GMOFILES%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@INTLDEPS@%$INTLDEPS%g +s%@INTLLIBS@%$INTLLIBS%g +s%@INTLOBJS@%$INTLOBJS%g +s%@POFILES@%$POFILES%g +s%@POSUB@%$POSUB%g +s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g +s%@GT_NO@%$GT_NO%g +s%@GT_YES@%$GT_YES%g +s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g +s%@l@%$l%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +srcdir=$ac_given_srcdir +while test -n "$ac_sources"; do + set $ac_dests; ac_dest=$1; shift; ac_dests=$* + set $ac_sources; ac_source=$1; shift; ac_sources=$* + + echo "linking $srcdir/$ac_source to $ac_dest" + + if test ! -r $srcdir/$ac_source; then + { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; } + fi + rm -f $ac_dest + + # Make relative symlinks. + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'` + if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then + # The dest file is in a subdirectory. + test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir" + ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dest_dir_suffix. + ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dest_dir_suffix= ac_dots= + fi + + case "$srcdir" in + [/$]*) ac_rel_source="$srcdir/$ac_source" ;; + *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;; + esac + + # Make a symlink if possible; otherwise try a hard link. + if ln -s $ac_rel_source $ac_dest 2>/dev/null || + ln $srcdir/$ac_source $ac_dest; then : + else + { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; } + fi +done +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h +case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac +echo timestamp > stamp-h +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/current/configure.in b/current/configure.in new file mode 100644 index 00000000..1af42d8f --- /dev/null +++ b/current/configure.in @@ -0,0 +1,311 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(lib/dialchk.c) +AM_INIT_AUTOMAKE(shadow, 20000902) +AM_CONFIG_HEADER(config.h) + +dnl Some hacks... +test "$prefix" = "NONE" && prefix="/usr" +test "$prefix" = "/usr" && exec_prefix="" +test "$CFLAGS" = "" && CFLAGS="-O2 -Wall" +test "$LDFLAGS" = "" && LDFLAGS="-s" + +ALL_LINGUAS="el fr pl sv" + +dnl Checks for programs. +AC_PROG_CC +AC_ISC_POSIX +dnl AC_PROG_INSTALL +AC_PROG_LN_S +dnl AC_PROG_MAKE_SET +AC_PROG_YACC +dnl AC_ARG_PROGRAM +AM_C_PROTOTYPES +AM_PROG_LIBTOOL + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h limits.h unistd.h sys/time.h utmp.h utmpx.h) +AC_CHECK_HEADERS(termios.h termio.h sgtty.h sys/ioctl.h syslog.h) +AC_CHECK_HEADERS(paths.h usersec.h utime.h ulimit.h sys/resource.h) +AC_CHECK_HEADERS(gshadow.h shadow.h lastlog.h rpc/key_prot.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_UID_T +AC_TYPE_OFF_T +AC_TYPE_PID_T +AC_TYPE_MODE_T +AC_STRUCT_ST_RDEV +AC_HEADER_STAT +AC_HEADER_TIME +AC_STRUCT_TM + +AC_CACHE_CHECK(for pw_age in struct passwd, +ac_cv_struct_passwd_pw_age, AC_TRY_COMPILE([#include ], +[ struct passwd pw; pw.pw_age = ""; ], +ac_cv_struct_passwd_pw_age=yes, ac_cv_struct_passwd_pw_age=no)) + +if test "$ac_cv_struct_passwd_pw_age" = "yes"; then + AC_DEFINE(ATT_AGE) +fi + +AC_CACHE_CHECK(for pw_comment in struct passwd, +ac_cv_struct_passwd_pw_comment, AC_TRY_COMPILE([#include ], +[ struct passwd pw; pw.pw_comment = ""; ], +ac_cv_struct_passwd_pw_comment=yes, ac_cv_struct_passwd_pw_comment=no)) + +if test "$ac_cv_struct_passwd_pw_comment" = "yes"; then + AC_DEFINE(ATT_COMMENT) +fi + +AC_CACHE_CHECK(for pw_quota in struct passwd, +ac_cv_struct_passwd_pw_quota, AC_TRY_COMPILE([#include ], +[ struct passwd pw; pw.pw_quota = 0; ], +ac_cv_struct_passwd_pw_quota=yes, ac_cv_struct_passwd_pw_quota=no)) + +if test "$ac_cv_struct_passwd_pw_quota" = "yes"; then + AC_DEFINE(BSD_QUOTA) +fi + +if test "$ac_cv_header_utmp_h" = "yes"; then + AC_CACHE_CHECK(for ut_host in struct utmp, + ac_cv_struct_utmp_ut_host, AC_TRY_COMPILE([#include ], + [ struct utmp ut; char *cp = ut.ut_host; ], + ac_cv_struct_utmp_ut_host=yes, ac_cv_struct_utmp_ut_host=no)) + + if test "$ac_cv_struct_utmp_ut_host" = "yes"; then + AC_DEFINE(UT_HOST) + fi + + AC_CACHE_CHECK(for ut_user in struct utmp, + ac_cv_struct_utmp_ut_user, AC_TRY_COMPILE([#include ], + [ struct utmp ut; char *cp = ut.ut_user; ], + ac_cv_struct_utmp_ut_user=yes, ac_cv_struct_utmp_ut_user=no)) + + if test "$ac_cv_struct_utmp_ut_user" = "no"; then + AC_DEFINE(ut_user, ut_name) + fi +fi + +if test "$ac_cv_header_lastlog_h" = "yes"; then + AC_CACHE_CHECK(for ll_host in struct lastlog, + ac_cv_struct_lastlog_ll_host, AC_TRY_COMPILE([#include ], + [ struct lastlog ll; char *cp = ll.ll_host; ], + ac_cv_struct_lastlog_ll_host=yes, ac_cv_struct_lastlog_ll_host=no)) + + if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then + AC_DEFINE(HAVE_LL_HOST) + fi +fi + +dnl Checks for library functions. +AC_TYPE_GETGROUPS +AC_PROG_GCC_TRADITIONAL +AC_TYPE_SIGNAL +AC_FUNC_UTIME_NULL +AC_FUNC_STRFTIME +dnl Disabled for now, strtoday.c has problems with year 2000 or later +dnl AC_CHECK_FUNCS(strptime) +AC_CHECK_FUNCS(a64l fchmod fchown fsync getgroups gethostname getspnam) +AC_CHECK_FUNCS(gettimeofday getusershell getutent initgroups lchown lckpwdf) +AC_CHECK_FUNCS(lstat memcpy memset setgroups sigaction strchr updwtmp updwtmpx) + +AC_REPLACE_FUNCS(mkdir putgrent putpwent putspent rename rmdir) +AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent) +AC_REPLACE_FUNCS(snprintf strcasecmp strdup strerror strstr) + +AC_CHECK_FUNC(setpgrp) +AC_FUNC_SETPGRP + +if test "$ac_cv_header_shadow_h" = "yes"; then +AC_CACHE_CHECK(for working shadow group support, +ac_cv_libc_shadowgrp, AC_TRY_RUN( +[ +#include +main() +{ + struct sgrp *sg = sgetsgent("test:x::"); + /* NYS libc on Red Hat 3.0.3 has broken shadow group support */ + return !sg || !sg->sg_adm || !sg->sg_mem; +} +], +ac_cv_libc_shadowgrp=yes,ac_cv_libc_shadowgrp=no,ac_cv_libc_shadowgrp=no)) + +if test "$ac_cv_libc_shadowgrp" = "yes"; then + AC_DEFINE(HAVE_SHADOWGRP) +fi +fi + +AC_MSG_CHECKING(location of shared mail directory) +for maildir in /var/spool/mail /var/mail /usr/spool/mail /usr/mail NONE; do + if test "$maildir" = "NONE"; then + AC_MSG_RESULT(None) + elif test -d $maildir; then + AC_DEFINE_UNQUOTED(MAIL_SPOOL_DIR, "$maildir") + AC_MSG_RESULT($maildir) + break + fi +done + +AC_MSG_CHECKING(location of user mail file) +for mailfile in Mailbox mailbox Mail mail .mail NONE; do + if test "$mailfile" = "NONE"; then + AC_MSG_RESULT(None) + elif test -f $HOME/$mailfile; then + AC_DEFINE_UNQUOTED(MAIL_SPOOL_FILE, "$mailfile") + AC_MSG_RESULT($mailfile) + break + fi +done + +AC_MSG_CHECKING(location of utmp) +for utmpdir in /var/run /var/adm /usr/adm /etc NONE; do + if test "$utmpdir" = "NONE"; then + AC_MSG_WARN(utmp file not found) + elif test -f $utmpdir/utmp; then + AC_DEFINE_UNQUOTED(_UTMP_FILE, "$utmpdir/utmp") + AC_MSG_RESULT($utmpdir) + break + fi +done + +AC_MSG_CHECKING(location of faillog/lastlog/wtmp) +for logdir in /var/log /var/adm /usr/adm /etc; do + if test -d $logdir; then + AC_DEFINE_UNQUOTED(_WTMP_FILE, "$logdir/wtmp") + AC_DEFINE_UNQUOTED(LASTLOG_FILE, "$logdir/lastlog") + AC_DEFINE_UNQUOTED(FAILLOG_FILE, "$logdir/faillog") + AC_MSG_RESULT($logdir) + break + fi +done + +AC_MSG_CHECKING(location of the passwd program) +if test -f /usr/bin/passwd; then + passwd_dir=/usr/bin +else + passwd_dir=/bin +fi +AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$passwd_dir/passwd") +AC_MSG_RESULT($passwd_dir) + +dnl XXX - quick hack, should disappear before anyone notices :). +AC_DEFINE(SHADOWPWD) +AC_DEFINE(USG) +AC_DEFINE(AGING) +AC_DEFINE(USE_SYSLOG) +AC_DEFINE(RLOGIN) +AC_DEFINE(RUSEROK, 0) +AC_DEFINE(LOGIN_ACCESS) +AC_DEFINE(SU_ACCESS) + +dnl Use our own version of getpass(), which handles long passwords +dnl (unlike many systems which have a limit of 8 characters), and can +dnl be interrupted with Ctrl-C (unlike Linux libc). +AC_DEFINE(getpass, libshadow_getpass) + +AC_ARG_ENABLE(desrpc, [ --enable-desrpc try to use secure RPC in login (default if found)]) +dnl AC_ARG_ENABLE(md5crypt, [ --enable-md5crypt include MD5-compatible crypt function]) +AC_ARG_ENABLE(shadowgrp, [ --enable-shadowgrp enable shadow group support [default=yes]]) + +AC_ARG_WITH(libcrack, [ --with-libcrack try to use libcrack (default if found)]) +AC_ARG_WITH(libcrypt, [ --with-libcrypt try to use libcrypt (default if found)]) +AC_ARG_WITH(libopie, [ --with-libopie use libopie for OPIE support]) +AC_ARG_WITH(libpam, [ --with-libpam use libpam for PAM support]) +AC_ARG_WITH(libskey, [ --with-libskey use libskey for S/Key support]) +AC_ARG_WITH(libtcfs, [ --with-libtcfs use libtcfs for TCFS support]) + +dnl Check for some functions in libc first, only if not found check for +dnl other libraries. This should prevent linking libnsl if not really +dnl needed (Linux glibc, Irix), but still link it if needed (Solaris). + +AC_CHECK_FUNC(inet_ntoa, [], AC_CHECK_LIB(inet, inet_ntoa)) +AC_CHECK_FUNC(socket, [], AC_CHECK_LIB(socket, socket)) +AC_CHECK_FUNC(gethostbyname, [], AC_CHECK_LIB(nsl, gethostbyname)) + +dnl XXX - getsecretkey() causes login to hang for 5 minutes on at least +dnl one RH 4.0 system. Use --disable-desrpc if you have this problem. +dnl Reported by Mohan Khurana . + +if test "$enable_desrpc" != "no" -a "$ac_cv_header_rpc_key_prot_h" = "yes" ; then + AC_CHECK_FUNC(getsecretkey, AC_DEFINE(DES_RPC), + AC_CHECK_LIB(rpcsvc, getsecretkey, AC_DEFINE(DES_RPC))) +fi + +if test "$enable_shadowgrp" != "no"; then + AC_DEFINE(SHADOWGRP) +fi + +AC_SUBST(LIBCRYPT) +if test "$with_libcrypt" != "no"; then + AC_CHECK_LIB(crypt, crypt, [AC_DEFINE(HAVE_LIBCRYPT) LIBCRYPT=-lcrypt]) +fi + +if test "$enable_md5crypt" = "yes"; then + LIBOBJS="$LIBOBJS md5.o md5crypt.o" + AC_DEFINE(MD5_CRYPT) +fi + +AC_SUBST(LIBCRACK) +if test "$with_libcrack" != "no"; then + echo "checking cracklib flavour, don't be surprised by the results" + AC_CHECK_LIB(crack, FascistCheck, AC_DEFINE(HAVE_LIBCRACK) LIBCRACK=-lcrack) + AC_CHECK_LIB(crack, FascistHistory, AC_DEFINE(HAVE_LIBCRACK_HIST)) + AC_CHECK_LIB(crack, FascistHistoryPw, AC_DEFINE(HAVE_LIBCRACK_PW)) +fi + +AC_SUBST(LIBSKEY) +AC_SUBST(LIBMD) +if test "$with_libskey" = "yes"; then + AC_CHECK_LIB(md, MD5Init, LIBMD=-lmd) + AC_CHECK_LIB(skey, skeychallenge, AC_DEFINE(SKEY) LIBSKEY=-lskey, , $LIBMD $LIBCRYPT) +elif test "$with_libopie" = "yes"; then + AC_CHECK_LIB(opie, opiechallenge, AC_DEFINE(OPIE) LIBSKEY=-lopie, , $LIBCRYPT) +fi + +AC_SUBST(LIBTCFS) +if test "$with_libtcfs" = "yes"; then + AC_CHECK_LIB(tcfs, tcfs_encrypt_key, AC_DEFINE(HAVE_TCFS) AC_DEFINE(TCFS_GDBM_SUPPORT) LIBTCFS="-ltcfs -lgdbm", , -lgdbm) +fi + +AC_SUBST(LIBPAM) +if test "$with_libpam" = "yes"; then + dnl AC_CHECK_LIB(pam, pam_start, AC_DEFINE(USE_PAM) LIBPAM=-lpam) + dnl the above doesn't work as there is no libpam.a (only .so) + dnl XXX - libpam_misc is probably Linux-PAM specific + LIBPAM="-lpam -lpam_misc -ldl" + AC_DEFINE(USE_PAM) + AC_CACHE_CHECK(whether pam_strerror needs two arguments, + ac_cv_pam_strerror_needs_two_args, + AC_TRY_COMPILE( + [#include ], + [ pam_handle_t *pamh; pam_strerror(pamh, PAM_SUCCESS); ], + ac_cv_pam_strerror_needs_two_args=yes, + ac_cv_pam_strerror_needs_two_args=no + ) + ) + if test "$ac_cv_pam_strerror_needs_two_args" = "yes"; then + AC_DEFINE(PAM_STRERROR_NEEDS_TWO_ARGS) + fi +fi + +LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.o/.lo/g'` +AC_SUBST(LTLIBOBJS) +dnl LTALLOCA=`echo "$ALLOCA" | sed 's/\.o/.lo/g'` +dnl AC_SUBST(LTALLOCA) + +AM_GNU_GETTEXT +dnl AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl) + +AC_OUTPUT(libmisc/Makefile man/Makefile man/pl/Makefile + lib/Makefile src/Makefile Makefile + contrib/Makefile debian/Makefile doc/Makefile etc/Makefile + intl/Makefile intl/po2tbl.sed po/Makefile.in + etc/pam.d/Makefile old/Makefile + redhat/Makefile redhat/shadow-utils.spec, + echo timestamp > stamp-h) + diff --git a/current/contrib/Makefile.am b/current/contrib/Makefile.am new file mode 100644 index 00000000..ea24774e --- /dev/null +++ b/current/contrib/Makefile.am @@ -0,0 +1,6 @@ +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + +EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh \ + atudel groupmems.shar pwdauth.c rpasswd.c shadow-anonftp.patch \ + udbachk.v012.tgz diff --git a/current/contrib/Makefile.in b/current/contrib/Makefile.in new file mode 100644 index 00000000..4f546120 --- /dev/null +++ b/current/contrib/Makefile.in @@ -0,0 +1,212 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh atudel groupmems.shar pwdauth.c rpasswd.c shadow-anonftp.patch udbachk.v012.tgz + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = README Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps contrib/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = contrib + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/contrib/README b/current/contrib/README new file mode 100644 index 00000000..c4d1bc03 --- /dev/null +++ b/current/contrib/README @@ -0,0 +1,10 @@ +People keep sending various adduser programs and scripts... They are +all in this directory. I haven't tested them, use at your own risk. +Anyway, the best one I've seen so far is adduser-3.x from Debian. + +atudel is a perl script to remove at jobs owned by the specified user +(atrm in at-2.9 for Linux can't do that). + +udbachk.tgz is a passwd/group/shadow file integrity checker. + +--marekm diff --git a/current/contrib/adduser-old.c b/current/contrib/adduser-old.c new file mode 100644 index 00000000..f924b36e --- /dev/null +++ b/current/contrib/adduser-old.c @@ -0,0 +1,300 @@ +/**** +** 03/17/96 +** hacked a bit more, removed unused code, cleaned up for gcc -Wall. +** --marekm +** +** 02/26/96 +** modified to call shadow utils (useradd,chage,passwd) on shadowed +** systems - Cristian Gafton, gafton@sorosis.ro +** +** 6/27/95 +** shadow-adduser 1.4: +** +** now it copies the /etc/skel dir into the person's dir, +** makes the mail folders, changed some defaults and made a 'make +** install' just for the hell of it. +** +** Greg Gallagher +** CIN.Net +** +** 1/28/95 +** shadow-adduser 1.3: +** +** Basically a bug-fix on my additions in 1.2. Thanx to Terry Stewart +** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced. +** It was such a stupid bug that I would have never seen it myself. +** +** Brandon +***** +** 01/27/95 +** +** shadow-adduser 1.2: +** I took the C source from adduser-shadow (credits are below) and made +** it a little more worthwhile. Many small changes... Here's +** the ones I can remember: +** +** Removed support for non-shadowed systems (if you don't have shadow, +** use the original adduser, don't get this shadow version!) +** Added support for the correct /etc/shadow fields (Min days before +** password change, max days before password change, Warning days, +** and how many days from expiry date does the account go invalid) +** The previous version just left all of those fields blank. +** There is still one field left (expiry date for the account, period) +** which I have left blank because I do not use it and didn't want to +** spend any more time on this. I'm sure someone will put it in and +** tack another plethora of credits on here. :) +** Added in the password date field, which should always reflect the last +** date the password was changed, for expiry purposes. "passwd" always +** updates this field, so the adduser program should set it up right +** initially (or a user could keep thier initial password forever ;) +** The number is in days since Jan 1st, 1970. +** +** Have fun with it, and someone please make +** a real version(this is still just a hack) +** for us all to use (and Email it to me???) +** +** Brandon +** photon@usis.com +** +***** +** adduser 1.0: add a new user account (For systems not using shadow) +** With a nice little interface and a will to do all the work for you. +** +** Craig Hagan +** hagan@opine.cs.umass.edu +** +** Modified to really work, look clean, and find unused uid by Chris Cappuccio +** chris@slinky.cs.umass.edu +** +***** +** +** 01/19/95 +** +** FURTHER modifications to enable shadow passwd support (kludged, but +** no more so than the original) by Dan Crowson - dcrowson@mo.net +** +** Search on DAN for all changes... +** +***** +** +** cc -O -o adduser adduser.c +** Use gcc if you have it... (political reasons beyond my control) (chris) +** +** I've gotten this program to work with success under Linux (without +** shadow) and SunOS 4.1.3. I would assume it should work pretty well +** on any system that uses no shadow. (chris) +** +** If you have no crypt() then try +** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c +** I'm not sure how login operates with no crypt()... I guess +** the same way we're doing it here. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */ +#define DEFAULT_HOME "/home" +#define USERADD_PATH "/usr/sbin/useradd" +#define CHAGE_PATH "/usr/sbin/chage" +#define PASSWD_PATH "/usr/bin/passwd" +#define DEFAULT_GROUP 100 + +#define DEFAULT_MAX_PASS 60 +#define DEFAULT_WARN_PASS 10 +/* if you use this feature, you will get a lot of complaints from users + who rarely use their accounts :) (something like 3 months would be + more reasonable) --marekm */ +#define DEFAULT_USER_DIE /* 10 */ 0 + +void main() +{ + char foo[32]; + char uname[9],person[32],dir[32],shell[32]; + unsigned int group,min_pass,max_pass,warn_pass,user_die; + /* the group and uid of the new user */ + int bad=0,done=0,correct=0,gets_warning=0; + char cmd[255]; + struct group *grp; + + /* flags, in order: + * bad to see if the username is in /etc/passwd, or if strange stuff has + * been typed if the user might be put in group 0 + * done allows the program to exit when a user has been added + * correct loops until a password is found that isn't in /etc/passwd + * gets_warning allows the fflush to be skipped for the first gets + * so that output is still legible + */ + + /* The real program starts HERE! */ + + if(geteuid()!=0) + { + printf("It seems you don't have access to add a new user. Try\n"); + printf("logging in as root or su root to gain super-user access.\n"); + exit(1); + } + + /* Sanity checks + */ + + if (!(grp=getgrgid(DEFAULT_GROUP))){ + printf("Error: the default group %d does not exist on this system!\n", + DEFAULT_GROUP); + printf("adduser must be recompiled.\n"); + exit(1); + }; + + while(!correct) { /* loop until a "good" uname is chosen */ + while(!done) { + printf("\nLogin to add (^C to quit): "); + if(gets_warning) /* if the warning was already shown */ + fflush(stdout); /* fflush stdout, otherwise set the flag */ + else + gets_warning=1; + + gets(uname); + if(!strlen(uname)) { + printf("Empty input.\n"); + done=0; + continue; + }; + + /* what I saw here before made me think maybe I was running DOS */ + /* might this be a solution? (chris) */ + if (getpwnam(uname) != NULL) { + printf("That name is in use, choose another.\n"); + done=0; + } else + done=1; + }; /* done, we have a valid new user name */ + + /* all set, get the rest of the stuff */ + printf("\nEditing information for new user [%s]\n",uname); + + printf("\nFull Name [%s]: ",uname); + gets(person); + if (!strlen(person)) { + bzero(person,sizeof(person)); + strcpy(person,uname); + }; + + do { + bad=0; + printf("GID [%d]: ",DEFAULT_GROUP); + gets(foo); + if (!strlen(foo)) + group=DEFAULT_GROUP; + else + if (isdigit (*foo)) { + group = atoi(foo); + if (! (grp = getgrgid (group))) { + printf("unknown gid %s\n",foo); + group=DEFAULT_GROUP; + bad=1; + }; + } else + if ((grp = getgrnam (foo))) + group = grp->gr_gid; + else { + printf("unknown group %s\n",foo); + group=DEFAULT_GROUP; + bad=1; + } + if (group==0){ /* You're not allowed to make root group users! */ + printf("Creation of root group users not allowed (must be done by hand)\n"); + group=DEFAULT_GROUP; + bad=1; + }; + } while(bad); + + + fflush(stdin); + + printf("\nIf home dir ends with a / then [%s] will be appended to it\n",uname); + printf("Home Directory [%s/%s]: ",DEFAULT_HOME,uname); + fflush(stdout); + gets(dir); + if (!strlen(dir)) { /* hit return */ + sprintf(dir,"%s/%s",DEFAULT_HOME,uname); + fflush(stdin); + } else + if (dir[strlen(dir)-1]=='/') + sprintf(dir,"%s%s",dir,uname); + + printf("\nShell [%s]: ",DEFAULT_SHELL); + fflush(stdout); + gets(shell); + if (!strlen(shell)) + sprintf(shell,"%s",DEFAULT_SHELL); + + printf("\nMin. Password Change Days [0]: "); + gets(foo); + min_pass=atoi(foo); + + printf("Max. Password Change Days [%d]: ",DEFAULT_MAX_PASS); + gets(foo); + if (strlen(foo) > 1) + max_pass = atoi(foo); + else + max_pass = DEFAULT_MAX_PASS; + + printf("Password Warning Days [%d]: ",DEFAULT_WARN_PASS); + gets(foo); + warn_pass = atoi(foo); + if (warn_pass==0) + warn_pass = DEFAULT_WARN_PASS; + + printf("Days after Password Expiry for Account Locking [%d]: ",DEFAULT_USER_DIE); + gets(foo); + user_die = atoi(foo); + if (user_die == 0) + user_die = DEFAULT_USER_DIE; + + printf("\nInformation for new user [%s] [%s]:\n",uname,person); + printf("Home directory: [%s] Shell: [%s]\n",dir,shell); + printf("GID: [%d]\n",group); + printf("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n", + min_pass,max_pass,warn_pass,user_die); + printf("\nIs this correct? [y/N]: "); + fflush(stdout); + gets(foo); + + done=bad=correct=(foo[0]=='y'||foo[0]=='Y'); + + if(bad!=1) + printf("\nUser [%s] not added\n",uname); + } + + bzero(cmd,sizeof(cmd)); + sprintf(cmd,"%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s", + USERADD_PATH,group,dir,shell,person,uname); + printf("Calling useradd to add new user:\n%s\n",cmd); + if(system(cmd)){ + printf("User add failed!\n"); + exit(errno); + }; + bzero(cmd,sizeof(cmd)); + sprintf(cmd,"%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH, + min_pass,max_pass,warn_pass,user_die,uname); + printf("%s\n",cmd); + if(system(cmd)){ + printf("There was an error setting password expire values\n"); + exit(errno); + }; + bzero(cmd,sizeof(cmd)); + sprintf(cmd,"%s %s",PASSWD_PATH,uname); + system(cmd); + printf("\nDone.\n"); +} + diff --git a/current/contrib/adduser.c b/current/contrib/adduser.c new file mode 100644 index 00000000..f303a41d --- /dev/null +++ b/current/contrib/adduser.c @@ -0,0 +1,502 @@ +/**** +** 04/21/96 +** hacked even more, replaced gets() with something slightly harder to buffer +** overflow. Added support for setting a default quota on new account, with +** edquota -p. Other cleanups for security, I let some users run adduser suid +** root to add new accounts. (overflow checks, clobber environment, valid +** shell checks, restrictions on gid + home dir settings). + +** Added max. username length. Used syslog() a bit for important events. +** Support to immediately expire account with passwd -e. + +** Called it version 2.0! Because I felt like it! + +** -- Chris, chris@ferret.lmh.ox.ac.uk + +** 03/17/96 +** hacked a bit more, removed unused code, cleaned up for gcc -Wall. +** --marekm +** +** 02/26/96 +** modified to call shadow utils (useradd,chage,passwd) on shadowed +** systems - Cristian Gafton, gafton@sorosis.ro +** +** 6/27/95 +** shadow-adduser 1.4: +** +** now it copies the /etc/skel dir into the person's dir, +** makes the mail folders, changed some defaults and made a 'make +** install' just for the hell of it. +** +** Greg Gallagher +** CIN.Net +** +** 1/28/95 +** shadow-adduser 1.3: +** +** Basically a bug-fix on my additions in 1.2. Thanx to Terry Stewart +** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced. +** It was such a stupid bug that I would have never seen it myself. +** +** Brandon +***** +** 01/27/95 +** +** shadow-adduser 1.2: +** I took the C source from adduser-shadow (credits are below) and made +** it a little more worthwhile. Many small changes... Here's +** the ones I can remember: +** +** Removed support for non-shadowed systems (if you don't have shadow, +** use the original adduser, don't get this shadow version!) +** Added support for the correct /etc/shadow fields (Min days before +** password change, max days before password change, Warning days, +** and how many days from expiry date does the account go invalid) +** The previous version just left all of those fields blank. +** There is still one field left (expiry date for the account, period) +** which I have left blank because I do not use it and didn't want to +** spend any more time on this. I'm sure someone will put it in and +** tack another plethora of credits on here. :) +** Added in the password date field, which should always reflect the last +** date the password was changed, for expiry purposes. "passwd" always +** updates this field, so the adduser program should set it up right +** initially (or a user could keep thier initial password forever ;) +** The number is in days since Jan 1st, 1970. +** +** Have fun with it, and someone please make +** a real version(this is still just a hack) +** for us all to use (and Email it to me???) +** +** Brandon +** photon@usis.com +** +***** +** adduser 1.0: add a new user account (For systems not using shadow) +** With a nice little interface and a will to do all the work for you. +** +** Craig Hagan +** hagan@opine.cs.umass.edu +** +** Modified to really work, look clean, and find unused uid by Chris Cappuccio +** chris@slinky.cs.umass.edu +** +***** +** +** 01/19/95 +** +** FURTHER modifications to enable shadow passwd support (kludged, but +** no more so than the original) by Dan Crowson - dcrowson@mo.net +** +** Search on DAN for all changes... +** +***** +** +** cc -O -o adduser adduser.c +** Use gcc if you have it... (political reasons beyond my control) (chris) +** +** I've gotten this program to work with success under Linux (without +** shadow) and SunOS 4.1.3. I would assume it should work pretty well +** on any system that uses no shadow. (chris) +** +** If you have no crypt() then try +** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c +** I'm not sure how login operates with no crypt()... I guess +** the same way we're doing it here. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed + * immediately upon next login */ +#define HAVE_QUOTAS /* Obvious */ +#define EXPIRE_VALS_SET /* If defined, 'normal' users can't change + * password expiry values (if running suid root) */ + +#define HAVE_GETUSERSHELL /* FIXME: Isn't this defined in config.h too? */ +#define LOGGING /* If we want to log various things to syslog */ +#define MAX_USRNAME 8 /* Longer usernames seem to work on my system.... + * But they're probably a poor idea */ + + +#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */ +#define DEFAULT_HOME "/home" +#define USERADD_PATH "/usr/sbin/useradd" +#define CHAGE_PATH "/usr/bin/chage" +#define PASSWD_PATH "/usr/bin/passwd" +#define EDQUOTA_PATH "/usr/sbin/edquota" +#define QUOTA_DEFAULT "defuser" +#define DEFAULT_GROUP 100 + +#define DEFAULT_MIN_PASS 0 +#define DEFAULT_MAX_PASS 100 +#define DEFAULT_WARN_PASS 14 +#define DEFAULT_USER_DIE 366 + +void safeget (char *, int); + +void +main (void) +{ + char foo[32]; + char usrname[32], person[32], dir[32], shell[32]; + unsigned int group, min_pass, max_pass, warn_pass, user_die; + /* the group and uid of the new user */ + int bad = 0, done = 0, correct = 0, olduid; + char cmd[255]; + struct group *grp; + + /* flags, in order: + * bad to see if the username is in /etc/passwd, or if strange stuff has + * been typed if the user might be put in group 0 + * done allows the program to exit when a user has been added + * correct loops until a username is found that isn't in /etc/passwd + */ + + /* The real program starts HERE! */ + + if (geteuid () != 0) + { + printf ("It seems you don't have access to add a new user. Try\n"); + printf ("logging in as root or su root to gain super-user access.\n"); + exit (1); + } + + /* Sanity checks + */ + +#ifdef LOGGING + openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); + syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name); +#endif + + if (!(grp = getgrgid (DEFAULT_GROUP))) + { + printf ("Error: the default group %d does not exist on this system!\n", + DEFAULT_GROUP); + printf ("adduser must be recompiled.\n"); +#ifdef LOGGING + syslog (LOG_ERR, "warning: failed. no such default group\n"); + closelog (); +#endif + exit (1); + }; + + while (!correct) + { /* loop until a "good" usrname is chosen */ + while (!done) + { + printf ("\nLogin to add (^C to quit): "); + fflush (stdout); + + safeget (usrname, sizeof (usrname)); + + if (!strlen (usrname)) + { + printf ("Empty input.\n"); + done = 0; + continue; + }; + + /* what I saw here before made me think maybe I was running DOS */ + /* might this be a solution? (chris) */ + if (strlen (usrname) > MAX_USRNAME) + { + printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME); + done = 0; + } + else if (getpwnam (usrname) != NULL) + { + printf ("That name is in use, choose another.\n"); + done = 0; + } + else if (strchr (usrname, ' ') != NULL) + { + printf ("No spaces in username!!\n"); + done = 0; + } + else + done = 1; + }; /* done, we have a valid new user name */ + + /* all set, get the rest of the stuff */ + printf ("\nEditing information for new user [%s]\n", usrname); + + printf ("\nFull Name [%s]: ", usrname); + fflush (stdout); + safeget (person, sizeof (person)); + if (!strlen (person)) + { + bzero (person, sizeof (person)); + strcpy (person, usrname); + }; + + if (getuid () == 0) + { + do + { + bad = 0; + printf ("GID [%d]: ", DEFAULT_GROUP); + fflush (stdout); + safeget (foo, sizeof (foo)); + if (!strlen (foo)) + group = DEFAULT_GROUP; + else if (isdigit (*foo)) + { + group = atoi (foo); + if (!(grp = getgrgid (group))) + { + printf ("unknown gid %s\n", foo); + group = DEFAULT_GROUP; + bad = 1; + }; + } + else if ((grp = getgrnam (foo))) + group = grp->gr_gid; + else + { + printf ("unknown group %s\n", foo); + group = DEFAULT_GROUP; + bad = 1; + } + if (group == 0) + { /* You're not allowed to make root group users! */ + printf ("Creation of root group users not allowed (must be done by hand)\n"); + group = DEFAULT_GROUP; + bad = 1; + }; + } + while (bad); + } + else + { + printf ("Group will be default of: %d\n", DEFAULT_GROUP); + group = DEFAULT_GROUP; + } + + if (getuid () == 0) + { + printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname); + printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname); + fflush (stdout); + safeget (dir, sizeof (dir)); + if (!strlen (dir)) + { /* hit return */ + sprintf (dir, "%s/%s", DEFAULT_HOME, usrname); + } + else if (dir[strlen (dir) - 1] == '/') + sprintf (dir, "%s%s", dir, usrname); + } + else + { + printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname); + sprintf (dir, "%s/%s", DEFAULT_HOME, usrname); + } + + printf ("\nShell [%s]: ", DEFAULT_SHELL); + fflush (stdout); + safeget (shell, sizeof (shell)); + if (!strlen (shell)) + sprintf (shell, "%s", DEFAULT_SHELL); + else + { + char *sh; + int ok = 0; +#ifdef HAVE_GETUSERSHELL + setusershell (); + while ((sh = getusershell ()) != NULL) + if (!strcmp (shell, sh)) + ok = 1; + endusershell (); +#endif + if (!ok) + { + if (getuid () == 0) + printf ("Warning: root allowed non standard shell\n"); + else + { + printf ("Shell NOT in /etc/shells, DEFAULT used\n"); + sprintf (shell, "%s", DEFAULT_SHELL); + } + } + } + +#ifdef EXPIRE_VALS_SET + if (getuid () == 0) + { +#endif + printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS); + fflush (stdout); + safeget (foo, sizeof (foo)); + if (strlen (foo) > 1) + min_pass = DEFAULT_MIN_PASS; + else + min_pass = atoi (foo); + + printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS); + fflush (stdout); + safeget (foo, sizeof (foo)); + if (strlen (foo) > 1) + max_pass = atoi (foo); + else + max_pass = DEFAULT_MAX_PASS; + + printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS); + fflush (stdout); + safeget (foo, sizeof (foo)); + warn_pass = atoi (foo); + if (warn_pass == 0) + + warn_pass = DEFAULT_WARN_PASS; + + printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE); + fflush (stdout); + safeget (foo, sizeof (foo)); + user_die = atoi (foo); + if (user_die == 0) + user_die = DEFAULT_USER_DIE; + +#ifdef EXPIRE_VALS_SET + } + else + { + printf ("\nSorry, account expiry values are set.\n"); + user_die = DEFAULT_USER_DIE; + warn_pass = DEFAULT_WARN_PASS; + max_pass = DEFAULT_MAX_PASS; + min_pass = DEFAULT_MIN_PASS; + } +#endif + + printf ("\nInformation for new user [%s] [%s]:\n", usrname, person); + printf ("Home directory: [%s] Shell: [%s]\n", dir, shell); + printf ("GID: [%d]\n", group); + printf ("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n", + min_pass, max_pass, warn_pass, user_die); + printf ("\nIs this correct? [y/N]: "); + fflush (stdout); + safeget (foo, sizeof (foo)); + + done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y'); + + if (bad != 1) + printf ("\nUser [%s] not added\n", usrname); + } + + /* Clobber the environment, I run this suid root sometimes to let + * non root privileged accounts add users --chris */ + + *environ = NULL; + + bzero (cmd, sizeof (cmd)); + sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s", + USERADD_PATH, group, dir, shell, person, usrname); + printf ("Calling useradd to add new user:\n%s\n", cmd); + if (system (cmd)) + { + printf ("User add failed!\n"); +#ifdef LOGGING + syslog (LOG_ERR, "could not add new user\n"); + closelog (); +#endif + exit (errno); + }; + + olduid = getuid (); /* chage, passwd, edquota etc. require ruid = root + */ + setuid (0); + + bzero (cmd, sizeof (cmd)); + + /* Chage runs suid root. => we need ruid root to run it with + * anything other than chage -l + */ + + sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH, + min_pass, max_pass, warn_pass, user_die, usrname); + printf ("%s\n", cmd); + if (system (cmd)) + { + printf ("There was an error setting password expire values\n"); +#ifdef LOGGING + syslog (LOG_ERR, "password expire values could not be set\n"); +#endif + }; + + /* I want to add a user completely with one easy command --chris */ + +#ifdef HAVE_QUOTAS + bzero (cmd, sizeof (cmd)); + sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname); + printf ("%s\n", cmd); + if (system (cmd)) + { + printf ("\nWarning: error setting quota\n"); +#ifdef LOGGING + syslog (LOG_ERR, "warning: account created but NO quotas set!\n"); +#endif /* LOGGING */ + } + else + printf ("\nDefault quota set.\n"); +#endif /* HAVE_QUOTAS */ + + bzero (cmd, sizeof (cmd)); + sprintf (cmd, "%s %s", PASSWD_PATH, usrname); + if (system (cmd)) + { + printf ("\nWarning: error setting password\n"); +#ifdef LOGGING + syslog (LOG_ERR, "warning: password set failed!\n"); +#endif + } +#ifdef IMMEDIATE_CHANGE + bzero (cmd, sizeof (cmd)); + sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname); + if (system (cmd)) + { + printf ("\nWarning: error expiring password\n"); +#ifdef LOGGING + syslog (LOG_ERR, "warning: password expire failed!\n"); +#endif /* LOGGING */ + } +#endif /* IMMEDIATE_CHANGE */ + + setuid (olduid); + +#ifdef LOGGING + closelog (); +#endif + + printf ("\nDone.\n"); +} + +void +safeget (char *buf, int maxlen) +{ + int c, i = 0, bad = 0; + char *bstart = buf; + while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen)) + { + bad = (!isalnum (c) && (c != '_') && (c != ' ')); + *(buf++) = (char) c; + } + *buf = '\0'; + + if (bad) + { + printf ("\nString contained banned character. Please stick to alphanumerics.\n"); + *bstart = '\0'; + } +} + diff --git a/current/contrib/adduser.sh b/current/contrib/adduser.sh new file mode 100755 index 00000000..0efb27a3 --- /dev/null +++ b/current/contrib/adduser.sh @@ -0,0 +1,90 @@ +#!/bin/sh +# adduser script for use with shadow passwords and useradd command. +# by Hrvoje Dogan , Dec 1995. + +echo -n "Login name for new user []:" +read LOGIN +if [ -z $LOGIN ] +then echo "Come on, man, you can't leave the login field empty...";exit +fi +echo +echo -n "User id for $LOGIN [ defaults to next available]:" +read ID +GUID="-u $ID" +if [ -z $ID ] +then GUID="" +fi + +echo +echo -n "Initial group for $LOGIN [users]:" +read GID +GGID="-g $GID" +if [ -z $GID ] +then GGID="" +fi + +echo +echo -n "Additional groups for $LOGIN []:" +read AGID +GAGID="-G $AGID" +if [ -z $AGID ] +then GAGID="" +fi + +echo +echo -n "$LOGIN's home directory [/home/$LOGIN]:" +read HME +GHME="-d $HME" +if [ -z $HME ] +then GHME="" +fi + +echo +echo -n "$LOGIN's shell [/bin/bash]:" +read SHL +GSHL="-s $SHL" +if [ -z $SHL ] +then GSHL="" +fi + +echo +echo -n "$LOGIN's account expiry date (MM/DD/YY) []:" +read EXP +GEXP="-e $EXP" +if [ -z $EXP ] +then GEXP="" +fi +echo +echo OK, I'm about to make a new account. Here's what you entered so far: +echo New login name: $LOGIN +if [ -z $GUID ] +then echo New UID: [Next available] +else echo New UID: $UID +fi +if [ -z $GGID ] +then echo Initial group: users +else echo Initial group: $GID +fi +if [ -z $GAGID ] +then echo Additional groups: [none] +else echo Additional groups: $AGID +fi +if [ -z $GHME ] +then echo Home directory: /home/$LOGIN +else echo Home directory: $HME +fi +if [ -z $GSHL ] +then echo Shell: /bin/bash +else echo Shell: $SHL +fi +if [ -z $GEXP ] +then echo Expiry date: [no expiration] +else echo Expiry date: $EXP +fi +echo "This is it... if you want to bail out, you'd better do it now." +read FOO +echo Making new account... +/usr/sbin/useradd $GHME -m $GEXP $GGID $GAGID $GSHL $GUID $LOGIN +/usr/bin/chfn $LOGIN +/usr/bin/passwd $LOGIN +echo "Done..." diff --git a/current/contrib/adduser2.sh b/current/contrib/adduser2.sh new file mode 100755 index 00000000..a2b36b25 --- /dev/null +++ b/current/contrib/adduser2.sh @@ -0,0 +1,743 @@ +#!/bin/bash +# +# adduser Interactive user adding program. +# +# Copyright (C) 1996 Petri Mattila, Prihateam Networks +# petri@prihateam.fi +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# Changes: +# 220496 v0.01 Initial version +# 230496 v0.02 More checks, embolden summary +# 240496 Even more checks +# 250496 Help with ? +# 040596 v0.03 Cleanups +# 050596 v0.04 Bug fixes, expire date checks +# 070596 v0.05 Iso-latin-1 names +# + +## Defaults + +# default groups +def_group="users" +def_other_groups="" + +# default home directory +def_home_dir=/home/users + +# default shell +def_shell=/bin/tcsh + +# Defaul expiration date (mm/dd/yy) +def_expire="" + +# default dates +def_pwd_min=0 +def_pwd_max=90 +def_pwd_warn=14 +def_pwd_iact=14 + + +# possible UIDs +uid_low=1000 +uid_high=64000 + +# skel directory +skel=/etc/skel + +# default mode for home directory +def_mode=711 + +# Regex, that the login name must meet, only ANSI characters +login_regex='^[0-9a-zA-Z_-]*$' + +# Regex, that the user name must meet +# ANSI version +##name_regex='^[0-9a-zA-Z_-\ ]*$' +# ISO-LATIN-1 version +name_regex='^[0-9a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöùúûüýþÿ_-\ ]*$' + +# set PATH +export PATH="/bin:/sbin:/usr/bin:/usr/sbin" + +# Some special characters +case "$TERM" in + vt*|ansi*|con*|xterm*|linux*) + S='' # start embolden + E='' # end embolden + ;; + *) + S='' + E='' + ;; +esac + + +## Functions + +check_root() { + if test "$EUID" -ne 0 + then + echo "You must be root to run this program." + exit 1 + fi +} + +check_user() { + local usr pwd uid gid name home sh + + cat /etc/passwd | ( + while IFS=":" read usr pwd uid gid name home sh + do + if test "$1" = "${usr}" + then + return 1 + fi + done + return 0 + ) +} + +check_group() { + local read grp pwd gid members + + cat /etc/group | ( + while IFS=":" read grp pwd gid members + do + if test "$1" = "${grp}" + then + return 1 + fi + done + return 0 + ) +} + +check_other_groups() { + local grp check IFS + + check="$1" + IFS="," + + set ${check} + for grp + do + if check_group "${grp}" + then + echo "Group ${grp} does not exist." + return 1 + fi + done + return 0 +} + +check_uid() { + local usr pwd uid gid name home sh + + cat /etc/passwd | ( + while IFS=":" read usr pwd uid gid name home sh + do + if test "$1" = "${uid}" + then + return 1 + fi + done + return 0 + ) +} + +read_yn() { + local ans ynd + + ynd="$1" + + while : + do + read ans + case "${ans}" in + "") return ${ynd} ;; + [nN]) return 1 ;; + [yY]) return 0 ;; + *) echo -n "Y or N, please ? " ;; + esac + done +} + +read_login() { + echo + while : + do + echo -n "Login: ${def_login:+[${def_login}] }" + read login + + if test "${login}" = '?' + then + less /etc/passwd + echo + continue + fi + + if test -z "${login}" -a -n "${def_login}" + then + login="${def_login}" + echo "Using ${login}" + return + fi + + if test "${#login}" -gt 8 + then + echo "Login must be at most 8 characters long" + continue + fi + + if test "${#login}" -lt 2 + then + echo "Login must be at least 2 characters long" + continue + fi + + if ! expr "${login}" : "${login_regex}" &> /dev/null + then + echo "Please use letters, numbers and special characters _-,." + continue + fi + + if ! check_user "${login}" + then + echo "Username ${login} is already in use" + continue + fi + + def_login="${login}" + return + done +} + +read_name () { + echo + while : + do + echo -n "Real name: ${def_name:+[${def_name}] }" + read name + + if test "${name}" = '?' + then + less /etc/passwd + echo + continue + fi + + if test -z "${name}" -a -n "${def_name}" + then + name="${def_name}" + echo "Using ${name}" + fi + + if test "${#name}" -gt 32 + then + echo "Name should be at most 32 characters long" + continue + fi + + if ! expr "${name}" : "${name_regex}" &> /dev/null + then + echo "Please use letters, numbers, spaces and special characters ,._-" + continue + fi + + def_name="${name}" + return + done +} + +read_home() { + local x + + echo + while : + do + echo -n "Home Directory: [${def_home_dir}/${login}] " + read home + + if test -z "${home}" + then + home="${def_home_dir}/${login}" + echo "Using ${home}" + fi + + if ! expr "${home}" : '^[0-9a-zA-Z,._-\/]*$' &> /dev/null + then + echo "Please use letters, numbers, spaces and special characters ,._-/" + continue + fi + + x="$(basename ${home})" + if test "${x}" != "${login}" + then + echo "Warning: you are about to use different login name and home directory." + fi + + x="$(dirname ${home})" + if ! test -d "${x}" + then + echo "Directory ${x} does not exist." + echo "If you still want to use it, please make it manually." + continue + fi + + def_home_dir="${x}" + return + done +} + +read_shell () { + local x + + echo + while : + do + echo -n "Shell: [${def_shell}] " + read shell + + if test -z "${shell}" + then + shell="${def_shell}" + echo "Using ${shell}" + fi + + for x in $(cat /etc/shells) + do + if test "${x}" = "${shell}" + then + def_shell="${shell}" + return + fi + done + + echo "Possible shells are:" + cat /etc/shells + done +} + +read_group () { + echo + while : + do + echo -n "Group: [${def_group}] " + read group + + if test -z "${group}" + then + group="${def_group}" + echo "Using ${group}" + fi + + if test "${group}" = '?' + then + less /etc/group + echo + continue + fi + + if check_group "${group}" + then + echo "Group ${group} does not exist." + continue + fi + + def_group="${group}" + return + done +} + +read_other_groups () { + echo + while : + do + echo -n "Other groups: [${def_og:-none}] " + read other_groups + + if test "${other_groups}" = '?' + then + less /etc/group + echo + continue + fi + + if test -z "${other_groups}" + then + if test -n "${def_og}" + then + other_groups="${def_og}" + echo "Using ${other_groups}" + else + echo "No other groups" + return + fi + fi + + + if ! check_other_groups "${other_groups}" + then + continue + fi + + def_og="${other_groups}" + return + done +} + +read_uid () { + echo + while : + do + echo -n "uid: [first free] " + read uid + + if test -z "${uid}" + then + echo "Using first free UID." + return + fi + + if test "${uid}" = '?' + then + less /etc/passwd + echo + continue + fi + + if ! expr "${uid}" : '^[0-9]+$' &> /dev/null + then + echo "Please use numbers only." + continue + fi + if test "${uid}" -lt "${uid_low}" + then + echo "UID must be greater than ${uid_low}" + continue + fi + if test "${uid}" -gt "${uid_high}" + then + echo "UID must be smaller than ${uid_high}" + continue + fi + if ! check_uid "${uid}" + then + echo "UID ${uid} is already in use" + continue + fi + + return + done +} + +read_max_valid_days() { + echo + while : + do + echo -en "Maximum days between password changes: [${def_pwd_max}] " + read max_days + + if test -z "${max_days}" + then + max_days="${def_pwd_max}" + echo "Using ${max_days}" + return + fi + + if ! expr "${max_days}" : '^[0-9]+$' &> /dev/null + then + echo "Please use numbers only." + continue + fi + if test "${max_days}" -lt 7 + then + echo "Warning: you are using a value shorter than a week." + fi + + def_pwd_max="${max_days}" + return + done +} + +read_min_valid_days() { + echo + while : + do + echo -en "Minimum days between password changes: [${def_pwd_min}] " + read min_days + + if test -z "${min_days}" + then + min_days="${def_pwd_min}" + echo "Using ${min_days}" + return + fi + + if ! expr "${min_days}" : '^[0-9]+$' &> /dev/null + then + echo "Please use numbers only." + continue + fi + if test "${min_days}" -gt 7 + then + echo "Warning: you are using a value longer than a week." + fi + + def_pwd_min="${min_days}" + return + done +} + +read_warning_days() { + echo + while : + do + echo -en "Number of warning days before password expires: [${def_pwd_warn}] " + read warn_days + + if test -z "${warn_days}" + then + warn_days="${def_pwd_warn}" + echo "Using ${warn_days}" + fi + + if ! expr "${warn_days}" : '^[0-9]+$' &> /dev/null + then + echo "Please use numbers only." + continue + fi + if test "${warn_days}" -gt 14 + then + echo "Warning: you are using a value longer than two week." + fi + + def_pwd_warn="${warn_days}" + return + done +} + + +read_inactive_days() { + echo + while : + do + echo -en "Number of usable days after expiration: [${def_pwd_iact}] " + read iact_days + + if test -z "${iact_days}" + then + iact_days="${def_pwd_iact}" + echo "Using ${iact_days}" + return + fi + if ! expr "${iact_days}" : '^[0-9]+$' &> /dev/null + then + echo "Please use numbers only." + continue + fi + if test "${iact_days}" -gt 14 + then + echo "Warning: you are using a value that is more than two weeks." + fi + + def_pwd_iact="${iact_days}" + return + done +} + +read_expire_date() { + local ans + + echo + while : + do + echo -en "Expire date of this account (mm/dd/yy): [${def_expire:-never}] " + read ans + + if test -z "${ans}" + then + if test -z "${def_expire}" + then + ans="never" + else + ans="${def_expire}" + echo "Using ${def_expire}" + fi + fi + + if test "${ans}" = "never" + then + echo "Account will never expire." + def_expire="" + expire="" + return + fi + + if ! expr "${ans}" : '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]$' &> /dev/null + then + echo "Please use format mm/dd/yy" + continue + fi + + if ! expire_date="$(date -d ${ans} '+%A, %B %d %Y')" + then + continue + fi + + def_expire="${expire}" + return + done +} + +read_passwd_yn() { + echo -en "\nDo you want to set password [Y/n] ? " + if read_yn 0 + then + set_pwd="YES" + else + set_pwd="" + fi +} + + +print_values() { + +clear +cat << EOM + +Login: ${S}${login}${E} +Group: ${S}${group}${E} +Other groups: ${S}${other_groups:-[none]}${E} + +Real Name: ${S}${name}${E} + +uid: ${S}${uid:-[first free]}${E} +home: ${S}${home}${E} +shell: ${S}${shell}${E} + +Account expiration date: ${S}${expire_date:-never}${E} +Minimum days between password changes: ${S}${min_days}${E} +Maximum days between password changes: ${S}${max_days}${E} +Number of usable days after expiration: ${S}${iact_days}${E} +Number of warning days before expiration: ${S}${warn_days}${E} + +${S}${set_pwd:+Set password for this account.}${E} + +EOM +} + +set_user() { + if ! useradd \ + -c "${name}" \ + -d "${home}" \ + -g "${group}" \ + -s "${shell}" \ + ${expire:+-e ${expire}} \ + ${uid:+-u ${uid}} \ + ${other_groups:+-G ${other_groups}} \ + ${login} + then + echo "Error ($?) in useradd...exiting..." + exit 1 + fi +} + +set_aging() { + if ! passwd \ + -x ${max_days} \ + -n ${min_days} \ + -w ${warn_days} \ + -i ${iact_days} \ + ${login} + then + echo "Error ($?) in setting password aging...exiting..." + exit 1 + fi +} + +set_password() { + if test -n "${set_pwd}" + then + echo + passwd ${login} + echo + fi +} + +set_system() { + if test -d "${home}" + then + echo "Directory ${home} already exists." + echo "Skeleton files not copied." + return + fi + + echo -n "Copying skeleton files..." + ( + mkdir ${home} + cd ${skel} && cp -af . ${home} + chmod ${def_mode} ${home} + chown -R ${login}:${group} ${home} + ) + echo "done." + + ## Add your own stuff here: + echo -n "Setting up other files..." + ( + mailbox="/var/spool/mail/${login}" + touch ${mailbox} + chown "${login}:mail" ${mailbox} + chmod 600 ${mailbox} + ) + echo "done." +} + + +read_values() { + clear + echo -e "\nPlease answer the following questions about the new user to be added." + + while : + do + read_login + read_name + read_group + read_other_groups + read_home + read_shell + read_uid + read_expire_date + read_max_valid_days + read_min_valid_days + read_warning_days + read_inactive_days + read_passwd_yn + + print_values + + echo -n "Is this correct [N/y] ? " + read_yn 1 && return + done +} + + +main() { + check_root + read_values + set_user + set_aging + set_system + set_password +} + + +## Run it 8-) +main + +# End. diff --git a/current/contrib/atudel b/current/contrib/atudel new file mode 100755 index 00000000..0ca87833 --- /dev/null +++ b/current/contrib/atudel @@ -0,0 +1,85 @@ +#!/usr/bin/perl +# +# Copyright (c) 1996 Brian R. Gaeke +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by Brian R. Gaeke. +# 4. The name of the author, Brian R. Gaeke, may not be used to endorse +# or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY BRIAN R. GAEKE ``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 BRIAN R. GAEKE 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. +# +# Additionally: +# +# This software is provided without support and without any obligation +# on the part of Brian R. Gaeke to assist in its use, correction, +# modification or enhancement. +# +####################################################################### +# +# this is atudel, version 2, by Brian R. Gaeke +# + +require "getopts.pl"; +&Getopts('v'); +$username = shift(@ARGV); +&usage unless $username; + +sub usage +{ + print STDERR "atudel - remove all at jobs owned by a user\n"; + print STDERR "usage: $0 [-v] username\n"; + exit(1); +} + +# odd. unless getpwnam($uname) doesn't seem to work for $uname eq "root" on +# my linux system. but this does. +die "user $username does not exist; stopping" + unless defined(getpwnam($username)); + +print "searching for at jobs owned by user $username ..." if $opt_v; + +chdir "/var/spool/atjobs" || + die "can't chdir to /var/spool/atjobs: $!\nstopping"; +opendir(DIR,".") || die "can't opendir(/var/spool/atjobs): $!\nstopping"; +@files = grep(!/^\./,grep(-f,readdir(DIR))); +closedir DIR; + +foreach $x (@files) +{ + $owner = (getpwuid((stat($x))[4]))[0]; + push(@nuke_bait,$x) if $owner eq $username; +} + +if (@nuke_bait) +{ + print "removed jobIDs: @{nuke_bait}.\n" if $opt_v; + unlink @nuke_bait; +} +elsif ($opt_v) +{ + print "\n"; +} + +exit 0; diff --git a/current/contrib/groupmems.shar b/current/contrib/groupmems.shar new file mode 100644 index 00000000..d45efd2e --- /dev/null +++ b/current/contrib/groupmems.shar @@ -0,0 +1,546 @@ +#!/bin/sh +# This is a shell archive (produced by GNU sharutils 4.2.1). +# To extract the files from this archive, save it to some FILE, remove +# everything before the `!/bin/sh' line above, then type `sh FILE'. +# +# Made on 2000-05-25 14:41 CDT by . +# Source directory was `/home/gk4/src/groupmem'. +# +# Existing files will *not* be overwritten unless `-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 1960 -rw-r--r-- Makefile +# 6348 -rw-r--r-- groupmems.c +# 3372 -rw------- groupmems.8 +# +save_IFS="${IFS}" +IFS="${IFS}:" +gettext_dir=FAILED +locale_dir=FAILED +first_param="$1" +for dir in $PATH +do + if test "$gettext_dir" = FAILED && test -f $dir/gettext \ + && ($dir/gettext --version >/dev/null 2>&1) + then + set `$dir/gettext --version 2>&1` + if test "$3" = GNU + then + gettext_dir=$dir + fi + fi + if test "$locale_dir" = FAILED && test -f $dir/shar \ + && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) + then + locale_dir=`$dir/shar --print-text-domain-dir` + fi +done +IFS="$save_IFS" +if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED +then + echo=echo +else + TEXTDOMAINDIR=$locale_dir + export TEXTDOMAINDIR + TEXTDOMAIN=sharutils + export TEXTDOMAIN + echo="$gettext_dir/gettext -s" +fi +if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then + shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"' +elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then + shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"' +elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then + shar_touch='touch -am $3$4$5$6$2 "$8"' +else + shar_touch=: + echo + $echo 'WARNING: not restoring timestamps. Consider getting and' + $echo "installing GNU \`touch', distributed in GNU File Utilities..." + echo +fi +rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch +# +if mkdir _sh10937; then + $echo 'x -' 'creating lock directory' +else + $echo 'failed to create lock directory' + exit 1 +fi +# ============= Makefile ============== +if test -f 'Makefile' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'Makefile' '(file already exists)' +else + $echo 'x -' extracting 'Makefile' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && +/* +# Copyright 2000, International Business Machines, Inc. +# All rights reserved. +# +# original author: George Kraft IV, gk4@us.ibm.com +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of International Business Machines, Inc., nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND +# CONTRIBUTORS ``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 +# INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS 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. +# +X +all: groupmems +X +groupmems: groupmems.c +X cc -g -o groupmems groupmems.c -L. -lshadow +X +install: groupmems +X -/usr/sbin/groupadd groups +X install -o root -g groups -m 4770 groupmems /usr/bin +X +install.man: groupmems.8 +X install -o root -g root -m 644 groupmems.8 /usr/man/man8 +X +SHAR_EOF + (set 20 00 05 25 14 40 28 'Makefile'; eval "$shar_touch") && + chmod 0644 'Makefile' || + $echo 'restore of' 'Makefile' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'Makefile:' 'MD5 check failed' +b46cf7ef8d59149093c011ced3f3103c Makefile +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`" + test 1960 -eq "$shar_count" || + $echo 'Makefile:' 'original size' '1960,' 'current size' "$shar_count!" + fi +fi +# ============= groupmems.c ============== +if test -f 'groupmems.c' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'groupmems.c' '(file already exists)' +else + $echo 'x -' extracting 'groupmems.c' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'groupmems.c' && +/* +X * Copyright 2000, International Business Machines, Inc. +X * All rights reserved. +X * +X * original author: George Kraft IV, gk4@us.ibm.com +X * +X * Redistribution and use in source and binary forms, with or without +X * modification, are permitted provided that the following conditions +X * are met: +X * +X * 1. Redistributions of source code must retain the above copyright +X * notice, this list of conditions and the following disclaimer. +X * 2. Redistributions in binary form must reproduce the above copyright +X * notice, this list of conditions and the following disclaimer in the +X * documentation and/or other materials provided with the distribution. +X * 3. Neither the name of International Business Machines, Inc., nor the +X * names of its contributors may be used to endorse or promote products +X * derived from this software without specific prior written permission. +X * +X * THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND +X * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +X * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +X * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +X * INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE +X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +X * SUCH DAMAGE. +X */ +/* +** +** Utility "groupmem" adds and deletes members from a user's group. +** +** Setup (as "root"): +** +** groupadd -r groups +** chmod 2770 groupmems +** chown root.groups groupmems +** groupmems -g groups -a gk4 +** +** Usage (as "gk4"): +** +** groupmems -a olive +** groupmems -a jordan +** groupmems -a meghan +** groupmems -a morgan +** groupmems -a jake +** groupmems -l +** groupmems -d jake +** groupmems -l +*/ +X +#include +#include +#include +#include +#include +#include +#include "defines.h" +#include "groupio.h" +X +/* Exit Status Values */ +X +#define EXIT_SUCCESS 0 /* success */ +#define EXIT_USAGE 1 /* invalid command syntax */ +#define EXIT_GROUP_FILE 2 /* group file access problems */ +#define EXIT_NOT_ROOT 3 /* not super user */ +#define EXIT_NOT_EROOT 4 /* not effective super user */ +#define EXIT_NOT_PRIMARY 5 /* not primary owner of group */ +#define EXIT_NOT_MEMBER 6 /* member of group does not exist */ +#define EXIT_MEMBER_EXISTS 7 /* member of group already exists */ +X +#define TRUE 1 +#define FALSE 0 +X +/* Globals */ +X +extern int optind; +extern char *optarg; +static char *adduser = NULL; +static char *deluser = NULL; +static char *thisgroup = NULL; +static int purge = FALSE; +static int list = FALSE; +static int exclusive = 0; +X +static int isroot(void) { +X return getuid() ? FALSE : TRUE; +} +X +static int isgroup(void) { +X gid_t g = getgid(); +X struct group *grp = getgrgid(g); +X +X return TRUE; +} +X +static char *whoami(void) { +X struct group *grp = getgrgid(getgid()); +X struct passwd *usr = getpwuid(getuid()); +X +X if (0 == strcmp(usr->pw_name, grp->gr_name)) { +X return (char *)strdup(usr->pw_name); +X } else { +X return NULL; +X } +} +X +static void +addtogroup(char *user, char **members) { +X int i; +X char **pmembers; +X +X for (i = 0; NULL != members[i]; i++ ) { +X if (0 == strcmp(user, members[i])) { +X fprintf(stderr, "Member already exists\n"); +X exit(EXIT_MEMBER_EXISTS); +X } +X } +X +X if (0 == i) { +X pmembers = (char **)calloc(2, sizeof(char *)); +X } else { +X pmembers = (char **)realloc(members, sizeof(char *)*(i+1)); +X } +X +X *members = *pmembers; +X members[i] = user; +X members[i+1] = NULL; +} +X +static void +rmfromgroup(char *user, char **members) { +X int i; +X int found = FALSE; +X +X i = 0; +X while (!found && NULL != members[i]) { +X if (0 == strcmp(user, members[i])) { +X found = TRUE; +X } else { +X i++; +X } +X } +X +X while (found && NULL != members[i]) { +X members[i] = members[++i]; +X } +X +X if (!found) { +X fprintf(stderr, "Member to remove could not be found\n"); +X exit(EXIT_NOT_MEMBER); +X } +} +X +static void +nomembers(char **members) { +X int i; +X +X for (i = 0; NULL != members[i]; i++ ) { +X members[i] = NULL; +X } +} +X +static void +members(char **members) { +X int i; +X +X for (i = 0; NULL != members[i]; i++ ) { +X printf("%s ", members[i]); +X +X if (NULL == members[i+1]) { +X printf("\n"); +X } else { +X printf(" "); +X } +X } +} +X +static void usage(void) { +X fprintf(stderr, "usage: groupmems -a username | -d username | -D | -l [-g groupname]\n"); +X exit(EXIT_USAGE); +} +X +main(int argc, char **argv) { +X int arg, i; +X char *name; +X struct group *grp; +X +X while ((arg = getopt(argc, argv, "a:d:g:Dl")) != EOF) { +X switch (arg) { +X case 'a': +X adduser = strdup(optarg); +X ++exclusive; +X break; +X case 'd': +X deluser = strdup(optarg); +X ++exclusive; +X break; +X case 'g': +X thisgroup = strdup(optarg); +X break; +X case 'D': +X purge = TRUE; +X ++exclusive; +X break; +X case 'l': +X list = TRUE; +X ++exclusive; +X break; +X default: +X usage(); +X } +X } +X +X if (exclusive > 1 || optind < argc) { +X usage(); +X } +X +X if (!isroot() && NULL != thisgroup) { +X fprintf(stderr, "Only root can add members to different groups\n"); +X exit(EXIT_NOT_ROOT); +X } else if (isroot() && NULL != thisgroup) { +X name = thisgroup; +X } else if (!isgroup()) { +X fprintf(stderr, "Group access is required\n"); +X exit(EXIT_NOT_EROOT); +X } else if (NULL == (name = whoami())) { +X fprintf(stderr, "Not primary owner of current group\n"); +X exit(EXIT_NOT_PRIMARY); +X } +X +X if (!gr_lock()) { +X fprintf(stderr, "Unable to lock group file\n"); +X exit(EXIT_GROUP_FILE); +X } +X +X if (!gr_open(O_RDWR)) { +X fprintf(stderr, "Unable to open group file\n"); +X exit(EXIT_GROUP_FILE); +X } +X +X grp = (struct group *)gr_locate(name); +X +X if (NULL != adduser) { +X addtogroup(adduser, grp->gr_mem); +X gr_update(grp); +X } else if (NULL != deluser) { +X rmfromgroup(deluser, grp->gr_mem); +X gr_update(grp); +X } else if (purge) { +X nomembers(grp->gr_mem); +X gr_update(grp); +X } else if (list) { +X members(grp->gr_mem); +X } +X +X if (!gr_close()) { +X fprintf(stderr, "Cannot close group file\n"); +X exit(EXIT_GROUP_FILE); +X } +X +X gr_unlock(); +X +X exit(EXIT_SUCCESS); +} +X +/* EOF */ +SHAR_EOF + (set 20 00 05 25 14 36 38 'groupmems.c'; eval "$shar_touch") && + chmod 0644 'groupmems.c' || + $echo 'restore of' 'groupmems.c' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'groupmems.c:' 'MD5 check failed' +f0dd68f8d762d89d24d3ce1f4141f981 groupmems.c +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.c'`" + test 6348 -eq "$shar_count" || + $echo 'groupmems.c:' 'original size' '6348,' 'current size' "$shar_count!" + fi +fi +# ============= groupmems.8 ============== +if test -f 'groupmems.8' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'groupmems.8' '(file already exists)' +else + $echo 'x -' extracting 'groupmems.8' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'groupmems.8' && +X.\" +X.\" Copyright 2000, International Business Machines, Inc. +X.\" All rights reserved. +X.\" +X.\" original author: George Kraft IV, gk4@us.ibm.com +X.\" +X.\" Redistribution and use in source and binary forms, with or without +X.\" modification, are permitted provided that the following conditions +X.\" are met: +X.\" +X.\" 1. Redistributions of source code must retain the above copyright +X.\" notice, this list of conditions and the following disclaimer. +X.\" 2. Redistributions in binary form must reproduce the above copyright +X.\" notice, this list of conditions and the following disclaimer in the +X.\" documentation and/or other materials provided with the distribution. +X.\" 3. Neither the name of International Business Machines, Inc., nor the +X.\" names of its contributors may be used to endorse or promote products +X.\" derived from this software without specific prior written permission. +X.\" +X.\" THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND +X.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +X.\" BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +X.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +X.\" INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE +X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +X.\" SUCH DAMAGE. +X.\" +X.\" $Id: groupmems.shar,v 1.1 2000/08/26 18:37:32 marekm Exp $ +X.\" +X.TH GROUPMEMS 8 +X.SH NAME +groupmems \- Administer members of a user's primary group +X.SH SYNOPSIS +X.B groupmems +\fB-a\fI user_name \fR | +\fB-d\fI user_name \fR | +\fB-l\fR | +\fB-D\fR | +[\fB-g\fI group_name \fR] +X.SH DESCRIPTION +The \fBgroupmems\fR utility allows a user to administer his/her own +group membership list without the requirement of super user privileges. +The \fBgroupmems\fR utility is for systems that configure its users to +be in their own name sake primary group (i.e., guest / guest). +X.P +Only the super user, as administrator, can use \fBgroupmems\fR to alter +the memberships of other groups. +X.IP "\fB-a \fIuser_name\fR" +Add a new user to the group membership list. +X.IP "\fB-d \fIuser_name\fR" +Delete a user from the group membership list. +X.IP "\fB-l\fR" +List the group membership list. +X.IP "\fB-D\fR" +Delete all users from the group membership list. +X.IP "\fB-g \fIgroup_name\fR" +The super user can specify which group membership list to modify. +X.SH SETUP +The \fBgroupmems\fR executable should be in mode \fB2770\fR as user \fBroot\fR +and in group \fBgroups\fR. The system administrator can add users to +group groups to allow or disallow them using the \fBgroupmems\fR utility +to manager their own group membership list. +X.P +X $ groupadd -r groups +X.br +X $ chmod 2770 groupmems +X.br +X $ chown root.groups groupmems +X.br +X $ groupmems -g groups -a gk4 +X.SH FILES +/etc/group +X.br +/etc/gshadow +X.SH SEE ALSO +X.BR chfn (1), +X.BR chsh (1), +X.BR useradd (8), +X.BR userdel (8), +X.BR usermod (8), +X.BR passwd (1), +X.BR groupadd (8), +X.BR groupdel (8) +X.SH AUTHOR +George Kraft IV (gk4@us.ibm.com) +X.\" EOF +SHAR_EOF + (set 20 00 05 25 14 38 23 'groupmems.8'; eval "$shar_touch") && + chmod 0600 'groupmems.8' || + $echo 'restore of' 'groupmems.8' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'groupmems.8:' 'MD5 check failed' +181e6cd3a3c9d3df320197fa2cde2b4a groupmems.8 +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.8'`" + test 3372 -eq "$shar_count" || + $echo 'groupmems.8:' 'original size' '3372,' 'current size' "$shar_count!" + fi +fi +rm -fr _sh10937 +exit 0 diff --git a/current/contrib/pwdauth.c b/current/contrib/pwdauth.c new file mode 100644 index 00000000..1bedf6bb --- /dev/null +++ b/current/contrib/pwdauth.c @@ -0,0 +1,308 @@ +/* + * pwdauth.c - program to verify a given username/password pair. + * + * Run it with username in argv[1] (may be omitted - default is the + * current user), and send it the password over a pipe on stdin. + * Exit status: 0 - correct password, 1 - wrong password, >1 - other + * errors. For use with shadow passwords, this program should be + * installed setuid root. + * + * This can be used, for example, by xlock - you don't have to install + * this large and complex (== possibly insecure) program setuid root, + * just modify it to run this simple program to do the authentication. + * + * Recent versions (xlockmore-3.9) are cleaner, and drop privileges as + * soon as possible after getting the user's encrypted password. + * Using this program probably doesn't make it more secure, and has one + * disadvantage: since we don't get the encrypted user's password at + * startup (but at the time the user is authenticated), it is not clear + * how we should handle errors (like getpwnam() returning NULL). + * - fail the authentication? Problem: no way to unlock (other than kill + * the process from somewhere else) if the NIS server stops responding. + * - succeed and unlock? Problem: it's too easy to unlock by unplugging + * the box from the network and waiting until NIS times out... + * + * This program is Copyright (C) 1996 Marek Michalkiewicz + * . + * + * It may be used and distributed freely for any purposes. There is no + * warranty - use at your own risk. I am not liable for any damages etc. + * If you improve it, please send me your changes. + */ + +static char rcsid[] = "$Id: pwdauth.c,v 1.2 1997/12/07 23:26:45 marekm Exp $"; + +/* + * Define USE_SYSLOG to use syslog() to log successful and failed + * authentication. This should be safe even if your system has + * the infamous syslog buffer overrun security problem... + */ +#define USE_SYSLOG + +/* + * Define HAVE_GETSPNAM to get shadow passwords using getspnam(). + * Some systems don't have getspnam(), but getpwnam() returns + * encrypted passwords only if running as root. + * + * According to the xlock source (not tested, except Linux) - + * define: Linux, Solaris 2.x, SVR4, ... + * undef: HP-UX with Secured Passwords, FreeBSD, NetBSD, QNX. + * Known not supported (yet): Ultrix, OSF/1, SCO. + */ +#define HAVE_GETSPNAM + +/* + * Define HAVE_PW_ENCRYPT to use pw_encrypt() instead of crypt(). + * pw_encrypt() is like the standard crypt(), except that it may + * support better password hashing algorithms. + * + * Define if linking with libshadow.a from the shadow password + * suite (Linux, SunOS 4.x?). + */ +#undef HAVE_PW_ENCRYPT + +/* + * Define HAVE_AUTH_METHODS to support the shadow suite specific + * extension: the encrypted password field contains a list of + * administrator defined authentication methods, separated by + * semicolons. This program only supports the standard password + * authentication method (a string that doesn't start with '@'). + */ +#undef HAVE_AUTH_METHODS + +/* + * FAIL_DELAY - number of seconds to sleep before exiting if the + * password was wrong, to slow down password guessing attempts. + */ +#define FAIL_DELAY 2 + +/* No user-serviceable parts below :-). */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_SYSLOG +#include +#ifndef LOG_AUTHPRIV +#define LOG_AUTHPRIV LOG_AUTH +#endif +#endif + +#ifdef HAVE_GETSPNAM +#include +#endif + +#ifdef HAVE_PW_ENCRYPT +extern char *pw_encrypt(); +#define crypt pw_encrypt +#endif + +/* + * Read the password (one line) from fp. We don't turn off echo + * because we expect input from a pipe. + */ +static char * +get_line(fp) + FILE *fp; +{ + static char buf[128]; + char *cp; + int ch; + + cp = buf; + while ((ch = getc(fp)) != EOF && ch != '\0' && ch != '\n') { + if (cp >= buf + sizeof buf - 1) + break; + *cp++ = ch; + } + *cp = '\0'; + return buf; +} + +/* + * Get the password file entry for the current user. If the name + * returned by getlogin() is correct (matches the current real uid), + * return the entry for that user. Otherwise, return the entry (if + * any) matching the current real uid. Return NULL on failure. + */ +static struct passwd * +get_my_pwent() +{ + uid_t uid = getuid(); + char *name = getlogin(); + + if (name && *name) { + struct passwd *pw = getpwnam(name); + + if (pw && pw->pw_uid == uid) + return pw; + } + return getpwuid(uid); +} + +/* + * Verify the password. The system-dependent shadow support is here. + */ +static int +password_auth_ok(pw, pass) + const struct passwd *pw; + const char *pass; +{ + int result; + char *cp; +#ifdef HAVE_AUTH_METHODS + char *buf; +#endif +#ifdef HAVE_GETSPNAM + struct spwd *sp; +#endif + + if (pw) { +#ifdef HAVE_GETSPNAM + sp = getspnam(pw->pw_name); + if (sp) + cp = sp->sp_pwdp; + else +#endif + cp = pw->pw_passwd; + } else + cp = "xx"; + +#ifdef HAVE_AUTH_METHODS + buf = strdup(cp); /* will be modified by strtok() */ + if (!buf) { + fprintf(stderr, "Out of memory.\n"); + exit(13); + } + cp = strtok(buf, ";"); + while (cp && *cp == '@') + cp = strtok(NULL, ";"); + + /* fail if no password authentication for this user */ + if (!cp) + cp = "xx"; +#endif + + if (*pass || *cp) + result = (strcmp(crypt(pass, cp), cp) == 0); + else + result = 1; /* user with no password */ + +#ifdef HAVE_AUTH_METHODS + free(buf); +#endif + return result; +} + +/* + * Main program. + */ +int +main(argc, argv) + int argc; + char **argv; +{ + struct passwd *pw; + char *pass, *name; + char myname[32]; + +#ifdef USE_SYSLOG + openlog("pwdauth", LOG_PID | LOG_CONS, LOG_AUTHPRIV); +#endif + pw = get_my_pwent(); + if (!pw) { +#ifdef USE_SYSLOG + syslog(LOG_ERR, "can't get login name for uid %d.\n", + (int) getuid()); +#endif + fprintf(stderr, "Who are you?\n"); + exit(2); + } + strncpy(myname, pw->pw_name, sizeof myname - 1); + myname[sizeof myname - 1] = '\0'; + name = myname; + + if (argc > 1) { + name = argv[1]; + pw = getpwnam(name); + } + + pass = get_line(stdin); + if (password_auth_ok(pw, pass)) { +#ifdef USE_SYSLOG + syslog(pw->pw_uid ? LOG_INFO : LOG_NOTICE, + "user `%s' entered correct password for `%.32s'.\n", + myname, name); +#endif + exit(0); + } +#ifdef USE_SYSLOG + /* be careful not to overrun the syslog buffer */ + syslog((!pw || pw->pw_uid) ? LOG_NOTICE : LOG_WARNING, + "user `%s' entered incorrect password for `%.32s'.\n", + myname, name); +#endif +#ifdef FAIL_DELAY + sleep(FAIL_DELAY); +#endif + fprintf(stderr, "Wrong password.\n"); + exit(1); +} + +#if 0 +/* + * You can use code similar to the following to run this program. + * Return values: >=0 - program exit status (use the + * macros to get the exit code, it is shifted left by 8 bits), + * -1 - check errno. + */ +int +verify_password(const char *username, const char *password) +{ + int pipe_fd[2]; + int pid, wpid, status; + + if (pipe(pipe_fd)) + return -1; + + if ((pid = fork()) == 0) { + char *arg[3]; + char *env[1]; + + /* child */ + close(pipe_fd[1]); + if (pipe_fd[0] != 0) { + if (dup2(pipe_fd[0], 0) != 0) + _exit(127); + close(pipe_fd[0]); + } + arg[0] = "/usr/bin/pwdauth"; + arg[1] = username; + arg[2] = NULL; + env[0] = NULL; + execve(arg[0], arg, env); + _exit(127); + } else if (pid == -1) { + /* error */ + close(pipe_fd[0]); + close(pipe_fd[1]); + return -1; + } + /* parent */ + close(pipe_fd[0]); + write(pipe_fd[1], password, strlen(password)); + write(pipe_fd[1], "\n", 1); + close(pipe_fd[1]); + + while ((wpid = wait(&status)) != pid) { + if (wpid == -1) + return -1; + } + return status; +} +#endif diff --git a/current/contrib/rpasswd.c b/current/contrib/rpasswd.c new file mode 100644 index 00000000..da6b77c0 --- /dev/null +++ b/current/contrib/rpasswd.c @@ -0,0 +1,591 @@ +/* rpasswd.c -- restricted `passwd' wrapper. + Copyright (C) 1996 Adam Solesby, Joshua Cowan + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This program is meant to be a wrapper for use with `sudo' and your + system's `passwd' program. It is *probably* secure, but there is no + warranty (see above). If you find errors or security holes, please + email me; please include a complete description of the problem in + your message in addition to any patches. */ + +/* This program currently assumes that the arguments given on the + command line are user names to pass to the `passwd' program; it loops + through the arguments calling `passwd' on each one. It might be + better to pass all remaining arguments after `--' to `passwd' (to + e.g., change the user's shell instead of the password by giving it + the `-s' option). */ + +/* Written by Adam Solesby . */ +/* Rewritten by Joshua Cowan . */ + +/* Usage: rpasswd USERNAME... + Enforce password-changing guidelines. + + --check[=file] check configuration information; if FILE is given, + use that instead of the standard configuration + file `./rpasswd.conf' + --help display this help and exit + --version output version information and exit + + You may never change a superuser's password with this command. + Changing certain other users' passwords may also be forbidden; for + details of who's passwords may not be changed, try `rpasswd --check'. */ + +/* TODO: + + - Make this more portable. It currently depends on several + GNU/Linux-specific features. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* This is the absolute path to the `passwd' program on your system. */ +#define _PATH_PASSWD "/usr/bin/passwd" + +/* This is the absolute path to the configuration file. */ +#define _PATH_RPASSWD_CONF "/etc/rpasswd.conf" + +/* Don't change the password of any user with a uid equal to or below + this number--no matter what the configuration file says. */ +#define UID_PWD_CHANGE_FLOOR 100 + +/* Everything past this point should probably be left alone. */ + +/* These are the facility and priority (respectively) used by the syslog + functions. */ +#define LOG_FACILITY LOG_AUTH +#define LOG_PRIORITY LOG_WARNING + +/* The name this program was run with. */ +char *program_name; + +/* The version information for this program. */ +char *version_string = "1.2"; + +/* If nonzero, display usage information and exit. */ +static int show_help; + +/* If nonzero, print the version on standard output then exit. */ +static int show_version; + +/* If nonzero, check the configuration file for errors and print the + list of restrictions on the standard output, then exit. */ +static int check_only; + +struct user_list +{ + char *name; + struct user_list *next; +}; + +struct config_info +{ + /* Don't change the password for any user with a uid less than or + equal to this number. */ + uid_t minimum_uid; + + /* Don't change the password for any user matching this list of user + names. */ + struct user_list *inviolate_user_names; +}; + +static const struct option long_options[] = +{ + {"check", optional_argument, 0, 10}, + {"version", no_argument, &show_version, 1}, + {"help", no_argument, &show_help, 1}, + {0, 0, 0, 0} +}; + +static struct config_info *get_config_info (); +static int dump_config_info (); +static void *xmalloc (); +static void *xrealloc (); +static void xsyslog (int, const char *, ...); +static void dal_error (int, int, const char *, ...); + +static void +usage (status) + int status; +{ + if (status != 0) + fprintf (stderr, "Try `%s --help' for more information.\n", + program_name); + else + { + printf ("Usage: %s USERNAME...\n", program_name); + fputs ("\ +Enforce password-changing guidelines.\n\ +\n\ + --check[=file] check configuration information; if FILE is given,\n\ + use that instead of the standard configuration file\n\ + `"_PATH_RPASSWD_CONF"'\n\ + --help display this help and exit\n\ + --version output version information and exit\n", + stdout); + + printf ("\n\ +You may never change a superuser's password with this command. Changing\n\ +certain other users' passwords may also be forbidden; for details of\n\ +who's passwords may not be changed, try `%s --check'.\n", + program_name); + } + + exit (status); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *executing_user_name; + char *config_file_name = _PATH_RPASSWD_CONF; + int opt; + struct config_info *config; + + /* Setting values of global variables. */ + program_name = argv[0]; + + while ((opt = getopt_long (argc, argv, "", long_options, 0)) + != EOF) + switch (opt) + { + case 0: + break; + + case 10: + check_only = 1; + if (optarg) + config_file_name = optarg; + break; + + default: + usage (1); + } + + if (show_version) + { + printf ("rpasswd %s\n", version_string); + return 0; + } + + if (show_help) + { + usage (0); + } + + if (check_only) + { + dump_config_info (config_file_name); + exit (0); + } + + if (optind >= argc) + { + fprintf (stderr, "%s: missing argument\n", program_name); + usage (1); + } + + /* FIXME: does `sudo' set the real user id to the effective user id? + If so, this won't work as intended: We want to get the name of the + user who ran `sudo'. I am reluctant to use `getlogin' for obvious + reasons, but it may be better than nothing. Maybe someone who + actually has `sudo' installed can tell me if this works, or how to + fix it if it doesn't. --JC */ + do + { + struct passwd *pwd; + uid_t uid = getuid (); + + pwd = getpwuid (uid); + + if (!pwd || !pwd->pw_name) + { + xsyslog (LOG_PRIORITY, + "Unknown user (uid #%d) attempted to change password for `%s'.", + uid, argv[optind]); + fprintf (stderr, "%s: you do not exist, go away\n", + program_name); + exit (1); + } + else + executing_user_name = pwd->pw_name; + } + while (0); + + config = get_config_info (config_file_name); + + for (; optind < argc; optind++) + { + int immutable_p = 0; + struct user_list *user_names = config->inviolate_user_names; + + /* Make sure we weren't given an illegal user name. */ + for (; user_names; user_names = user_names->next) + { + if (strcmp (argv[optind], user_names->name) + == 0) + { + immutable_p = 1; + break; + } + } + + if (!immutable_p) + { + struct passwd *pwd; + + pwd = getpwnam (argv[optind]); + + if (!pwd) + { + fprintf (stderr, "%s: invalid user `%s'\n", + program_name, argv[optind]); + + continue; + } + else if (pwd->pw_uid <= config->minimum_uid) + immutable_p = 1; + } + + if (immutable_p) + { + xsyslog (LOG_PRIORITY, + "`%s' attempted to change password for `%s'.", + executing_user_name, argv[optind]); + fprintf (stderr, + "You are not allowed to change the password for `%s'.\n", + argv[optind]); + } + else + { + int pid, status; + + pid = fork (); + switch (pid) + { + case -1: + dal_error (1, errno, "cannot fork"); + + case 0: + execl (_PATH_PASSWD, _PATH_PASSWD, "--", argv[optind], 0); + _exit (1); + + default: + while (wait (&status) != pid) + ; + + if (status & 0xFFFF) + dal_error (1, EIO, "%s", _PATH_PASSWD); + + break; + } + } + } + + exit (0); +} + +/* Get configuration information from FILE and return a pointer to a + `config_info' structure containing that information. It currently + does minimal checking of the validity of the information. + + This function never returns NULL, even when the configuration file is + empty. If the configuration file doesn't exist, it just exits with a + failed exit status. */ + +static struct config_info * +get_config_info (file) + const char *const file; +{ + FILE *config_file; + struct config_info *config; + char linebuf[BUFSIZ]; + unsigned int lineno = 0; + + config = (struct config_info *) xmalloc (sizeof (struct config_info)); + config->minimum_uid = (uid_t) 0; + config->inviolate_user_names = 0; + + config_file = fopen (file, "r"); + if (!config_file) + dal_error (1, errno, "%s", file); + + if (fseek (config_file, 0L, SEEK_SET)) + dal_error (1, errno, "%s", file); + + while (fgets (linebuf, BUFSIZ, config_file)) + { + int len, i, uid_found = 0; + + lineno++; + + len = strlen (linebuf); + + /* Chomp any whitespace off the end of the line. */ + while (isspace (linebuf[len - 1])) + linebuf[--len] = '\0'; + + /* If this line is empty or a comment, skip it and go to the next. */ + if (len == 0 || *linebuf == '#') + continue; + + for (i = 0; i < len; i++) + if (!isalnum (linebuf[i]) + && linebuf[i] != '.' + && linebuf[i] != '-' + && linebuf[i] != '_') + { + dal_error (1, 0, "%s:%u: invalid user name `%s'", + file, lineno, linebuf); + } + + /* Only accept positive integers as candidates for `minimum_uid'. */ + for (i = 0; i < len; i++) + if (!isdigit (linebuf[i])) + break; + + if (!uid_found && i == len) + { + unsigned long num; + + errno = 0; + num = strtoul (linebuf, 0, 10); + config->minimum_uid = (uid_t) num; + + if (errno || config->minimum_uid != num) + dal_error (1, 0, "%s:%u: `%s' out of range", + file, lineno, linebuf); + + uid_found = 1; + } + else + { + struct user_list *tail = config->inviolate_user_names; + struct user_list *user_names = 0; + + /* This could be more efficient, but makes the list of users + printed out with the `--check' switch easier to read. */ + + for (; tail; tail = tail->next) + { + if (strcmp (linebuf, tail->name) == 0) + break; + + user_names = tail; + } + + if (!tail) + { + tail = user_names; + + user_names = xmalloc (sizeof (struct user_list)); + user_names->name = strcpy (xmalloc (len + 1), linebuf); + user_names->next = 0; + + if (!config->inviolate_user_names) + config->inviolate_user_names = user_names; + else + tail->next = user_names; + } + } + } + + fclose (config_file); + + if (config->minimum_uid < UID_PWD_CHANGE_FLOOR) + config->minimum_uid = UID_PWD_CHANGE_FLOOR; + + return config; +} + +/* Dump the configuration info contained in FILE to the standard output. */ + +static int +dump_config_info (file) + char *file; +{ + struct config_info *config; + + config = get_config_info (file); + + printf ("\ +The lowest uid who's password may be changed is number %d. Changing +the following users' passwords is also forbidden:\n", + config->minimum_uid + 1); + + if (!config->inviolate_user_names) + { + printf ("\n (no users listed in configuration file `%s')\n", + file); + } + else + { + int column; + struct user_list *user_names = config->inviolate_user_names; + + for (column = 73; user_names; user_names = user_names->next) + { + int name_len = strlen (user_names->name); + + if (user_names->next) + name_len++; + + column += name_len; + + if (column > 72) + { + fputs ("\n ", stdout); + column = name_len + 2; + } + else if (column - name_len > 0) + { + fputc (' ', stdout); + column++; + } + + fputs (user_names->name, stdout); + + if (user_names->next) + fputc (',', stdout); + } + + fputc ('\n', stdout); + } + + return 0; +} + +static void * +xmalloc (n) + size_t n; +{ + void *ptr; + + ptr = malloc (n); + + if (!ptr) + { + fprintf (stderr, "%s: Memory exhausted\n", program_name); + exit (1); + } + + return ptr; +} + +static void * +xrealloc (ptr, n) + void *ptr; + size_t n; +{ + ptr = realloc (ptr, n); + + if (!ptr) + { + fprintf (stderr, "%s: Memory exhausted\n", program_name); + exit (1); + } + + return ptr; +} + +static void +xsyslog (int priority, const char *format, ...) +{ + va_list args; + static int logfd_opened = 0; + + if (!logfd_opened) + { + openlog (program_name, LOG_PID, LOG_FACILITY); + logfd_opened = 1; + } + + va_start (args, format); + vsyslog (priority, format, args); + va_end (args); +} + +/* Format and display MESSAGE on the standard error and send it to the + system logger. If ERRNUM is not 0, append the system error message + corresponding to ERRNUM to the output. If STATUS is not 0, exit with + an exit status of STATUS. */ + +static void +dal_error (int status, int errnum, const char *message, ...) +{ + va_list args; + size_t bufsize; + char *formatted_message; + + fflush (stdout); + + bufsize = strlen (message) * 2; + formatted_message = (char *) xmalloc (bufsize); + + va_start (args, message); + + while (1) + { + int printed; + printed = vsnprintf (formatted_message, bufsize, message, args); + + if ((size_t) printed < bufsize) + break; + + bufsize *= 2; + formatted_message = xrealloc (formatted_message, bufsize); + } + + va_end (args); + + if (errnum) + { + char *error_message = strerror (errnum); + + formatted_message + = xrealloc (formatted_message, + (strlen (formatted_message) + + strlen (error_message) + + 3)); + + strcat (formatted_message, ": "); + strcat (formatted_message, error_message); + } + + fprintf (stderr, "%s: %s\n", program_name, formatted_message); + + xsyslog (LOG_PRIORITY, "%s", formatted_message); + + free (formatted_message); + fflush (stderr); + + if (status) + { + closelog (); + exit (status); + } +} diff --git a/current/contrib/shadow-anonftp.patch b/current/contrib/shadow-anonftp.patch new file mode 100644 index 00000000..6938fe4f --- /dev/null +++ b/current/contrib/shadow-anonftp.patch @@ -0,0 +1,147 @@ +Hello Marek, + +I have created a diffile against the 980403 release that adds +functionality to newusers for automatic handling of users with only +anonomous ftp login (using the guestgroup feature in ftpaccess, which +means that the users home directory looks like '/home/user/./'). It also +adds a commandline argument to specify an initial directory structure +for such users, with a tarball normally containing the bin,lib,etc +directories used in the chrooted environment. + +I am using it to automatically create chunks of users with only ftp +access for a webserver. + +I have tried to follow your coding standards and I believe it is bug +free but.. well, who knows. :) It's not much code however. + +I hope you find it useful. Do what you like with it, feel free to ask if +anything is unclear. + +Best rgds, + Calle Karlsson + ckn@kash.se + +diff -uNr shadow-980403.orig/src/newusers.c shadow-980403/src/newusers.c +--- shadow-980403.orig/src/newusers.c Fri Jan 30 00:22:43 1998 ++++ shadow-980403/src/newusers.c Fri Apr 17 16:55:33 1998 +@@ -76,11 +76,35 @@ + static void + usage(void) + { +- fprintf(stderr, "Usage: %s [ input ]\n", Prog); ++ fprintf (stderr, "Usage: %s [-p prototype tarfile] [ input ]\n", Prog); ++ fprintf (stderr, "The prototype tarfile is only used for users\n"); ++ fprintf (stderr, "marked as anonymous ftp users. It must be a full pathname.\n"); + exit(1); + } + + /* ++ * createuserdir - create a directory and chmod it ++ */ ++ ++static int ++createuserdir (char * dir, int uid, int gid, int line) ++{ ++ if (mkdir (dir, 0777 & ~getdef_num("UMASK", 077))) { ++ fprintf (stderr, "%s: line %d: mkdir %s failed\n", ++ Prog, line, dir); ++ return -1; ++ } ++ ++ if (chown (dir, uid, gid)) { ++ fprintf (stderr, "%s: line %d: chown %s failed\n", ++ Prog, line, dir); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* + * add_group - create a new group or add a user to an existing group + */ + +@@ -328,6 +352,8 @@ + main(int argc, char **argv) + { + char buf[BUFSIZ]; ++ char anonproto[BUFSIZ]; ++ int flag; + char *fields[8]; + int nfields; + char *cp; +@@ -340,12 +366,23 @@ + + Prog = Basename(argv[0]); + +- if (argc > 1 && argv[1][0] == '-') +- usage (); ++ * anonproto = '\0'; ++ ++ while ((flag = getopt (argc, argv, "p:h")) != EOF) { ++ switch (flag) { ++ case 'p': ++ STRFCPY(anonproto, optarg); ++ break; ++ case 'h': ++ default: ++ usage (); ++ break; ++ } ++ } + +- if (argc == 2) { +- if (! freopen (argv[1], "r", stdin)) { +- snprintf(buf, sizeof buf, "%s: %s", Prog, argv[1]); ++ if (optind < argc) { ++ if (! freopen (argv[optind], "r", stdin)) { ++ snprintf(buf, sizeof buf, "%s: %s", Prog, argv[optind]); + perror (buf); + exit (1); + } +@@ -499,15 +536,36 @@ + if (fields[6][0]) + newpw.pw_shell = fields[6]; + +- if (newpw.pw_dir[0] && access(newpw.pw_dir, F_OK)) { +- if (mkdir (newpw.pw_dir, +- 0777 & ~getdef_num("UMASK", 077))) +- fprintf (stderr, "%s: line %d: mkdir failed\n", +- Prog, line); +- else if (chown (newpw.pw_dir, +- newpw.pw_uid, newpw.pw_gid)) +- fprintf (stderr, "%s: line %d: chown failed\n", +- Prog, line); ++ if (newpw.pw_dir[0]) { ++ char * userdir = strdup (newpw.pw_dir); ++ char * anonpart; ++ int rc; ++ ++ if ((anonpart = strstr (userdir, "/./"))) { ++ * anonpart = '\0'; ++ anonpart += 2; ++ } ++ ++ if (access(userdir, F_OK)) ++ rc = createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line); ++ else ++ rc = 0; ++ ++ if (rc == 0 && anonpart) { ++ if (* anonproto) { ++ char cmdbuf [BUFSIZ]; ++ snprintf(cmdbuf, sizeof cmdbuf, ++ "cd %s; tar xf %s", ++ userdir, anonproto); ++ system (cmdbuf); ++ } ++ if (strlen (anonpart) > 1) { ++ strcat (userdir, anonpart); ++ if (access (userdir, F_OK)) ++ createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line); ++ } ++ } ++ free (userdir); + } + + /* diff --git a/current/contrib/udbachk.v012.tgz b/current/contrib/udbachk.v012.tgz new file mode 100644 index 0000000000000000000000000000000000000000..82bd320412905ccc23dd3f557f7943eb25489845 GIT binary patch literal 20228 zcmV((K;XY0iwFSIVs?CKmEWTvDJRM zy)AwcLOk8s%Kg?qZ6S7^KH1*d>2$ZcLUg*_?e+O1A!6`{_02XBvl6N&VFCFbEs#^Pq`xl@tEQi^0M#Vn2{ zu@eYSi6jz3DZCJb>-%y92v&Lh-sW7zn||av{_5&Tj-9!myjWeCxUSHq*mA|jX;*Cc zf!O!}tHs7lj+`*@U_3HFyQ?cIiM?6&+4ZFp0;U+2jk94*0!(;gpj{|qY z4&fKtp#~KjBk@mlrna#;^upb{<^w0hf6wj&l8IZI4+Q!|P02kQ1_IBIkUjqVxRubJ2GKPyCGpM_B&F2}3D* zo;UR_|1-Y!U>U9?0<7RM#(<)tadP9tau*$iaGg-Za^#`YAI=k?Awi6r5U_%1n-6`6CC8pCL-0}#Y>gvoDo0{ScyPsAq@k~A z5N{(u>?9BmcZKv|K2GCf*X*GYHboR8k~+9Oa&gfN*EN9LTj4uNwzRc?{fx^I`boq+ zjb@TPDe!pXfrE$WI#+T$_nU|UfW?QS^LM8g=VJflckyAr*V{ii|9uyLlW7FA@>((~ zFPQlrUIr1ZdJ48GtEyWm5636qEVf=SctODx%k(fHy5)|x8?;2=xgbT)W zzw!`?<456y*aYBAkh=onJp`wwxB*L*n2?mzipw+2HpNlswwmCGwjm=@O6*^QGG9Bv zF!n|h`1Ad~Xm>kLo;Srsf8XW-jS~V&;0%WAj&ze5$l_)tDEcA z4`KoKe1KC#xb?HS`m@JV;^oMT5z+LOH8zn6*l>PKB_l5?4f)=%I2Hrbg|S<;ncU8# zDi4DzF6@(dfy|FUjsQF5#{$eEU?k78X8R4~wxNd_E^$uGg9rR|?)eEEHJ$HJRzg-P zj>hDEZooaD360`t2A(O92527|@|ge%51W`{(Zl z=cj|S{eJ($o0S?RChU7_C7{FJ>BX6bA-`M(>A%~5bNWHUu%oWP!%#wFGGNI52Xrjp zMh#c`Ob#W9-~=-~aqakXiQWm$l$ZyOx@v+iT2sVe1pAcmZT*K0^62oB(kio=o zOiqRaXaOIo2=R&T_D+Tm+?}Qv@cGdMGv|HmXgG)kd~+gQjBDdK3Pc2fP>jJbs#Z}XhrP46N5>%L)5D_^p{0Bb zRU-*e2Zo6s4M9kE3;6Zv$=jpDi{AeE(do$mk-`y3Yf!5u;3}zBb|R@KIpqDW!S^~t zzwAgepW;p-r(D;eD0Bh|^(pwD1i1yl=>%ZFk{5eeWOsL0iMaLPb^s0zJj*UI{W`}T z$aD@-2DZ?D<(dCu6;o>3o&CuGt?;95WS@647_z0iLD)~+gXSI}$QKPc=w-4&-akL4 zaTNe7N9jx`J|l%uzc@-;DL$WtQQsb=Y$EW&xi_*0oG*m|uEwfuJuf1rlXuk|Mr!oWF zx!yqJioK#197On;6Jt>jPv!w6LW-s8VDm}Ca5^veI3uC~kEoBI#oj6(z&~m_Bd9gO zNe&FQCUU(tTKn46P&(#U0L?NW4*C@^lMF^j^9mqkAzBP|m_ebst3bvXh<0C9P}dpM zRQi=Lerd3+tzdu4ed9{*U1AmE6;iW5i@b{DvJ z?cv|fLzmQxkt(7rb&-=NKaZwH2X_z-l4t-Q>+Jf`?3#4A!^Z9^AMzw6yiNmyC?2RL z6TS{}175^YfL$XhgVDH=Zx9(Q5F;=O)sZi;KK5djFszo2i-(;@{4mn1;UA=BvpU=F zb>xl2`j@7#Ki&c;{RJ_R$f%b|(p-|0<1Nni8Kj9y`r|r&wuX5jGG7uN z(9M6~8I;kOE!bMi1DZe`B+3+O-c$HRdl@+Ln25%Z%J`uO4{20~cL;a9bSC3~Vv|O| znNLa1s*@MA>Kabw%9+TVT=W^sjom~sREL_`nPJo@XO{cSjOIT9Or!b$pzWWT4n%@V zsy2HnE5$zKbioX~bA5(A8A!_HhVNa;26u)aqe0feg)7X*%#o^N%=vc}#Yw|>>7|TO z`&20B>+5uI)*IrBcq!5k0J0LxWFEsF8=VHb18imI*WB7`zF2GQCD~{jM!(*}uFi0m zYj8)6qBJCowAdn5U!DW5beOdxsCucz3@pcUPsdrDf*6eg^FZcy#Uvh!P6NC-UdGfB<3|so=AKx4vDV-_2EzCF@h*dC z?0X^<8+v651iLv&g)M}Ro^74RWeocx*-E?EqVEcO1VI~DoYs9dhM zOu)fPcX&&`w6MN|U$?~Ru_z(GAz50Yd@u(8SI?F=NE!q<1{z#@3Y4%ybv;&oxJ5*l zE|7k5{s$Td>PfR^v9dfFFY!a=g&F0UvQXSm#cEhtz&a=icwad z0zM`@Nu*lo9nqO9Fv)d}QEye_BPVeR;gamhM1tRPR#Dl@N%X@OPd!NT2C z2z_a|FsW(U2-I@n*_KuOf{b^zws!5=tO~A}v!WC zT`rea+Ep`7<|*dlIrCp;m`Z5maC`enX~m>^#bm(>tGX^N%N5x$+j){FJ}b6i@=2!6 z*Rh1i&TTu0hmKLLzVg!dFyJ7tNA4!r_DZ!(W&`NJ5zFwpUVC@?{-CDQ3NVe(o!!>i z=9&h&nQQ&ouuhV~);3$Y=2U(W#6-*uKoNRD1H-@J=X9oTd~80b??znYER+r!MiNYM zv)yCE136|Ja!;IG93MBx;~b5vT5vZG_liMsMrtAfnOTiH)2dskBBI>4TbiJgi2I|h zmhdHBEYTH=3GTR|o%$JhQNqN%P01}0&=o!^(LxNkA%Hp5h%b{=G9QnPATejCgR>xe z6dbKB3LCrVNgh8Yzl#A|)j2J&71|WJ6~xS2FXRg`wz0JFLWH>UBqcX%x2$9aSx-|# z$RVe(-gE8ewT8~HG-w(QP@kc2@%;vMo#6-EUYZ0L*=w`I@rHO+w8{?XVP&jbC(OwJ z6!>ucYg;kH!R~&8drzNg&9fW;LXmf?o!KI0Cw$ zLApshoS+I!N^SaKMC-+HXJ@8+6r$~s8sbn6h4y>XoKilDohH&SE-rfO2vnIC@0({G-^^Tf7W>Ip?di7QzAY;B>Aga7C4(C z^Gr;=Q4Vg4-7yp%orJ1=A{nMk1+18Cf2N-1||`uJ4n1fqXbF_-n>QrDLU4(8Bj2CZDe^ zE14fg&g5I@>AySeogehixurZf*@qmjV5il2cZtAiyF5NUIb0sS|E=g#^2yNd!e2=K zzmfdq(EHzt{yoU#;;7_Si$w=u^OwN}p5hK{rdC-N8_;%m7j2VorR@%ErYc$zTmRj` z@$q24cX;vs;N-l2r^T9rYDv@wC$D?IpPh4t4leib-T4Ca#hPr%4Gs?uPy3Mj9~{3~ zM0mcOTZk7HK)k24R@dk)@h%92y73Zsx4{29Va&7; zh3FTmv>SYVa^-R6c|+AE-&}*Le4PU`4zoXO>f@(6Q~aoJ)sYz#mycF&D=ieMxa1{7 zIpFKJRAN0yC}KAR)8ncee0=1@Azo$=u_oaXS+137MvD4_qkiw;uufYwiZ>cKdwlXY zGrL-8cW-e6wkm$xt8Rl~gl{MD%9IQZiM4V6QH^QemvQnyJXGfOm$nq_k=r=QbjatJp>J%chQ317A#05^;Jg(rgdYF#bYUr?gT8RauT_Vx5M69HE#=8 zTL9l(#MuJ)PJyu;y}+OS+0q?r-&P)v+{NMP`MXLE7cjU0yt{zE1>l{6-k3~OoQ@kb zof+|7-drK7RvGo<{BpcC!Y52OQ%MgYbB7fUDa9Uo6U^t+l3PaXgFQPSRyvV03ok@5 z%Yo1~4_i-0bX^5R+*;2saXj@fR#a`~9wFp(s~?79P*r5p> zA?&3SChOt?!iVp8VG~tG-C#%Qd)q0t zw8c$~JzV|RG#c}TFurfcAN~Ck&iU}$Cuj_q(&8NmNyZ5wa}A}7Us#B51?N+-oJDbB zQ0R@vs3hK5Khd?`5CSnXP>=a;s0?PwZOb;c+?&0|J?Ti6SL?nvke=fc>~RG4n6jJZ z)?{?~y}%7sJQ&O;))2wx9zUVL`b+c276N}MPC!E`N8l9rdp?D5U3gZ(OP@5Xu)PRq z%N&Gz+t^@)+{?~-TO=ApNrWqn|M{jD1{ch^*!X6k(_e3+3b-_6RYrrD`c?(SqX z?QG>~dd{~P%j}O%4^Ii$ckJ?4U(GGeJ(TF$bU8!MZ3bDkoZ##CCAK2<>KYtVO5+U+ zy6%*9jUzdiXO#1oEnvH30gHhvR8xE%QLU$ID6K|SoO`KMTjDHI82O-R1_?tXq1jy2wPe z@!(z=tAE;b4$CAz`B5YvekYQ#byOsJYbm1n`4RV+AV{arp~{#4Hty~8wvNL1CB_-- z(`c-_)%y?uEBO_<>rOuN6!D8Y?kv4ymU`@o4RUK%GSXQ<+NZE|^C?Or>2+Ks3oE(J zbq2|oliB_o+4(5YK~MU4n|5xS!b_$6+b8qjt@ff;eDtO`9#Yh!c2Q)#Z7Zn7z7M`E zz5#3BW5oX^02;J3p70 zzrN%IobzubY8B+Ys(e56UC7hlC8?yYf)W$4O!Qh}W9>~S_soI;L{U4%E7I+{^WE z(;_RqP0T>=N=(ZsTOnrXA~|gx$}gTuGDb{~bR}hh{9T)a)#lpw*xNL5!BGxXo zuAag)4gdoOlc4qmjOBE3wU=>WExY;7=1xGX=}X_b0IpS6V88muHb%)->kb# zZ;<@-!SE#)xuuuAsaGUQGfNFAX*R)CMFM@e{{A;L9JqsE)$_SD1}t(Soe&vR-(G-_m)F7 zXH8&xrtD5 ztv2BpbiIT_vDLy@Kd>{7Lp+AS)sy~)EC4@^&7)YJc{YAwZKM#yvh#M>cPypPGW1eo zX|(XAWLHPslmd|xPRUSA0W^s-47DzRH;cI;oDjz)5H!(`3u{ERm$D@Ph+c|Gn9V1& z27pYC6Vn~3XH7MI%3zsG09MkPOO6;ZAR?Zhl9@@7`=^ILk!R|4D@19E$DIk6jse}6 z&EXHwDkP^&t5C7Fp|?p;r1ose*}u6Z+y&1UwS>Q0X7w&=6<*869)70*{2q2^UNzVF z%oAqp5;bv|aoI~lD=j)VFP505Z_vAsA+s{R`+v}A2@KFh;$36#;jMKq6K#d1Vna61 zB4zc@MtzjGc8FP=B?QgQ@NZth z^{F7{!6Y=;|rPk?wn+oAt3Ko>c~UZ`+JNdzAD18H*GT_|Oiuvp6O5!6f4?xKM_ zcjaNEiVHEjqC=_EWR_a%^hGSp$RZbTf8kIbyD;$pa1XJRb>PW$Oz{l3s^K{5UEx!X z28>`W9p4Fj(#JKX^bg>VR^du8LMXwc9SxLUDH)@UNx=_MtaOENlQL)p>rFoy)}+6( z5Ge%+Dv|@eM_-jJc+QFHv2bom`S5BZ!~wJW(_wx%`1Sf~z2?>D zsfAknVaHJH9@6UO*<0BtT^RF6e8yqH@Z1t{l$3W~!3LL??A=HGN3ZTk@bOcF%84q= zl6JggpSwTxQe*rCo_q9L`Ssz#&&#lw5-bq5v;h$IlRgPylAp=q-4a;2-`%Ur;pcSe zLioWw=AYA}2igaBdH7kA{B3;>sLw%fl;*Kz9`v$HML6opZ+-n{-Pq2ZcV)E3YFtuD zTR;<#K#~m@=^uPH)p%(!_u+jMgtq(f^)|OmEXW;!u@G00J4ywtnC~^sS1a$Z4IH&! zW9Q@7uIM!`*;Db7EoxtSXSb@90!80*Ofy$DggCZ!|Oz87^qU`WIv;`blkG@VrUz^mY|nR2{Zj?4p>L=w+&@IAgyz zc)m!Wv2`&OPb?<+k?7^Ix*|$>QqCsgSsBrwIHyutqMz|*t%~X!ykkzT&ES5Ma>u%S zR>K9;VhN|TT2)gUE}R=Ra`%!we15}46QpPy5;uNHyG|Ah+c?=u0HO@-7~W>^>jGXs zNkK(wjnRe^O^lTF){#=kA|qSH(pxFUWy)~b0$f^p%PqR)>Qa@_!0wR=<7hIcVAq?g zTQ7pL8aN1gLum>cC8eFizHll(EuWT9dwJk&bh8yp@9GnmDi|y%y18 zaSK6Ft^k#@76E^KGf(=cp=fnc4i&!PqCLgpT3E$~)GAk;wg`lwo{M(lPeG~N+fNg? zSqPryo8>nP!P4No%LPdQ51EjTveEBz zEeSGAP39cqh7UatHbvm+CnK!ej5R3Gfo?x0UnP~E!~&GGg~fU%EwW2TRX{9ao%S}$ zOOB4FWoZbOnC<_J-!U)JMSxX1*jl*zm5mFr0o( z%A=T@>tFx)pRcGe%AaW1KPKTfJ{poz;ZzYcmJbZ6yL0wb3vz>Kxwpuaj^LmT^e<&G z1=jrG@N++;QB-}p;UZUYuGpHbSE;C{Ov&-Mk-$O+e1OiAOi4(YCb2nrg+7sxXQG7# zPtrzlU`{z6!E|ARxZw|t+g zONws_rbJX&1v*15ajxGj4*2tvVaSkbfyJYvkx)C70&d6TgWp#oKX+LUKYv+<I%QF03m&N4ae9prBQLDu+q+*7^Z6wNd3S@5c zcZDcV&&idxa9v7ymw}qoDmbWnp2wp&&$TQA0WphX+|irGrErV}UY>7B)iI^8tynLF zl?d~0sbx`VsynDsk4z8dq3HtOsD*C6^=ZlnDxr~I#UEIrX_`#91RB<;a3?>kn0z5% z!yjA)0HoHor^qm~a3z6!rpOEuXC9-9>K6Ew<`qc~S*7>odm>oto~Z z*KfqBhALiU?pxSPx!N%mYNJ%;Sd52S#W>BDld@OHp)~j;wTJH)lk5~hE@f1H-D7U7`-CghR0Z9e(3f6S(95#SFWdbC6Tr%& zawCv zyZ)z>?B_;s@3|Oi0p{VVX8QGhryRcpOUxlNc2%p&lUuWi87_y*JicR??<%7O1+H!o z5InFWG|nRCE%M9Z4Lb(ZM-(5&$LHwLInE|TVnj*hBo%T59Tjb$?#IcjIPrxz`>p5n z(9&*SG^fmtyJEe}NVdFRi_*=!!GGtCee@;AE(vG%8v25Y<3kC^+ZU3k5TSGNmro_K4i+U9mu7d1V%}u8uSwZ>=OLiOPoT_#2 z+jTm_b)I!|ISX{t*{Fqi`4C$&j0NI{uLZTqT2~NmY?%}?<&~wEC3aO~&9a*$uM`=L zh+H(2dXTO*uZnzJWhHfXk$i93TWlURgA#4dv5(rE>3f<)3HuAqdudh%{blT|J%>tE zSXY;=!y@5Rg)qaJtgY1^OX3?_J=|FHU@0qwwvS$gb=9``*fFo#yJTM#1FORB#~!bz ztnkm`!f6d;mb3wsH_|DWlj3+&O;nnc4l5Dog$_aMlpA;179QoH)J2DDmC91B@`}wz z`*Mjz_};rmjJyP1hdABWIP5BzOH8~L)YbOgyG&GvXk#f4pU?{JR6Vv+A%1=hQ?MvO!Kmf7@7bIKHWU=*@bV9dhh+=83c`}IyMUj;H0 z!Kcu(!1IlJi*}H^xi)$Z$uwI`je8!Liw3?TlphLVM~HO{eLk?4Qh`d5+23TE!xl4I zQlN*}|N5Sj*}ASPF}KI@?$S$<`LY8TtyUJJ!|m|o!|~}J){fgn$&6M{@V>%6>)}6U zq0yScgL-lu;l zeQCnXBkP=@^MwAaw-7*kuT4U9RcGHV?o6SxxH}w9MQ5f=0SUe39ICrK5EN=& z3{CJtZdgQe-n4r_3f#GqG%<(<^#7!qG9&lUCSOx5RP$xd?;Su^h-{+jfQa?cC{LG! zR#b_8RkEfTN?`-4J=5P2F0Pk$#WKl+DVlBtvkeIAU%Lh~n!^}RRkxu87|c$?#ejm! z^cC++Ha(BciXtwTFBO7A6si)Wiqb^+0Iia|;TOZX2dBC-5JXbM@X$Xh2?&odDruBZ znvXds*h87RN!_J1fLR(~DeE}uU0GwOuPbmVom;o{?vBD8 zfx^?LA_}93lLn|0O&p*sf?wur-MCSK=%yYvX6F2O@?Ahf13K#$6CSVyMRF=NFiAtK zZ4Cn7n9p^iG$`m~N*OblMhtr+&CMhcB*|osfJLx$qrM&(9A5(|X=zjp+2!(C1X3Gq z?Yx&ov#UC_aUqBQ(BU6$-KT{JA!d5qDs09#+Kh-}cz4saCzvnX_~`rU5{2+%p(!R3 zoSWYIPLJL5C4cXfTw}S?Zx8{Do574$yb?C@T-_A%op10(SA}WGe?z<&{!Q1nB3W{4 z+g`@HG3Ee1kV8;u<2at&QvOoT_l;YL7IH9}=T};^(d-&?J|4|M{9U-;3pC|hC)LcM zi>1SOfpG0j3ua?5bRbQz+_lNZq1Xy%t=W+g{A6NBFXe10r zo-qvBf_MjHlHb(kZCaS;rerR8(Upbh&!+} zf3L}`H20%y7%OP@9z`j}a=8T(rXE|DW3I@ADP0;1=eJCcUYEj9JW^?+Pn6^QNd{dR zdP3h?W>g%fVI}h3$QwvJOZXRH$8Jd!yR^O6Zjb{3ThtlU9+9ly zq~Ro%4mJuA{;u5SjH-~x;6dpNB{MkFCQ9KV-@<%`#hC&gSniW4kUMp0a=#VX5LN8f z1O7Lrf z?4$|uojU5`nH;BL@~!ZEf^>GJd<)NXnZyYl%)-kz_RLVxK?3ldb=+6A0L2V_fvjRW{WxCmDEYhc$G!U zV{>*l*49hVjt^w^#+Kq+yQ2?l!SzZ8RGSXI+?-1Ggu87CrD6T$%MYu<#&DN?f%lU2 z{tAv&x@fA4mC~+r_xK%dnWE9*UNpd8U9s)cSk(+!WC}&6ZPE3|gq5T;HNj&>w~M7@ zj+A}=E|%g(6x9y`9N_Lpwt~~)5}X`DT05O6IF3L;fj`m4ITNj%sy7wHyG1M8`+1p6 zCozzcJ#31gx!D_%NM8(Z&7JjP@Gl;KIiQIOA!$)jRg1I~hg-k1YOG)9=F_k1djpC2 zGS!%B`t*ZXJ^fy<;?dM}$%*uLb$E$yy}~mQe>^+K<4-$37dutMQ>EHut9>%gIEO?L z?8rmnGCj=e7-r_so;X8cKEVHn;Z{G~+R~y?=3*xyr%(X2x8qrFTi&0-`?5v&?1)hR zl~@{Y|IjBx_=NTE1)sQ{Q2GLPz?RIQ`U_`z^2s4~qTej}q}0~{J|r*^#N`jE9OD$% zlDDtnZABMz$=iBAnZV{Avn-B_ffBfUeg&Ts%D9(&&b9S=8Bjl6A5#&Qf*`x|Ar<9< z6--A_9{or1F{uv{7F-D_`ND#?psI!V2VdL4AAXN(-tR`Bqi!F!_M4~s&EKVu-JP9h zPo9K-060B==Kl-VPH=kUj~-M!~KVYvJF@v~=t2zP#$(G;#Z`u)Q254s|Y z-n;Ah|I&+%@Q0_D;bHT%*=`(%=a+8)8A3vcPE)M(aQz@#W3Lwebq*5f?#q|Ezz5N! zoKf!P#{MSUeDShIkHWXG3qWZa%x+M0ev8f{+E2BxHR(yo-OB6P^QYknP@u4J4WxTN z8h5j#KO_w_+}YcG3>{o{8UYL2DMtv>DUGuk^UWSwxus|(=u=%h;{e|6Lic0Q8v>TS zF}4s`>jaO5PJ2|6yG9Z^7Cju&X&Ez9*&4;hxL*(OSOFa8IWX~YcNC*Aa6xWGYAI(; z4a>^pI(t5wI8TNX9^nlA*K|c1e-MWw!3(5GFUPhvA!B;=oyylQ%Ku z1&b$f7LCI5c^A44j%6aqStgu7OMZoUl;KI0F?AI#>k6L*I_9k{^|Mn!ZX&-rog}As zxdb=WoXV-<6bLaS=>-1JLLFK(osLjx!y&d#hO*3fxHH)xzfaS%@d#nI_VYI>@577yYqlX76PfHlO) z0ECNP3^P1~=Br1RmvGNrQ$ETxAi<3a##-!f_KsDxz43(`f;-ueP$6LM7iZTftxCDh znrBZYP)Pn&NZlnR_6libEdPnH{-2CR4%7gQ3;)3nZ*dH9+#`6 z<^dSpq#ppXa>Nb5e?nVbI^mXZ;E2-sM}9=5?=#%ET+W2ws)Mjd-*~;imd@!6dL(yT zTp!<9U%<-m1Kb~4esH%3QOb|?;BXt zSv<{OkqxA0Sfvkjj8NIw+XVQ*J{L4`I1_7G2&0@Ha+ciGtJR84*W49`Hn)il(K5RI z(Wo1v93X^iL4jaQJ|E>e6%~77LX7aV8x`RN;Q|79tXz1Ghzr6L*4!$^=|IQGg`5i1 z9BV77);T2VOck1_Xx`wun?NPFvlrAo*|zFyhGY*4=2F>`;jI};Lr>@AZJ8F zDFfYb&V&wG=_l7opX<$~T_PmhiIHb8>>-Q+H+!_(q0a!x{j40 zLLQDriux$bggwxQWP|_$nGkQku92a*sDYx^BM~={%A@xuo!R&JFp#>+U{hRwvvY|* zr7%OLn%E|86qrHHk}tvafU!;eFDXiUB&+!Tq8Crj4q9(p`whH-W8aY|%?e3Lu#sR56JRlhoYPDg)HD-B z2pMF((@`Yo%H@}p>RhEGg!T)Zyim= z0JmB|B8wS5aRp}%IQkl=w}$I9m2SkFnR?dN0xo4B#&YLLNJqb5rR*%Zh6TG8Z#@s* zPIwgEyb823HuBd9Hy*$1gv%CN4pCJ{EFf8;7RUgM3V|~~^6p|xt`yg>=DwI7CbVL~ z2)5=t8Y0Lx&{z$0U@*fN82vzkYLiKCH19hV;VIKs9!~;YnQ-0heH{hQCWrLW!f>){ zzn{fKC8IoC2iCC;2;Bhce$DbhDsV-)YSFgvCdt{zAa_~;nXyCA;kAuNhmq$A?RYeZ zq*Fze2#Mt&$mWw0=!GV$pcD6NBCy4#3a}b@<&(gX)#)JnWI!F_+7b&ODw@oQA%-PH z3$*7Apn~xfC9er7B|xw!UKp*~M7Qujr1FS2>%lvgZ$g7)8AcmZTRHZkY{yIzjip4b zcIzy|M7Q_RS5;J#W*+6P7=z2}%GL=*s?iP^0~45!$uJ32KDOd-fS{Qsy?Hv%N8CFd z-2|i@a2M`Oaiar&fk}{vAcJ(@3hYi3$|IBLjiO}C{w-zvufvaVJjE@67$Cx3z@O#H zuu%LVQ=dx-C71zmr<=!ktOWV|Zf(;6AIdJyGsbF14)8%oN7zko4Pldhf{0SVS!}a! z!%~@5Vnv5!S5tCudUcz_<`@ZH^JZ3UjeBDG?p9ifL`>wO^dj;Z>Btekkmr6<#av}( z!kj&eIU?Rsi#)5W8ex=T3S|qJvcVg3VvA!Q?m|*r6IRN2>dKi!+I>PO1U{@_B^{aE zZb0W@Rp2EjvW(-Hk%VWF#||5R#m<*#)9L_xHWv0|L`F7zqht)QCBR~o)O78aX&i)`2msTp11|uM>@3l2fu^%#HXYGZlD{&O z&OzYB+zn)Pu8+%KSoRP{nMmE~pe9E@SV4)-ji6rebcj^(8CewV#w6>TRuF*}Ndn6H zr6|s(O6~^q%IGI(K}WF?PlCwxd^WaDVf_V|&*)Yr&!?CAyp86kUQFcbl^$05ig9!|LHWExc zkk^=qc@#)zQ~A}7qmpeuE0cL%AWL4u+HJg3O$ zJQlMH!3UK|`h;bng*&rGY)Q`ffh~}y6KIVLxhNTBBp_O`gQ}m&5y#X)F5=!8Kzxl_ z*bFy;gWlIZgr`DOulVhF%Js zh!>$;s4pFyEbFjzJNzM>f$iu|X%^5qWj&)!<&}~E%(*o|%_3o6&KL<@G#nz7v{_Mkcpem^QPEIP6t##x z(#<7;$R_@d!s~Q2N0a^llwQor1HDQ}x}6`3zLp4eGbMk{=$L8}PNR}i$>bg{m(+_> zD2^UANam#~{p@Wbi%Pq{phZP3;Lg#zD3DdK-=L#AZkNWeCx?nIkfDGWr1tnpHfR6@ ztoVedl8vV*tzbNft_I#4#l-3|wkQ)HloP?WkeA~iS$?uQNKN*6Q+MSz+}El$#-$(=`Xk@&Y%K|tmgXDVt7;9PvI5ff(EQwv3i zJ1n}mINmyt+{gU)ervE8{ydY~iBO9F>*CQ(?@sK+O6JUZ@3AMiGUKXVD18 zGGTfqQj9ol**ZX>g81s1*U39)54e=Zac)Z(f?OkxwIob*PmCTr#%q zgq?X;xkHzsFOrMr9vfJq!Ui!O3poXOImU)_;!Eg?6FaT1m;pS=ANp2KPPT()gPhs= z+T#+1ed_o0(HMHyM81r)o{JSW8@%Ja0Bs67m}0LJ0>;{l!qt>?k%`%H(k zWXk?zWY~f7FC1JlvJpAxafRL^S8%X1f>|EH!e1lMQML>6X-q2~t1Me9&Bxs?ffa-igatn>wbQOry9?1?RJF^cxVDf{K zwBWRkB9^lQ&{rd7GD371UjVIB*Ak9F(s3k?Xu<}vQj1ipUxg^H18K%l78)pFpNiWg zj8bDErMRI$8dQmu9+jj50BB$xUOBWq5q~+`ILA}anVgUkr;&oS$N>h43{R}cfJnq< zAU4+2FiU8p;;SpPc%nqWh>FM?f108hm((ZW^h(VgNd;Y*XkMD(`5pm@I5#8=rVG1Y z+&hv_bSg0llA|b^BNvznFGD7h;5vFv&x&CMW*aJeQGzCqkfE(?u_9ookDXQ*8H5UG zjz!Qo-!yC?$!zS685r#xS|!wOkQD0xKpjLc7yNI4c|=6@5_aBK#*IVNm$*<_6Mth^i7(K+R$0Ihw4+=mmXgCt*@T|^W6bhqe`DB@-f5(hx zZbU<20}1lyl)c1rR*Dv=7g?Tgm$)UzH zkAgz>ydJg&%-6}9LRCP;FMvD%l=ffd{UKTMSVnP_Q+7B9Ac!KviS?y{tfzVp&|DL4 zu&a5TNMNBjt6{s&<9xFgI9N!sFu{=!0dZ$Tf?se_JSq_UNFV`iSv$6rdQ;gn#`(cE znTeopx+v_C8avx~FC)7^(6RHE{XC<02GWWD(~C#ua9t{aUk36I_8oiNmZZIbFu(U%;jL?LWdq9-Se zLV?>Y`cGS)#cevzh=Ns^++bzq!k_6E?|LWnB)35oTuEwnE5~@9^JW}&0_OAGBdxoJ* z$smsa3&Rsy$2gsioOqmIh*2F>&KRkVbYnE}8+71j)(MPYvhKeas;_Rges_lL{;RWae_vuquDaBcZ`4!;|3WLPn zJzIeptB%hSBN-$IpO|O~A%nsRnGj#43CV;PgHjC~E;k(6RIsSsf4u63jKl*QZzHKKG{RM7#i7V@F)Tbl6O# z#$lP!%>UF&1z=;&gk*p*Xaa!+1XGTAE*->ux;4TV8SuXqNn>Jdm|t5RT3w01C0V zo8VuVUI*vqwn2Lb@e&w(g0vk^ii7l5A~Kta7rhqO}p15Y~7OlSZyo zI+W&a-5Cso+bR$gTx7Q z2LoaU#>AMLXlF^$KpsYL*JFhN<@?H+I!ixq8&>GKyv0B$_w9H8vxzX z>>e*?hFeOxTmy@I+`~Bj%GK)05GyO>;Uu3*R-`?Z)ZFds_e9dibWf-?;2F z!;7P4c-}rcY&TBAR!2i(55l+YW-~l{8}1)9+K0^=zSnNz8*W<|AnP;$Z=KQa=07f) zrx)RQvwhOKxPaE)ybl}a=g@fL&2ck4ZoC6%Hvh5TJiiFv9W_sbGi?4{3&zvAXy6B} z)9_upbIPKdJRb2Zp^K zzH40^on2m-!Q-+ih&+?38KCUL6+?u%!6|;=twUG0wK#{QD)$rvekOjm9Bh8v@f= z_uyR%I>!|%E`E(Zfd_W+-vb(*g(r>o9F_fE&;y2P!nS>^0Hm!*2fGL*hPQ8#8reF(n#2V<;1BW z9?Fv89zn(J(e7t;*bAMOz~oF?5ICBce%K}aens^D?~`l& z?|5ncxBOejvzESeAItN{ja#b3eTh26^X{=iLHwtK@?kYud(Yw z3>p&1Dd)=HB(vTX+GM^8Pt#fa%72VOWgr}(lu6xSuzrSmJR7G)lJ9AP)Oq9L=)=X? zhjU;j?+(_!qN){Is^Tlx-e+DtY@c18ubH2nqsGD6JNx^PZ-fDi?S`)AJt%q;#8`mmtMKKMCjqdn<_F+63O3kG?p=mZ z;ikYT44>@mIIjw{=q`+`gGalefr8I7=M(CtY0g%Brw*2TqzQ}LA5>HM0PS!zFG!de zyju@IsAyj_I~QDb{KIJjB!|7=`0Vtsa5H>i-=%33-*s<3p*2n>$#~B8opJPu{+6@y zK+c_;^LXHox@ZYwG<9O8;6&~I&z?Sg`~(_96HYRuNsDq-sCa`prQ_ridSs`HPMT7T zGoFy+;W~!4ysk-+Zed+-v1rRFVO;+QciTr3Xn?+fdT;_D!6U-)f(2{*gMRTq@!6sG z?9e=ep0Sd5^`^{Cd<EmVvvj%yy@nteASgid=%Fcet_oVtNDHgg zJU;#aQa=cTrx%@&u;`eNF2oQ5KD;vSo0C}p&-oskKO|h1PAZUXM^B-Zk!0ZaC@+A_ zR^$HD9M{@d73)+fLCbOar@zR$AU4uA(y$3M?y*e}Rt%7$O(rgy98Z4tG5Z*C9JGRu z_bA5ZE9pOIp6<8bpI=ZiA67?1X><26&ivFlI}#SaMA`P4Q0QLiT@5D2qe$!ik&2=Y zG~{R#M=eW;l$q%DVe{~;!woSi6HSn18Ko(!#oYETRW4?nzZHIENEA&oOm z2mk+wJgdvORQ~$`^kP8Y-=&Yc?>W}* zc^Ry=C~+qorfEOyB01SOXNOWW3NI(gC!&Qd^cGBj4R+$*9Nk#8V677#M%e&svybSV z!>}`r20)DZpnX4T#|Z{Nv^sB2!`-c?&z`>A+uD8dV(Z0butxk5BNF;?L|#BF`-=>E z5J$6lM&fCTm20q;7V|5TIp9l)GN94o=k@TNN&J;Bz7JcE(C>PSv6gd8+K=&Idp&I! zd9tYo5=-`KNd6N%e|DZlCSb81tTiOa-E_za{LyToScLA}V2#B>9Jx7M8&y&%a+uGj z=&#L{wJ8gOiFZ{rtf3j@nr$RxuHLl5rs3GZnll!Zba=AUqFwqnW+sU)0L*uR8IzTnWa1g0b`~!CE)UL2g9( zP4}~8FzNA8{Vbhgpm%Hnj>&lyti8iI-slm3+>WIQR0)iAR2Hb>Pf0$@nVu+R09q3F zt@DfH_DKALg?lhOc7Os*GXRFbgC;Appx9Ch4BMc&^ylL#YJkp^Hf7>iA~!YxQdBAs zHu6z48kleZg%rO?x+CgPYf8O9(AM@e`Bv;7#J)M?fnaR)0z^nubD;#olFS{4P& z^>E9q+YuhdHA=XM47yoccnk}lqy-2Hvm2#T&a=A@)c&VA-0E6(sr=V&HV#gHpYo4) z%70IvmgK*^$B$R?-@oFrm1wc1>6k+^1t|>iCi=g1-z(VX_%^B7L@89`n4)cFGc;&n z@l+E!Z@lZlub^;ihW~Cz)$xFcwM_9YO!WhbgaQ!xd)X{##H{awJ)}h*K0EWv6apJdED0_2gV~XXS8d$PMKLYJwKo2NYiT&3nVo=)g7a;B@xJI84+j_=jesSVA9MWSeps;}IG> zV^Txv0ZJgaYP6#;?hPccnUu^(rg&B&r3TR}0&g8>>tIgkbR1JwrvDVFKC2pgt^S?gUnbE$`M&@-D`Z|DoJ z+%To}O=yr3P)!;g^^A)e*zOq}Sg1x!hh>D%9+3hH9p<-EIg6gyIG|Tsn*p#59;K5b zTD6-r&}_}20BdWs5Met>u99E=JG)MTwX+c&4|f%XFT$hn<+EVz<=*bzPS|cVj+(*R z+t%rE-qW^d2$@7)` z_pi9>Kds-fk?;-OOaHBV32(aF34iO3g1_na1Gf}?c5xJ59=vJnAN>t_T6fHm;g&0n z?!l{_qY(XmfeNcXZGHA(3e;HV{ps0xr_~ASZ&Uyde%$K+9R9d9CGR!_BdPwk9%H z1@OSDbCqNiWQc4Jhi)8surlXCy%nziv;`ymY3nCFaAG~!cMh6x{q^)W8$jt#XI}h> zZ#XSaxn=%-JvgsEkwQ#7rbe`y3+qlxLvD$B_ZxCfI=@FdIk&?j^&4`R<{m8_%806( z@|JmND+6u?UtAB~k(8zsQ=5YJ1u=X?_oA3osDR!vyR@w{uvZMd4okMM6Jk@^d!{{?F0bNprjI zhA^#Zpowwr3clt+y_*Hw^E}(eV}nM7ir$x{_s`D*%86CevlT6E8H0R*p8%9tTqHVu zFb}CB6y|5&%E^?JH8`B48Cw1JjVFRrT1lcbbwR%hH?E@mYLh|i2g)qkDs|N_X`on8 zbE0;AjX*}>(r=PNDi-XS&uWlkN)~ONVv`}A=6cr{7q|J~!BWG85SqZHH)EDFc7b27bH#*At&lbi-{a@IaS`){-O>ul)jGL2i z=!Z*b1t0QcRfJgaAS)t@f-ew76>dD<48Bkt6`oEPFuJ7^Dd_N7aa7VfPuvYn3cg(Q zlrC_O>g$)Ir#R+STE($S^&vK1({Y?ZK^__;RBAtqhiJCW9~OaylFggT!;Yyy&4Lie zDvZ&!nq=q>yhcF~6s5sHC;vrukQgIni`)R@drUU8`$#t*+Iz zx>ncfT3xGab*-+|wYpZ<>RMf^Yjv%z)wQ}-*Xmkbt7~ /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/debian/changelog b/current/debian/changelog new file mode 100644 index 00000000..b1548b5e --- /dev/null +++ b/current/debian/changelog @@ -0,0 +1,175 @@ +shadow (19990827) unstable; urgency=low + + * upstream upgrade, see CHANGES for more details. Note: this is + not the official Debian changelog entry - it is here only for + dpkg-buildpackage to work (so I can build and test this package + on my system). To the Debian maintainers: please feel free to + replace this entry with your own, and put your name (instead of + mine) in the debian/control Maintainer field. Thanks, and keep + up the good work! + + -- Marek Michalkiewicz Fri, 27 Aug 1999 21:00:00 +0200 + +shadow (980403-0.3.2) unstable; urgency=low + + * configure.in patched for utmpx.h (for arm) + + -- Jim Pick Sun, 4 Oct 1998 19:06:15 -0700 + +shadow (980403-0.3.1) frozen unstable; urgency=low + + * Non maintainer upload. + changes.{guess,sub} changed to recognize a Arm architecture. + + -- Turbo Fredriksson Fri, 14 Aug 1998 22:37:58 -0400 + +shadow (980403-0.3) frozen unstable; urgency=high + + * Non maintainer upload. + * src/login.c: Applied patch from to + fix security hole of login not checking the return code from setgid(), + initgroups() or setuid(). [#24710] + + -- James Troup Fri, 17 Jul 1998 18:56:31 +0100 + +shadow (980403-0.2) frozen unstable; urgency=low + + * (login.defs): fixed UMASK + (thanks to James Troup for noticing my screwup :) + * Pruned non-Debian changelog entries. + + -- Joel Klecker Mon, 11 May 1998 11:25:22 -0700 + +shadow (980403-0.1) frozen unstable; urgency=low + + * Non-maintainer release. + * New upstream release (18225). + * (debian/login.postinst) + * Use 'touch' instead of 'cat >' when creating /var/log/faillog + (15998,16187,21687). + * No longer fails if no previous configured version exists (11433). + * (gpasswd): now checks which user invoked it before calling setuid() (18132). + * (debian/passwd.postinst): removed bashism (13753). + * (groupmod): NULL dereference fixed upstream, as a result, it no longer + dumps core when changing group name (16893,17894). + * (useradd): no longer segfaults if /etc/default/useradd is missing (18628). + * (login.defs.1): now documents more options (13485). + * (source): includes 'missing' (13815,18133,21280). + * (login.1): + * Removed mention of "d_passwd(5)", which doesn't exist, + and login.defs.5 now documents /etc/dialups (15176). + * Added /etc/nologin to FILES section and reference nologin(5) (21695). + * The URL mentioned in Bug#15391 is no longer valid. + * (login.defs): no longer sets ULIMIT (17529). + * (login): + * No longer uses static buffers for group lines (17532). + * Doesn't seem to make assumptions about gid_t any longer (21767). + * (faillog.8): s-/usr/adm-/var/log-g (19974). + * (lastlog.8): notes that "some systems" use /var/log instead of + /usr/adm (21746). + * Install upstream changelog as 'changelog.gz' as per policy (20052). + * (secure-su): Changed /etc/suauth to reference the group 'root' + instead of 'wheel' (17593). + + -- Joel Klecker Thu, 30 Apr 1998 18:32:12 -0700 + +shadow (970616-1) unstable; urgency=low + + * Upstream upgrade. + * chage works (10561). + * Fix NIS behavior (5634,8734,10032,10545,10984,11160,12064). + * Wrote pwconv,pwunconv,grpconv,grpunconv manpage (10940). + * vipw fixes (10521,10696,11618,11924,12184,13001) + * Fixes for new automake. + * Compile with glibc2. (8627,8777,9824,11713,11719,12082,12108,11442). + * debian/rules fixes (8876,12468). + * /etc/login.defs: UMASK=002 (9102). + * chown /dev/vcs* on login (9421,13255). + * Added tty9-tty12 to /etc/securetty (11644). + * Provide template and manpage for /etc/limits (12289). + * Fix security hole in postinst (11769). + * login fills out ut_addr field in utmp (10701). + * shadowconfig.sh fixes (9189,9328,9386,10968,12452,12469). + * Overcome postinst bug in old shadow-passwd package (9939,12120). + * useradd default GROUP=100 (9244). + * Allow 8 bit chars in chfn (12367). + * secure-su - set HOME, use SHELL if set (11003,11189). + + -- Guy Maor Fri, 26 Sep 1997 19:23:42 -0500 + +shadow (970616) unstable; urgency=low + + * vipw preserves permissions on edited files (10521). + * various other bug fixes. + + -- Marek Michalkiewicz Mon, 16 Jun 1997 02:02:00 +0200 + +shadow (970601) unstable; urgency=low + + * Fix typo in libmisc/mail.c causing login to segfault. + + -- Marek Michalkiewicz Mon, 2 Jun 1997 07:33:00 +0200 + +shadow (970502-2) unstable; urgency=low + + * Fixes to shadow group support (grpconv didn't work). + + -- Marek Michalkiewicz Fri, 2 May 1997 15:48:00 +0200 + +shadow (970502-1) unstable; urgency=low + + * Upstream upgrade. + + -- Marek Michalkiewicz Fri, 2 May 1997 03:18:00 +0200 + +shadow (961025-2) frozen unstable; urgency=medium + + * Fix useradd -D segfault (8098, 8152, 8733). + * Fix shadowconfig - permfix only on xlock; /etc/init.d/xdm rewrite, chmod + (8102, 8320, 8333, 8708). + * Remove HOWTO from usr/doc/passwd as it's in linux-doc (8150). + * Fixes to su.1 (8153). + * login, passwd, su each conflict and replace with the old shadow-* + version. (8269, 8290, 8393, 8394). + * Put /etc/shells back in passwd (8328). + * Fixed login.postinst for upgrade from shadow-login (8392). + * Added -e to pwck for use in shadowconfig: reports only errors, no + warnings (8542). + * Wrote shadowconfig.8 (8588). + + -- Guy Maor Sat, 19 Apr 1997 02:34:59 -0500 + +shadow (961025-1) unstable; urgency=low + + * Upstream upgrade, new source format. + + -- Guy Maor Mon, 10 Feb 1997 02:56:56 -0600 + +shadow (960530-1) experimental; urgency=LOW + + * Added grpunconv script + * Changed prerm/postinst scripts to remove/create shadowed group + file + * Added vipw/vigr binaries + * Renamed package to shadow-passwd + * Added packages shadow-su and shadow-login + * Added 'Essential: yes' to be able to replace passwd and login + * Section now base for shadow-passwd and shadow-login + * Added /etc/shell conffile + * Added /etc/securetty conffile + * Added new conffile /etc/suauth. Set it up so only users in group 0 + can su to root. + +shadow (960810-1) base; urgency=LOW + + * Added useradd default file so that default group is no longer 1 + * Also corrected the useradd manpage + * Replaced grpunconv script by real binary which does correct + locking. + * Added 'source' field control file to control files + * Changed version naming in debian.rules + * New upstream version + +Local variables: +mode: debian-changelog +End: diff --git a/current/debian/checksums b/current/debian/checksums new file mode 100755 index 00000000..9d227c30 --- /dev/null +++ b/current/debian/checksums @@ -0,0 +1,7 @@ +#!/bin/sh +# This script is run from debian/rules to generate MD5 checksums +# for all files in the package. +# $Id: checksums,v 1.1 1997/12/14 21:05:37 marekm Exp $ +set -e +cd $1 +md5sum `find * -type f ! -regex "DEBIAN/.*"` >DEBIAN/md5sums +Standards-Version: 2.3.0.0 + +Package: login +Architecture: any +Pre-Depends: ${shlibs:Depends} +Conflicts: shadow-login +Replaces: shadow-login, shadow-passwd +Essential: yes +Section: base +Priority: required +Description: Sign on to the system. + login and newgrp change the user and group. + +Package: passwd +Architecture: any +Depends: ${shlibs:Depends}, login (>= 970502-1) +Conflicts: shadow-passwd +Replaces: shadow-passwd +Replaces: manpages (<=1.15-2) +Section: base +Priority: required +Description: Change and administer password and group data. + This package includes passwd, chsh, chfn, and many other programs to + maintain password and group data. + . + Shadow passwords are supported. See /usr/doc/passwd/README.Debian + +Package: secure-su +Architecture: any +Depends: ${shlibs:Depends}, login (>= 970502-1) +Conflicts: shadow-su +Replaces: shadow-su +Section: admin +Priority: optional +Description: su with more security options + secure-su offers more security options than the normal su, such as a + wheel group, and from-user and to-user specific restrictions. diff --git a/current/debian/control.gnu b/current/debian/control.gnu new file mode 100644 index 00000000..5b052739 --- /dev/null +++ b/current/debian/control.gnu @@ -0,0 +1,16 @@ +Source: shadow +Section: base +Priority: required +Maintainer: Guy Maor +Standards-Version: 2.3.0.0 + +Package: passwd +Architecture: any +Depends: ${shlibs:Depends} +Section: base +Priority: required +Description: Change and administer password and group data. + This package includes passwd, chsh, chfn, and many other programs to + maintain password and group data. + . + Shadow passwords are supported. See /usr/doc/passwd/README.Debian diff --git a/current/debian/control.linux b/current/debian/control.linux new file mode 100644 index 00000000..430c4b3a --- /dev/null +++ b/current/debian/control.linux @@ -0,0 +1,41 @@ +Source: shadow +Section: base +Priority: required +Maintainer: Marek Michalkiewicz +Standards-Version: 2.3.0.0 + +Package: login +Architecture: any +Pre-Depends: ${shlibs:Depends} +Conflicts: shadow-login +Replaces: shadow-login, shadow-passwd +Essential: yes +Section: base +Priority: required +Description: Sign on to the system. + login and newgrp change the user and group. + +Package: passwd +Architecture: any +Depends: ${shlibs:Depends}, login (>= 970502-1) +Conflicts: shadow-passwd +Replaces: shadow-passwd +Replaces: manpages (<=1.15-2) +Section: base +Priority: required +Description: Change and administer password and group data. + This package includes passwd, chsh, chfn, and many other programs to + maintain password and group data. + . + Shadow passwords are supported. See /usr/doc/passwd/README.Debian + +Package: secure-su +Architecture: any +Depends: ${shlibs:Depends}, login (>= 970502-1) +Conflicts: shadow-su +Replaces: shadow-su +Section: admin +Priority: optional +Description: su with more security options + secure-su offers more security options than the normal su, such as a + wheel group, and from-user and to-user specific restrictions. diff --git a/current/debian/login.conffiles b/current/debian/login.conffiles new file mode 100644 index 00000000..c1d83cba --- /dev/null +++ b/current/debian/login.conffiles @@ -0,0 +1,6 @@ +/etc/login.defs +/etc/login.access +/etc/securetty +/etc/porttime +/etc/limits +/etc/init.d/logoutd diff --git a/current/debian/login.copyright b/current/debian/login.copyright new file mode 100644 index 00000000..a848548c --- /dev/null +++ b/current/debian/login.copyright @@ -0,0 +1,76 @@ +This is Debian/GNU Linux's prepackaged version of login and related +utilities. + +It was downloaded from: . + +This software is copyright 1988 - 1994, Julianne Frances Haugh. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of Julianne F. Haugh nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + +This source code is currently archived on ftp.uu.net in the +comp.sources.misc portion of the USENET archives. You may also contact +the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have +any questions regarding this package. + +THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL +LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE +FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO +OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS +ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL +LOSS OF INFORMATION OR MACHINE RESOURCES. + +Special thanks are due to Chip Rosenthal for his fine testing efforts; +to Steve Simmons for his work in porting this code to BSD; and to Bill +Kennedy for his contributions of LaserJet printer time and energies. +Also, thanks for Dennis L. Mumaugh for the initial shadow password +information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System +V Release 4 changes. Effort in porting to SunOS has been contributed +by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr. +(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release +4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au). +Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl) +for taking over the Linux port of this software. + +Source files: login_access.c, login_desrpc.c, login_krb.c are derived +from the logdaemon-5.0 package, which is under the following license: + +/************************************************************************ +* Copyright 1995 by Wietse Venema. All rights reserved. Individual files +* may be covered by other copyrights (as noted in the file itself.) +* +* This material was originally written and compiled by Wietse Venema at +* Eindhoven University of Technology, The Netherlands, in 1990, 1991, +* 1992, 1993, 1994 and 1995. +* +* Redistribution and use in source and binary forms are permitted +* provided that this entire copyright notice is duplicated in all such +* copies. +* +* This software is provided "as is" and without any expressed or implied +* warranties, including, without limitation, the implied warranties of +* merchantibility and fitness for any particular purpose. +************************************************************************/ + diff --git a/current/debian/login.postinst b/current/debian/login.postinst new file mode 100644 index 00000000..32b19a06 --- /dev/null +++ b/current/debian/login.postinst @@ -0,0 +1,42 @@ +#!/bin/sh +set -e + +[ "$1" = configure -a "$2" ] \ + && dpkg --compare-versions $2 lt 961025 \ + || [ -z "$2" ] \ + || exit 0 + +if [ -f /etc/usertty ] ; then + cat > /etc/usertty$$ <> /etc/usertty$$ + mv -f /etc/usertty$$ /etc/usertty + + if egrep -vqn '^#|^ *$' /etc/usertty ; then cat < /dev/null diff --git a/current/debian/login.postrm b/current/debian/login.postrm new file mode 100644 index 00000000..ccfa914f --- /dev/null +++ b/current/debian/login.postrm @@ -0,0 +1,6 @@ +#!/bin/sh +set -e + +if [ "$1" = "purge" ] ; then + update-rc.d logoutd remove >/dev/null +fi diff --git a/current/debian/login.preinst b/current/debian/login.preinst new file mode 100644 index 00000000..96637b51 --- /dev/null +++ b/current/debian/login.preinst @@ -0,0 +1,4 @@ +#!/bin/sh +set -e +dpkg --assert-support-predepends || +( echo -e "\nPlease upgrade to a newer version of dpkg\n"; exit 1; ) diff --git a/current/debian/login.prerm b/current/debian/login.prerm new file mode 100644 index 00000000..ba1301b3 --- /dev/null +++ b/current/debian/login.prerm @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +case $1 in + remove|upgrade|deconfigure) + /etc/init.d/logoutd stop + ;; +esac diff --git a/current/debian/logoutd.init b/current/debian/logoutd.init new file mode 100644 index 00000000..60594465 --- /dev/null +++ b/current/debian/logoutd.init @@ -0,0 +1,36 @@ +#! /bin/sh +# start/stop logoutd + +set -e + +DAEMON=/usr/sbin/logoutd +test -f $DAEMON || exit 0 + +# Most people won't need logoutd(8) running, so we'll only run it if +# /etc/porttime has non-comment lines. +egrep -vq '^#|^ *$' /etc/porttime || exit 0 + +case "$1" in + start) + echo -n "Starting login time and port restriction enforcer: logoutd" + start-stop-daemon --start --quiet --exec $DAEMON + echo "." + ;; + stop) + echo -n "Stopping login time and port restriction enforcer: logoutd" + start-stop-daemon --stop --quiet --exec $DAEMON + echo "." + ;; + force-reload|restart) + $0 stop + $0 start + ;; + reload) + ;; + *) + echo "Usage: /etc/init.d/logoutd start|stop|restart" + exit 1 + ;; +esac + +exit 0 diff --git a/current/debian/passwd.conffiles b/current/debian/passwd.conffiles new file mode 100644 index 00000000..48979eaf --- /dev/null +++ b/current/debian/passwd.conffiles @@ -0,0 +1,3 @@ +/etc/cron.daily/passwd +/etc/init.d/passwd +/etc/shells diff --git a/current/debian/passwd.copyright b/current/debian/passwd.copyright new file mode 100644 index 00000000..701d899f --- /dev/null +++ b/current/debian/passwd.copyright @@ -0,0 +1,55 @@ +This is Debian/GNU Linux's prepackaged version of the passwd +utilities. + +It was downloaded from: . + +This software is copyright 1988 - 1994, Julianne Frances Haugh. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of Julianne F. Haugh nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + +This source code is currently archived on ftp.uu.net in the +comp.sources.misc portion of the USENET archives. You may also contact +the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have +any questions regarding this package. + +THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL +LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE +FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO +OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS +ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL +LOSS OF INFORMATION OR MACHINE RESOURCES. + +Special thanks are due to Chip Rosenthal for his fine testing efforts; +to Steve Simmons for his work in porting this code to BSD; and to Bill +Kennedy for his contributions of LaserJet printer time and energies. +Also, thanks for Dennis L. Mumaugh for the initial shadow password +information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System +V Release 4 changes. Effort in porting to SunOS has been contributed +by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr. +(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release +4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au). +Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl) +for taking over the Linux port of this software. diff --git a/current/debian/passwd.cron b/current/debian/passwd.cron new file mode 100644 index 00000000..4bc868ef --- /dev/null +++ b/current/debian/passwd.cron @@ -0,0 +1,8 @@ +#!/bin/sh +# +# cron.daily script to check integrity of the password and group files + +test -f /usr/sbin/pwck || exit 0 + +pwck -q -r +grpck -r diff --git a/current/debian/passwd.init b/current/debian/passwd.init new file mode 100755 index 00000000..83ef2071 --- /dev/null +++ b/current/debian/passwd.init @@ -0,0 +1,25 @@ +#!/bin/sh +# +# /etc/init.d/passwd +# script to check integrity of the password and group files at system startup +# + +set -e +test -f /usr/sbin/pwck || exit 0 + +case "$1" in + start) + echo -n 'Checking password and group files... ' + pwck -q -r + grpck -r + echo "done." + ;; + stop|restart|reload|force-reload) + ;; + *) + echo "Usage: /etc/init.d/passwd start" + exit 1 + ;; +esac + +exit 0 diff --git a/current/debian/passwd.postinst b/current/debian/passwd.postinst new file mode 100644 index 00000000..bb8ed870 --- /dev/null +++ b/current/debian/passwd.postinst @@ -0,0 +1,41 @@ +#!/bin/sh +set -e + +if [ configure != "$1" ] ; then + exit 0 +fi + +# passwd 961025-1 incorrectly did permfix on sulogin and xdm-shadow in +# shadowconfig +permfix () { + [ -f $1 ] || return 0 + chown root:root $1 + chmod 755 $1 +} +permfix /sbin/sulogin +permfix /usr/X11R6/bin/xdm-shadow + +# check password and group files at boot time +update-rc.d passwd start 60 S . >/dev/null + +grep -q '^shadow:[^:]*:42' /etc/group && exit 0 +groupadd -g 42 shadow || ( + cat </dev/null +fi diff --git a/current/debian/porttime b/current/debian/porttime new file mode 100644 index 00000000..5888d63a --- /dev/null +++ b/current/debian/porttime @@ -0,0 +1,8 @@ +# /etc/porttime contains user time restrictions. +# See porttime(5). + +# If you add restrictions to this file, be sure that +# PORTTIME_CHECKS_ENAB is set to `yes' in /etc/login.defs. logoutd(8) +# will be started automatically on bootup if this file contains +# non-comment lines. You may also start it manually with +# `/etc/init.d/logoutd start'. diff --git a/current/debian/rules b/current/debian/rules new file mode 100755 index 00000000..63284d78 --- /dev/null +++ b/current/debian/rules @@ -0,0 +1,159 @@ +#!/usr/bin/make -f + +# FIXME - this is out of date, please update for current Debian + +package = shadow + +# see dpkg-architecture(8) +DEB_BUILD_ARCH := $(shell dpkg --print-installation-architecture) +DEB_BUILD_GNU_CPU := $(patsubst hurd-%,%,$(DEB_BUILD_ARCH)) +ifeq ($(filter-out hurd-%,$(DEB_BUILD_ARCH)),) + DEB_BUILD_GNU_SYSTEM := gnu +else + DEB_BUILD_GNU_SYSTEM := linux +endif +DEB_BUILD_GNU_TYPE=$(DEB_BUILD_GNU_CPU)-$(DEB_BUILD_GNU_SYSTEM) + +DEB_HOST_GNU_SYSTEM=$(DEB_BUILD_GNU_SYSTEM) +DEB_HOST_GNU_TYPE=$(DEB_BUILD_GNU_TYPE) + +ifeq ($(DEB_HOST_GNU_SYSTEM),linux) +package-list = binary-login binary-passwd binary-su +else +package-list = binary-passwd +endif + +# for "exec login" to work for ordinary users, /bin/login needs to be setuid +# but very few people use this feature, so we make it non-setuid by default +LOGIN_PERM = 0755 + +build: + $(checkdir) + cp -a debian/control.$(DEB_HOST_GNU_SYSTEM) debian/control + # shared lib support is untested, so... + ./configure --disable-shared --disable-desrpc \ + --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE) + $(MAKE) + touch build + +clean: + $(checkdir) + rm -f build debian/tar + -$(MAKE) -i distclean + rm -rf {libmisc,lib,src}/.deps + rm -rf debian/tmp{-l,-p,-s} debian/{files*,substvars} + cp -a debian/control.linux debian/control + find . -name '*~' -print0 | xargs -0 rm -f + +binary-indep: checkroot build + $(checkdir) + +binary-arch: $(package-list) + +binary-login: checkroot build + $(checkdir) + -rm -rf debian/tmp-l + install -d debian/tmp-l/{DEBIAN,bin,etc/init.d,usr/{bin,man/man{1,5,8},doc/login,sbin}} + install -s -m$(LOGIN_PERM) src/login debian/tmp-l/bin/ + install -s -m4755 src/newgrp debian/tmp-l/usr/bin/ + install -s src/{faillog,lastlog} debian/tmp-l/usr/bin/ + install -s src/logoutd debian/tmp-l/usr/sbin/ + install -m644 man/{login.1,newgrp.1} debian/tmp-l/usr/man/man1/ + install -m644 man/{login.defs.5,login.access.5,porttime.5,faillog.5,limits.5} debian/tmp-l/usr/man/man5/ + install -m644 man/{faillog.8,logoutd.8,lastlog.8} debian/tmp-l/usr/man/man8/ + ln -s newgrp debian/tmp-l/usr/bin/sg + ln -s newgrp.1.gz debian/tmp-l/usr/man/man1/sg.1.gz + install -m600 etc/login.defs.linux debian/tmp-l/etc/login.defs + install -m600 etc/{login.access,limits} debian/{securetty,porttime} debian/tmp-l/etc/ + install debian/logoutd.init debian/tmp-l/etc/init.d/logoutd + install -m644 debian/changelog debian/tmp-l/usr/doc/login/changelog.Debian + install -m644 doc/CHANGES debian/tmp-l/usr/doc/login/changelog + find debian/tmp-l/usr/{doc,man} -type f | xargs gzip -9 + install -m644 debian/login.copyright debian/tmp-l/usr/doc/login/copyright + install debian/login.preinst debian/tmp-l/DEBIAN/preinst + install debian/login.postinst debian/tmp-l/DEBIAN/postinst + install debian/login.prerm debian/tmp-l/DEBIAN/prerm + install debian/login.postrm debian/tmp-l/DEBIAN/postrm + install -m644 debian/login.conffiles debian/tmp-l/DEBIAN/conffiles + dpkg-shlibdeps debian/tmp-l/{bin/*,usr/bin/*,usr/sbin/*} + dpkg-gencontrol -isp -plogin -Pdebian/tmp-l + ./debian/checksums debian/tmp-l + +binary-passwd: checkroot build + $(checkdir) + -rm -rf debian/tmp-p + install -d debian/tmp-p/{DEBIAN,etc/{cron.daily,init.d},usr/{sbin,bin,man/{man1,man5,man8},doc/passwd}} + install -m644 etc/shells debian/tmp-p/etc/ + install debian/passwd.cron debian/tmp-p/etc/cron.daily/passwd + install debian/passwd.init debian/tmp-p/etc/init.d/passwd + install -s -m4755 src/{chage,chfn,chsh,expiry,gpasswd,passwd} debian/tmp-p/usr/bin/ + install -s src/{chpasswd,groupadd,groupdel,groupmod,grpck,grpconv,grpunconv} \ + src/{newusers,pwck,pwconv,pwunconv,useradd,userdel} \ + src/{dpasswd,usermod,vipw} debian/tmp-p/usr/sbin/ + install -m644 man/{chage.1,chfn.1,chsh.1,gpasswd.1,passwd.1} \ + debian/tmp-p/usr/man/man1/ + install -m644 man/{chpasswd.8,groupadd.8,groupdel.8,groupmod.8,grpck.8} \ + man/{newusers.8,pwck.8,dpasswd.8} \ + man/{useradd.8,userdel.8,usermod.8,vipw.8,shadowconfig.8,pwconv.8} \ + debian/tmp-p/usr/man/man8/ + install -m644 man/{passwd.5,shadow.5} debian/tmp-p/usr/man/man5/ + ln -s vipw debian/tmp-p/usr/sbin/vigr + ln -s vipw.8.gz debian/tmp-p/usr/man/man8/vigr.8.gz + for i in pwunconv.8.gz grpconv.8.gz grpunconv.8.gz ; do \ + ln -s pwconv.8.gz debian/tmp-p/usr/man/man8/$$i ; done + install -m644 debian/changelog debian/tmp-p/usr/doc/passwd/changelog.Debian + install -m644 doc/{CHANGES,README,README.limits,README.linux,README.debian} \ + debian/tmp-p/usr/doc/passwd/ + find debian/tmp-p/usr/{doc,man} -type f | xargs gzip -9f + install -m644 debian/passwd.copyright debian/tmp-p/usr/doc/passwd/copyright + install debian/login.preinst debian/tmp-p/DEBIAN/preinst + install debian/passwd.postinst debian/tmp-p/DEBIAN/postinst + install debian/passwd.postrm debian/tmp-p/DEBIAN/postrm + install -m644 debian/passwd.conffiles debian/tmp-p/DEBIAN/conffiles + dpkg-shlibdeps debian/tmp-p/usr/{bin/*,sbin/*} + # dpkg-shlibdeps fails on scripts, so install them now... + install src/shadowconfig.sh debian/tmp-p/usr/sbin/shadowconfig +ifeq ($(DEB_HOST_GNU_SYSTEM),gnu) + install etc/login.defs.hurd debian/tmp-p/etc/login.defs + echo "/etc/login.defs" >> debian/tmp-p/DEBIAN/conffiles +endif + dpkg-gencontrol -isp -ppasswd -Pdebian/tmp-p + ./debian/checksums debian/tmp-p + +binary-su: checkroot build + $(checkdir) + -rm -rf debian/tmp-s + install -d debian/tmp-s/{DEBIAN,etc,bin,usr/{doc/secure-su,man/man{1,5}}} + install -s -m4755 src/su debian/tmp-s/bin/ + install -m644 etc/suauth debian/tmp-s/etc/ + install -m644 man/suauth.5 debian/tmp-s/usr/man/man5/ + install -m644 man/su.1 debian/tmp-s/usr/man/man1/ + install -m644 debian/secure-su.README debian/tmp-s/usr/doc/secure-su/README + install -m644 debian/changelog debian/tmp-s/usr/doc/secure-su/ + find debian/tmp-s/usr/{doc,man} -type f | xargs gzip -9f + install -m644 debian/secure-su.copyright debian/tmp-s/usr/doc/secure-su/copyright + install debian/secure-su.preinst debian/tmp-s/DEBIAN/preinst + install debian/secure-su.postrm debian/tmp-s/DEBIAN/postrm + install -m644 debian/secure-su.conffiles debian/tmp-s/DEBIAN/conffiles + dpkg-shlibdeps debian/tmp-s/bin/su + dpkg-gencontrol -isp -psecure-su -Pdebian/tmp-s + ./debian/checksums debian/tmp-s + +define checkdir + test -f lib/shadow.c -a -f debian/rules +endef + + +binary: binary-indep binary-arch + +source diff: + @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false + +checkroot: + $(checkdir) +# test root = "`whoami`" + +.PHONY: binary binary-arch binary-indep clean checkroot + +# Local Variables: +# mode:Makefile diff --git a/current/debian/secure-su.README b/current/debian/secure-su.README new file mode 100644 index 00000000..723f37a0 --- /dev/null +++ b/current/debian/secure-su.README @@ -0,0 +1,4 @@ +The su from shellutils is diverted into /bin/secure-su. That +directory MUST be owned by root and have permissions 700. Otherwise +you will lost any security advantages you will gain by installing +secure-su as users can still invoke the old su. diff --git a/current/debian/secure-su.conffiles b/current/debian/secure-su.conffiles new file mode 100644 index 00000000..2853262a --- /dev/null +++ b/current/debian/secure-su.conffiles @@ -0,0 +1 @@ +/etc/suauth diff --git a/current/debian/secure-su.copyright b/current/debian/secure-su.copyright new file mode 100644 index 00000000..de1479c6 --- /dev/null +++ b/current/debian/secure-su.copyright @@ -0,0 +1,54 @@ +This is Debian/GNU Linux's prepackaged version of secure-su. + +It was downloaded from: . + +This software is copyright 1988 - 1994, Julianne Frances Haugh. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of Julianne F. Haugh nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + +This source code is currently archived on ftp.uu.net in the +comp.sources.misc portion of the USENET archives. You may also contact +the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have +any questions regarding this package. + +THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL +LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE +FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO +OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS +ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL +LOSS OF INFORMATION OR MACHINE RESOURCES. + +Special thanks are due to Chip Rosenthal for his fine testing efforts; +to Steve Simmons for his work in porting this code to BSD; and to Bill +Kennedy for his contributions of LaserJet printer time and energies. +Also, thanks for Dennis L. Mumaugh for the initial shadow password +information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System +V Release 4 changes. Effort in porting to SunOS has been contributed +by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr. +(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release +4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au). +Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl) +for taking over the Linux port of this software. diff --git a/current/debian/secure-su.postrm b/current/debian/secure-su.postrm new file mode 100644 index 00000000..aef1e6ab --- /dev/null +++ b/current/debian/secure-su.postrm @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +if [ remove = "$1" ] ; then + dpkg-divert --package secure-su --remove --rename \ + --divert /bin/secure-su/su /bin/su + dpkg-divert --package secure-su --remove --rename \ + --divert /usr/man/man1/gnu-su.1.gz /usr/man/man1/su.1.gz + rm /bin/secure-su/README.gz + rmdir /bin/secure-su || true +fi diff --git a/current/debian/secure-su.preinst b/current/debian/secure-su.preinst new file mode 100644 index 00000000..d5522c2e --- /dev/null +++ b/current/debian/secure-su.preinst @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +if [ install = "$1" ] ; then + # dpkg-divert uses rename so can't do cross-device diversions. bleah. + [ -d /bin/secure-su ] || mkdir /bin/secure-su + chmod 700 /bin/secure-su + ln -sf ../../usr/doc/secure-su/README.gz /bin/secure-su/README.gz + dpkg-divert --package secure-su --add --rename \ + --divert /bin/secure-su/su /bin/su + dpkg-divert --package secure-su --add --rename \ + --divert /usr/man/man1/gnu-su.1.gz /usr/man/man1/su.1.gz +fi diff --git a/current/debian/securetty b/current/debian/securetty new file mode 100644 index 00000000..d66d2a63 --- /dev/null +++ b/current/debian/securetty @@ -0,0 +1,14 @@ +# /etc/securetty: list of terminals on which root is allowed to login. +# See securetty(5) and login(1). +tty1 +tty2 +tty3 +tty4 +tty5 +tty6 +tty7 +tty8 +tty9 +tty10 +tty11 +tty12 diff --git a/current/debian/tar.c b/current/debian/tar.c new file mode 100644 index 00000000..1f45eaa0 --- /dev/null +++ b/current/debian/tar.c @@ -0,0 +1,409 @@ +/* + * $Id: tar.c,v 1.2 1999/03/07 19:14:24 marekm Exp $ + * + * This is a wrapper for tar to ensure that all files within the + * newly created tar archive have the owner and group set to + * root:root. This makes it possible to build Debian packages + * without root privileges (normally needed to chown files). + * + * Assumptions: + * - the directory containing this program is listed in $PATH + * before the directory containing the real tar program (/bin) + * - the options passed to tar cause it to output the archive + * (not compressed) on standard output + * + * Written by Marek Michalkiewicz , + * public domain, no warranty, etc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef REAL_TAR +#define REAL_TAR "/bin/tar" +#endif + +#define RECORD_SIZE 512 + +union record { + char data[RECORD_SIZE]; + struct header { + char name[100]; /* NUL-terminated if NUL fits */ + char mode[8]; /* 0+ spaces, 1-6 octal digits, space, NUL */ + char uid[8]; /* format same as mode */ + char gid[8]; /* format same as mode */ + char size[12]; /* 0+ spaces, 1-11 octal digits, space */ + /* if '1' <= typeflag <= '6', ignore size */ + char mtime[12]; /* format same as size */ + char chksum[8]; /* 0+ spaces, 1-6 octal digits, NUL, space */ + char typeflag; + char linkname[100]; /* NUL-terminated if NUL fits */ +/* XXX - for GNU tar, magic is "ustar " (no NUL) and version is " \0" */ + char magic[6]; /* must be TMAGIC (NUL term.) */ + char version[2]; /* must be TVERSION */ + char uname[32]; /* NUL-terminated */ + char gname[32]; /* NUL-terminated */ + char devmajor[8]; + char devminor[8]; +#ifdef GNU_TAR_FORMAT + char atime[12]; + char ctime[12]; + char offset[12]; + char longnames[4]; + char pad; + struct sparse { + char offset[12]; + char numbytes[12]; + } sp[4]; + char isextended; + char realsize[12]; +#else +/* if prefix[0] != NUL then filename = prefix/name else filename = name */ + char prefix[155]; /* NUL-terminated if NUL fits */ +#endif + } h; +#ifdef GNU_TAR_FORMAT + struct exthdr { + struct sparse sp[21]; + char isextended; + } xh; +#endif +}; + +static union record tarbuf; +static int infd = -1, outfd = -1; + +int main(int, char **); +static ssize_t xread(int, char *, size_t); +static ssize_t xwrite(int, const char *, size_t); +static int block_is_eof(void); +static void block_read(void); +static void block_write(void); +static void verify_magic(void); +static void verify_checksum(void); +static void update_checksum(void); +static void set_owner(const char *); +static void set_group(const char *); +static void process_archive(void); + + +int +main(int argc, char **argv) +{ + int pipefd[2]; + pid_t pid; + const char *real_tar; + int status; + + real_tar = getenv("REAL_TAR"); + if (!real_tar) + real_tar = REAL_TAR; + if (pipe(pipefd)) { + perror("pipe"); + exit(1); + } + pid = fork(); + if (pid == 0) { /* child */ + /* redirect stdout to the pipe */ + if (dup2(pipefd[1], STDOUT_FILENO) != 1) { + perror("dup2"); + _exit(126); + } + close(pipefd[0]); + close(pipefd[1]); + /* run the real tar program */ + execv(real_tar, argv); + if (errno == ENOENT) { + perror("execve"); + _exit(127); + } else { + perror("execve"); + _exit(126); + } + } else if (pid < 0) { /* error */ + perror("fork"); + exit(1); + } + /* parent */ + close(pipefd[1]); + /* read from pipefd[0], modify tar headers, write to stdout ... */ + infd = pipefd[0]; + outfd = STDOUT_FILENO; + process_archive(); + /* wait for the tar subprocess to finish, and return its exit status */ + status = 1; + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid"); + exit(1); + } + if (WIFSIGNALED(status)) { + kill(getpid(), WTERMSIG(status)); + exit(1); + } + exit(WEXITSTATUS(status)); +} + +/* EINTR-safe versions of read() and write() - they don't really help much + as GNU tar itself (version 1.11.8 at least) is not EINTR-safe, but it + doesn't hurt... Also, these functions never return errors - instead, + they print an error message to stderr, and exit(1). End of file is + indicated by returning the number of bytes actually read. */ + +static ssize_t +xread(int fd, char *buf, size_t count) +{ + ssize_t n; + size_t left; + + left = count; + do { + n = read(fd, buf, left); + if ((n < 0) && (errno == EINTR)) + continue; + if (n <= 0) + break; + left -= n; + buf += n; + } while (left > 0); + if (count > left) + return count - left; + if (n < 0) { + perror("read"); + exit(1); + } + return 0; +} + + +static ssize_t +xwrite(int fd, const char *buf, size_t count) +{ + ssize_t n; + size_t left; + + left = count; + do { + n = write(fd, buf, left); + if (n < 0) { + if (errno == EINTR) + continue; + /* any other write errors are fatal */ + perror("write"); + exit(1); + } + left -= n; + buf += n; + } while (left > 0); + return count; +} + + +static int +block_is_eof(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(tarbuf.data); i++) { + if (tarbuf.data[i]) + return 0; + } + return 1; +} + + +static void +block_read(void) +{ + ssize_t nread; + + nread = xread(infd, tarbuf.data, RECORD_SIZE); + if (nread != RECORD_SIZE) { + fprintf(stderr, "unexpected end of file\n"); + exit(1); + } +} + + +static void +block_write(void) +{ + xwrite(outfd, tarbuf.data, RECORD_SIZE); +} + + +static void +verify_magic(void) +{ + /* only check that magic starts with "ustar" - works for + standard UNIX tar as well as GNU tar formats. */ + if (strncmp(tarbuf.h.magic, "ustar", 5) != 0) { + fprintf(stderr, "bad tar header magic\n"); + exit(1); + } +} + + +static void +verify_checksum(void) +{ + unsigned int i; + int csum; + + if (sscanf(tarbuf.h.chksum, "%o", &csum) != 1) { + fprintf(stderr, "bad tar checksum format\n"); + exit(1); + } + memset(tarbuf.h.chksum, ' ', sizeof(tarbuf.h.chksum)); + for (i = 0; i < sizeof(tarbuf.data); i++) + csum -= (unsigned char) tarbuf.data[i]; + if (csum) { + fprintf(stderr, "bad tar checksum value\n"); + exit(1); + } +} + + +static void +update_checksum(void) +{ + unsigned int i; + int csum; + + memset(tarbuf.h.chksum, ' ', sizeof(tarbuf.h.chksum)); + csum = 0; + for (i = 0; i < sizeof(tarbuf.data); i++) + csum += (unsigned char) tarbuf.data[i]; + snprintf(tarbuf.h.chksum, sizeof(tarbuf.h.chksum), "%6o", csum); +} + + +static void +set_owner(const char *username) +{ + const struct passwd *pw; + + pw = getpwnam(username); + memset(tarbuf.h.uname, 0, sizeof(tarbuf.h.uname)); + snprintf(tarbuf.h.uname, sizeof(tarbuf.h.uname), "%s", username); + snprintf(tarbuf.h.uid, sizeof(tarbuf.h.uid), "%6o ", (int) (pw ? pw->pw_uid : 0)); +} + + +static void +set_group(const char *groupname) +{ + const struct group *gr; + + gr = getgrnam(groupname); + memset(tarbuf.h.gname, 0, sizeof(tarbuf.h.gname)); + snprintf(tarbuf.h.gname, sizeof(tarbuf.h.gname), "%s", groupname); + snprintf(tarbuf.h.gid, sizeof(tarbuf.h.gid), "%6o ", (int) (gr ? gr->gr_gid : 0)); +} + + +static void +process_archive(void) +{ + ssize_t nread; + long size; + + size = 0; + for (;;) { + /* read the header or data block */ + block_read(); + /* copy data blocks, if any */ + if (size > 0) { + block_write(); + size -= RECORD_SIZE; + continue; + } + if (block_is_eof()) { + /* eof marker */ + block_write(); + break; + } + + verify_magic(); + verify_checksum(); + + /* process the header */ + switch (tarbuf.h.typeflag) { + case LNKTYPE: + case SYMTYPE: + case CHRTYPE: + case BLKTYPE: + case DIRTYPE: + case FIFOTYPE: + /* no data blocks - ignore size */ + break; + case REGTYPE: + case AREGTYPE: + case CONTTYPE: + default: + if (sscanf(tarbuf.h.size, "%lo", &size) != 1) { + fprintf(stderr, "bad size format\n"); + exit(1); + } + break; + } + + /* XXX - for now, just chown all files to root:root. */ + set_owner("root"); + set_group("root"); + + update_checksum(); + /* write the modified header */ + block_write(); + } + /* eof marker detected, copy anything beyond it */ + for (;;) { + nread = xread(infd, tarbuf.data, RECORD_SIZE); + if (nread == 0) + break; /* end of file */ + xwrite(outfd, tarbuf.data, (size_t) nread); + } +} + +#if 0 +/* permission specification file format, fixperms-1.00 compatible: + type filename owner group mode [linkname | major minor] [# comment] + + type: + - = regular file + l = link + d = directory + c = char dev + b = block dev + p = fifo + s = socket + + filename - absolute pathname, wildcards ok [not for fixperms] + linkname - only for type l + major, minor - only for type c or b + owner group - numeric, or names [not for fixperms] + + XXX not yet implemented +*/ + +struct permspec { + char *name; + uid_t uid; + gid_t gid; + mode_t mode; + char *uname; + char *gname; + char *linkname; + dev_t dev; + struct permspec *next; +}; +#endif diff --git a/current/doc/ANNOUNCE b/current/doc/ANNOUNCE new file mode 100644 index 00000000..a19ad596 --- /dev/null +++ b/current/doc/ANNOUNCE @@ -0,0 +1,48 @@ +$Id: ANNOUNCE,v 1.4 2000/08/26 18:27:09 marekm Exp $ + +[ This is the original comp.os.linux.announce posting (only the + author's name and e-mail address has been updated), kept here + for historical reasons. Many things have changed since then. + Linux distributions are using it, and the mailing list address + has been changed. See README.linux (in the same directory) + for more up to date information. --marekm ] + +This is a new beta release of the Shadow Password Suite for Linux. +Many bugs have been reported (and fixed!), and the package is now +under a BSD-style copyright. It was written by Julianne F. Haugh +, and the Linux port is now maintained by me. + +Again, this is beta software which may still have some bugs, please +treat it as such. Please don't install it if you don't know what +you're doing. Please test it as much as you can, and report any +bugs - if you report them, they will be fixed! If all goes well, +Shadow should be stable enough for general use within a few months. +Once it is stable, Linux distributions can start using it - there +are no copyright problems anymore. + +Thanks to Greg Gallagher there is now +a developers mailing list, shadow-list@neptune.cin.net. Send the +command "subscribe" to shadow-list-request@neptune.cin.net (NOT to +the mailing list itself!) to subscribe if you are interested. + + +LSM entry follows: + +Begin3 +Title: Shadow Password Suite +Version: 3.3.3-951218 +Entered-date: 18DEC95 +Description: +Keywords: login passwd security shadow +Author: jfh@austin.ibm.com (Julie Haugh) +Maintained-by: marekm@i17linuxb.ists.pwr.wroc.pl (Marek Michalkiewicz) +Primary-site: sunsite.unc.edu /pub/Linux/system/Admin + 220K shadow-951218.tar.gz +Alternate-site: ftp.ists.pwr.wroc.pl /pub/linux/shadow +Original-site: ftp.uu.net ? +Platforms: +Copying-policy: BSD-like +End + +Marek Michalkiewicz +marekm@i17linuxb.ists.pwr.wroc.pl diff --git a/current/doc/CHANGES b/current/doc/CHANGES new file mode 100644 index 00000000..36d2ab10 --- /dev/null +++ b/current/doc/CHANGES @@ -0,0 +1,694 @@ +$Id: CHANGES,v 1.30 2000/09/02 18:40:42 marekm Exp $ + +shadow-20000826 => shadow-20000902 + +This is probably the last release from me. +Tomasz Kloczko is the new maintainer. +Good luck! + +(I'm still interested to know what is going on with this package, +which is fairly important to many Linux distributions, so please +Cc: marekm@linux.org.pl in any related discussions - just don't +expect me to respond quickly...) + +Previous warning still applies - be careful! + +- applied some of the Red Hat patches (revised slightly), thanks to + Bernhard Rosenkraenzer : fix for truncated long + lines (>8K) in /etc/group, send SIGHUP to nscd (caching daemon + in glibc 2.1.x) after changing anything, add usermod -L and -U + options, remove LOG_CONS from openlog(), chage -d and -E handles + dates in yyyy-mm-dd format ('/' is not required) +- various cleanups + +shadow-19990827 => shadow-20000826 + +WARNING: this release is not tested (other than that it compiles for me), +please be careful. Previous release was a year ago, so it is really time +to release something and start looking for a new, better maintainer... +(I've been extremely busy recently. Credit for most of the real work, +such as complete PAM support, should go to Ben Collins +who maintains this package for Debian.) + +- merged most of the changes from Debian (not all of them yet, PAM support + should be complete but is not tested - need to upgrade to potato first) +- added Polish translations of manual pages from PLD +- change sulog() to not depend on global variables oldname, name +- try to not follow symbolic links when deleting files recursively + in userdel (still not perfect, safest to do it in single user mode) +- removed workarounds for ancient (pre-ANSI) C compilers - use gcc! + (a few ANSI C constructs were used already, and no one complained) +- updated author's e-mail address (jfh@bga.com -> jfh@austin.ibm.com) + +shadow-19990709 => shadow-19990827 + +- upgrade to autoconf-2.13, automake-1.4, libtool-1.3.3 +- i18n: added French translation by Vincent Renardias +- i18n: added Swedish translation by Kristoffer Brånemyr +- logoutd no longer reads /etc/logoutd.mesg at startup - instead, read + it when sending to luser's tty (no need to reload with SIGHUP) +- added support for "usergroups" feature often found in Linux distributions + (if USERGROUPS_ENAB in login.defs set to "yes", uid != 0, uid == gid, and + username == groupname, then set umask to 002 instead of 022) +- Debian: pwck and grpck are now run from a daily cron job (root will + receive an e-mail if something is wrong), and at system startup +- added support for setting umask in /etc/limits +- when using OPIE, re-prompt with echo on after empty password was entered +- GETPASS_ASTERISKS now run time configurable (login.defs) +- getpass() now uses stdin and stderr (not stdout) if it can't open /dev/tty +- getpass() allows all input to be erased using Control-U, and beeps when + too many characters are entered +- removed obsolete sgtty support, in 1999 everyone should have termios :) +- Debian: tar wrapper no longer needed to build packages as non-root user + (install libtricks, and use "dpkg-buildpackage -rfakeroot" instead) +- Debian: changes for GNU Hurd by Marcus Brinkmann : + dpkg-architecture, cross compilation, only build passwd, add + etc/login.defs.hurd conffile, conditionalize CBAUD +- newgrp sets $HOME before running the new shell +- both "sg group command" (usage message) and "sg group -c command" + (man page) work, updated both the usage message and the man page :) +- i18n: added missing _() for some translatable strings + +shadow-19990607 => shadow-19990709 + +- added PAM support to chfn and chsh (thanks to Thorsten Kukuk) +- fixed a bug in newgrp if the user is in >= 17 groups +- added @LIBSKEY@ to LDADD for all programs (for some reason, + almost all programs need it if skey/opie support is enabled) +- changed grpconv/grpunconv to compile with --disable-shadowgrp +- changed faillog to do something (assume -p) with no options specified +- updated version of the udbachk passwd/shadow/group file integrity + checker (contrib/udbachk.v012.tgz) + +shadow-19990307 => shadow-19990607 + +- upgraded to libtool-1.2, latest config.{guess,sub} +- added missing #include "defines.h" in libmisc/login_desrpc.c - thanks + to almost everyone for reporting it :-) +- moved PAM-related defines to pam_defs.h +- added some braces to if/else to avoid egcs warnings +- started adding PAM support to login (based on util-linux, not finished yet) +- changed "!" to "x" for pw_passwd in src/newusers.c +- a few more Y2K fixes +- added contrib/udbachk.tgz (passwd/shadow/group file integrity checker), + thanks to Sami Kerola +- Debian: made /etc/{limits,login.access,login.defs,porttime,securetty} + files all mode 0600 (Bug#38729 - login: /etc/limits is world readable) +- updated mailing list information (moved again, now hosted by SuSE), + updated README.mirrors, other minor documentation updates +- made getpass work with redirected stdin +- new readpass echoing asterisks disabled by default by popular demand + (can be enabled at compile time: ./configure --enable-readpass) +- the random number of asterisks in readpass is now more random + (random number generator initialization was missing) +- commented out --enable-md5crypt (obsolete) in configure.in +- when checking for libskey, link with -lcrypt if libcrypt is available + (otherwise the configure test for libskey fails - libskey needs libcrypt) +- added Package/Version ident strings (so you can use the RCS "ident" + command to check any binary, which version of shadow it comes from) + +shadow-981228 => shadow-19990307 + +- added support for setting process priority in /etc/limits +- i18n: updated Greek translation +- i18n: added Polish translation by Arkadiusz Miskiewicz +- documented the -p option in useradd.8 and usermod.8 man pages +- some "const" gcc warning fixes +- attempt to fix lib/snprintf.c compilation problems +- added restart/reload/force-reload to /etc/init.d/logoutd (found by lintian) +- always require password for root logins (even with NO_PASSWORD_CONSOLE) +- workaround for RedHat's CREATE_HOME feature in /etc/login.defs +- changed to Y2K compatible version numbering +- more Y2K fixes, use the ISO 8601 date format (yyyy-mm-dd) for default + values of user-entered dates (you can still enter dates in any format + supported by GNU date) +- oops, added doc/README.nls to list of files to distribute +- added missing sanitize_env() call to src/login.c +- debian/rules installs /bin/login non-setuid by default, just in case... +- build Debian packages with cracklib support (depends on cracklib-runtime) + +shadow-980724 => shadow-981228 + +- login now clears the username in argv[] (in case someone types the + password instead of username, by mistake) +- i18n support, Greek translation (Nikos Mavroyanopoulos), see README.nls +- updated author's e-mail address (jfh@tab.com -> jfh@bga.com) +- new getpass() replacement that displays *'s (Pavel Machek) +- no password required when logging in from ttys listed under + NO_PASSWORD_CONSOLE in login.defs (Pavel Machek) +- fixed limits code so RLIMIT_AS should work +- upgraded to Debian 2.0 +- built a new machine (P2 350MHz, 64MB RAM) so the thing can be compiled + in reasonable time again +- upgraded to automake-1.3, libtool-1.0h (also new config.guess and + config.sub that work on i686) +- usermod fixed to handle group names starting with digits (not recommended) + +shadow-980626 => shadow-980724 + +- security: login no longer gives you a root shell if setgid() + or initgroups() or setuid() fails for any reason, discovered + by Ted Hickman +- remove libshadow.so -> libshadow.so.x.x symlink after install +- a few int -> uid_t type cleanups +- fail immediately (don't retry) in *_lock() if euid != 0 +- added sample PAM config files etc/pam.d/{passwd,su} +- preliminary PAM support in su (untested - use at your own risk, + comments and patches welcome!) +- cleanup and more comments in OPIE code (Algis Rudys) +- added support for TCFS (Transparent Cryptographic File System) + (use ./configure --with-libtcfs, see http://tcfs.dia.unisa.it/ + for more info), thanks to Aniello Del Sorbo + +shadow-980529 => shadow-980626 + +- fixed bug in commonio_lock() (infinite recursion if lckpwdf() not + used and database cannot be locked), thanks to Jonathan Hankins +- fixed bug in copy_tree() (NUL-terminate readlink() results), + thanks to Lutz Schwalowsky +- no need to press Enter after Ctrl-C to interrupt password prompt +- removed a few harmless gcc warnings +- secure RPC login disabled if not found (glibc 2.0) +- faillog.8: changed /usr/adm -> /var/log +- pwconv.8: documented that it may fail on invalid password files + +shadow-980417 => shadow-980529 + +- fixed "interesting" strzero() bug introduced by me in 980417: + strzero(cp) didn't work as intended (the macro used a local + variable called "cp" - oops...); Leonard N. Zubkoff was the + first person to report it - thanks! +- fixed usermod -e to accept empty argument (like useradd), + thanks to Martin Bene +- several changes from Debian 980403-0.2, see debian/changelog +- added contrib/shadow-anonftp.patch (not yet merged, sorry...) + thanks to Calle Karlsson + +shadow-980403 => shadow-980417 + +- fixed login session limits (again - broken since 980130) +- more symbolic constants for exit status values +- fixed logoutd to work with 8-character usernames in utmp + (no room for terminating NUL!) +- various fixes to make the code more glibc2-friendly +- updated doc/cracklib26.diff (fix for empty gecos, etc.) +- updated the files in redhat/ from shadow-utils-970616-11.src.rpm + (RH 5.0 updates) + +shadow-980130 => shadow-980403 + +- security: su now creates the sulog file (if enabled and doesn't + already exist) with umask 077 +- hopefully removed arbitrary group size limits (not yet for + shadow groups though - sgetsgent() still needs a rewrite, + but I don't want to delay this release any longer...) +- fixed NULL dereference in groupmod -n + +shadow-971215 => shadow-980130 + +- Debian binary packages can be built without root privileges + (tar wrapper - debian/tar.c) +- new subdir "redhat" (needs more work, see redhat/README) +- in several places, exit(127) if exec fails with ENOENT, and + exit(126) on other errors (as in ksh and bash) +- renamed getpass() and md5_crypt() to libshadow_* to avoid name + conflicts with libc functions - md5_crypt() is also in libcrypt.a + on Linux/PPC, thanks to Anton Gluck +- handle crypt() returning NULL (possible according to Single Unix + Spec) more gracefully (exit instead of SIGSEGV) +- fixed bug in putgrent() that showed up when realloc() moved the + buffer while expanding it, thanks to Floody +- fixed bug in login session limits (with a limit set to N logins, + only N-1 logins were allowed), thanks to Floody +- upgraded to libtool-1.0h (now recognizes GNU ld on Debian 1.3.1) +- newer config.guess and config.sub (should work on x86 for x > 5) +- removed doc/automake-1.0.diff (obsoleted by automake-1.2) +- added doc/cracklib26.diff (some patches for cracklib-2.6) +- documented more (not all yet) login.defs(5) settings +- replaced more exit status numeric values with #defines +- shadow-utils.spec now generated from shadow-utils.spec.in + (so I don't have to edit version numbers for every new release) +- groupadd -f option, based on RedHat's shadow-utils-970616-9 patch + ("force" - exit(0) if the group already exists); other RedHat- + specific options not added yet (best done in a perl script that + runs useradd/usermod/groupadd - see Debian's adduser-3.x) +- added -O option (override login.defs values) to useradd and groupadd +- if usermod can't update the group file(s), exit(10) but update the + password file(s) anyway (as documented by Solaris man page) +- useradd should no longer set sp_expire to the current date (oops) +- configure.in: added --enable-desrpc, check for gethostbyname in libc + before trying libnsl (necessary for Solaris; not for Linux or Irix, + even though libnsl may be present), fixed pw_age/pw_comment/pw_quota + detection, setpgrp vs. setpgid, other minor tweaks +- various */Makefile.am tweaks +- login.defs: added FAKE_SHELL - program to run instead of the login + shell, with the real shell in argv[0] (Frank Denis) +- login.defs: ignore case in yes/no settings +- more E_* defines instead of hardcoded numbers for exit() +- added sanitize_env() for setuid programs +- login_desrpc() checks for getnetname() errors +- new password is not "too similar" if it is long enough +- replacement strstr() was static, no one noticed :-) +- {pw,spw}_lock() and {pw,spw}_unlock() track the lock count and call + lckpwdf() and ulckpwdf() as needed, *_lock_first() hack removed +- login sets $REMOTEHOST for remote logins +- added newgrp -l option (Single Unix Spec, same as "-") +- EXPERIMENTAL shared lib support using libtool (libshadow.so saves about + 200K of disk space on Linux/x86), enabled by default if supported by + the system, use ./configure --disable-shared if it causes any problems. + Warning: libshadow.so is intended for internal use by this package + only - binary compatibility with future releases is not guaranteed. + There should be no need to link any other programs with libshadow.so - + the libshadow.so -> libshadow.so.x.x symlink is unnecessary. +- pam_strerror() takes one or two arguments, depending on the Linux-PAM + version (!) - added check to configure; fixed do_pam_passwd prototype +- libmisc/login_access.c should compile on Linux/PPC and Solaris +- added information about the new ftp site to doc/README.mirrors + +shadow-971001 => shadow-971215 + +- added workaround for NYS libc 5.3.12 (RedHat 4.2) bug to grpck +- updated the RPM .spec file +- renamed rlogin() to do_rlogin() to avoid Linux/PPC build problem + (glibc defines something else named "rlogin" in utmpbits.h ?) +- added MD5 checksums in Debian packages +- added -p and -g options to vipw (edit the password or group file + respectively, regardless of the command name in argv[0]) +- removed old DBM support (NDBM code is still there) +- fixed a bug in gpasswd: current username was incorrectly identified as + "root" because of setuid(0) done too early. It may be a security hole + when using shadow groups - if "root" is listed as a group administrator, + any user can add/remove members in that group. Thanks to Jesse Thilo. +- gpasswd now logs which user (root or group admin) made the changes +- passwd now uses $PATH to search for the chfn, chsh, gpasswd commands +- newgrp and add_groups() allocate supplementary group lists dynamically +- moved check_shell() from src/chsh.c to libmisc/chkshell.c +- CHFN_RESTRICT in login.defs can now specify exactly which fields may be + changed by regular users (any combination of letters "frwh") +- fixed contrib/pwdauth.c segfault with non-existent usernames +- minor change in lib/getdef.c to handle quotes better (Juergen Heinzl) +- new date parsing code (from GNU date) used by useradd, usermod, chage +- upgraded to automake-1.2, added libtool-0.7 (no libshadow.so yet) +- converted code to ANSI C, added ansi2knr (untested - use gcc!) +- fixed useradd -G segfault (one '*' that shouldn't be there) +- allow 8-bit characters in chfn +- added support for RLIMIT_AS (max address space) in libmisc/limits.c +- changed the handling of NIS plus entries in password files +- some more tweaking in various debian/* files +- logoutd uses getutent() instead of reading utmp file directly +- fixed lckpwdf() called twice (and failing) when changing password + if the user is not listed in /etc/shadow (Mike Pakovic) +- erase and kill characters left unchanged if not defined in login.defs + +shadow-970616 => shadow-971001 + +- Debian: mkpasswd no longer installed (dbm files not supported) +- chpasswd checks for shadow/non-shadow at run time, too +- added chpasswd -e (input file with encrypted passwords) - Jay Soffian +- changed libmisc/login_access.c as suggested by Dave Hagewood +- replaced sprintf() with snprintf() in several places +- added lib/snprintf.[ch] (from XFree86) for systems without snprintf() +- minor tweaks in contrib/adduser.c (/usr/local -> /usr) +- non-root users can only run su with a terminal on stdin +- temporarily disabled DES_RPC because getsecretkey() causes login to hang + for 5 minutes on at least one RH 4.0 system. Not sure if this is a bug + in libc, or system misconfiguration. Needs further investigation. +- check for strerror() and -lrpcsvc (should compile on SunOS again) +- fixed free() called twice in libmisc/mail.c +- added information about mirror sites (doc/README.mirrors) +- updated pwconv.8 and pwunconv.8 man pages +- "make install" now installs pwconv, pwunconv, grpconv, grpunconv +- pwauth.8 no longer installed (AUTH_METHODS not supported by default) +- corrected su.1 man page ($SHELL not used) +- no need for --with-md5crypt if the MD5-based crypt() is already in libc + (or another library specified in /etc/ld.so.preload - Linux ld.so 1.8.0+) +- cleaned up PASS_MAX in getpass() (127 always assumed) +- default editor for vipw changed from /bin/ae to a real editor :) + +shadow-970601 => shadow-970616 + +- fixed execlp call (missing NULL) in src/vipw.c +- vipw now preserves permissions on edited files +- commented out the xdm-shadow hack in shadowconfig +- improved RedHat spec file (Timo Karjalainen) +- updated mailing list information +- added information about the shadow paper (doc/README.shadow-paper) +- renamed doc/console.c.spec (confused RPM) + +shadow-970502-2 => shadow-970601 + +- fixed a typo in libmisc/mail.c causing login to segfault + if MAIL_CHECK_ENAB=yes (sorry!) +- patches for OPIE support (Algis Rudys) (untested) +- programs that modify /etc/passwd or /etc/shadow will use + lckpwdf() if available +- now compiles with PAM support! (still untested) +- cosmetic error message changes (prefixed by argv[0]:) + +shadow-970216 => shadow-970502-2 + +- shadow group support fixes (grpconv didn't work - for some + reason, putsgent() returns 1 instead of 0 on success; + now -1 = failure, anything else = success) +- upgraded to autoconf-2.12 +- pwconv and pwunconv now follow other UN*X systems and SVID3 + (modify files in place), original versions moved to "old" +- scologin.c moved to "old" (it was only for SCO Xenix) so + people stop sending patches for scologin.c gcc warnings :) +- don't use the MD5* functions in libmisc/salt.c (glibc has + the new md5 crypt(), but no and MD5* functions!) +- support for MkLinux, Solaris, JIS, Qmail (Frank Denis) +- "passwd -S -a" now really works +- support for Debian, vipw, a few fixes (Guy Maor) +- src/login.c radius bug fix (Rafal Maszkowski) +- ISSUE_FILE_ENAB -> ISSUE_FILE in the sample /etc/login.defs +- fixes for glibc and DES_RPC (Thorsten Kukuk) +- limits.5 man page (Luca Berra) +- expiry will work setgid shadow too, removed euid 0 check +- added check for a64l() to configure (glibc) + +shadow-961025 => shadow-970216 + +- major rewrite of *io.c (no more 4 copies of almost identical code) +- use fsync() (if available) instead of sync() when updating password files +- use fchmod() and fchown() if available +- keep the NIS "plus on a line by itself" entries at end of passwd/group +- configure checks location of passwd/chfn/chsh programs (/usr/bin or /bin) +- passwd -S -a: list information about all users (root only) +- passwd -k: change only expired passwords +- passwd -q: quiet mode +- first attempt at PAM support in passwd +- passwd updates the non-shadow password if /etc/shadow exists but the + user has no shadow password +- passwd logs who changed the password, added hook to allow non-root + administrators who can change passwords (not implemented yet) +- su sets $HOME even without the "-" option (suggested by Joey Hess) +- added -p (set encrypted password) option to useradd and usermod + (idea from hpux10 - undocumented option used internally by SAM) +- useradd -D -e does the right thing (set default expiration date) +- USERDEL_CMD in login.defs instead of hardcoded {ATRM,CRONTAB}_COMMAND + because there are just too many systems that need different commands +- removed #ifdef FAILLOG_LOCKTIME (now always enabled), warning: the + faillog file format has been changed (somewhere between 960129 and + 960810), please truncate the old file (if any) to zero length +- ISSUE_FILE (may be different from /etc/issue) instead of ISSUE_FILE_ENAB +- wtmp, lastlog, faillog file location guessed by configure +- separate checks for invalid user and group names, max username length + based on struct utmp (it's not always 8 characters) +- pwck and grpck now check for invalid user/group names +- pwck -q (quiet, report only serious problems) option added +- separate cleaner sgetpwent() without the NIS magic +- NIS entries ignored (never changed) by *io.c, pwck, grpck +- various code cleanups +- new get_my_pwent() function for getting my own username, uid etc. +- faillog opens the file read-write if possible (even if not root) +- passwd -S allowed for normal users (for their own uid only) +- handle the case of login denied to passwordless accounts better + ("Login incorrect" without "Password:" prompt looks strange) +- corrected author information and removed a copyright restriction + +shadow-960925 => shadow-961025 + +- fixed a few typos in shadow group code +- don't check for names starting with 'r' to determine if the shell + is restricted, use /etc/shells instead (for the "rc" shell) +- removed extra definition of LASTLOG_FILE in configure.in +- expiry no longer segfaults if no /etc/shadow +- userdel -r "can't remove mailbox" warning no longer printed on success +- useradd exit codes changed to match hpux10 man page +- fixed possible fd leak etc. in file locking code (lib/commonio.c) + +shadow-960920 => shadow-960925 + +- bug fixes to the new environment code using malloc +- use hardcoded names instead of basename(argv[0]) for openlog() in programs + that users can run (chage, chfn, chsh, gpasswd, login, newgrp, passwd, su) +- small fix to isexpired(), and use it in passwd as well +- use strftime() and strptime() if available +- added chmod 600 /etc/passwd- at the end of pwconv5 (backup file may + contain encrypted passwords!) +- pass size to change_field (chage, chfn, chsh) instead of assuming BUFSIZ + (nothing bad happened yet, just a cleanup) +- gpasswd should work with both shadow and non-shadow group passwords +- detect unsupported options if no shadow (gpasswd, useradd, usermod) +- passwd -e for sunos4 (ATT_AGE), untested +- read environment from file (ENVIRON_FILE in login.defs), idea from ssh +- small fix to l64a() +- passwd prints a message after password successfully changed (for things + like poppassd which run passwd and expect some output) +- passwd logs if password was changed by root (as opposed to a luser) +- passwd uses current uid if no username argument and getlogin() fails + +shadow-960910 => shadow-960920 + +- use malloc for environment variables, no more MAXENV (Juergen Heinzl) +- newusers should work with both shadow and non-shadow passwords + (still left to do: chpasswd, gpasswd) +- login-static no longer compiled by default +- more SYSLOG() macros + +shadow-960810 => shadow-960910 + +- updated README.linux to point to the new ftp site +- chfn and chsh optionally (CHFN_AUTH) prompt for password like util-linux +- man pages now closer to LDP standards (Ivan Nejgebauer) +- newgrp uses SYSLOG_SG_ENAB (not SU) as in the /etc/login.defs comments +- obscure.c fixed to compile with HAVE_LIBCRACK +- cosmetic message changes in age.c +- utmp open error check fixed in utmp.c +- grpunconv added (Michael Meskes) +- login reports invalid login time, not "Login incorrect" (Ivan Nejgebauer) +- logoutd sets OPOST before writing to the tty (Ivan Nejgebauer) +- sulogin: don't use syslog(), other minor changes (Ivan Nejgebauer) +- passwords can be changed if sp_max == -1 (now considered infinity) +- usermod: don't use sizeof(struct lastlog) when writing to faillog (ugh) +- started replacing lots of #ifdef USE_SYSLOG with cleaner macros +- contrib/rpasswd.c added (Joshua Cowan) +- PASS_MAX is 127 with MD5_CRYPT (not just for Linux - sunos4 too...) +- workarounds for a RedHat NYS libc getspnam() bug (if /etc/shadow + doesn't exist, it succeeds and returns sp_lstchg==0 instead of -1). + +shadow-960129 => shadow-960810 + +- automake, configure checks for libcrypt and libcrack (Janos Farkas) +- added --enable-shadowgrp to configure (shadow groups disabled by default) +- should compile on SunOS 4.1.x - but it does NOT mean that it works :-) +- login sets HUSHLOGIN=TRUE or FALSE (for shell startup scripts etc.) +- hopefully removed all the rcsid warnings +- contrib/atudel perl script to remove at jobs (thanks to Brian Gaeke) +- resource limits (Cristian Gafton) +- workaround for buggy init/getty(?) leaving junk in ut_host on RedHat +- more fixes in man pages +- pwck and grpck no longer suggest to run mkpasswd if *DBM not compiled in +- most programs (groupadd, groupdel, groupmod, grpck, login, passwd, pwck, + su, useradd, userdel, usermod) should now work with both shadow and + non-shadow passwords/groups (check for /etc/shadow and /etc/gshadow at + run time); a few programs still left to do +- mailbox mv/chown/rm in usermod/userdel (suggested by Cristian Gafton) +- new contrib/adduser.c from Chris Evans +- lots of other minor changes +- source tree reorganization, GNU autoconf, portability cleanups +- basename() renamed to Basename() to avoid name space confusion +- new programs to create /etc/shadow and /etc/gshadow: pwconv5, grpconv +- newgrp cleanup and a few fixes +- useradd uses PASS_MAX_DAYS, PASS_MIN_DAYS and PASS_WARN_AGE +- don't make the first group member the group admin by default + (define FIRST_MEMBER_IS_ADMIN to get the old gpasswd behaviour) +- password aging constants, NGROUPS_MAX and syslog stuff in only one + place (defines.h) instead of repeating it in all source files... +- added userdel -r safety check (refuse to remove the home directory + if it would result in removing some other user's home directory) +- usermod -u now correctly checks for non-unique uid (unless -o) +- sync() after updating password files, just to be more safe +- "make install" should install /etc/login.defs if it doesn't exist +- new option to control what happens if we can't cd to the home directory + (DEFAULT_HOME in /etc/login.defs) +- enter the home directory as the user, not as root (for NFS etc.) +- added check for Slackware bugs (nobody UID -1) in pwck and grpck +- new CONSOLE_GROUPS feature (thanks to pacman@tardis.mars.net), it is + possible to add specified groups (floppy etc.) for console logins +- new faillog feature: lock account for specified (per-user) time since + the last failure after exceeding the failure limit +- new man pages (gpasswd.1, login.access.5, suauth.5) +- fixes in man pages, renamed *.4 to *.5 +- new "contrib" directory (two adduser programs) +- changed some "system" to "feature" #ifdefs (autoconf someday...) +- sulogin no longer requires to be run from init, should work from rc + scripts too +- changes to prevent unshadowing with libc SHADOW_COMPAT (get info + using xx_locate(), modify it and call xx_update(), don't write back + anything returned by getpwnam() etc.) +- stupid bug fixed in lastlog.c +- don't move non-directories in "usermod -m" +- don't log unknown usernames (passwords mistyped for usernames) (lmain.c) +- macros to get around ancient compilers which don't like prototypes +- make more use of "const" (not everywhere yet) +- added #ifdef AUTH_METHODS - very few people use administrator defined + authentication methods because many programs are not aware of them; + not supporting them makes the code simpler +- new "save" and "restore" Makefile targets, thanks to Rafal Maszkowski +- sgetgrent() in libshadow.a is optional, some versions of libc have it, + see HAVE_SGETGRENT in config.h (grent.c) +- don't use continued lines in /etc/group, the standard getgr*() functions + don't support that (grent.c) +- removed the third main() argument (according to libc docs, not allowed by + POSIX.1 - use environ instead) (lmain.c, smain.c, newgrp.c, sulogin.c) +- login access control (lmain.c, login_access.c) +- added copyright notice to login_access.c (from logdaemon-5.0) +- detailed su access control (smain.c, suauth.c) - thanks to Chris Evans +- added closelog() in su before executing the shell (smain.c) +- getting current user name changed (smain.c) +- "x" instead of "*" in pw_passwd, consistent with pwconv (useradd.c) +- getpass() shouldn't return NULL except on errors (getpass.c) +- moved isexpired() to isexpired.c (now part of libshadow.a) from age.c +- SunOS4-like passwd -e (force change on next login) (isexpired.c, passwd.c) +- can use shadow support in new versions of Linux libc instead of libshadow.a, + see HAVE_SHADOWPWD, HAVE_SHADOWGRP in config.h.linux (shadow.c, gshadow.c) +- "no shadow password" not logged, the same /bin/login should work with both + shadow and non-shadow passwords (lmain.c) +- some cleanup in various places (lmain.c, passwd.c) +- new program to verify username/password pairs, for xlock etc.; it is not + installed by default, read the comments first (pwdauth.c) +- authentication programs run with empty environment for safety (pwauth.c) +- added missing fstat error checks (faillog.c, lastlog.c, setup.c, *io.c) +- common code separated from *io.c (commonio.c) +- ownership and permissions on password files are now preserved (we may try + to make more use of setgid and setuid non-root programs in the future) +- added (untested) MD5-based crypt() from FreeBSD (md5crypt.c), see + MD5_CRYPT in config.h.linux and MD5_CRYPT_ENAB in login.defs.linux +- termios/termio/sgtty macros cleaned up a bit + +shadow-951218 => shadow-960129 + +Emergency bug fix release - no new features since 951218. There are many +new changes, but this bug really can't wait until they are tested. + +Probably all previous versions of the shadow suite have a serious bug which +makes it possible to overwrite the stack by entering very long username at +the login prompt. This can give root access to any remote user! + +Changed the maximum size in login.c from BUFSIZ (1024) to 32 (to match +size of the array in lmain.c). Aaargh!!! + +shadow-951203 => shadow-951218 + +Changes: +- Linux utmp handling fixes (utmp.c) +- last failure date printing fixes (failure.c) +- minor fix to compile with USE_CRACKLIB (obscure.c) +- eliminated the use of snprintf (env.c, lmain.c, login.c, shell.c, smain.c) +- basename.c added, replacing duplicated code in various places +- "su -" runs the shell with '-' in argv[0] again (smain.c) +- removing at/cron jobs cleaned up (userdel.c) +- /etc/gshadow should not be world-readable (sgroupio.c) +- if fflush() failed, files were not closed (*io.c) +- login prompt is now "hostname login: " on Linux (lmain.c, login.c) +- "save" and "restore" targets commented out (don't work) (Makefile.linux) +- some minor cleanups for gcc -Wall (unused variables etc.) +- removed README.FIRST (copyrights are OK now) +- updated ANNOUNCE, README.linux, WISHLIST +- as suggested, converted to RCS + +shadow-3.3.2-951127 => shadow-951203-jfh + +Changes: +- Added the BSD-style copyright to all of the files. Any files with the + old copyright have multiple copyright holders and need to be cleanroomed + to produce BSD-style copyrightable files, or I need to get the consent + of the others to change the copyright. +- Changed the ANNOUNCE file to not refer to the README.FIRST file. Now + that all of the files should have the correct copyright there is no need + to refer to that e-mail message. +- Changes SCCS strings to "%W% %U% %G%". Marek needs to either convert to + RCS or check into SCCS and then checkout. I'd suggest using RCS ;-) + + jfh@rpp386.cactus.org + +shadow-3.3.2-951106 => shadow-951127 + +Note: for now this code only supports Linux. All the #ifdef's are there +(and will be; support for at least SunOS 4.1.x would be nice) but: +- I had to fix some potential security problems resulting from sloppy + coding (no bounds checking), and it was easier for me to use snprintf() + (not available on many systems, unfortunately), I'll fix that later. + Old versions of Linux libc don't have snprintf() either, and the one + in libbsd.a ignores the max size - don't use it! (libc-4.6.27 is OK) +- I am lazy and only updated Makefile.linux and config.h.linux this time +- I don't have root access to non-Linux systems (this means no testing) +- this code needs some major reorganization, which will (hopefully) + make porting easier + +Changes: +- some code cleanup, prototypes.h, defines.h, Makefile and config.h changes +- login can be statically linked (not that I think it's a good idea, better + fix the telnetd, but paranoid people will like it :-) +- login is installed non-setuid by default +- check for NULL from getpass() +- wipe cleartext password from getpass() when no longer needed (pwauth.c) +- use standard "Password: " prompt by default (pwauth.c) +- hopefully fixed bogus sigaction() stuff (Linux only) (getpass.c) +- oops, setrlimit wants bytes, ulimit wants 512-byte units (lmain.c) +- Linux has +- print ll_host on Linux too (lmain.c) +- size checking in various places (setuid root programs, argh!) +- preserve TERM from getty (lmain.c) +- don't ignore SIGHUP (lmain.c) +- :%s/setenv/set_env/g (setenv(3) conflict) (env.c, lmain.c, login.c) +- remove LD_xxx (env.c) +- use bzero() instead of memset() for BSD portability and less #ifdef's + (if the system has no bzero(), implement it as a macro using memset()) +- the above fixes wrong order of memset() parameters (log.c) +- use getutent/pututline instead of doing it by hand (utmp.c) +- added the new settings to login.defs.linux +- added login_access.c to the distribution (not used yet) + +========== + +shadow-3.3.2 => shadow-3.3.2-951106 + +- added dummy pad.c and #ifdef'ed out references to pad_auth (pwauth.c) +- malloc/strdup error checking, hopefully no more core dumps... +- define HAVE_RLIMIT instead of HAVE_ULIMIT for Linux (config.h.linux) +- changed pathnames on Linux to conform to new FSSTND (/var/log etc.) +- larger buffer for cipher, for md5 crypt() if and when (encrypt.c, passwd.c) +- use POSIX termios whenever possible on Linux +- list.c, removed add_list/del_list from gpmain.c, user{add,del,mod}.c +- strtoday.c, removed duplicates from chage.c, useradd.c, usermod.c +- login -h only for root (lmain.c) +- login -r not needed for Linux (lmain.c) +- sample login.defs modified for Linux (login.defs.linux) +- swapped chfn USAGE and ADMUSAGE (chfn.c) +- added -u to passwd usage (passwd.c) +- no #! check necessary for Linux (shell.c) +- define OLD_CRON for some old incompatible Linux distributions (userdel.c) +- PASS_MAX is now 127 (not 8) for Linux (getpass.c) +- LOGIN_RETRIES, LOGIN_TIMEOUT, PASS_CHANGE_TRIES are no longer compiled in, + can now be set in login.defs, old values are used as defaults (lmain.c) +- unique uid/gid selection now more robust (useradd.c, groupadd.c) +- UID_MIN, UID_MAX, GID_MIN, GID_MAX in login.defs (useradd.c, groupadd.c) +- CRACKLIB_DICTPATH no longer compiled in, can be set in login.defs (passwd.c) +- PASS_ALWAYS_WARN: warn about weak passwords even for root (passwd.c) +- PASS_MAX_LEN, check truncated passwords again (obscure.c) +- check for weak passwords too if previous password was empty (obscure.c) +- CHFN_RESTRICT: don't let users change their full names (chfn.c) +- Linux has getusershell(), use it (chsh.c) +- check if the new shell is executable by the user (chsh.c) +- sleep before printing "Login incorrect", not the other way around (lmain.c) +- don't be picky about utmp only if any of -rfh flags given (lmain.c) +- do "wheel group" more like BSD does (smain.c) +- use getlogin() in su (smain.c) +- UMASK from login.defs defaults to 077, not 0 (lmain.c, newusers.c) +- #undef HAS_ATRM for Linux until atrm can do what we need (config.h.linux) +- Linux has most commands in /usr/bin, not /bin (age.c, passwd.c, userdel.c) +- ULIMIT from login.defs works on systems using setrlimit() too (lmain.c) +- LOGIN_STRING should work now (pwauth.c, getdef.c) +- kludge to avoid conflict with Linux (gshadow.h) +- mv Makefile Makefile.xenix ; mv config.h config.h.xenix - so that they are + not lost when you copy the right ones to Makefile and config.h + +========== + +shadow-3.3.2 + +Original version, received directly from the author. + diff --git a/current/doc/HOWTO b/current/doc/HOWTO new file mode 100644 index 00000000..01a90ed4 --- /dev/null +++ b/current/doc/HOWTO @@ -0,0 +1,1918 @@ +[ Note: the installation instructions in this document are somewhat + out of date - the package now uses GNU autoconf and is configured + just like most GNU packages: run ./configure then make. --marekm ] + + Linux Shadow Password HOWTO + Michael H. Jackson, mhjack@tscnet.com + v1.3, 3 April 1996 + + This document aims to describe how to obtain, install, and configure + the Linux password Shadow Suite. It also discusses obtaining, and + reinstalling other software and network daemons that require access to + user passwords. This other software is not actually part of the + Shadow Suite, but these programs will need to be recompiled to support + the Shadow Suite. This document also contains a programming example + for adding shadow support to a program. Answers to some of the more + frequently asked questions are included near the end of this document. + + 1. Introduction. + + This is the Linux Shadow-Password-HOWTO. This document describes why + and how to add shadow password support on a Linux system. Some + examples of how to use some of the Shadow Suite's features is also + included. + + When installing the Shadow Suite and when using many of the utility + programs, you must be logged in as root. When installing the Shadow + Suite you will be making changes to system software, and it is highly + recommended that you make backup copies of programs as indicated. I + also recommend that you read and understand all the instructions + before you begin. + + 1.1. Changes from the previous release. + + Additions: + Added a sub-section on why you might not want to install shadow + Added a sub-section on updating the xdm program + Added a section on how to put Shadow Suite features to work + Added a section containing frequently asked questions + + Corrections/Updates: + Corrected html references on Sunsite + Corrected section on wu-ftp to reflect adding -lshadow to the Makefile + Corrected minor spelling and verbiage errors + Changed section on wu-ftpd to support ELF + Updated to reflect security problems in various login programs + Updated to recommend the Linux Shadow Suite by Marek Michalkiewicz + + 1.2. New versions of this document. + + The latest released version of this document can always be retrieved + by anonymous FTP from: + + sunsite.unc.edu + + /pub/Linux/docs/HOWTO/Shadow-Password-HOWTO + + or: + + /pub/Linux/docs/HOWTO/other-formats/Shadow-Password-HOWTO{-html.tar,ps,dvi}.gz + + or via the World Wide Web from the Linux Documentation Project Web + Server , at page: Shadow- + Password-HOWTO or directly from me, . It will also be + posted to the newsgroup: comp.os.linux.answers + + This document is now packaged with the Shadow-YYDDMM packages. + + 1.3. Feedback. + + Please send any comments, updates, or suggestions to me: Michael H. + Jackson The sooner I get feedback, the sooner I + can update and correct this document. If you find any problems with + it, please mail me directly as I very rarely stay up-to-date on the + newsgroups. + + 2. Why shadow your passwd file? + + By default, most current Linux distributions do not contain the Shadow + Suite installed. This includes Slackware 2.3, Slackware 3.0, and + other popular distributions. One of the reasons for this is that the + copyright notices in the original Shadow Suite were not clear on + redistribution if a fee was charged. Linux uses a GNU Copyright + (sometimes refereed to as a Copyleft) that allows people to package it + into a convenient package (like a CD-ROM distribution) and charge a + fee for it. + + The current maintainer of the Shadow Suite, Marek Michalkiewicz + received the source code from the + original author under a BSD style copyright that allowed + redistribution. Now that the copyright issues are resolved, it is + expected that future distributions will contain password shadowing by + default. Until then, you will need to install it yourself. + + If you installed your distribution from a CD-ROM, you may find that, + even though the distribution did not have the Shadow Suite installed, + some of the files you need to install the Shadow Suite may be on the + CD-ROM. + + However, Shadow Suite versions 3.3.1, 3.3.1-2, and shadow-mk all have + security problems with their login program and several other suid root + programs that came with them, and should no longer be used. + + All of the necessary files may be obtained via anonymous FTP or + through the World Wide Web. + + On a Linux system without the Shadow Suite installed, user information + including passwords is stored in the /etc/passwd file. The password + is stored in an encrypted format. If you ask a cryptography expert, + however, he or she will tell you that the password is actually in an + encoded rather than encrypted format because when using crypt(3), the + text is set to null and the password is the key. Therefore, from here + on, I will use the term encoded in this document. + + The algorithm used to encode the password field is technically + referred to as a one way hash function. This is an algorithm that is + easy to compute in one direction, but very difficult to calculate in + the reverse direction. More about the actual algorithm used can be + found in section 2.4 or your crypt(3) manual page. + + When a user picks or is assigned a password, it is encoded with a + randomly generated value called the salt. This means that any + particular password could be stored in 4096 different ways. The salt + value is then stored with the encoded password. + + When a user logs in and supplies a password, the salt is first + retrieved from the stored encoded password. Then the supplied + password is encoded with the salt value, and then compared with the + encoded password. If there is a match, then the user is + authenticated. + + It is computationally difficult (but not impossible) to take a + randomly encoded password and recover the original password. However, + on any system with more than just a few users, at least some of the + passwords will be common words (or simple variations of common words). + + System crackers know all this, and will simply encrypt a dictionary of + words and common passwords using all possible 4096 salt values. Then + they will compare the encoded passwords in your /etc/passwd file with + their database. Once they have found a match, they have the password + for another account. This is referred to as a dictionary attack, and + is one of the most common methods for gaining or expanding + unauthorized access to a system. + + If you think about it, an 8 character password encodes to 4096 * 13 + character strings. So a dictionary of say 400,000 common words, + names, passwords, and simple variations would easily fit on a 4GB hard + drive. The attacker need only sort them, and then check for matches. + Since a 4GB hard drive can be had for under $1000.00, this is well + within the means of most system crackers. + + Also, if a cracker obtains your /etc/passwd file first, they only need + to encode the dictionary with the salt values actually contained in + your /etc/passwd file. This method is usable by your average teenager + with a couple of hundred spare Megabytes and a 486 class computer. + + Even without lots of drive space, utilities like crack(1) can usually + break at least a couple of passwords on a system with enough users + (assuming the users of the system are allowed to pick their own + passwords). + + The /etc/passwd file also contains information like user ID's and + group ID's that are used by many system programs. Therefore, the + /etc/passwd file must remain world readable. If you were to change + the /etc/passwd file so that nobody can read it, the first thing that + you would notice is that the ls -l command now displays user ID's + instead of names! + + The Shadow Suite solves the problem by relocating the passwords to + another file (usually /etc/shadow). The /etc/shadow file is set so + that it cannot be read by just anyone. Only root will be able to read + and write to the /etc/shadow file. Some programs (like xlock) don't + need to be able to change passwords, they only need to be able to + verify them. These programs can either be run suid root or you can + set up a group shadow that is allowed read only access to the + /etc/shadow file. Then the program can be run sgid shadow. + + By moving the passwords to the /etc/shadow file, we are effectively + keeping the attacker from having access to the encoded passwords with + which to perform a dictionary attack. + + Additionally, the Shadow Suite adds lots of other nice features: + + · A configuration file to set login defaults (/etc/login.defs) + + · Utilities for adding, modifying, and deleting user accounts and + groups + + · Password aging and expiration + + · Account expiration and locking + + · Shadowed group passwords (optional) + + · Double length passwords (16 character passwords) NOT RECOMMENDED + + · Better control over user's password selection + + · Dial-up passwords + + · Secondary authentication programs NOT RECOMMENDED + + Installing the Shadow Suite contributes toward a more secure system, + but there are many other things that can also be done to improve the + security of a Linux system, and there will eventually be a series of + Linux Security HOWTO's that will discuss other security measures and + related issues. + + For current information on other Linux security issues, including + warnings on known vulnerabilities see the Linux Security home page. + + + 2.1. Why you might NOT want to shadow your passwd file. + + There are a few circumstances and configurations in which installing + the Shadow Suite would NOT be a good idea: + + · The machine does not contain user accounts. + + · Your machine is running on a LAN and is using NIS (Network + Information Services) to get or supply user names and passwords to + other machines on the network. (This can actually be done, but is + beyond the scope of this document, and really won't increase + security much anyway) + + · Your machine is being used by terminal servers to verify users via + NFS (Network File System), NIS, or some other method. + + · Your machine runs other software that validates users, and there is + no shadow version available, and you don't have the source code. + + 2.2. Format of the /etc/passwd file + + A non-shadowed /etc/passwd file has the following format: + + username:passwd:UID:GID:full_name:directory:shell + + Where: + + username + The user (login) name + + passwd + The encoded password + + UID + Numerical user ID + + GID + Numerical default group ID + + full_name + The user's full name - Actually this field is called the GECOS + (General Electric Comprehensive Operating System) field and can + store information other than just the full name. The Shadow + commands and manual pages refer to this field as the comment + field. + + directory + User's home directory (Full pathname) + + shell + User's login shell (Full Pathname) + + For example: + + username:Npge08pfz4wuk:503:100:Full Name:/home/username:/bin/sh + + Where Np is the salt and ge08pfz4wuk is the encoded password. The + encoded salt/password could just as easily have been kbeMVnZM0oL7I and + the two are exactly the same password. There are 4096 possible encod­ + ings for the same password. (The example password in this case is + 'password', a really bad password). + + Once the shadow suite is installed, the /etc/passwd file would instead + contain: + + username:x:503:100:Full Name:/home/username:/bin/sh + + The x in the second field in this case is now just a place holder. + The format of the /etc/passwd file really didn't change, it just no + longer contains the encoded password. This means that any program + that reads the /etc/passwd file but does not actually need to verify + passwords will still operate correctly. + + The passwords are now relocated to the shadow file (usually + /etc/shadow file). + + 2.3. Format of the shadow file + + The /etc/shadow file contains the following information: + + username:passwd:last:may:must:warn:expire:disable:reserved + + Where: + + username + The User Name + + passwd + The Encoded password + last + Days since Jan 1, 1970 that password was last changed + + may + Days before password may be changed + + must + Days after which password must be changed + + warn + Days before password is to expire that user is warned + + expire + Days after password expires that account is disabled + + disable + Days since Jan 1, 1970 that account is disabled + + reserved + A reserved field + + The previous example might then be: + + username:Npge08pfz4wuk:9479:0:10000:::: + + 2.4. Review of crypt(3). + + From the crypt(3) manual page: + + "crypt is the password encryption function. It is based on the Data + Encryption Standard algorithm with variations intended (among other + things) to discourage use of hardware implementations of a key search. + + The key is a user's typed password. The encoded string is all NULLs + + The salt is a two-character string chosen from the set a-zA-Z0-9./. + This string is used to perturb the algorithm in one of 4096 different + ways. + + By taking the lowest 7 bits of each character of the key, a 56-bit key + is obtained. This 56-bit key is used to encrypt repeatedly a constant + string (usually a string consisting of all zeros). The returned value + points to the encrypted password, a series of 13 printable ASCII + characters (the first two characters represent the salt itself). The + return value points to static data whose content is overwritten by + each call. + + Warning: The key space consists of 2**56 equal 7.2e16 possible values. + Exhaustive searches of this key space are possible using massively + parallel computers. Software, such as crack(1), is available which + will search the portion of this key space that is generally used by + humans for passwords. Hence, password selection should, at minimum, + avoid common words and names. The use of a passwd(1) program that + checks for crackable passwords during the selection process is + recommended. + + The DES algorithm itself has a few quirks which make the use of the + crypt(3) interface a very poor choice for anything other than password + authentication. If you are planning on using the crypt(3) interface + for a cryptography project, don't do it: get a good book on encryption + and one of the widely available DES libraries." + + Most Shadow Suites contain code for doubling the length of the + password to 16 characters. Experts in des recommend against this, as + the encoding is simply applied first to the left half and then to the + right half of the longer password. Because of the way crypt works, + this may make for a less secure encoded password then if double length + passwords were not used in the first place. Additionally, it is less + likely that a user will be able to remember a 16 character password. + + There is development work under way that would allow the + authentication algorithm to be replaced with something more secure and + with support for longer passwords (specifically the MD5 algorithm) and + retain compatibility with the crypt method. + + If you are looking for a good book on encryption, I recommend: + + "Applied Cryptography: Protocols, Algorithms, and Source Code in C" + by Bruce Schneier + ISBN: 0-471-59756-2 + + 3. Getting the Shadow Suite. + + 3.1. History of the Shadow Suite for Linux + + DO NOT USE THE PACKAGES IN THIS SECTION, THEY HAVE SECURITY PROBLEMS + + The original Shadow Suite was written by Julianne F. Haugh + + There are several versions that have been used on Linux systems: + + · shadow-3.3.1 is the original. + + · shadow-3.3.1-2 is Linux specific patch made by Florian La Roche + and contains some further enhancements. + + · shadow-mk was specifically packaged for Linux. + + The shadow-mk package contains the shadow-3.3.1 package distributed by + Julianne F. Haugh with the shadow-3.3.1-2 patch installed, a few fixes + made by Mohan Kokal that make installation a lot + easier, a patch by Joseph R.M. Zbiciak for login1.c (login.secure) + that eliminates the -f, -h security holes in /bin/login, and some + other miscellaneous patches. + + The shadow.mk package was the previously recommended package, but + should be replaced due to a security problem with the login program. + + There are security problems with Shadow versions 3.3.1, 3.3.1-2, and + shadow-mk involving the login program. This login bug involves not + checking the length of a login name. This causes the buffer to + overflow causing crashes or worse. It has been rumored that this + buffer overflow can allow someone with an account on the system to use + this bug and the shared libraries to gain root access. I won't + discuss exactly how this is possible because there are a lot of Linux + systems that are affected, but systems with these Shadow Suites + installed, and most pre-ELF distributions without the Shadow Suite are + vulnerable! + + For more information on this and other Linux security issues, see the + Linux Security home page (Shared Libraries and login Program + Vulnerability) + + 3.2. Where to get the Shadow Suite. + + The only recommended Shadow Suite is still in BETA testing, however + the latest versions are safe in a production environment and don't + contain a vulnerable login program. + + The package uses the following naming convention: + + shadow-YYMMDD.tar.gz + + where YYMMDD is the issue date of the Suite. + + This version will eventually be Version 3.3.3 when it is released from + Beta testing, and is maintained by Marek Michalkiewicz + . It's available as: shadow- + current.tar.gz + . + + The following mirror sites have also been established: + + · ftp://ftp.icm.edu.pl/pub/Linux/shadow/shadow-current.tar.gz + + · ftp://iguana.hut.fi/pub/linux/shadow/shadow-current.tar.gz + + · ftp://ftp.cin.net/usr/ggallag/shadow/shadow-current.tar.gz + + · ftp://ftp.netural.com/pub/linux/shadow/shadow-current.tar.gz + + You should use the currently available version. + + You should NOT use a version older than shadow-960129 as they also + have the login security problem discussed above. + + When this document refers to the Shadow Suite I am referring to the + this package. It is assumed that this is the package that you are + using. + + For reference, I used shadow-960129 to make these installation + instructions. + + If you were previously using shadow-mk, you should upgrade to this + version and rebuild everything that you originally compiled. + + 3.3. What is included with the Shadow Suite. + + The Shadow Suite contains replacement programs for: + + su, login, passwd, newgrp, chfn, chsh, and id + + The package also contains the new programs: + + chage, newusers, dpasswd, gpasswd, useradd, userdel, usermod, + groupadd, groupdel, groupmod, groups, pwck, grpck, lastlog, pwconv, + and pwunconv + + Additionally, the library: libshadow.a is included for writing and/or + compiling programs that need to access user passwords. + + Also, manual pages for the programs are also included. + + There is also a configuration file for the login program which will be + installed as /etc/login.defs. + + 4. Compiling the programs. + + 4.1. Unpacking the archive. + + The first step after retrieving the package is unpacking it. The + package is in the tar (tape archive) format and compressed using gzip, + so first move it to /usr/src, then type: + + tar -xzvf shadow-current.tar.gz + + This will unpack it into the directory: /usr/src/shadow-YYMMDD + + 4.2. Configuring with the config.h file + + The first thing that you need to do is to copy over the Makefile and + the config.h file: + + cd /usr/src/shadow-YYMMDD + cp Makefile.linux Makefile + cp config.h.linux config.h + + You should then take a look at the config.h file. This file contains + definitions for some of the configuration options. If you are using + the recommended package, I recommend that you disable group shadow + support for your first time around. + + By default shadowed group passwords are enabled. To disable these + edit the config.h file, and change the #define SHADOWGRP to #undef + SHADOWGRP. I recommend that you disable them to start with, and then + if you really want group passwords and group administrators that you + enable it later and recompile. If you leave it enabled, you must + create the file /etc/gshadow. + + Enabling the long passwords option is NOT recommended as discussed + above. + + Do NOT change the setting: #undef AUTOSHADOW + + The AUTOSHADOW option was originally designed so that programs that + were shadow ignorant would still function. This sounds good in + theory, but does not work correctly. If you enable this option, and + the program runs as root, it may call getpwnam() as root, and later + write the modified entry back to the /etc/passwd file (with the no- + longer-shadowed password). Such programs include chfn and chsh. (You + can't get around this by swapping real and effective uid before + calling getpwnam() because root may use chfn and chsh too.) + + The same warning is also valid if you are building libc, it has a + SHADOW_COMPAT option which does the same thing. It should NOT be + used! If you start getting encoded passwords back in your /etc/passwd + file, this is the problem. + + If you are using a libc version prior to 4.6.27, you will need to make + a couple more changes to config.h and the Makefile. To config.h edit + and change: + + #define HAVE_BASENAME + + to: + + #undef HAVE_BASENAME + + And then in the Makefile, change: + + SOBJS = smain.o env.o entry.o susetup.o shell.o \ + sub.o mail.o motd.o sulog.o age.o tz.o hushed.o + + SSRCS = smain.c env.c entry.c setup.c shell.c \ + pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c \ + tz.c hushed.c + + SOBJS = smain.o env.o entry.o susetup.o shell.o \ + sub.o mail.o motd.o sulog.o age.o tz.o hushed.o basename.o + + SSRCS = smain.c env.c entry.c setup.c shell.c \ + pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c \ + tz.c hushed.c basename.c + + These changes add the code contained in basename.c which is contained + in libc 4.6.27 and later. + + 4.3. Making backup copies of your original programs. + + It would also be a good idea to track down and make backup copies of + the programs that the shadow suite will replace. On a Slackware 3.0 + system these are: + + · /bin/su + + · /bin/login + + · /usr/bin/passwd + + · /usr/bin/newgrp + + · /usr/bin/chfn + + · /usr/bin/chsh + + · /usr/bin/id + + The BETA package has a save target in the Makefile, but it's commented + out because different distributions place the programs in different + places. + + You should also make a backup copy of your /etc/passwd file, but be + careful to name it something else if you place it in the same + directory so you don't overwrite the passwd command. + + 4.4. Running make + + You need to be logged as root to do most of the installation. + + Run make to compile the executables in the package: + + make all + + You may see the warning: rcsid defined but not used. This is fine, it + just happens because the author is using a version control package. + + 5. Installing + + 5.1. Have a boot disk handy in case you break anything. + + If something goes terribly wrong, it would be handy to have a boot + disk. If you have a boot/root combination from your installation, + that will work, otherwise see the Bootdisk-HOWTO + , which + describes how to make a bootable disk. + + 5.2. Removing duplicate man pages + + You should also move the manual pages that are about to be replaced. + Even if you are brave enough install the Shadow Suite without making + backups, you will still want to remove the old manual pages. The new + manual pages won't normally overwrite the old ones because the old + ones are probably compressed. + + You can use a combination of: man -aW command and locate command to + locate the manual pages that need to be (re)moved. It's generally + easier to figure out which are the older pages before you run make + install. + + If you are using the Slackware 3.0 distribution, then the manual pages + you want to remove are: + + · /usr/man/man1/chfn.1.gz + + · /usr/man/man1/chsh.1.gz + + · /usr/man/man1/id.1.gz + + · /usr/man/man1/login.1.gz + + · /usr/man/man1/passwd.1.gz + + · /usr/man/man1/su.1.gz + + · /usr/man/man5/passwd.5.gz + + There may also be man pages of the same name in the /var/man/cat[1-9] + subdirectories that should also be deleted. + + 5.3. Running make install + + You are now ready to type: (do this as root) + + make install + + This will install the new and replacement programs and fix-up the file + permissions. It will also install the man pages. + + This also takes care of installing the Shadow Suite include files in + the correct places in /usr/include/shadow. + + Using the BETA package you must manually copy the file login.defs to + the /etc subdirectory and make sure that only root can make changes to + it. + + cp login.defs /etc + chmod 700 /etc/login.defs + + This file is the configuration file for the login program. You should + review and make changes to this file for your particular system. This + is where you decide which tty's root can login from, and set other + security policy settings (like password expiration defaults). + + 5.4. Running pwconv + + The next step is to run pwconv. This must also be done as root, and + is best done from the /etc subdirectory: + + cd /etc + /usr/sbin/pwconv + + pwconv takes your /etc/passwd file and strips out the fields to create + two files: /etc/npasswd and /etc/nshadow. + + A pwunconv program is also provided if you need to make a normal + /etc/passwd file out of an /etc/passwd and /etc/shadow combination. + + 5.5. Renaming npasswd and nshadow + + Now that you have run pwconv you have created the files /etc/npasswd + and /etc/nshadow. These need to be copied over to /etc/passwd and + /etc/shadow. We also want to make a backup copy of the original + /etc/passwd file, and make sure only root can read it. We'll put the + backup in root's home directory: + + cd /etc + cp passwd ~passwd + chmod 600 ~passwd + mv npasswd passwd + mv nshadow shadow + + You should also ensure that the file ownerships and permissions are + correct. If you are going to be using X-Windows, the xlock and xdm + programs need to be able to read the shadow file (but not write it). + + There are two ways that this can be done. You can set xlock to suid + root (xdm is usually run as root anyway). Or you can make the shadow + file owned by root with a group of shadow, but before you do this, + make sure that you have a shadow group (look in /etc/group). None of + the users on the system should actually be in the shadow group. + + chown root.root passwd + chown root.shadow shadow + chmod 0644 passwd + chmod 0640 shadow + + Your system now has the password file shadowed. You should now pop + over to another virtual terminal and verify that you can login. + + Really, do this now! + + If you can't, then something is wrong! To get back to a non-shadowed + state, do the following the following: + + cd /etc + cp ~passwd passwd + chmod 644 passwd + + You would then restore the files that you saved earlier to their + proper locations. + + 6. Other programs you may need to upgrade or patch + + Even though the shadow suite contains replacement programs for most + programs that need to access passwords, there are a few additional + programs on most systems that require access to passwords. + + If you are running a Debian Distribution (or even if you are not), you + can obtain Debian sources for the programs that need to be rebuild + from: ftp://ftp.debian.org/debian/stable/source/ + + The remainder of this section discusses how to upgrade adduser, + wu_ftpd, ftpd, pop3d, xlock, xdm and sudo so that they support the + shadow suite. + + See the section ``Adding Shadow Support to a C program'' for a + discussion on how to put shadow support into any other program that + needs it (although the program must then be run SUID root or SGID + shadow to be able to actually access the shadow file). + + 6.1. Slackware adduser program + + Slackware distributions (and possibly some others) contain a + interactive program for adding users called /sbin/adduser. A shadow + version of this program can be obtained from + ftp://sunsite.unc.edu/pub/Linux/ + system/Admin/accounts/adduser.shadow-1.4.tar.gz. + + I would encourage you to use the programs that are supplied with the + Shadow Suite (useradd, usermod, and userdel) instead of the slackware + adduser program. They take a little time to learn how to use, but + it's well worth the effort because you have much more control and they + perform proper file locking on the /etc/passwd and /etc/shadow file + (adduser doesn't). + + See the section on ``Putting the Shadow Suite to use'' for more + information. + + But if you gotta have it, here is what you do: + + tar -xzvf adduser.shadow-1.4.tar.gz + cd adduser + make clean + make adduser + chmod 700 adduser + cp adduser /sbin + + 6.2. The wu_ftpd Server + + Most Linux systems some with the wu_ftpd server. If your distribution + does not come with shadow installed, then your wu_ftpd will not be + compiled for shadow. wu_ftpd is launched from inetd/tcpd as a root + process. If you are running an old wu_ftpd daemon, you will want to + upgrade it anyway because older ones had a bug that would allow the + root account to be compromised (For more info see the Linux security + home page ). + + Fortunately, you only need to get the source code and recompile it + with shadow enabled. + + If you are not running an ELF system, The wu_ftp server can be found + on Sunsite as wu-ftp-2.4-fixed.tar.gz + + + Once you retrieve the server, put it in /usr/src, then type: + + cd /usr/src + tar -xzvf wu-ftpd-2.4-fixed.tar.gz + cd wu-ftpd-2.4-fixed + cp ./src/config/config.lnx.shadow ./src/config/config.lnx + + Then edit ./src/makefiles/Makefile.lnx, and change the line: + + LIBES = -lbsd -support + + to: + + LIBES = -lbsd -support -lshadow + + Now you are ready to run the build script and install: + + cd /usr/src/wu-ftpd-2.4-fixed + /usr/src/wu-ftp-2.4.fixed/build lnx + cp /usr/sbin/wu.ftpd /usr/sbin/wu.ftpd.old + cp ./bin/ftpd /usr/sbin/wu.ftpd + + This uses the Linux shadow configuration file, compiles and installs + the server. + + On my Slackware 2.3 system I also had to do the following before + running build: + + cd /usr/include/netinet + ln -s in_systm.h in_system.h + cd - + + Problems have been reported compiling this package under ELF systems, + but the Beta version of the next release works fine. It can be found + as wu-ftp-2.4.2-beta-10.tar.gz + + + Once you retrieve the server, put it in /usr/src, then type: + + cd /usr/src + tar -xzvf wu-ftpd-2.4.2-beta-9.tar.gz + cd wu-ftpd-beta-9 + cd ./src/config + + Then edit config.lnx, and change: + + #undef SHADOW.PASSWORD + + to: + + #define SHADOW.PASSWORD + + Then, + + cd ../Makefiles + + and edit the file Makefile.lnx and change: + + LIBES = -lsupport -lbsd # -lshadow + + to: + + LIBES = -lsupport -lbsd -lshadow + + Then build and install: + + cd .. + build lnx + cp /usr/sbin/wu.ftpd /usr/sbin/wu.ftpd.old + cp ./bin/ftpd /usr/sbin/wu.ftpd + + Note that you should check your /etc/inetd.conf file to make sure that + this is where your wu.ftpd server really lives. It has been reported + that some distributions place the server daemons in different places, + and then wu.ftpd in particular may be named something else. + + 6.3. Standard ftpd + + If you are running the standard ftpd server, I would recommend that + you upgrade to the wu_ftpd server. Aside from the known bug discussed + above, it's generally thought to be more secure. + + If you insist on the standard one, or you need NIS support, Sunsite + has ftpd-shadow-nis.tgz + + + 6.4. pop3d (Post Office Protocol 3) + + If you need to support the third Post Office Protocol (POP3), you will + need to recompile a pop3d program. pop3d is normally run by + inetd/tcpd as root. + + There are two versions available from Sunsite: + pop3d-1.00.4.linux.shadow.tar.gz + + and pop3d+shadow+elf.tar.gz + + + Both of these are fairly straight forward to install. + + 6.5. xlock + + If you install the shadow suite, and then run X Windows System and + lock the screen without upgrading your xlock, you will have to use + CNTL-ALT-Fx to switch to another tty, login, and kill the xlock + process (or use CNTL-ALT-BS to kill the X server). Fortunately it's + fairly easy to upgrade your xlock program. + + If you are running XFree86 Versions 3.x.x, you are probably using + xlockmore (which is a great screen-saver in addition to a lock). This + package supports shadow with a recompile. If you have an older xlock, + I recommend that you upgrade to this one. + + xlockmore-3.5.tgz is available at: + + + Basically, this is what you need to do: + + Get the xlockmore-3.7.tgz file and put it in /usr/src unpack it: + + tar -xzvf xlockmore-3.7.tgz + + Edit the file: /usr/X11R6/lib/X11/config/linux.cf, and change the + line: + + #define HasShadowPasswd NO + + to + + #define HasShadowPasswd YES + + Then build the executables: + + cd /usr/src/xlockmore + xmkmf + make depend + make + + Then move everything into place and update file ownerships and + permissions: + + cp xlock /usr/X11R6/bin/ + cp XLock /var/X11R6/lib/app-defaults/ + chown root.shadow /usr/X11R6/bin/xlock + chmod 2755 /usr/X11R6/bin/xlock + chown root.shadow /etc/shadow + chmod 640 /etc/shadow + + Your xlock will now work correctly. + + 6.6. xdm + + xdm is a program that presents a login screen for X-Windows. Some + systems start xdm when the system is told to goto a specified run + level (see /etc/inittab. + + With the Shadow Suite install, xdm will need to be updated. + Fortunately it's fairly easy to upgrade your xdm program. + + xdm.tar.gz is available at: + + + Get the xdm.tar.gz file and put it in /usr/src, then to unpack it: + + tar -xzvf xdm.tar.gz + + Edit the file: /usr/X11R6/lib/X11/config/linux.cf, and change the + line: + + #define HasShadowPasswd NO + + to + + #define HasShadowPasswd YES + + Then build the executables: + + cd /usr/src/xdm + xmkmf + make depend + make + + Then move everything into place: + + cp xdm /usr/X11R6/bin/ + + xdm is run as root so you don't need to change it file permissions. + + 6.7. sudo + + The program sudo allows a system administrator to let users run + programs that would normally require root access. This is handy + because it lets the administrator limit access to the root account + itself while still allowing users to do things like mounting drives. + + sudo needs to read passwords because it verifies the users password + when it's invoked. sudo already runs SUID root, so accessing the + /etc/shadow file is not a problem. + + sudo for the shadow suite, is available as at: + + + Warning: When you install sudo your /etc/sudoers file will be replaced + with a default one, so you need to make a backup of it if you have + added anything to the default one. (you could also edit the Makefile + and remove the line that copies the default file to /etc). + + The package is already setup for shadow, so all that's required is to + recompile the package (put it in /usr/src): + + cd /usr/src + tar -xzvf sudo-1.2-shadow.tgz + cd sudo-1.2-shadow + make all + make install + + 6.8. imapd (E-Mail pine package) + + imapd is an e-mail server similar to pop3d. imapd comes with the Pine + E-mail package. The documentation that comes with the package states + that the default for Linux systems is to include support for shadow. + However, I have found that this is not true. Furthermore, the build + script / Makefile combination on this package is makes it very + difficult to add the libshadow.a library at compile time, so I was + unable to add shadow support for imapd. + + If anyone has this figured out, please E-mail me, and I'll include the + solution here. + + 6.9. pppd (Point-to-Point Protocol Server) + + The pppd server can be setup to use several types of authentication: + Password Authentication Protocol (PAP) and Cryptographic Handshake + Authentication Protocol (CHAP). The pppd server usually reads the + password strings that it uses from /etc/ppp/chap-secrets and/or + /etc/ppp/pap-secrets. If you are using this default behavior of pppd, + it is not necessary to reinstall pppd. + + pppd also allows you to use the login parameter (either on the command + line, or in the configuration or options file). If the login option + is given, then pppd will use the /etc/passwd file for the username and + passwords for the PAP. This, of course, will no longer work now that + our password file is shadowed. For pppd-1.2.1d this requires adding + code for shadow support. + + The example given in the next section is adding shadow support to + pppd-1.2.1d (an older version of pppd). + + pppd-2.2.0 already contains shadow support. + + 7. Putting the Shadow Suite to use. + + This section discusses some of the things that you will want to know + now that you have the Shadow Suite installed on your system. More + information is contained in the manual pages for each command. + + 7.1. Adding, Modifying, and deleting users + + The Shadow Suite added the following command line oriented commands + for adding, modifying, and deleting users. You may also have + installed the adduser program. + + 7.1.1. useradd + + The useradd command can be used to add users to the system. You also + invoke this command to change the default settings. + + The first thing that you should do is to examine the default settings + and make changes specific to your system: + + useradd -D + + ______________________________________________________________________ + GROUP=1 + HOME=/home + INACTIVE=0 + EXPIRE=0 + SHELL= + SKEL=/etc/skel + ______________________________________________________________________ + + The defaults are probably not what you want, so if you started adding + users now you would have to specify all the information for each user. + However, we can and should change the default values. + + On my system: + + · I want the default group to be 100 + + · I want passwords to expire every 60 days + + · I don't want to lock an account because the password is expired + + · I want to default shell to be /bin/bash + + To make these changes I would use: + + useradd -D -g100 -e60 -f0 -s/bin/bash + + Now running useradd -D will give: + + ______________________________________________________________________ + GROUP=100 + HOME=/home + INACTIVE=0 + EXPIRE=60 + SHELL=/bin/bash + SKEL=/etc/skel + ______________________________________________________________________ + + Just in case you wanted to know, these defaults are stored in the file + /etc/default/useradd. + + Now you can use useradd to add users to the system. For example, to + add the user fred, using the defaults, you would use the following: + + useradd -m -c "Fred Flintstone" fred + + This will create the following entry in the /etc/passwd file: + + fred:*:505:100:Fred Flintstone:/home/fred:/bin/bash + + And the following entry in the /etc/shadow file: + + fred:!:0:0:60:0:0:0:0 + + fred's home directory will be created and the contents of /etc/skel + will be copied there because of the -m switch. + + Also, since we did not specify a UID, the next available one was used. + + fred's account is created, but fred still won't be able to login until + we unlock the account. We do this by changing the password. + + passwd fred + + ______________________________________________________________________ + Changing password for fred + Enter the new password (minimum of 5 characters) + Please use a combination of upper and lower case letters and numbers. + New Password: ******* + Re-enter new password: ******* + ______________________________________________________________________ + + Now the /etc/shadow will contain: + + fred:J0C.WDR1amIt6:9559:0:60:0:0:0:0 + + And fred will now be able to login and use the system. The nice thing + about useradd and the other programs that come with the Shadow Suite + is that they make changes to the /etc/passwd and /etc/shadow files + atomically. So if you are adding a user, and another user is changing + their password at the same time, both operations will be performed + correctly. + + You should use the supplied commands rather than directly editing + /etc/passwd and /etc/shadow. If you were editing the /etc/shadow + file, and a user were to change his password while you are editing, + and then you were to save the file you were editing, the user's + password change would be lost. + + Here is a small interactive script that adds users using useradd and + passwd: + + ______________________________________________________________________ + #!/bin/bash + # + # /sbin/newuser - A script to add users to the system using the Shadow + # Suite's useradd and passwd commands. + # + # Written my Mike Jackson as an example for the Linux + # Shadow Password Howto. Permission to use and modify is expressly granted. + # + # This could be modified to show the defaults and allow modification similar + # to the Slackware Adduser program. It could also be modified to disallow + # stupid entries. (i.e. better error checking). + # + ## + # Defaults for the useradd command + ## + GROUP=100 # Default Group + HOME=/home # Home directory location (/home/username) + SKEL=/etc/skel # Skeleton Directory + INACTIVE=0 # Days after password expires to disable account (0=never) + EXPIRE=60 # Days that a passwords lasts + SHELL=/bin/bash # Default Shell (full path) + ## + # Defaults for the passwd command + ## + PASSMIN=0 # Days between password changes + PASSWARN=14 # Days before password expires that a warning is given + ## + # Ensure that root is running the script. + ## + WHOAMI=`/usr/bin/whoami` + if [ $WHOAMI != "root" ]; then + echo "You must be root to add news users!" + exit 1 + fi + ## + # Ask for username and fullname. + ## + echo "" + echo -n "Username: " + read USERNAME + echo -n "Full name: " + read FULLNAME + # + echo "Adding user: $USERNAME." + # + # Note that the "" around $FULLNAME is required because this field is + # almost always going to contain at least on space, and without the "'s + # the useradd command would think that you we moving on to the next + # parameter when it reached the SPACE character. + # + /usr/sbin/useradd -c"$FULLNAME" -d$HOME/$USERNAME -e$EXPIRE \ + -f$INACTIVE -g$GROUP -m -k$SKEL -s$SHELL $USERNAME + ## + # Set password defaults + ## + /bin/passwd -n $PASSMIN -w $PASSWARN $USERNAME >/dev/null 2>&1 + ## + # Let the passwd command actually ask for password (twice) + ## + /bin/passwd $USERNAME + ## + # Show what was done. + ## + echo "" + echo "Entry from /etc/passwd:" + echo -n " " + grep "$USERNAME:" /etc/passwd + echo "Entry from /etc/shadow:" + echo -n " " + grep "$USERNAME:" /etc/shadow + echo "Summary output of the passwd command:" + echo -n " " + passwd -S $USERNAME + echo "" + ______________________________________________________________________ + + Using a script to add new users is really much more preferable than + editing the /etc/passwd or /etc/shadow files directly or using a + program like the Slackware adduser program. Feel free to use and + modify this script for your particular system. + + For more information on the useradd see the online manual page. + + 7.1.2. usermod + + The usermod program is used to modify the information on a user. The + switches are similar to the useradd program. + + Let's say that you want to change fred's shell, you would do the + following: + + usermod -s /bin/tcsh fred + + Now fred's /etc/passwd file entry would be change to this: + + fred:*:505:100:Fred Flintstone:/home/fred:/bin/tcsh + + Let's make fred's account expire on 09/15/97: + + usermod -e 09/15/97 fred + + Now fred's entry in /etc/shadow becomes: + + fred:J0C.WDR1amIt6:9559:0:60:0:0:10119:0 + + For more information on the usermod command see the online manual + page. + + 7.1.3. userdel + + userdel does just what you would expect, it deletes the user's + account. You simply use: + + userdel -r username + + The -r causes all files in the user's home directory to be removed + along with the home directory itself. Files located in other file + system will have to be searched for and deleted manually. + + If you want to simply lock the account rather than delete it, use the + passwd command instead. + + 7.2. The passwd command and passwd aging. + + The passwd command has the obvious use of changing passwords. + Additionally, it is used by the root user to: + + · Lock and unlock accounts (-l and -u) + + · Set the maximum number of days that a password remains valid (-x) + + · Set the minimum days between password changes (-n) + + · Sets the number of days of warning that a password is about to + expire (-w) + + · Sets the number of days after the password expires before the + account is locked (-i) + + · Allow viewing of account information in a clearer format (-S) + + For example, let look again at fred + + passwd -S fred + fred P 03/04/96 0 60 0 0 + + This means that fred's password is valid, it was last changed on + 03/04/96, it can be changed at any time, it expires after 60 days, + fred will not be warned, and and the account won't be disabled when + the password expires. + + This simply means that if fred logs in after the password expires, he + will be prompted for a new password at login. + + If we decide that we want to warn fred 14 days before his password + expires and make his account inactive 14 days after he lets it expire, + we would need to do the following: + + passwd -w14 -i14 fred + + Now fred is changed to: + fred P 03/04/96 0 60 14 14 + + For more information on the passwd command see the online manual page. + + 7.3. The login.defs file. + + The file /etc/login is the configuration file for the login program + and also for the Shadow Suite as a whole. + + /etc/login contains settings from what the prompts will look like to + what the default expiration will be when a user changes his password. + + The /etc/login.defs file is quite well documented just by the comments + that are contained within it. However, there are a few things to + note: + + · It contains flags that can be turned on or off that determine the + amount of logging that takes place. + + · It contains pointers to other configuration files. + + · It contains defaults assignments for things like password aging. + + From the above list you can see that this is a rather important file, + and you should make sure that it is present, and that the settings are + what you desire for your system. + + 7.4. Group passwords. + + The /etc/groups file may contain passwords that permit a user to + become a member of a particular group. This function is enabled if + you define the constant SHADOWGRP in the /usr/src/shadow- + YYMMDD/config.h file. + + If you define this constant and then compile, you must create an + /etc/gshadow file to hold the group passwords and the group + administrator information. + + When you created the /etc/shadow, you used a program called pwconv, + there no equivalent program to create the /etc/gshadow file, but it + really doesn't matter, it takes care of itself. + + To create the initial /etc/gshadow file do the following: + + touch /etc/gshadow + chown root.root /etc/gshadow + chmod 700 /etc/gshadow + + Once you create new groups, they will be added to the /etc/group and + the /etc/gshadow files. If you modify a group by adding or removing + users or changing the group password, the /etc/gshadow file will be + changed. + + The programs groups, groupadd, groupmod, and groupdel are provided as + part of the Shadow Suite to modify groups. + + The format of the /etc/group file is as follows: + + groupname:!:GID:member,member,... + + Where: + + groupname + The name of the group + + ! The field that normally holds the password, but that is now + relocated to the /etc/gshadow file. + + GID + The numerical group ID number + + member + List of group members + + The format of the /etc/gshadow file is as follows: + + groupname:password:admin,admin,...:member,member,... + + Where: + + groupname + The name of the group + + password + The encoded group password. + + admin + List of group administrators + + member + List of group members + + The command gpasswd is used only for adding or removing administrators + and members to or from a group. root or someone in the list of + administrators may add or remove group members. + + The groups password can be changed using the passwd command by root or + anyone listed as an administrator for the group. + + Despite the fact that there is not currently a manual page for + gpasswd, typing gpasswd without any parameters gives a listing of + options. It's fairly easy to grasp how it all works once you + understand the file formats and the concepts. + + 7.5. Consistency checking programs + + 7.5.1. pwck + + The program pwck is provided to provide a consistency check on the + /etc/passwd and /etc/shadow files. It will check each username and + verify that it has the following: + + · the correct number of fields + + · unique user name + + · valid user and group identifier + + · valid primary group + + · valid home directory + + · valid login shell + + It will also warn of any account that has no password. + + It's a good idea to run pwck after installing the Shadow Suite. It's + also a good idea to run it periodically, perhaps weekly or monthly. + If you use the -r option, you can use cron to run it on a regular + basis and have the report mailed to you. + + 7.5.2. grpck + + grpck is the consistency checking program for the /etc/group and + /etc/gshadow files. It performs the following checks: + + · the correct number of fields + + · unique group name + + · valid list of members and administrators + + It also has the -r option for automated reports. + + 7.6. Dial-up passwords. + + Dial-up passwords are another optional line of defense for systems + that allow dial-in access. If you have a system that allows many + people to connect locally or via a network, but you want to limit who + can dial in and connect, then dial-up passwords are for you. To + enable dial-up passwords, you must edit the file /etc/login.defs and + ensure that DIALUPS_CHECK_ENAB is set to yes. + + Two files contain the dial-up information, /etc/dialups which contains + the ttys (one per line, with the leading "/dev/" removed). If a tty + is listed then dial-up checks are performed. + + The second file is the /etc/d_passwd file. This file contains the + fully qualified path name of a shell, followed by an optional + password. + + If a user logs into a line that is listed in /etc/dialups, and his + shell is listed in the file /etc/d_passwd he will be allowed access + only by suppling the correct password. + + Another useful purpose for using dial-up passwords might be to setup a + line that only allows a certain type of connect (perhaps a PPP or UUCP + connection). If a user tries to get another type of connection (i.e. + a list of shells), he must know a password to use the line. + + Before you can use the dial-up feature, you must create the files. + + The command dpasswd is provided to assign passwords to the shells in + the /etc/d_passwd file. See the manual page for more information. + 8. Adding shadow support to a C program + + Adding shadow support to a program is actually fairly straightforward. + The only problem is that the program must be run by root (or SUID + root) in order for the the program to be able to access the + /etc/shadow file. + + This presents one big problem: very careful programming practices must + be followed when creating SUID programs. For instance, if a program + has a shell escape, this must not occur as root if the program is SUID + root. + + For adding shadow support to a program so that it can check passwords, + but otherwise does need to run as root, it's a lot safer to run the + program SUID shadow instead. The xlock program is an example of this. + + In the example given below, pppd-1.2.1d already runs SUID as root, so + adding shadow support should not make the program any more vulnerable. + + 8.1. Header files + + The header files should reside in /usr/include/shadow. There should + also be a /usr/include/shadow.h, but it will be a symbolic link to + /usr/include/shadow/shadow.h. + + To add shadow support to a program, you need to include the header + files: + + #include + #include + + It might be a good idea to use compiler directives to conditionally + compile the shadow code (I do in the example below). + + 8.2. libshadow.a library + + When you installed the Shadow Suite the libshadow.a file was created + and installed in /usr/lib. + + When compiling shadow support into a program, the linker needs to be + told to include the libshadow.a library into the link. + + This is done by: + + gcc program.c -o program -lshadow + + However, as we will see in the example below, most large programs use + a Makefile, and usually have a variable called LIBS=... that we will + modify. + + 8.3. Shadow Structure + + The libshadow.a library uses a structure called spwd for the + information it retrieves from the /etc/shadow file. This is the + definition of the spwd structure from the /usr/include/shadow/shadow.h + header file: + + ______________________________________________________________________ + struct spwd + { + char *sp_namp; /* login name */ + char *sp_pwdp; /* encrypted password */ + sptime sp_lstchg; /* date of last change */ + sptime sp_min; /* minimum number of days between changes */ + sptime sp_max; /* maximum number of days between changes */ + sptime sp_warn; /* number of days of warning before password + expires */ + sptime sp_inact; /* number of days after password expires + until the account becomes unusable. */ + sptime sp_expire; /* days since 1/1/70 until account expires + */ + unsigned long sp_flag; /* reserved for future use */ + }; + ______________________________________________________________________ + + The Shadow Suite can put things into the sp_pwdp field besides just + the encoded passwd. The password field could contain: + + username:Npge08pfz4wuk;@/sbin/extra:9479:0:10000:::: + + This means that in addition to the password, the program /sbin/extra + should be called for further authentication. The program called will + get passed the username and a switch that indicates why it's being + called. See the file /usr/include/shadow/pwauth.h and the source code + for pwauth.c for more information. + + What this means is that we should use the function pwauth to perform + the actual authentication, as it will take care of the secondary + authentication as well. The example below does this. + + The author of the Shadow Suite indicates that since most programs in + existence don't do this, and that it may be removed or changed in + future versions of the Shadow Suite. + + 8.4. Shadow Functions + + The shadow.h file also contains the function prototypes for the + functions contained in the libshadow.a library: + + ______________________________________________________________________ + extern void setspent __P ((void)); + extern void endspent __P ((void)); + extern struct spwd *sgetspent __P ((__const char *__string)); + extern struct spwd *fgetspent __P ((FILE *__fp)); + extern struct spwd *getspent __P ((void)); + extern struct spwd *getspnam __P ((__const char *__name)); + extern int putspent __P ((__const struct spwd *__sp, FILE *__fp)); + ______________________________________________________________________ + + The function that we are going to use in the example is: getspnam + which will retrieve for us a spwd structure for the supplied name. + + 8.5. Example + + This is an example of adding shadow support to a program that needs + it, but does not have it by default. + + This example uses the Point-to-Point Protocol Server (pppd-1.2.1d), + which has a mode in which it performs PAP authentication using user + names and passwords from the /etc/passwd file instead of the PAP or + CHAP files. You would not need to add this code to pppd-2.2.0 because + it's already there. + + This feature of pppd probably isn't used very much, but if you + installed the Shadow Suite, it won't work anymore because the + passwords are no longer stored in /etc/passwd. + + The code for authenticating users under pppd-1.2.1d is located in the + /usr/src/pppd-1.2.1d/pppd/auth.c file. + + The following code needs to be added to the top of the file where all + the other #include directives are. We have surrounded the #includes + with conditional directives (i.e. only include if we are compiling for + shadow support). + + ______________________________________________________________________ + #ifdef HAS_SHADOW + #include + #include + #endif + ______________________________________________________________________ + + The next thing to do is to modify the actual code. We are still + making changes to the auth.c file. + + Function auth.c before modifications: + + ______________________________________________________________________ + /* + * login - Check the user name and password against the system + * password database, and login the user if OK. + * + * returns: + * UPAP_AUTHNAK: Login failed. + * UPAP_AUTHACK: Login succeeded. + * In either case, msg points to an appropriate message. + */ + static int + login(user, passwd, msg, msglen) + char *user; + char *passwd; + char **msg; + int *msglen; + { + struct passwd *pw; + char *epasswd; + char *tty; + + if ((pw = getpwnam(user)) == NULL) { + return (UPAP_AUTHNAK); + } + /* + * XXX If no passwd, let them login without one. + */ + if (pw->pw_passwd == '\0') { + return (UPAP_AUTHACK); + } + + epasswd = crypt(passwd, pw->pw_passwd); + if (strcmp(epasswd, pw->pw_passwd)) { + return (UPAP_AUTHNAK); + } + + syslog(LOG_INFO, "user %s logged in", user); + + /* + * Write a wtmp entry for this user. + */ + tty = strrchr(devname, '/'); + if (tty == NULL) + tty = devname; + else + tty++; + logwtmp(tty, user, ""); /* Add wtmp login entry */ + logged_in = TRUE; + + return (UPAP_AUTHACK); + } + ______________________________________________________________________ + + The user's password is placed into pw->pw_passwd, so all we really + need to do is add the function getspnam. This will put the password + into spwd->sp_pwdp. + + We will add the function pwauth to perform the actual authentication. + This will automatically perform secondary authentication if the shadow + file is setup for it. + + Function auth.c after modifications to support shadow: + + ______________________________________________________________________ + /* + * login - Check the user name and password against the system + * password database, and login the user if OK. + * + * This function has been modified to support the Linux Shadow Password + * Suite if USE_SHADOW is defined. + * + * returns: + * UPAP_AUTHNAK: Login failed. + * UPAP_AUTHACK: Login succeeded. + * In either case, msg points to an appropriate message. + */ + static int + login(user, passwd, msg, msglen) + char *user; + char *passwd; + char **msg; + int *msglen; + { + struct passwd *pw; + char *epasswd; + char *tty; + + #ifdef USE_SHADOW + struct spwd *spwd; + struct spwd *getspnam(); + #endif + + if ((pw = getpwnam(user)) == NULL) { + return (UPAP_AUTHNAK); + } + + #ifdef USE_SHADOW + spwd = getspnam(user); + if (spwd) + pw->pw_passwd = spwd->sp-pwdp; + #endif + + /* + * XXX If no passwd, let NOT them login without one. + */ + if (pw->pw_passwd == '\0') { + return (UPAP_AUTHNAK); + } + #ifdef HAS_SHADOW + if ((pw->pw_passwd && pw->pw_passwd[0] == '@' + && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL)) + || !valid (passwd, pw)) { + return (UPAP_AUTHNAK); + } + #else + epasswd = crypt(passwd, pw->pw_passwd); + if (strcmp(epasswd, pw->pw_passwd)) { + return (UPAP_AUTHNAK); + } + #endif + + syslog(LOG_INFO, "user %s logged in", user); + + /* + * Write a wtmp entry for this user. + */ + tty = strrchr(devname, '/'); + if (tty == NULL) + tty = devname; + else + tty++; + logwtmp(tty, user, ""); /* Add wtmp login entry */ + logged_in = TRUE; + + return (UPAP_AUTHACK); + } + ______________________________________________________________________ + + Careful examination will reveal that we made another change as well. + The original version allowed access (returned UPAP_AUTHACK if there + was NO password in the /etc/passwd file. This is not good, because a + common use of this login feature is to use one account to allow access + to the PPP process and then check the username and password supplied + by PAP with the username in the /etc/passwd file and the password in + the /etc/shadow file. + + So if we had set the original version up to run as the shell for a + user i.e. ppp, then anyone could get a ppp connection by setting + their PAP to user ppp and a password of null. + + We fixed this also by returning UPAP_AUTHNAK instead of UPAP_AUTHACK + if the password field was empty. + + Interestingly enough, pppd-2.2.0 has the same problem. + + Next we need to modify the Makefile so that two things occur: + USE_SHADOW must be defined, and libshadow.a needs to be added to the + linking process. + + Edit the Makefile, and add: + + LIBS = -lshadow + + Then we find the line: + + COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t + + And change it to: + + COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t -DUSE_SHADOW + + Now make and install. + + 9. Frequently Asked Questions. + + Q: I used to control which tty's root could log into using the file + /etc/securettys, but it doesn't seem to work anymore, what's going on? + + A: The file /etc/securettys does absolutely nothing now that the + Shadow Suite is installed. The tty's that root can use are now + located in the login configuration file /etc/login.defs. The entry in + this file may point to another file. + + Q: I installed the Shadow Suite, but now I can't login, what did I + miss? + + A: You probably installed the Shadow programs, but didn't run pwconv + or you forgot to copy /etc/npasswd to /etc/passwd and /etc/nshadow to + /etc/shadow. Also, you may need to copy login.defs to /etc. + + Q: In the section on xlock, it said to change the group ownership of + the /etc/shadow file to shadow. I don't have a shadow group, what do + I do? + + A: You can add one. Simply edit the /etc/group file, and insert a + line for the shadow group. You need to ensure that the group number + is not used by another group, and you need to insert it before the + nogroup entry. Or you can simply suid xlock to root. + + Q: Is there a mailing list for the Linux Shadow Password Suite? + + A: Yes, but it's for the development and beta testing of the next + Shadow Suite for Linux. You can get added to the list by mailing to: + shadow-list-request@neptune.cin.net with a subject of: subscribe. The + list is actually for discussions of the Linux shadow-YYMMSS series of + releases. You should join if you want to get involved in further + development or if you install the Suite on your system and want to get + information on newer releases. + + Q: I installed the Shadow Suite, but when I use the userdel command, I + get "userdel: cannot open shadow group file", what did I do wrong? + + A: You compiled the Shadow Suite with the SHADOWGRP option enabled, + but you don't have an /etc/gshadow file. You need to either edit the + config.h file and recompile, or create an /etc/group file. See the + section on shadow groups. + + Q: I installed the Shadow Suite but now I'm getting encoded passwords + back in my /etc/passwd file, what's wrong? + + A: You either enabled the AUTOSHADOW option in the Shadow config.h + file, or your libc was compiled with the SAHDOW_COMPAT option. You + need to determine which is the problem, and recompile. + + 10. Copyright Message. + + The Linux Shadow Password HOWTO is Copyright (c) 1996 Michael H. + Jackson. + + Permission is granted to make and distribute verbatim copies of this + document provided the copyright notice and this permission notice are + preserved on all copies. + + Permission is granted to copy and distribute modified versions of this + document under the conditions for verbatim copies above, provided a + notice clearly stating that the document is a modified version is also + included in the modified document. + + Permission is granted to copy and distribute translations of this + document into another language, under the conditions specified above + for modified versions. + + Permission is granted to convert this document into another media + under the conditions specified above for modified versions provided + the requirement to acknowledge the source document is fulfilled by + inclusion of an obvious reference to the source document in the new + media. Where there is any doubt as to what defines 'obvious' the + copyright owner reserves the right to decide. + + 11. Miscellaneous and Acknowledgments. + + The code examples for auth.c are taken from pppd-1.2.1d and + ppp-2.1.0e, Copyright (c) 1993 and The Australian National University + and Copyright (c) 1989 Carnegie Mellon University. + + Thanks to Marek Michalkiewicz for + writing and maintaining the Shadow Suite for Linux, and for his review + and comments on this document. + + Thanks to Ron Tidd for his helpful review and + testing. + + Thanks to everyone who has sent me feedback to help improve this + document. + + Please, if you have any comments or suggestions then mail them to me. + + regards + + Michael H. Jackson + diff --git a/current/doc/INSTALL b/current/doc/INSTALL new file mode 100644 index 00000000..3b50ea95 --- /dev/null +++ b/current/doc/INSTALL @@ -0,0 +1,176 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/current/doc/LICENSE b/current/doc/LICENSE new file mode 100644 index 00000000..718fbbb3 --- /dev/null +++ b/current/doc/LICENSE @@ -0,0 +1,118 @@ +NOTE: + This license has been obsoleted by the change to the BSD-style copyright. + You may continue to use this license if you wish, but you are under no + obligation to do so. + +(* +This document is freely plagiarised from the 'Artistic Licence', +distributed as part of the Perl v4.0 kit by Larry Wall, which is +available from most major archive sites. I stole it from CrackLib. + + $Id: LICENSE,v 1.2 1997/05/01 23:14:30 marekm Exp $ +*) + +This documents purpose is to state the conditions under which this +Package (See definition below) viz: "Shadow", the Shadow Password Suite +which is held by Julianne Frances Haugh, may be copied, such that the +copyright holder maintains some semblance of artistic control over the +development of the package, while giving the users of the package the +right to use and distribute the Package in a more-or-less customary +fashion, plus the right to make reasonable modifications. + +So there. + +*************************************************************************** + +Definitions: + + +A "Package" refers to the collection of files distributed by the +Copyright Holder, and derivatives of that collection of files created +through textual modification, or segments thereof. + +"Standard Version" refers to such a Package if it has not been modified, +or has been modified in accordance with the wishes of the Copyright +Holder. + +"Copyright Holder" is whoever is named in the copyright or copyrights +for the package. + +"You" is you, if you're thinking about copying or distributing this +Package. + +"Reasonable copying fee" is whatever you can justify on the basis of +media cost, duplication charges, time of people involved, and so on. +(You will not be required to justify it to the Copyright Holder, but +only to the computing community at large as a market that must bear the +fee.) + +"Freely Available" means that no fee is charged for the item itself, +though there may be fees involved in handling the item. It also means +that recipients of the item may redistribute it under the same +conditions they received it. + + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated +disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, +provided that you insert a prominent notice in each changed file stating +how and when AND WHY you changed that file, and provided that you do at +least ONE of the following: + +a) place your modifications in the Public Domain or otherwise make them +Freely Available, such as by posting said modifications to Usenet or an +equivalent medium, or placing the modifications on a major archive site +such as uunet.uu.net, or by allowing the Copyright Holder to include +your modifications in the Standard Version of the Package. + +b) use the modified Package only within your corporation or organization. + +c) rename any non-standard executables so the names do not conflict with +standard executables, which must also be provided, and provide separate +documentation for each non-standard executable that clearly documents +how it differs from the Standard Version. + +d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + +a) distribute a Standard Version of the executables and library files, +together with instructions (in the manual page or equivalent) on where +to get the Standard Version. + +b) accompany the distribution with the machine-readable source of the +Package with your modifications. + +c) accompany any non-standard executables with their corresponding +Standard Version executables, giving the non-standard executables +non-standard names, and clearly documenting the differences in manual +pages (or equivalent), together with instructions on where to get the +Standard Version. + +d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this Package. +YOU MAY NOT CHARGE A FEE FOR THIS PACKAGE ITSELF. However, you may +distribute this Package in aggregate with other (possibly commercial) +programs as part of a larger (possibly commercial) software distribution +provided that YOU DO NOT ADVERTISE this package as a product of your +own. + +6. The name of the Copyright Holder may not be used to endorse or +promote products derived from this software without specific prior +written permission. + +7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End diff --git a/current/doc/LSM b/current/doc/LSM new file mode 100644 index 00000000..75a215e1 --- /dev/null +++ b/current/doc/LSM @@ -0,0 +1,20 @@ +Begin3 +Title: Shadow Password Suite +Version: 20000902 +Entered-date: 02SEP00 +Description: Shadow password file utilities. This package includes + the programs necessary to convert traditional V7 UNIX + password files to the SVR4 shadow password format, and + additional tools to maintain password and group files + (that work with both shadow and non-shadow passwords). +Keywords: login passwd security shadow +Author: jfh@austin.ibm.com (Julianne F. Haugh) +Maintained-by: kloczek@rudy.mif.pg.gda.pl (Tomasz Kloczko) + marekm@linux.org.pl (Marek Michalkiewicz) - previous maintainer +Primary-site: piast.t19.ds.pwr.wroc.pl /pub/linux/shadow/ + 718K shadow-20000902.tar.gz +Alternate-site: ftp.ists.pwr.wroc.pl /pub/linux/shadow/ +Original-site: ftp.uu.net ? +Platforms: Linux, SunOS, ... +Copying-policy: FRS +End diff --git a/current/doc/Makefile.am b/current/doc/Makefile.am new file mode 100644 index 00000000..487677a0 --- /dev/null +++ b/current/doc/Makefile.am @@ -0,0 +1,7 @@ +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + +EXTRA_DIST = ANNOUNCE CHANGES HOWTO LICENSE LSM README README.debian \ + README.limits README.linux README.mirrors README.nls README.pam \ + README.platforms README.shadow-paper README.sun4 \ + WISHLIST console.c.spec.txt cracklib26.diff diff --git a/current/doc/Makefile.in b/current/doc/Makefile.in new file mode 100644 index 00000000..b4ee0917 --- /dev/null +++ b/current/doc/Makefile.in @@ -0,0 +1,212 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +EXTRA_DIST = ANNOUNCE CHANGES HOWTO LICENSE LSM README README.debian README.limits README.linux README.mirrors README.nls README.pam README.platforms README.shadow-paper README.sun4 WISHLIST console.c.spec.txt cracklib26.diff + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = README INSTALL Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = doc + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/doc/README b/current/doc/README new file mode 100644 index 00000000..c177638f --- /dev/null +++ b/current/doc/README @@ -0,0 +1,253 @@ +[ $Id: README,v 1.4 2000/08/26 18:27:09 marekm Exp $ ] + +This is the explanatory document for Julianne Frances Haugh's login +replacement, release 3. This document was last updated 16 Feb 1997. + +This software is copyright 1988 - 1997, Julianne F. Haugh. All rights +reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of Julianne F. Haugh nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + +This source code is currently archived on ftp.uu.net in the +comp.sources.misc portion of the USENET archives. You may also contact +the author, Julianne F. Haugh, at jfh@austin.ibm.com if you have any questions +regarding this package. + +THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL +LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE +FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO +OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS +ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL +LOSS OF INFORMATION OR MACHINE RESOURCES. + +Special thanks are due to Chip Rosenthal for his fine testing efforts; +to Steve Simmons for his work in porting this code to BSD; and to Bill +Kennedy for his contributions of LaserJet printer time and energies. +Also, thanks for Dennis L. Mumaugh for the initial shadow password +information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System +V Release 4 changes. Effort in porting to SunOS has been contributed +by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr. +(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release +4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au). +Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl) +for taking over the Linux port of this software. + +New for Release 3.3: + User-defined authentication has been added. This allows you to + write programs to replace the password authentication method + which uses the crypt() function. + + The CrackLib password checking library is supported as of release + 3.3.0. It allows you to perform pro-active password checking as + each password is changed. + +Warning: + The newuser command will be removed in a later release. + The libsec.a library will be removed at some point after + version 3.3.3. + +This software is described in the 3rd USENIX Security Symposium +proceedings. These proceedings are available from + + USENIX Association + 2560 Ninth Street, Suite 215 + Berkeley, CA 94710 + +The current price is $30 for USENIX members and $39 for non-members. + +Begin by reading and editing the config.h file. All options are selected +by using #define's. A brief description for each available option appears +below. You may want to print this file out as it is LONG and you will +need to refer to it while editting config.h. You will also have to edit +the Makefile. The possible differences are documented there. Pay close +attention to the install: rule. Login now runs on about 30 different +varieties of UNIX that I have been made aware of. If you have any qualms, +you should run "make save" before running "make install". If something +breaks you can use "make restore" to put things back. In any case, you +should have a recent system backup as the potential for serious damage +exists. + +There are special Makefile and config.h files for SVR4, SunOS 4.1, and +Linux systems. If there is a major UNIX variant that you would like to +see supported, please send working Makefile and config.h files and I will +try to include then in the base distribution. + +Note that there are MANY options. As distributed most options are turned +on, which produces a really nice package. This is the system as used on +some of the authors' machines. There are many options which may be +selected at run time. You should refer to the login.5 manual page for +more information regarding these options. + +There are several files which you may have to replace. If your system has +a lastlog.h file, you should replace the one which I provide with your +system version. The pwd.h file that is produced by "make" must agree +exactly with the system supplied version. You should re-arrange the +fields or #define's until they match. The same is true for "shadow.h", +if you system provides one. You may want to replace large portions of +that file (or the entire file) with your system version. It is provided +for those systems which do NOT provide /usr/include/shadow.h. If you +do not have a the crypt() function in your library (perhaps because you +are located outside the United States), you may wish to look into the +UFC-crypt package which was posted to comp.sources.misc in volume 23, +issues 97 and 98. + +Login Defaults File - + This option selects the name of the file to read for the + run-time configurable options. The default value for + LOGINDEFS is "/etc/login.defs". + +Shadow [ unreadable ] Password Files - + This option utilizes an alternate, non-readable file to + contain the actual encrypted passwords. This is presumed + to increase system security by increasing the difficulty + with which system crackers obtain encrypted passwords. + + Select this option by defining the SHADOWPWD macro. + + This feature is optional, but only certain commands may + be compiled with this option disabled. + +Shadow Group Files - + This option utilizes an alternate, non-readable file to + contain encrypted group passwords and group administrator + information. + + This feature allows one or more users to be defined as + the administrators of a group for the purpose of adding + or deleting members and changing the group password. + + Select this option by defining the SHADOWGRP macro. You + must also create an emptry /etc/gshadow file. You must + select the SHADOWPWD option if you select SHADOWGRP. + +DBM Password Files - + This option utilizes the DBM database access routines to + increase the performance of user name and ID lookups in the + password file. You may select the NDBM database instead + and have DBM-style access to all user information files. + + Select this option by defining both the DBM and GETPWENT + macros. The FGETPWENT macro must also be defined or the + fgetpwent() library routine must be present. + +Double Length Passwords - + This option extends the maximum length of a user password + to 16 characters from eight. + + Select this option by defining the DOUBLESIZE macro. + Credit for this option is due Jonathan Bayer. + +Password Aging - + This option includes code to perform password aging. + Password aging is presumed to increase system security + by forcing users to change passwords on a regular + basis. The resolution on password age is in weeks for + non-shadow password systems and in days otherwise. + + Select this option by defining the AGING macro. + +Syslog - + This option causes the code to log various errors or + special conditions to the syslog daemon. The types of + information that are logged security violations, changes + to the user database, and program errors. + + Select syslog processing by defining the USE_SYSLOG + macro. + +Remote Login - + This option causes certain network login code to be + inserted to enable the "rlogin" and "telnet" commands to + work. To enable network logins, define the RLOGIN macro. + If your file includes a ut_host member, you must + also define the UT_HOST macro. Note that SVR4 has a + "utmpx" file to hold the ut_host member, so UT_HOST is + not required. + +Directory Reading Routines - + Three different macros are defined for opening and reading + directories. They are DIR_XENIX, DIR_BSD, and DIR_SYSV. + Refer to config.h for more details. + +Library Configuration Macros - + The following macros define the functions which are present + in your system library: + + HAVE_ULIMIT - Define if your UNIX supports ulimit() + GETPWENT - Define if you want my GETPWENT(3) routines + GETGRENT - Define if you want my GETGRENT(3) routines + NEED_AL64 - Define if library does not include a64l() + NEED_MKDIR - Define if system does not have mkdir() + NEED_RMDIR - Define if system does not have rmdir() + NEED_RENAME - Define if system does not have rename() + NEED_STRSTR - Define if library does not include strstr() + +Password File Information - + The following macros define the fields which are present in + your system password file. Because the system was compiled + to use the password file in its original form, these macros + must agree with the actual contents of the file. + + BSD_QUOTA - the pw_quota field exists + ATT_AGE - the pw_age field exists + ATT_COMMENT - the pw_comment field exists + +Signal Return Type - + Because different systems return different data types for + the signal() system call, you must define SIGTYPE to be + the data type your system uses. The default is "int", but + "void" is another popular value. + +SunOS 4.1.1 Notes: (mke@kaberd.rain.com) Michael J. Miller Jr. + +[ These notes were edited from the original. The standard Makefile + and config.h have notes indicating the changes required for SunOS. + Steve Allen at Lick has been working on cleaning up this platform. ] + +You'll need to do the following to get the shadow password dist to +compile on a sun 4.1.1 system. + +If using csh, then type 'rehash'. cd to the /etc directory and type +'pwconv'. This will create two files, nshadow and npasswd. +now type 'mkpasswd -f nshadow' and 'mkpasswd -f npasswd'. This will +create the shadow password file. + +Note: ftp will still use the old password file. Modified versions of + ftpd are available, or you may modify the version of ftpd from + any of the freely redistributable ftpd clones. + +Note: If you run suns pcnfs, be aware that it will still be looking at the + old password file as well. I may work out a patch for this, as I am + fairly certain the stuff on the sun side comes with source. + +Note: I have compiled this package with the standard c compiler and + suns unbundled c compiler at an optomization level of 2 in + both casses. Haven't tried gcc yet, so I don't know wether it + works. Same goes for suns C++ compiler. + +Note: Has been compiled on a sun 3/75 running sunos 4.1.1. Should compile + fine on sun 4's running 4.1.1, and may compile on suns running + 4.1. Have no idea what sort of success people will have that + are running 4.03 and older versions. diff --git a/current/doc/README.debian b/current/doc/README.debian new file mode 100644 index 00000000..43b749be --- /dev/null +++ b/current/doc/README.debian @@ -0,0 +1,68 @@ +Read this file first for a brief overview of the new versions of login +and passwd. + + +---Shadow passwords + +The command `shadowconfig on' will turn on shadow password support. +`shadowconfig off' will turn it back off. If you turn on shadow +password support, you'll gain the ability to set password ages and +expirations with chage(1). + +You may want to install the secure-su package which allows more +restrictions on su, for example a wheel group. + + +---General configuration + +Most of the configuration for the shadow utilities is in +/etc/login.defs. See login.defs(5). The defaults are quite +reasonable. + + +---MD5 Encryption + +If you set MD5_CRYPT_ENAB=yes in /etc/login.defs, passwords will be +encrypted with an MD5-based algorithm. It also supports of passwords +of unlimited length and longer salt strings. + + +---Login and resource control + +/etc/login.access and /etc/porttime control who may login to which +ports and when they may login. To enforce time restrictions, you'll +need to run logoutd. /etc/init.d/logoutd will start it on bootup if +there are non-comment lines in /etc/portttime. + +The lastlog and faillog commands will report the last time a user had +a successful and failed login, respectively. + +You may set per-user resource limits by editing /etc/limits. See +limits(5). + + +---Adding users and groups + +Though you may add users and groups with the SysV type commands, +useradd and groupadd, I recommend you add them with Debian adduser +version 3+. adduser gives you more configuration and conforms to the +Debian UID and GID allocation. + +Editing user and group parameters can be done with usermod and +groupmod. Removing users and groups can be done with userdel and +groupdel. + + +--- Group administration + +Local group allocation is much easier. With gpasswd(1) you can +designate users to administer groups. They can then securely add or +remove users from the group. + + +--- What to read next? + +Read the manpages, the other files in this directory, and the Shadow +Password HOWTO (included in the doc-linux package). A large portion +of these files deals with getting shadow installed. You can, of +course, ignore those parts. diff --git a/current/doc/README.limits b/current/doc/README.limits new file mode 100644 index 00000000..6551ad72 --- /dev/null +++ b/current/doc/README.limits @@ -0,0 +1,66 @@ + +ABOUT shadow-login limits: + +This code is merged into shadow login program from the original LShell 2.01 +written by Joel Katz. The port and some additional features have been added +by Cristian Gafton (gafton@sorosis.ro). + + +Changes: + - 96/04/16 + - {spaces,tabs} allowed within limits string + - Warn via syslog multiple default limits + - added few paragraphs to the login man page + - 96/04/14 + - code merged into lmain.c --cristiang + +TODO: - support groups in the limits file + (only usernames are supported at this momment :-( ) + +Setting user limits for shadow login program + +First, make a root-only-readable file (/etc/limits by default or LIMITS_FILE +defined config.h) that describes the resource limits you wish to impose. By +default no quotas are imposed on 'root'. In fact, there is no way to impose +limits via this procedure to root-equiv accounts (accounts with UID 0). + +Each line describes a limit for a user in the form: + + user LIMITS_STRING + +The LIMITS_STRING is a string of a concatenated list of resource limits. +Each limit consists of a letter identifier followed by a numerical limit. +The valid identifiers are: + + A: max address space (KB) + C: max core file size (KB) + D: max data size (KB) + F: maximum filesize (KB) + M: max locked-in-memory address space (KB) + N: max number of open files + R: max resident set size (KB) + S: max stack size (KB) + T: max CPU time (MIN) + U: max number of processes + L: max number of logins for this user + +For example, L2D2048N5 is a valid LIMITS_STRING. For reading convenience, +the following entries are equivalent: + +username L2D2048N5 +username L2 D2048 N5 + +Be aware that after the rest of the line is considered a limit +string, thus comments are not allowed. A invalid limits string will be +rejected (not considered) by the login program. + +The default entry is denoted by username '*'. If you have multiple 'default' +entries in your LIMITS_FILE, then the last one will be used as the default +entry. + +To completely disable limits for a user, a single dash (-) will do. + +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/current/doc/README.linux b/current/doc/README.linux new file mode 100644 index 00000000..cd55c940 --- /dev/null +++ b/current/doc/README.linux @@ -0,0 +1,166 @@ +$Id: README.linux,v 1.20 2000/08/26 18:27:09 marekm Exp $ + +This is the shadow suite hacked a bit for Linux. See CHANGES for +short description of changes. See also WISHLIST if you have too +much time on your hands :-). Now that copyright issues have been +resolved, the most important thing is testing. Please test this +code as much as you can, and report any problems. At this point, +I made so many changes that any bugs are probably mine. + +This package uses GNU autoconf, so it should be quite portable +- but it hasn't been tested much on anything but Linux/x86. +Long time ago, it has been reported to work on SunOS 4.1.x, +and recently there has been some success on Solaris 2.x and Irix. +I'd like to compile a current list of platforms this package is +known to work on - if you get it to work on some new OS (non-x86 +Linux, or non-Linux), please let me know. Please specify: host +type guessed by autoconf, libc version, distribution, changes +you needed to make (if any), etc. Please see README.platforms +for the current (incomplete - I know there are more...) list of +platforms this package is known to work on. + +There is a developers mailing list. It has moved again, and is +now hosted by SuSE - thanks to Thorsten Kukuk . +Send the command "subscribe shadow" to majordomo@suse.com to +subscribe if you are interested. To send mail to everyone on +the list, send it to shadow@suse.com. + +Before reporting bugs, please check if they still exist in my latest +development snapshot. Every few weeks I make a new version available +at the following URLs: +ftp://piast.t19.ds.pwr.wroc.pl/pub/linux/shadow/ +ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/ +http://www.itnet.pl/amelektr/linux/shadow/ +(there are also mirror sites, see README.mirrors). + +After installation, please remember to remove any old binaries like +/bin/passwd (this version installs /usr/bin/passwd). If your passwd +program doesn't like the new /etc/login.defs settings, and complains +about "configuration error", this is most likely the problem. + +Current versions of the Linux C library (both libc 5.x and glibc 2.x) +have the shadow support, including MD5-based crypt(), built in. +Because of this, libshadow.a will build without these functions, +and the ones from libc will be used instead. Currently, libshadow.a +is for internal use only, so if you see -lshadow in a Makefile of +some other package, it is safe to remove it. + +Remember that shadow passwords will not make your system more secure +if your distribution has gaping holes which let any user become root. +Some distributions, especially the older ones, are much like SunOS 4.1 +without any security patches installed :-). Read the linux-security +mailing list archives, and plug all holes before attempting to install +the shadow suite. + +Very old versions of this package (shadow-3.3.x, shadow-mk) had a few +nasty security holes, too. Please use the latest version if possible. + +Encrypted passwords are not readable, but it is highly recommended +to use cracklib with a big dictionary to prevent users from choosing +weak passwords. This way if someone ever gets access to /etc/shadow +(for example, because of some not yet discovered bug), they will not +get half of the passwords using Crack... There is a configure option +to use cracklib, I haven't tested it myself but I'm told it works. + +The code feels like stabilizing now - while still BETA, it should +work quite well. Many bugs have been fixed, but there may be still +a few lurking. Again, please test it and report any problems. + +Thanks to Julianne Frances Haugh who wrote the thing +in the first place, sent me the latest version, and released it under +a "free" BSD-style license, so that it can be included in Linux +distributions (at least Debian 1.3 and Slackware 3.2 are already +doing that; Debian and Red Hat packaging standards are supported in +the standard source tree). David Frey , Michael +Meskes and Guy Maor have +done a lot of work to integrate shadow passwords into Debian Linux. + +Ben Collins maintains this package for Debian +and added complete PAM support, now available in Debian 2.2. + +Thanks to Bradley Glonka of Linux System Labs +(http://www.lsl.com/) for sending me a free Red Hat 4.2 CD-ROM, +making it possible to test this package on this distribution. + +Special thanks to Michael H. Jackson who wrote +the Linux Shadow Password HOWTO. Special thanks to Greg Gallagher + and Jon Lewis for maintaining the +developers mailing list for a long time. + +Thanks to Maciej 'Tycoon' Majchrowski +for ftp server space on piast.t19.ds.pwr.wroc.pl, and to Pawel Wiecek + for keeping bach.ists.pwr.wroc.pl up and running. + +Ian Jackson criticized the current shadow password +system (see the linux-security mailing list archives). We disagree on +some points, but this started a discussion on possible better solutions. +Theodore Ts'o has started a new project to implement +Pluggable Authentication Modules - a relatively new standard API which +makes it easier to add new authentication mechanisms (it's more than +just shadow passwords). See http://parc.power.net/morgan/Linux-PAM/ for +more information. (XXX - this URL has changed, I have to check where +PAM is now... -MM) + +Thanks to at least the following people for sending me patches, bug +reports and various comments. This list may be incomplete, I received +a lot of mail... + +John Adelsberger +Martin Bene +Luca Berra +Darcy Boese +Judd Bourgeois +Ulisses Alonso Camaro +Ed Carp +Rani Chouha +Ben Collins +Joshua Cowan +Alan Curry +Frank Denis +Hrvoje Dogan +Chris Evans +Marc Ewing +Janos Farkas +Werner Fink +Floody +David Frey +Brian R. Gaeke +Cristian Gafton +Anton Gluck +Dave Hagewood +Jonathan Hankins +Juergen Heinzl +Joey Hess +Tim Hockin +David A. Holland +Andreas Jaeger +Timo Karjalainen +Calle Karlsson +Sami Kerola +Thorsten Kukuk +Jon Lewis +Pavel Machek +Guy Maor +Martin Mares +Rafal Maszkowski +Nikos Mavroyanopoulos +Michael Meskes +Arkadiusz Miskiewicz +Greg Mortensen +Mike Pakovic +Steve M. Robbins +Adam Rudnicki +Algis Rudys +Lutz Schwalowsky +Jay Soffian +Aniello Del Sorbo +Juha Virtanen +Michael Talbot-Wilson +Jesse Thilo +Shane Watts +Alexander O. Yuriev +Leonard N. Zubkoff + +If you want to be added here, or your e-mail address changes, +please let me know. Thanks. +-- Marek Michalkiewicz diff --git a/current/doc/README.mirrors b/current/doc/README.mirrors new file mode 100644 index 00000000..ddc96115 --- /dev/null +++ b/current/doc/README.mirrors @@ -0,0 +1,60 @@ +Primary sites for the Shadow Password Suite for Linux: + +ftp://piast.t19.ds.pwr.wroc.pl/pub/linux/shadow/ +ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/ +http://www.itnet.pl/amelektr/linux/shadow/ + +I upload latest versions here (and sometimes also to sunsite, but not +every new release). If you are not in Poland, these sites may be slow +for you - please use a mirror near you. + +Thanks to several people who offered to mirror this archive. Mirror +sites known to me (with addresses of people who submitted them to +this list) are listed below. If you want your site to be added here, +please let me know (specify the URL, and contact e-mail address). +If any of these sites become way out of date and should be removed, +or if they are good but the URL changes, please let me know too. + +Working mirrors that I know of, sorted by country (note: I removed +a few mirrors that didn't work when I tried to access them several +times - if any of them are still alive, please let me know): + +(XXX - list may be out of date now.) + +Brazil: + + ftp://ftp.athena.pads.ufrj.br/pub/linux/shadow/ + Rafael Jorge Csura Szendrodi + +Czech Republic: + + ftp://ftp.gts.cz/pub/linux/security/shadow/ + Martin Mares + +Greece: + + ftp://linux.forthnet.gr/pub/linux/shadow/ + http://linux.forthnet.gr/pub/linux/shadow/ + Sotiris Tsimbonis + +Poland: + + ftp://xenium.pdi.net/pub/Crypto/shadow/ + Marcin E. Bednarz + + ftp://giswitch.sggw.waw.pl/pub/Linux/shadow/ + Marek Czajko + +Romania: + + ftp://ftp.kappa.ro/pub/Linux/Security/shadow/ + Mircea Damian + +United States: + + ftp://ftp.cqc.com/pub/mirrors/linux-shadow/ + pacman@cqc.com + +Thanks, +Marek Michalkiewicz +(or marekm@piast.t19.ds.pwr.wroc.pl, or marekm@bach.ists.pwr.wroc.pl) diff --git a/current/doc/README.nls b/current/doc/README.nls new file mode 100644 index 00000000..5a4ea285 --- /dev/null +++ b/current/doc/README.nls @@ -0,0 +1,30 @@ +I've added in password suite 980724 nls and locale support (currently +only for greek). Before compiling (configuring) you must have set the +environment variable LINGUAS=el for greek or LINGUAS="" just for english. +To see your language at login (to the other programs export LANG=el is +enough) when you enter your login add LANG=xx, where xx is your language. +An other way to accomplish it is change the variable ENVIRON_FILE in +/etc/login.defs from /etc/environment to .environment. Thus any user +can add, to his .environment file, his language eg. LANG=el. + +Nikos Mavroyanopoulos + nmav@i-net.paiko.gr + +Note: i18n support as of this release (981218) can have some rough +edges - because of the large number of files updated, there is always +a possibility that I have introduced some new bugs. There are also +potential security problems in GNU gettext (both the included one and +one found in glibc 2.0.x) related to environment variables (LANG, +LANGUAGE, LC_*, NLSPATH) when used in setuid programs. I have tried +to work around them in sanitize_env() but no guarantees. The problem +has been reported to the gettext maintainer. + +Also, you may not be able to legally distribute binaries compiled +with included gettext (GPL and BSD-like licenses are not compatible). +I believe that distribution in the same source archive is OK though +(it's a "mere aggregation of another work not based on the Program +with the Program" - here Program == gettext library - "on a volume of +a storage or distribution medium"). Please tell the FSF politely that +they should consider changing the gettext license to LGPL. Thanks! + +Marek diff --git a/current/doc/README.pam b/current/doc/README.pam new file mode 100644 index 00000000..4a873640 --- /dev/null +++ b/current/doc/README.pam @@ -0,0 +1,35 @@ + +About PAM support in the Shadow Password Suite + +Warning: this code is still considered BETA. It needs more testing. +Please let me know if it works, or if something doesn't work. + +Use "./configure --with-libpam" to enable PAM support in the login, +passwd and su applications. + +When compiled with PAM support enabled, the following traditional features +of the shadow suite are not implemented directly in the applications - +instead, they should be implemented in the PAM modules. + +login: + - /etc/login.access + - /etc/porttime + - resource limits + - console groups + - password expiration / password strength checks + - /etc/motd and mail check + +passwd: + - administrator defined authentication methods + - TCFS support + - password expiration + - password strength checks + +su: + - wheel group + - console groups + - su access control (/etc/suauth) + - password expiration + - time restrictions + - resource limits + diff --git a/current/doc/README.platforms b/current/doc/README.platforms new file mode 100644 index 00000000..a475af9e --- /dev/null +++ b/current/doc/README.platforms @@ -0,0 +1,33 @@ +# $Id: README.platforms,v 1.4 1999/06/07 16:40:44 marekm Exp $ +# +# This is the current (still incomplete) list of platforms this +# package has been verified to work on. Additions (preferably +# in the format as described below) are welcome. Thanks! +# +# V: last version reported to work +# H: host type +# L: Linux libc version +# D: Linux distribution, or other OS name and version +# C: changes (if any) +# R: reported by + +V: 980529 +H: sparc-unknown-linux-gnu +L: glibc-2.0.7 +D: Ultrapenguin-1.0.9 +C: had to explicitly disable desrpc. +R: Bjorn Christianson + +V: 980724 +H: i486-pc-linux-gnulibc1 +L: libc-5.4.33 +D: Debian-1.3.1.r6 +C: none (use dpkg-buildpackage) +R: Marek Michalkiewicz + +V: current +H: i686-pc-linux-gnu +L: glibc-2.0.7.19981211 +D: Debian-2.1 +C: none (use dpkg-buildpackage) +R: Marek Michalkiewicz diff --git a/current/doc/README.shadow-paper b/current/doc/README.shadow-paper new file mode 100644 index 00000000..bf4a83b2 --- /dev/null +++ b/current/doc/README.shadow-paper @@ -0,0 +1,25 @@ +Date: Fri, 06 Jun 1997 22:57:27 -0500 +From: Julie Haugh +To: marekm@piast.t19.ds.pwr.wroc.pl +CC: shadow-list@neptune.cin.net, debian-devel@lists.debian.org +Subject: Shadow Paper available from the web now. + +Greets, + +I've finally managed to key in my '92 security paper on Shadow. You can +find it at + + http://www.tab.com/~jfh/shadow-paper.html + +As I get some time to go over how things have changed in the last 5 +years I intend to update it. + +My next Shadow-related project is cleaning up the documentation I +started for the Trusted Subsystem evaluation I started a couple of +years ago. There are a few really worthwhile documents a system +administrator might enjoy in there. +-- +Julianne Frances Haugh Feminism: +mailto:jfh@tab.com The belief (considered radical by +http://www.tab.com/~jfh some) that women are people, too. + diff --git a/current/doc/README.sun4 b/current/doc/README.sun4 new file mode 100644 index 00000000..8c3f037e --- /dev/null +++ b/current/doc/README.sun4 @@ -0,0 +1,39 @@ +[ $Id: README.sun4,v 1.1.1.1 1996/08/10 07:59:52 marekm Exp $ ] + +You'll need to do the following to get the shadow password dist to +compile on a sun 4.1.1 system. + +copy Makefile.sun4 to Makefile, and make any system specific changes. + +copy config.h.sun4 config.h, and make any system specific changes. + +You may have to edit the pwd.h.m4 file by hand, as the sunos m4 may +not grok the pwd.h.m4 file corectly. If you have the /usr/5bin/m4, +substitute that. Be sure to delete the pwd.h file before typeing +'make' again, as there will be an empty one left from the failed attempt +to use the standard sunos m4. + +type 'make'. If everything goes well, then type 'make install' + +If using csh, then type 'rehash'. cd to the /etc directory and type +'pwconv'. This will create two files, nshadow and npasswd. +now type 'mkpasswd -f nshadow' and 'mkpasswd -f npasswd'. This will +create the shadow password file. + +Note: The shadow group stuff does not work with sunos. + +Note: ftp will still use the old password file. + +Note: if you run suns pcnfs, be aware that it will still be looking at the + old password file as well. I may work out a patch for this, as I am + fairly certain the stuff on the sun side comes with source. + +Note: I have compiled this package with the standard c compiler and + suns unbundled c compiler at an optomization level of 2 in + both casses. Haven't tried gcc yet, so I don't know wether it + works. Same goes for suns C++ compiler. + +Note: has been compiled on a sun 3/75 running sunos 4.1.1. Should compile + fine on sun 4's running 4.1.1, and may compile on suns running + 4.1. Have no idea what sort of success people will have that + are running 4.03 and older versions. diff --git a/current/doc/WISHLIST b/current/doc/WISHLIST new file mode 100644 index 00000000..8ae49d50 --- /dev/null +++ b/current/doc/WISHLIST @@ -0,0 +1,53 @@ +$Id: WISHLIST,v 1.24 2000/08/26 18:27:09 marekm Exp $ + +This is my wishlist for the shadow suite, in no particular order. Feel +free to do anything from this list and mail me the diffs :-). + +Patches in diff -u format, against the latest version (sometimes in the +"beta" directory) are preferred and make my job easier. Please, no +MIME, base64, quoted-printable, or HTML. For very big patches, or if +your mailer can corrupt them, please use gzip and uuencode. Thanks! + +New ideas to add to this list are welcome, too. --marekm + +- fix all the bugs, of course +- implement "su only" accounts (no logins, only su from other account) +- rewrite getdef.c to be more general? (no hardcoded names) +- update man pages to reflect all the changes (real programmers ... :-) +- patch for rlogind/telnetd to create utmp entry and fill in ut_addr +- fix the usermod -l bug properly [for now it's OK - #undef AUTH_METHODS] +- option to specify encrypted password in passwd (for yppasswdd, so it + doesn't need to know about shadow/non-shadow); should probably use a pipe + (less insecure than command line arguments) +- add support for changing NIS passwords +- clean up NDBM support, do it in the library and not in all programs +- add option to check passwords by piping them to external programs +- add functionality of the contrib/rpasswd.c wrapper to passwd +- option to generate pronounceable passwords (like on SCO), external program? +- poppassd (remote password change for eudora etc.) +- add support for passwd/shadow db files (glibc) +- better documentation +- su -l, -m, -p, -s options (as in GNU su) - done in the Debian patches +- vipw: check password files for errors after editing +- clean up login utmp(x) handling code +- add "maximum time users allowed to stay logged in" limit option to logoutd +- handle quotes in /etc/environment like the shell does (but sshd doesn't...) +- write man pages: dialups.5, d_passwd.5 +- better utmpx support (logoutd, ...) +- better OPIE support (report number of logins left, etc.) +- new option for /etc/suauth: don't load user's environment (force "su -") + suggested by Ulisses Alonso Camaro +- clean up error messages - "program_name: text of error message\n" + (maybe some common code for common messages about failing to lock/open + something) +- find out why recent releases won't compile on Solaris +- newusers UID/GID selection algorithm should be the same as useradd + (and use UID_MIN, UID_MAX from login.defs) +- newusers should be able to copy /etc/skel to the new home directory + (like useradd) +- integrate the changes from Debian (complete PAM support, bug fixes) +- add directories where other packages can add hooks for package-specific + per-user configuration, to be executed with run-parts. Some hooks should + be executed at package install time for existing users, likewise for + package removal and possibly modification. (Debian Bug#36019) + diff --git a/current/doc/console.c.spec.txt b/current/doc/console.c.spec.txt new file mode 100644 index 00000000..27830e7f --- /dev/null +++ b/current/doc/console.c.spec.txt @@ -0,0 +1,36 @@ +$Id: console.c.spec.txt,v 1.1 1997/06/16 00:02:41 marekm Exp $ + +Specification for console.c source file -- + +input values -- + tty -- character pointer to device name with leading "/dev/" + removed. + +return values -- + 0 -- false + 1 -- true + +int console (char * tty) + if "CONSOLE" string value is not present in login.defs + return true + + if the first character of "CONSOLE" string value is not "/" + treat the string as a ":" delimited list of device + names and search for the value of tty in that + tokenized list. + + if a match is found + return true + + return false + + if the file named by "CONSOLE" cannot be opened + return true + + scan the file looking for a match between the input line + and the value of tty + + if a match is found + return true + + return false diff --git a/current/doc/cracklib26.diff b/current/doc/cracklib26.diff new file mode 100644 index 00000000..09160b8c --- /dev/null +++ b/current/doc/cracklib26.diff @@ -0,0 +1,340 @@ +diff -ur orig/cracklib26_small/cracklib/fascist.c cracklib26_small/cracklib/fascist.c +--- orig/cracklib26_small/cracklib/fascist.c Mon Dec 15 02:56:55 1997 ++++ cracklib26_small/cracklib/fascist.c Sat Apr 4 22:14:45 1998 +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #define ISSKIP(x) (isspace(x) || ispunct(x)) + +@@ -460,28 +461,27 @@ + } + + char * +-FascistGecos(password, uid) ++FascistGecosPw(password, pwd) + char *password; +- int uid; ++ struct passwd *pwd; + { + int i; + int j; + int wc; + char *ptr; +- struct passwd *pwp; + char gbuffer[STRINGSIZE]; + char tbuffer[STRINGSIZE]; + char *uwords[STRINGSIZE]; + char longbuffer[STRINGSIZE * 2]; + +- if (!(pwp = getpwuid(uid))) ++ if (!pwd) + { + return ("you are not registered in the password file"); + } + + /* lets get really paranoid and assume a dangerously long gecos entry */ + +- strncpy(tbuffer, pwp->pw_name, STRINGSIZE); ++ strncpy(tbuffer, pwd->pw_name, STRINGSIZE); + tbuffer[STRINGSIZE-1] = '\0'; + if (GTry(tbuffer, password)) + { +@@ -490,12 +490,13 @@ + + /* it never used to be that you got passwd strings > 1024 chars, but now... */ + +- strncpy(tbuffer, pwp->pw_gecos, STRINGSIZE); ++ strncpy(tbuffer, pwd->pw_gecos, STRINGSIZE); + tbuffer[STRINGSIZE-1] = '\0'; + strcpy(gbuffer, Lowercase(tbuffer)); + + wc = 0; + ptr = gbuffer; ++ uwords[0] = (char *) 0; + + while (*ptr) + { +@@ -530,6 +531,8 @@ + *(ptr++) = '\0'; + } + } ++ if (!uwords[0]) ++ return ((char *) 0); /* empty gecos */ + #ifdef DEBUG + for (i = 0; uwords[i]; i++) + { +@@ -586,9 +589,10 @@ + } + + char * +-FascistLook(pwp, instring) ++FascistLookPw(pwp, instring, pwd) + PWDICT *pwp; + char *instring; ++ struct passwd *pwd; + { + int i; + char *ptr; +@@ -667,7 +671,7 @@ + return ("it looks like a National Insurance number."); + } + +- if (ptr = FascistGecos(password, getuid())) ++ if (ptr = FascistGecosPw(password, pwd ? pwd : getpwuid(getuid()))) + { + return (ptr); + } +@@ -715,9 +719,10 @@ + } + + char * +-FascistCheck(password, path) ++FascistCheckPw(password, path, pwd) + char *password; + char *path; ++ struct passwd *pwd; + { + static char lastpath[STRINGSIZE]; + static PWDICT *pwp; +@@ -750,5 +755,29 @@ + strncpy(lastpath, path, STRINGSIZE); + } + +- return (FascistLook(pwp, pwtrunced)); ++ return (FascistLookPw(pwp, pwtrunced, pwd)); ++} ++ ++char * ++FascistGecos(password, uid) ++ char *password; ++ int uid; ++{ ++ return (FascistGecosPw(password, getpwuid(uid))); ++} ++ ++char * ++FascistLook(pwp, instring) ++ PWDICT *pwp; ++ char *instring; ++{ ++ return (FascistLookPw(pwp, instring, (char *) 0)); ++} ++ ++char * ++FascistCheck(password, path) ++ char *password; ++ char *path; ++{ ++ return (FascistCheckPw(password, path, (char *) 0)); + } +diff -ur orig/cracklib26_small/cracklib/packer.h cracklib26_small/cracklib/packer.h +--- orig/cracklib26_small/cracklib/packer.h Mon Dec 15 00:09:30 1997 ++++ cracklib26_small/cracklib/packer.h Sat Jan 10 22:13:46 1998 +@@ -34,6 +34,7 @@ + FILE *dfp; + FILE *wfp; + ++ int canfree; + int32 flags; + #define PFOR_WRITE 0x0001 + #define PFOR_FLUSH 0x0002 +diff -ur orig/cracklib26_small/cracklib/packlib.c cracklib26_small/cracklib/packlib.c +--- orig/cracklib26_small/cracklib/packlib.c Fri Jul 9 22:22:58 1993 ++++ cracklib26_small/cracklib/packlib.c Sat Jan 10 22:28:49 1998 +@@ -16,7 +16,7 @@ + char *mode; + { + int32 i; +- static PWDICT pdesc; ++ PWDICT *pdesc; + char iname[STRINGSIZE]; + char dname[STRINGSIZE]; + char wname[STRINGSIZE]; +@@ -25,92 +25,94 @@ + FILE *ifp; + FILE *wfp; + +- if (pdesc.header.pih_magic == PIH_MAGIC) +- { +- fprintf(stderr, "%s: another dictionary already open\n", prefix); ++ if ((pdesc = (PWDICT *) malloc(sizeof(PWDICT))) == 0) + return ((PWDICT *) 0); +- } + +- memset(&pdesc, '\0', sizeof(pdesc)); ++ memset(pdesc, '\0', sizeof(*pdesc)); + + sprintf(iname, "%s.pwi", prefix); + sprintf(dname, "%s.pwd", prefix); + sprintf(wname, "%s.hwm", prefix); + +- if (!(pdesc.dfp = fopen(dname, mode))) ++ if (!(pdesc->dfp = fopen(dname, mode))) + { + perror(dname); ++ free(pdesc); + return ((PWDICT *) 0); + } + +- if (!(pdesc.ifp = fopen(iname, mode))) ++ if (!(pdesc->ifp = fopen(iname, mode))) + { +- fclose(pdesc.dfp); ++ fclose(pdesc->dfp); + perror(iname); ++ free(pdesc); + return ((PWDICT *) 0); + } + +- if (pdesc.wfp = fopen(wname, mode)) ++ if (pdesc->wfp = fopen(wname, mode)) + { +- pdesc.flags |= PFOR_USEHWMS; ++ pdesc->flags |= PFOR_USEHWMS; + } + +- ifp = pdesc.ifp; +- dfp = pdesc.dfp; +- wfp = pdesc.wfp; ++ ifp = pdesc->ifp; ++ dfp = pdesc->dfp; ++ wfp = pdesc->wfp; + + if (mode[0] == 'w') + { +- pdesc.flags |= PFOR_WRITE; +- pdesc.header.pih_magic = PIH_MAGIC; +- pdesc.header.pih_blocklen = NUMWORDS; +- pdesc.header.pih_numwords = 0; ++ pdesc->flags |= PFOR_WRITE; ++ pdesc->header.pih_magic = PIH_MAGIC; ++ pdesc->header.pih_blocklen = NUMWORDS; ++ pdesc->header.pih_numwords = 0; + +- fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp); ++ fwrite((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp); + } else + { +- pdesc.flags &= ~PFOR_WRITE; ++ pdesc->flags &= ~PFOR_WRITE; + +- if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp)) ++ if (!fread((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp)) + { + fprintf(stderr, "%s: error reading header\n", prefix); + +- pdesc.header.pih_magic = 0; ++ pdesc->header.pih_magic = 0; + fclose(ifp); + fclose(dfp); ++ free(pdesc); + return ((PWDICT *) 0); + } + +- if (pdesc.header.pih_magic != PIH_MAGIC) ++ if (pdesc->header.pih_magic != PIH_MAGIC) + { + fprintf(stderr, "%s: magic mismatch\n", prefix); + +- pdesc.header.pih_magic = 0; ++ pdesc->header.pih_magic = 0; + fclose(ifp); + fclose(dfp); ++ free(pdesc); + return ((PWDICT *) 0); + } + +- if (pdesc.header.pih_blocklen != NUMWORDS) ++ if (pdesc->header.pih_blocklen != NUMWORDS) + { + fprintf(stderr, "%s: size mismatch\n", prefix); + +- pdesc.header.pih_magic = 0; ++ pdesc->header.pih_magic = 0; + fclose(ifp); + fclose(dfp); ++ free(pdesc); + return ((PWDICT *) 0); + } + +- if (pdesc.flags & PFOR_USEHWMS) ++ if (pdesc->flags & PFOR_USEHWMS) + { +- if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms)) ++ if (fread(pdesc->hwms, 1, sizeof(pdesc->hwms), wfp) != sizeof(pdesc->hwms)) + { +- pdesc.flags &= ~PFOR_USEHWMS; ++ pdesc->flags &= ~PFOR_USEHWMS; + } + } + } +- +- return (&pdesc); ++ pdesc->canfree = 1; ++ return (pdesc); + } + + int +@@ -159,8 +161,13 @@ + + fclose(pwp->ifp); + fclose(pwp->dfp); ++ if (pwp->wfp) ++ fclose(pwp->wfp); + +- pwp->header.pih_magic = 0; ++ if (pwp->canfree) ++ free(pwp); ++ else ++ pwp->header.pih_magic = 0; + + return (0); + } +@@ -307,6 +314,11 @@ + register char *this; + int idx; + ++/* ++ * comment in npasswd-2.0beta4 says this: ++ * This does not work under all circumstances, so don't bother ++ */ ++#if 0 + if (pwp->flags & PFOR_USEHWMS) + { + idx = string[0] & 0xff; +@@ -317,6 +329,10 @@ + lwm = 0; + hwm = PW_WORDS(pwp) - 1; + } ++#else ++ lwm = 0; ++ hwm = PW_WORDS(pwp); ++#endif + + #ifdef DEBUG + printf("---- %lu, %lu ----\n", lwm, hwm); +diff -ur orig/cracklib26_small/util/mkdict cracklib26_small/util/mkdict +--- orig/cracklib26_small/util/mkdict Fri Jul 9 22:23:03 1993 ++++ cracklib26_small/util/mkdict Sat Apr 4 22:31:45 1998 +@@ -14,9 +14,16 @@ + SORT="sort" + ###SORT="sort -T /tmp" + +-cat $* | ++### Use zcat to read compressed (as well as uncompressed) dictionaries. ++### Compressed dictionaries can save quite a lot of disk space. ++ ++CAT="gzip -cdf" ++###CAT="zcat" ++###CAT="cat" ++ ++$CAT $* | + tr '[A-Z]' '[a-z]' | +- tr -cd '[\012a-z0-9]' | ++ tr -cd '\012[a-z][0-9]' | + $SORT | + uniq | + grep -v '^#' | diff --git a/current/etc/Makefile.am b/current/etc/Makefile.am new file mode 100644 index 00000000..f2ce1621 --- /dev/null +++ b/current/etc/Makefile.am @@ -0,0 +1,7 @@ +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + +EXTRA_DIST = limits login.access login.defs login.defs.hurd login.defs.linux \ + shells suauth + +SUBDIRS = pam.d diff --git a/current/etc/Makefile.in b/current/etc/Makefile.in new file mode 100644 index 00000000..c27dab48 --- /dev/null +++ b/current/etc/Makefile.in @@ -0,0 +1,318 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +EXTRA_DIST = limits login.access login.defs login.defs.hurd login.defs.linux shells suauth + + +SUBDIRS = pam.d +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps etc/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = etc + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/etc/limits b/current/etc/limits new file mode 100644 index 00000000..fc741b1a --- /dev/null +++ b/current/etc/limits @@ -0,0 +1,28 @@ +# /etc/limits contains user resource limits. +# See limits(5). +# +# Format: +# +# +# default entry is '*' for username +# +# Valid flags are: +# A: max address space (KB) +# C: max core file size (KB) +# D: max data size (KB) +# F: maximum filesize (KB) +# M: max locked-in-memory address space (KB) [only for root on Linux 2.0.x] +# N: max number of open files +# R: max resident set size (KB) [no effect on Linux 2.0.x] +# S: max stack size (KB) +# T: max CPU time (MIN) +# U: max number of processes +# L: max number of logins for this user +# +# Examples: +# the default entry +#* L2 D6144 R2048 S2048 U32 N32 F16384 T5 C0 +# another way of suspending a user login +#guest L0 +# this account has no limits +#sysadm - diff --git a/current/etc/login.access b/current/etc/login.access new file mode 100644 index 00000000..60cbd63f --- /dev/null +++ b/current/etc/login.access @@ -0,0 +1,54 @@ +# $Id: login.access,v 1.2 1996/09/10 02:45:04 marekm Exp $ +# +# Login access control table. +# +# When someone logs in, the table is scanned for the first entry that +# matches the (user, host) combination, or, in case of non-networked +# logins, the first entry that matches the (user, tty) combination. The +# permissions field of that table entry determines whether the login will +# be accepted or refused. +# +# Format of the login access control table is three fields separated by a +# ":" character: +# +# permission : users : origins +# +# The first field should be a "+" (access granted) or "-" (access denied) +# character. +# +# The second field should be a list of one or more login names, group +# names, or ALL (always matches). A pattern of the form user@host is +# matched when the login name matches the "user" part, and when the +# "host" part matches the local machine name. +# +# The third field should be a list of one or more tty names (for +# non-networked logins), host names, domain names (begin with "."), host +# addresses, internet network numbers (end with "."), ALL (always +# matches) or LOCAL (matches any string that does not contain a "." +# character). +# +# If you run NIS you can use @netgroupname in host or user patterns; this +# even works for @usergroup@@hostgroup patterns. Weird. +# +# The EXCEPT operator makes it possible to write very compact rules. +# +# The group file is searched only when a name does not match that of the +# logged-in user. Only groups are matched in which users are explicitly +# listed: the program does not look at a user's primary group id value. +# +############################################################################## +# +# Disallow console logins to all but a few accounts. +# +#-:ALL EXCEPT wheel shutdown sync:console +# +# Disallow non-local logins to privileged accounts (group wheel). +# +#-:wheel:ALL EXCEPT LOCAL .win.tue.nl +# +# Some accounts are not allowed to login from anywhere: +# +#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL +# +# All other accounts are allowed to login from anywhere. +# diff --git a/current/etc/login.defs b/current/etc/login.defs new file mode 100644 index 00000000..7af8d118 --- /dev/null +++ b/current/etc/login.defs @@ -0,0 +1,214 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# $Id: login.defs,v 1.2 1997/05/01 23:14:35 marekm Exp $ +# +# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# + +# +# Delay in seconds before being allowed another attempt after a login failure +# +FAIL_DELAY 5 + +# +# Enable additional passwords upon dialup lines specified in /etc/dialups. +# +DIALUPS_CHECK_ENAB yes + +# +# Enable logging and display of /usr/adm/faillog login failure info. +# +FAILLOG_ENAB yes + +# +# Enable display of unknown usernames when login failures are recorded. +# +LOG_UNKFAIL_ENAB yes + +# +# Enable logging and display of /usr/adm/lastlog login time info. +# +LASTLOG_ENAB yes + +# +# Enable checking and display of mailbox status upon login. +# +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 no +SYSLOG_SG_ENAB no + +# +# 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/consoles +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# If defined, all su activity is logged to this file. +# +SULOG_FILE /usr/adm/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. +# +FTMP_FILE /etc/ftmp + +# +# 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/nologins + +# +# 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. +# MAILDIR is for Qmail +# +#MAILDIR Maildir +MAIL_DIR /usr/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, the presence of this value in an /etc/passwd "shell" field will +# disable logins for that user, although "su" will still be allowed. +# +NOLOGIN_STR NOLOGIN + +# +# 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. +# +ENV_HZ HZ=50 + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +ENV_SUPATH PATH=/etc/local:/etc:/local/bin:/usr/bin:/bin +ENV_PATH PATH=/local/bin:/usr/bin:/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 7 +#TTYPERM 0620 +TTYPERM 0622 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# UMASK Default "umask" value. +# 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. +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 010 +KILLCHAR 025 +UMASK 022 +ULIMIT 2097152 + +# +# 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 + +# +# Only allow group 0 members to "su" to root. +# +SU_WHEEL_ONLY no + +# +# If compiled with cracklib support, where are the dictionaries +# +#CRACKLIB_DICTPATH /usr/share/lib/pw_dict diff --git a/current/etc/login.defs.hurd b/current/etc/login.defs.hurd new file mode 100644 index 00000000..e7cdb4df --- /dev/null +++ b/current/etc/login.defs.hurd @@ -0,0 +1,143 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# $Id: login.defs.hurd,v 1.2 2000/08/26 18:27:10 marekm Exp $ +# +# One item must be defined: MAIL_DIR. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# +# Modified for the Hurd. --brinkmd + +# +# Enable additional checks upon password changes. +# +OBSCURE_CHECKS_ENAB yes + +# +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, MAIL_DIR takes precedence. +# QMAIL_DIR is for Qmail +# +#QMAIL_DIR Maildir +MAIL_DIR /var/spool/mail +#MAIL_FILE .mail + +# +# 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 compiled with cracklib support, where are the dictionaries +# +#CRACKLIB_DICTPATH /usr/lib/passwd/pw_dict + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 100 +GID_MAX 60000 + +# +# 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 rwh + +# +# 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". +# +#MD5_CRYPT_ENAB no + +# +# 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 + +# +# When prompting for password without echo, getpass() can optionally +# display a random number (in the range 1 to GETPASS_ASTERISKS) of '*' +# characters for each character typed. This feature is designed to +# confuse people looking over your shoulder when you enter a password :-). +# Also, the new getpass() accepts both Backspace (8) and Delete (127) +# keys to delete previous character (to cope with different terminal +# types), Control-U to delete all characters, and beeps when there are +# no more characters to delete, or too many characters entered. +# +# Setting GETPASS_ASTERISKS to 1 results in more traditional behaviour - +# exactly one '*' displayed for each character typed. +# +# Setting GETPASS_ASTERISKS to 0 disables the '*' characters (Backspace, +# Delete, Control-U and beep continue to work as described above). +# +# Setting GETPASS_ASTERISKS to -1 reverts to the traditional getpass() +# without any new features. This is the default. +# +#GETPASS_ASTERISKS 1 + +# +# 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 + diff --git a/current/etc/login.defs.linux b/current/etc/login.defs.linux new file mode 100644 index 00000000..94402934 --- /dev/null +++ b/current/etc/login.defs.linux @@ -0,0 +1,370 @@ +# +# /etc/login.defs - Configuration control definitions for the login package. +# +# $Id: login.defs.linux,v 1.12 2000/08/26 18:27:10 marekm Exp $ +# +# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH. +# If unspecified, some arbitrary (and possibly incorrect) value will +# be assumed. All other items are optional - if not specified then +# the described action or option will be inhibited. +# +# Comment lines (lines beginning with "#") and blank lines are ignored. +# +# Modified for Linux. --marekm + +# +# Delay in seconds before being allowed another attempt after a login failure +# +FAIL_DELAY 3 + +# +# Enable additional passwords upon dialup lines specified in /etc/dialups. +# +DIALUPS_CHECK_ENAB yes + +# +# 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. +# QMAIL_DIR is for Qmail +# +#QMAIL_DIR Maildir +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, the presence of this value in an /etc/passwd "shell" field will +# disable logins for that user, although "su" will still be allowed. +# +# XXX this does not seem to be implemented yet... --marekm +# no, it was implemented but I ripped it out ;-) -- jfh +NOLOGIN_STR NOLOGIN + +# +# 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=/sbin:/bin:/usr/sbin:/usr/bin +ENV_PATH PATH=/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 0600 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# UMASK Default "umask" value. +# 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 +UMASK 022 +#ULIMIT 2097152 + +# +# 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 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 100 +GID_MAX 60000 + +# +# 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 rwh + +# +# 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". +# +#MD5_CRYPT_ENAB no + +# +# 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... +# +#CONSOLE_GROUPS floppy:audio:cdrom + +# +# 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 + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. No password is required to log in +# as a non-root user on these devices. +# +#NO_PASSWORD_CONSOLE tty1:tty2:tty3:tty4:tty5:tty6 + +# +# When prompting for password without echo, getpass() can optionally +# display a random number (in the range 1 to GETPASS_ASTERISKS) of '*' +# characters for each character typed. This feature is designed to +# confuse people looking over your shoulder when you enter a password :-). +# Also, the new getpass() accepts both Backspace (8) and Delete (127) +# keys to delete previous character (to cope with different terminal +# types), Control-U to delete all characters, and beeps when there are +# no more characters to delete, or too many characters entered. +# +# Setting GETPASS_ASTERISKS to 1 results in more traditional behaviour - +# exactly one '*' displayed for each character typed. +# +# Setting GETPASS_ASTERISKS to 0 disables the '*' characters (Backspace, +# Delete, Control-U and beep continue to work as described above). +# +# Setting GETPASS_ASTERISKS to -1 reverts to the traditional getpass() +# without any new features. This is the default. +# +#GETPASS_ASTERISKS 1 + +# +# 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 + diff --git a/current/etc/pam.d/Makefile.am b/current/etc/pam.d/Makefile.am new file mode 100644 index 00000000..c9041de6 --- /dev/null +++ b/current/etc/pam.d/Makefile.am @@ -0,0 +1,4 @@ +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + +EXTRA_DIST = passwd su diff --git a/current/etc/pam.d/Makefile.in b/current/etc/pam.d/Makefile.in new file mode 100644 index 00000000..83dbbb8b --- /dev/null +++ b/current/etc/pam.d/Makefile.in @@ -0,0 +1,211 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +EXTRA_DIST = passwd su +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps etc/pam.d/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = etc/pam.d + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/etc/pam.d/passwd b/current/etc/pam.d/passwd new file mode 100644 index 00000000..989d5b96 --- /dev/null +++ b/current/etc/pam.d/passwd @@ -0,0 +1,5 @@ +#%PAM-1.0 +#[For version 1.0 syntax, the above header is optional] +# $Id: passwd,v 1.1 1998/07/23 22:13:15 marekm Exp $ +# /etc/pam.d/passwd - sample PAM config file for the `passwd' service +password required pam_unix_passwd.so diff --git a/current/etc/pam.d/su b/current/etc/pam.d/su new file mode 100644 index 00000000..066be02e --- /dev/null +++ b/current/etc/pam.d/su @@ -0,0 +1,7 @@ +#%PAM-1.0 +#[For version 1.0 syntax, the above header is optional] +# $Id: su,v 1.1 1998/07/23 22:13:15 marekm Exp $ +# /etc/pam.d/su - sample PAM config file for the `su' service +auth sufficient pam_rootok.so +auth required pam_unix_auth.so +account required pam_unix_acct.so diff --git a/current/etc/shells b/current/etc/shells new file mode 100644 index 00000000..e7f0e538 --- /dev/null +++ b/current/etc/shells @@ -0,0 +1,10 @@ +# /etc/shells: valid login shells +/bin/ash +/bin/bash +/bin/csh +/bin/sh +/usr/bin/es +/usr/bin/ksh +/usr/bin/rc +/usr/bin/tcsh +/usr/bin/zsh diff --git a/current/etc/suauth b/current/etc/suauth new file mode 100644 index 00000000..85620c4f --- /dev/null +++ b/current/etc/suauth @@ -0,0 +1,4 @@ +# /etc/suauth - secure-su control file. See suauth(5) for full documentation. + +# Uncommenting this line will only allow members of group root to su to root. +# root:ALL EXCEPT GROUP root:DENY diff --git a/current/install-sh b/current/install-sh new file mode 100755 index 00000000..e9de2384 --- /dev/null +++ b/current/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/current/intl/ChangeLog b/current/intl/ChangeLog new file mode 100644 index 00000000..19895015 --- /dev/null +++ b/current/intl/ChangeLog @@ -0,0 +1,1086 @@ +1998-04-29 Ulrich Drepper + + * intl/localealias.c (read_alias_file): Use unsigned char for + local variables. Remove unused variable tp. + * intl/l10nflist.c (_nl_normalize_codeset): Use unsigned char * + for type of codeset. For loosing Solaris systems. + * intl/loadinfo.h: Adapt prototype of _nl_normalize_codeset. + * intl/bindtextdom.c (BINDTEXTDOMAIN): Don't define local variable + len if not needed. + Patches by Jim Meyering. + +1998-04-28 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): Don't assign the element use_mmap if + mmap is not supported. + + * hash-string.h: Don't include . + +1998-04-27 Ulrich Drepper + + * textdomain.c: Use strdup is available. + + * localealias.c: Define HAVE_MEMPCPY so that we can use this + function. Define and use semapahores to protect modfication of + global objects when compiling for glibc. Add code to allow + freeing alias table. + + * l10nflist.c: Don't assume stpcpy not being a macro. + + * gettextP.h: Define internal_function macri if not already done. + Use glibc byte-swap macros instead of defining SWAP when compiled + for glibc. + (struct loaded_domain): Add elements to allow unloading. + + * Makefile.in (distclean): Don't remove libintl.h here. + + * bindtextdomain.c: Carry over changes from glibc. Use strdup if + available. + + * dcgettext.c: Don't assume stpcpy not being a macro. Mark internal + functions. Add memory freeing code for glibc. + + * dgettext.c: Update copyright. + + * explodename.c: Include stdlib.h and string.h only if they exist. + Use strings.h eventually. + + * finddomain.c: Mark internal functions. Use strdup if available. + Add memory freeing code for glibc. + +1997-10-10 20:00 Ulrich Drepper + + * libgettext.h: Fix dummy textdomain and bindtextdomain macros. + They should return reasonable values. + Reported by Tom Tromey . + +1997-09-16 03:33 Ulrich Drepper + + * libgettext.h: Define PARAMS also to `args' if __cplusplus is defined. + * intlh.inst.in: Likewise. + Reported by Jean-Marc Lasgouttes . + + * libintl.glibc: Update from current glibc version. + +1997-09-06 02:10 Ulrich Drepper + + * intlh.inst.in: Reformat copyright. + +1997-08-19 15:22 Ulrich Drepper + + * dcgettext.c (DCGETTEXT): Remove wrong comment. + +1997-08-16 00:13 Ulrich Drepper + + * Makefile.in (install-data): Don't change directory to install. + +1997-08-01 14:30 Ulrich Drepper + + * cat-compat.c: Fix copyright. + + * localealias.c: Don't define strchr unless !HAVE_STRCHR. + + * loadmsgcat.c: Update copyright. Fix typos. + + * l10nflist.c: Don't define strchr unless !HAVE_STRCHR. + (_nl_make_l10nflist): Handle sponsor and revision correctly. + + * gettext.c: Update copyright. + * gettext.h: Likewise. + * hash-string.h: Likewise. + + * finddomain.c: Remoave dead code. Define strchr only if + !HAVE_STRCHR. + + * explodename.c: Include . + + * explodename.c: Reformat copyright text. + (_nl_explode_name): Fix typo. + + * dcgettext.c: Define and use __set_errno. + (guess_category_value): Don't use setlocale if HAVE_LC_MESSAGES is + not defined. + + * bindtextdom.c: Pretty printing. + +1997-05-01 02:25 Ulrich Drepper + + * dcgettext.c (guess_category_value): Don't depend on + HAVE_LC_MESSAGES. We don't need the macro here. + Patch by Bruno Haible . + + * cat-compat.c (textdomain): DoN't refer to HAVE_SETLOCALE_NULL + macro. Instead use HAVE_LOCALE_NULL and define it when using + glibc, as in dcgettext.c. + Patch by Bruno Haible . + + * Makefile.in (CPPFLAGS): New variable. Reported by Franc,ois + Pinard. + +Mon Mar 10 06:51:17 1997 Ulrich Drepper + + * Makefile.in: Implement handling of libtool. + + * gettextP.h: Change data structures for use of generic lowlevel + i18n file handling. + +Wed Dec 4 20:21:18 1996 Ulrich Drepper + + * textdomain.c: Put parentheses around arguments of memcpy macro + definition. + * localealias.c: Likewise. + * l10nflist.c: Likewise. + * finddomain.c: Likewise. + * bindtextdom.c: Likewise. + Reported by Thomas Esken. + +Mon Nov 25 22:57:51 1996 Ulrich Drepper + + * textdomain.c: Move definition of `memcpy` macro to right + position. + +Fri Nov 22 04:01:58 1996 Ulrich Drepper + + * finddomain.c [!HAVE_STRING_H && !_LIBC]: Define memcpy using + bcopy if not already defined. Reported by Thomas Esken. + * bindtextdom.c: Likewise. + * l10nflist.c: Likewise. + * localealias.c: Likewise. + * textdomain.c: Likewise. + +Tue Oct 29 11:10:27 1996 Ulrich Drepper + + * Makefile.in (libdir): Change to use exec_prefix instead of + prefix. Reported by Knut-HåvardAksnes . + +Sat Aug 31 03:07:09 1996 Ulrich Drepper + + * l10nflist.c (_nl_normalize_codeset): We convert to lower case, + so don't prepend uppercase `ISO' for only numeric arg. + +Fri Jul 19 00:15:46 1996 Ulrich Drepper + + * l10nflist.c: Move inclusion of argz.h, ctype.h, stdlib.h after + definition of _GNU_SOURCE. Patch by Roland McGrath. + + * Makefile.in (uninstall): Fix another bug with `for' loop and + empty arguments. Patch by Jim Meyering. Correct name os + uninstalled files: no intl- prefix anymore. + + * Makefile.in (install-data): Again work around shells which + cannot handle mpty for list. Reported by Jim Meyering. + +Sat Jul 13 18:11:35 1996 Ulrich Drepper + + * Makefile.in (install): Split goal. Now depend on install-exec + and install-data. + (install-exec, install-data): New goals. Created from former + install goal. + Reported by Karl Berry. + +Sat Jun 22 04:58:14 1996 Ulrich Drepper + + * Makefile.in (MKINSTALLDIRS): New variable. Path to + mkinstalldirs script. + (install): use MKINSTALLDIRS variable or if the script is not present + try to find it in the $top_scrdir). + +Wed Jun 19 02:56:56 1996 Ulrich Drepper + + * l10nflist.c: Linux libc *partly* includes the argz_* functions. + Grr. Work around by renaming the static version and use macros + for renaming. + +Tue Jun 18 20:11:17 1996 Ulrich Drepper + + * l10nflist.c: Correct presence test macros of __argz_* functions. + + * l10nflist.c: Include based on test of it instead when + __argz_* functions are available. + Reported by Andreas Schwab. + +Thu Jun 13 15:17:44 1996 Ulrich Drepper + + * explodename.c, l10nflist.c: Define NULL for dumb systems. + +Tue Jun 11 17:05:13 1996 Ulrich Drepper + + * intlh.inst.in, libgettext.h (dcgettext): Rename local variable + result to __result to prevent name clash. + + * l10nflist.c, localealias.c, dcgettext.c: Define _GNU_SOURCE to + get prototype for stpcpy and strcasecmp. + + * intlh.inst.in, libgettext.h: Move declaration of + `_nl_msg_cat_cntr' outside __extension__ block to prevent warning + from gcc's -Wnested-extern option. + +Fri Jun 7 01:58:00 1996 Ulrich Drepper + + * Makefile.in (install): Remove comment. + +Thu Jun 6 17:28:17 1996 Ulrich Drepper + + * Makefile.in (install): Work around for another Buglix stupidity. + Always use an `else' close for `if's. Reported by Nelson Beebe. + + * Makefile.in (intlh.inst): Correct typo in phony rule. + Reported by Nelson Beebe. + +Thu Jun 6 01:49:52 1996 Ulrich Drepper + + * dcgettext.c (read_alias_file): Rename variable alloca_list to + block_list as the macro calls assume. + Patch by Eric Backus. + + * localealias.c [!HAVE_ALLOCA]: Define alloca as macro using + malloc. + (read_alias_file): Rename varriabe alloca_list to block_list as the + macro calls assume. + Patch by Eric Backus. + + * l10nflist.c: Correct conditional for inclusion. + Reported by Roland McGrath. + + * Makefile.in (all): Depend on all-@USE_INCLUDED_LIBINTL@, not + all-@USE_NLS@. + + * Makefile.in (install): intlh.inst comes from local dir, not + $(srcdir). + + * Makefile.in (intlh.inst): Special handling of this goal. If + used in gettext, this is really a rul to construct this file. If + used in any other package it is defined as a .PHONY rule with + empty body. + + * finddomain.c: Extract locale file information handling into + l10nfile.c. Rename local stpcpy__ function to stpcpy. + + * dcgettext.c (stpcpy): Add local definition. + + * l10nflist.c: Solve some portability problems. Patches partly by + Thomas Esken. Add local definition of stpcpy. + +Tue Jun 4 02:47:49 1996 Ulrich Drepper + + * intlh.inst.in: Don't depend including on + HAVE_LOCALE_H. Instead configure must rewrite this fiile + depending on the result of the configure run. + + * Makefile.in (install): libintl.inst is now called intlh.inst. + Add rules for updating intlh.inst from intlh.inst.in. + + * libintl.inst: Renamed to intlh.inst.in. + + * localealias.c, dcgettext.c [__GNUC__]: Define HAVE_ALLOCA to 1 + because gcc has __buitlin_alloca. + Reported by Roland McGrath. + +Mon Jun 3 00:32:16 1996 Ulrich Drepper + + * Makefile.in (installcheck): New goal to fulfill needs of + automake's distcheck. + + * Makefile.in (install): Reorder commands so that VERSION is + found. + + * Makefile.in (gettextsrcdir): Now use subdirectory intl/ in + @datadir@/gettext. + (COMSRCS): Add l10nfile.c. + (OBJECTS): Add l10nfile.o. + (DISTFILES): Rename to DISTFILE.normal. Remove $(DISTFILES.common). + (DISTFILE.gettext): Remove $(DISTFILES.common). + (all-gettext): Remove goal. + (install): If $(PACKAGE) = gettext install, otherwose do nothing. No + package but gettext itself should install libintl.h + headers. + (dist): Extend goal to work for gettext, too. + (dist-gettext): Remove goal. + + * dcgettext.c [!HAVE_ALLOCA]: Define macro alloca by using malloc. + +Sun Jun 2 17:33:06 1996 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): Parameter is now comes from + find_l10nfile. + +Sat Jun 1 02:23:03 1996 Ulrich Drepper + + * l10nflist.c (__argz_next): Add definition. + + * dcgettext.c [!HAVE_ALLOCA]: Add code for handling missing alloca + code. Use new l10nfile handling. + + * localealias.c [!HAVE_ALLOCA]: Add code for handling missing + alloca code. + + * l10nflist.c: Initial revision. + +Tue Apr 2 18:51:18 1996 Ulrich Drepper + + * Makefile.in (all-gettext): New goal. Same as all-yes. + +Thu Mar 28 23:01:22 1996 Karl Eichwalder + + * Makefile.in (gettextsrcdir): Define using @datadir@. + +Tue Mar 26 12:39:14 1996 Ulrich Drepper + + * finddomain.c: Include . Reported by Roland McGrath. + +Sat Mar 23 02:00:35 1996 Ulrich Drepper + + * finddomain.c (stpcpy): Rename to stpcpy__ to prevent clashing + with external declaration. + +Sat Mar 2 00:47:09 1996 Ulrich Drepper + + * Makefile.in (all-no): Rename from all_no. + +Sat Feb 17 00:25:59 1996 Ulrich Drepper + + * gettextP.h [loaded_domain]: Array `successor' must now contain up + to 63 elements (because of codeset name normalization). + + * finddomain.c: Implement codeset name normalization. + +Thu Feb 15 04:39:09 1996 Ulrich Drepper + + * Makefile.in (all): Define to `all-@USE_NLS@'. + (all-yes, all_no): New goals. `all-no' is noop, `all-yes' + is former all. + +Mon Jan 15 21:46:01 1996 Howard Gayle + + * localealias.c (alias_compare): Increment string pointers in loop + of strcasecmp replacement. + +Fri Dec 29 21:16:34 1995 Ulrich Drepper + + * Makefile.in (install-src): Who commented this goal out ? :-) + +Fri Dec 29 15:08:16 1995 Ulrich Drepper + + * dcgettext.c (DCGETTEXT): Save `errno'. Failing system calls + should not effect it because a missing catalog is no error. + Reported by Harald Knig . + +Tue Dec 19 22:09:13 1995 Ulrich Drepper + + * Makefile.in (Makefile): Explicitly use $(SHELL) for running + shell scripts. + +Fri Dec 15 17:34:59 1995 Andreas Schwab + + * Makefile.in (install-src): Only install library and header when + we use the own implementation. Don't do it when using the + system's gettext or catgets functions. + + * dcgettext.c (find_msg): Must not swap domain->hash_size here. + +Sat Dec 9 16:24:37 1995 Ulrich Drepper + + * localealias.c, libintl.inst, libgettext.h, hash-string.h, + gettextP.h, finddomain.c, dcgettext.c, cat-compat.c: + Use PARAMS instead of __P. Suggested by Roland McGrath. + +Tue Dec 5 11:39:14 1995 Larry Schwimmer + + * libgettext.h: Use `#if !defined (_LIBINTL_H)' instead of `#if + !_LIBINTL_H' because Solaris defines _LIBINTL_H as empty. + +Mon Dec 4 15:42:07 1995 Ulrich Drepper + + * Makefile.in (install-src): + Install libintl.inst instead of libintl.h.install. + +Sat Dec 2 22:51:38 1995 Marcus Daniels + + * cat-compat.c (textdomain): + Reverse order in which files are tried you load. First + try local file, when this failed absolute path. + +Wed Nov 29 02:03:53 1995 Nelson H. F. Beebe + + * cat-compat.c (bindtextdomain): Add missing { }. + +Sun Nov 26 18:21:41 1995 Ulrich Drepper + + * libintl.inst: Add missing __P definition. Reported by Nelson Beebe. + + * Makefile.in: + Add dummy `all' and `dvi' goals. Reported by Tom Tromey. + +Sat Nov 25 16:12:01 1995 Franc,ois Pinard + + * hash-string.h: Capitalize arguments of macros. + +Sat Nov 25 12:01:36 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): Prevent files names longer than 13 + characters. libintl.h.glibc->libintl.glibc, + libintl.h.install->libintl.inst. Reported by Joshua R. Poulson. + +Sat Nov 25 11:31:12 1995 Eric Backus + + * dcgettext.c: Fix bug in preprocessor conditionals. + +Sat Nov 25 02:35:27 1995 Nelson H. F. Beebe + + * libgettext.h: Solaris cc does not understand + #if !SYMBOL1 && !SYMBOL2. Sad but true. + +Thu Nov 23 16:22:14 1995 Ulrich Drepper + + * hash-string.h (hash_string): + Fix for machine with >32 bit `unsigned long's. + + * dcgettext.c (DCGETTEXT): + Fix horrible bug in loop for alternative translation. + +Thu Nov 23 01:45:29 1995 Ulrich Drepper + + * po2tbl.sed.in, linux-msg.sed, xopen-msg.sed: + Some further simplifications in message number generation. + +Mon Nov 20 21:08:43 1995 Ulrich Drepper + + * libintl.h.glibc: Use __const instead of const in prototypes. + + * Makefile.in (install-src): + Install libintl.h.install instead of libintl.h. This + is a stripped-down version. Suggested by Peter Miller. + + * libintl.h.install, libintl.h.glibc: Initial revision. + + * localealias.c (_nl_expand_alias, read_alias_file): + Protect prototypes in type casts by __P. + +Tue Nov 14 16:43:58 1995 Ulrich Drepper + + * hash-string.h: Correct prototype for hash_string. + +Sun Nov 12 12:42:30 1995 Ulrich Drepper + + * hash-string.h (hash_string): Add prototype. + + * gettextP.h: Fix copyright. + (SWAP): Add prototype. + +Wed Nov 8 22:56:33 1995 Ulrich Drepper + + * localealias.c (read_alias_file): Forgot sizeof. + Avoid calling *printf function. This introduces a big overhead. + Patch by Roland McGrath. + +Tue Nov 7 14:21:08 1995 Ulrich Drepper + + * finddomain.c, cat-compat.c: Wrong indentation in #if for stpcpy. + + * finddomain.c (stpcpy): + Define substitution function local. The macro was to flaky. + + * cat-compat.c: Fix typo. + + * xopen-msg.sed, linux-msg.sed: + While bringing message number to right place only accept digits. + + * linux-msg.sed, xopen-msg.sed: Now that the counter does not have + leading 0s we don't need to remove them. Reported by Marcus + Daniels. + + * Makefile.in (../po/cat-id-tbl.o): Use $(top_srdir) in + dependency. Reported by Marcus Daniels. + + * cat-compat.c: (stpcpy) [!_LIBC && !HAVE_STPCPY]: Define replacement. + Generally cleanup using #if instead of #ifndef. + + * Makefile.in: Correct typos in comment. By Franc,ois Pinard. + +Mon Nov 6 00:27:02 1995 Ulrich Drepper + + * Makefile.in (install-src): Don't install libintl.h and libintl.a + if we use an available gettext implementation. + +Sun Nov 5 22:02:08 1995 Ulrich Drepper + + * libgettext.h: Fix typo: HAVE_CATGETTS -> HAVE_CATGETS. Reported + by Franc,ois Pinard. + + * libgettext.h: Use #if instead of #ifdef/#ifndef. + + * finddomain.c: + Comments describing what has to be done should start with FIXME. + +Sun Nov 5 19:38:01 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): Split. Use DISTFILES with normal meaning. + DISTFILES.common names the files common to both dist goals. + DISTFILES.gettext are the files only distributed in GNU gettext. + +Sun Nov 5 17:32:54 1995 Ulrich Drepper + + * dcgettext.c (DCGETTEXT): Correct searching in derived locales. + This was necessary since a change in _nl_find_msg several weeks + ago. I really don't know this is still not fixed. + +Sun Nov 5 12:43:12 1995 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): Test for FILENAME == NULL. This + might mark a special condition. + + * finddomain.c (make_entry_rec): Don't make illegal entry as decided. + + * Makefile.in (dist): Suppress error message when ln failed. + Get files from $(srcdir) explicitly. + + * libgettext.h (gettext_const): Rename to gettext_noop. + +Fri Nov 3 07:36:50 1995 Ulrich Drepper + + * finddomain.c (make_entry_rec): + Protect against wrong locale names by testing mask. + + * libgettext.h (gettext_const): Add macro definition. + Capitalize macro arguments. + +Thu Nov 2 23:15:51 1995 Ulrich Drepper + + * finddomain.c (_nl_find_domain): + Test for pointer != NULL before accessing value. + Reported by Tom Tromey. + + * gettext.c (NULL): + Define as (void*)0 instad of 0. Reported by Franc,ois Pinard. + +Mon Oct 30 21:28:52 1995 Ulrich Drepper + + * po2tbl.sed.in: Serious typo bug fixed by Jim Meyering. + +Sat Oct 28 23:20:47 1995 Ulrich Drepper + + * libgettext.h: Disable dcgettext optimization for Solaris 2.3. + + * localealias.c (alias_compare): + Peter Miller reported that tolower in some systems is + even dumber than I thought. Protect call by `isupper'. + +Fri Oct 27 22:22:51 1995 Ulrich Drepper + + * Makefile.in (libdir, includedir): New variables. + (install-src): Install libintl.a and libintl.h in correct dirs. + +Fri Oct 27 22:07:29 1995 Ulrich Drepper + + * Makefile.in (SOURCES): Fix typo: intrl.compat.c -> intl-compat.c. + + * po2tbl.sed.in: Patch for buggy SEDs by Christian von Roques. + + * localealias.c: + Fix typo and superflous test. Reported by Christian von Roques. + +Fri Oct 6 11:52:05 1995 Ulrich Drepper + + * finddomain.c (_nl_find_domain): + Correct some remainder from the pre-CEN syntax. Now + we don't have a constant number of successors anymore. + +Wed Sep 27 21:41:13 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): Add libintl.h.glibc. + + * Makefile.in (dist-libc): Add goal for packing sources for glibc. + (COMSRCS, COMHDRS): Splitted to separate sources shared with glibc. + + * loadmsgcat.c: Forget to continue #if line. + + * localealias.c: + [_LIBC]: Rename strcasecmp to __strcasecmp to keep ANSI C name + space clean. + + * dcgettext.c, finddomain.c: Better comment to last change. + + * loadmsgcat.c: + [_LIBC]: Rename fstat, open, close, read, mmap, and munmap to + __fstat, __open, __close, __read, __mmap, and __munmap resp + to keep ANSI C name space clean. + + * finddomain.c: + [_LIBC]: Rename stpcpy to __stpcpy to keep ANSI C name space clean. + + * dcgettext.c: + [_LIBC]: Rename getced and stpcpy to __getcwd and __stpcpy resp to + keep ANSI C name space clean. + + * libgettext.h: + Include sys/types.h for those old SysV systems out there. + Reported by Francesco Potorti`. + + * loadmsgcat.c (use_mmap): Define if compiled for glibc. + + * bindtextdom.c: Include all those standard headers + unconditionally if _LIBC is defined. + + * finddomain.c: Fix 2 times defiend -> defined. + + * textdomain.c: Include libintl.h instead of libgettext.h when + compiling for glibc. Include all those standard headers + unconditionally if _LIBC is defined. + + * localealias.c, loadmsgcat.c: Prepare to be compiled in glibc. + + * gettext.c: + Include libintl.h instead of libgettext.h when compiling for glibc. + Get NULL from stddef.h if we compile for glibc. + + * finddomain.c: Include libintl.h instead of libgettext.h when + compiling for glibc. Include all those standard headers + unconditionally if _LIBC is defined. + + * dcgettext.c: Include all those standard headers unconditionally + if _LIBC is defined. + + * dgettext.c: If compiled in glibc include libintl.h instead of + libgettext.h. + (locale.h): Don't rely on HAVE_LOCALE_H when compiling for glibc. + + * dcgettext.c: If compiled in glibc include libintl.h instead of + libgettext.h. + (getcwd): Don't rely on HAVE_GETCWD when compiling for glibc. + + * bindtextdom.c: + If compiled in glibc include libintl.h instead of libgettext.h. + +Mon Sep 25 22:23:06 1995 Ulrich Drepper + + * localealias.c (_nl_expand_alias): Don't call bsearch if NMAP <= 0. + Reported by Marcus Daniels. + + * cat-compat.c (bindtextdomain): + String used in putenv must not be recycled. + Reported by Marcus Daniels. + + * libgettext.h (__USE_GNU_GETTEXT): + Additional symbol to signal that we use GNU gettext + library. + + * cat-compat.c (bindtextdomain): + Fix bug with the strange stpcpy replacement. + Reported by Nelson Beebe. + +Sat Sep 23 08:23:51 1995 Ulrich Drepper + + * cat-compat.c: Include for stpcpy prototype. + + * localealias.c (read_alias_file): + While expand strdup code temporary variable `cp' hided + higher level variable with same name. Rename to `tp'. + + * textdomain.c (textdomain): + Avoid warning by using temporary variable in strdup code. + + * finddomain.c (_nl_find_domain): Remove unused variable `application'. + +Thu Sep 21 15:51:44 1995 Ulrich Drepper + + * localealias.c (alias_compare): + Use strcasecmp() only if available. Else use + implementation in place. + + * intl-compat.c: + Wrapper functions now call *__ functions instead of __*. + + * libgettext.h: Declare prototypes for *__ functions instead for __*. + + * cat-compat.c, loadmsgcat.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + + * bindtextdom.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + Rename to bindtextdomain__ if not used in GNU C Library. + + * dgettext.c: + Rename function to dgettext__ if not used in GNU C Library. + + * gettext.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + Functions now called gettext__ if not used in GNU C Library. + + * dcgettext.c, localealias.c, textdomain.c, finddomain.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + +Sun Sep 17 23:14:49 1995 Ulrich Drepper + + * finddomain.c: Correct some bugs in handling of CEN standard + locale definitions. + +Thu Sep 7 01:49:28 1995 Ulrich Drepper + + * finddomain.c: Implement CEN syntax. + + * gettextP.h (loaded_domain): Extend number of successors to 31. + +Sat Aug 19 19:25:29 1995 Ulrich Drepper + + * Makefile.in (aliaspath): Remove path to X11 locale dir. + + * Makefile.in: Make install-src depend on install. This helps + gettext to install the sources and other packages can use the + install goal. + +Sat Aug 19 15:19:33 1995 Ulrich Drepper + + * Makefile.in (uninstall): Remove stuff installed by install-src. + +Tue Aug 15 13:13:53 1995 Ulrich Drepper + + * VERSION.in: Initial revision. + + * Makefile.in (DISTFILES): + Add VERSION file. This is not necessary for gettext, but + for other packages using this library. + +Tue Aug 15 06:16:44 1995 Ulrich Drepper + + * gettextP.h (_nl_find_domain): + New prototype after changing search strategy. + + * finddomain.c (_nl_find_domain): + We now try only to find a specified catalog. Fall back to other + catalogs listed in the locale list is now done in __dcgettext. + + * dcgettext.c (__dcgettext): + Now we provide message fall back even to different languages. + I.e. if a message is not available in one language all the other + in the locale list a tried. Formerly fall back was only possible + within one language. Implemented by moving one loop from + _nl_find_domain to here. + +Mon Aug 14 23:45:50 1995 Ulrich Drepper + + * Makefile.in (gettextsrcdir): + Directory where source of GNU gettext library are made + available. + (INSTALL, INSTALL_DATA): Programs used for installing sources. + (gettext-src): New. Rule to install GNU gettext sources for use in + gettextize shell script. + +Sun Aug 13 14:40:48 1995 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): + Use mmap for loading only when munmap function is + also available. + + * Makefile.in (install): Depend on `all' goal. + +Wed Aug 9 11:04:33 1995 Ulrich Drepper + + * localealias.c (read_alias_file): + Do not overwrite '\n' when terminating alias value string. + + * localealias.c (read_alias_file): + Handle long lines. Ignore the rest not fitting in + the buffer after the initial `fgets' call. + +Wed Aug 9 00:54:29 1995 Ulrich Drepper + + * gettextP.h (_nl_load_domain): + Add prototype, replacing prototype for _nl_load_msg_cat. + + * finddomain.c (_nl_find_domain): + Remove unneeded variable filename and filename_len. + (expand_alias): Remove prototype because functions does not + exist anymore. + + * localealias.c (read_alias_file): + Change type of fname_len parameter to int. + (xmalloc): Add prototype. + + * loadmsgcat.c: Better prototypes for xmalloc. + +Tue Aug 8 22:30:39 1995 Ulrich Drepper + + * finddomain.c (_nl_find_domain): + Allow alias name to be constructed from the four components. + + * Makefile.in (aliaspath): New variable. Set to preliminary value. + (SOURCES): Add localealias.c. + (OBJECTS): Add localealias.o. + + * gettextP.h: Add prototype for _nl_expand_alias. + + * finddomain.c: Aliasing handled in intl/localealias.c. + + * localealias.c: Aliasing for locale names. + + * bindtextdom.c: Better prototypes for xmalloc and xstrdup. + +Mon Aug 7 23:47:42 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): gettext.perl is now found in misc/. + + * cat-compat.c (bindtextdomain): + Correct implementation. dirname parameter was not used. + Reported by Marcus Daniels. + + * gettextP.h (loaded_domain): + New fields `successor' and `decided' for oo, lazy + message handling implementation. + + * dcgettext.c: + Adopt for oo, lazy message handliing. + Now we can inherit translations from less specific locales. + (find_msg): New function. + + * loadmsgcat.c, finddomain.c: + Complete rewrite. Implement oo, lazy message handling :-). + We now have an additional environment variable `LANGUAGE' with + a higher priority than LC_ALL for the LC_MESSAGE locale. + Here we can set a colon separated list of specifications each + of the form `language[_territory[.codeset]][@modifier]'. + +Sat Aug 5 09:55:42 1995 Ulrich Drepper + + * finddomain.c (unistd.h): + Include to get _PC_PATH_MAX defined on system having it. + +Fri Aug 4 22:42:00 1995 Ulrich Drepper + + * finddomain.c (stpcpy): Include prototype. + + * Makefile.in (dist): Remove `copying instead' message. + +Wed Aug 2 18:52:03 1995 Ulrich Drepper + + * Makefile.in (ID, TAGS): Do not use $^. + +Tue Aug 1 20:07:11 1995 Ulrich Drepper + + * Makefile.in (TAGS, ID): Use $^ as command argument. + (TAGS): Give etags -o option t write to current directory, + not $(srcdir). + (ID): Use $(srcdir) instead os $(top_srcdir)/src. + (distclean): Remove ID. + +Sun Jul 30 11:51:46 1995 Ulrich Drepper + + * Makefile.in (gnulocaledir): + New variable, always using share/ for data directory. + (DEFS): Add GNULOCALEDIR, used in finddomain.c. + + * finddomain.c (_nl_default_dirname): + Set to GNULOCALEDIR, because it always has to point + to the directory where GNU gettext Library writes it to. + + * intl-compat.c (textdomain, bindtextdomain): + Undefine macros before function definition. + +Sat Jul 22 01:10:02 1995 Ulrich Drepper + + * libgettext.h (_LIBINTL_H): + Protect definition in case where this file is included as + libgettext.h on Solaris machines. Add comment about this. + +Wed Jul 19 02:36:42 1995 Ulrich Drepper + + * intl-compat.c (textdomain): Correct typo. + +Wed Jul 19 01:51:35 1995 Ulrich Drepper + + * dcgettext.c (dcgettext): Function now called __dcgettext. + + * dgettext.c (dgettext): Now called __dgettext and calls + __dcgettext. + + * gettext.c (gettext): + Function now called __gettext and calls __dgettext. + + * textdomain.c (textdomain): Function now called __textdomain. + + * bindtextdom.c (bindtextdomain): Function now called + __bindtextdomain. + + * intl-compat.c: Initial revision. + + * Makefile.in (SOURCES): Add intl-compat.c. + (OBJECTS): We always compile the GNU gettext library functions. + OBJECTS contains all objects but cat-compat.o, ../po/cat-if-tbl.o, + and intl-compat.o. + (GETTOBJS): Contains now only intl-compat.o. + + * libgettext.h: + Re-include protection matches dualistic character of libgettext.h. + For all functions in GNU gettext library define __ counter part. + + * finddomain.c (strchr): Define as index if not found in C library. + (_nl_find_domain): For relative paths paste / in between. + +Tue Jul 18 16:37:45 1995 Ulrich Drepper + + * loadmsgcat.c, finddomain.c: Add inclusion of sys/types.h. + + * xopen-msg.sed: Fix bug with `msgstr ""' lines. + A little bit better comments. + +Tue Jul 18 01:18:27 1995 Ulrich Drepper + + * Makefile.in: + po-mode.el, makelinks, combine-sh are now found in ../misc. + + * po-mode.el, makelinks, combine-sh, elisp-comp: + Moved to ../misc/. + + * libgettext.h, gettextP.h, gettext.h: Uniform test for __STDC__. + +Sun Jul 16 22:33:02 1995 Ulrich Drepper + + * Makefile.in (INSTALL, INSTALL_DATA): New variables. + (install-data, uninstall): Install/uninstall .elc file. + + * po-mode.el (Installation comment): + Add .pox as possible extension of .po files. + +Sun Jul 16 13:23:27 1995 Ulrich Drepper + + * elisp-comp: Complete new version by Franc,ois: This does not + fail when not compiling in the source directory. + +Sun Jul 16 00:12:17 1995 Ulrich Drepper + + * Makefile.in (../po/cat-id-tbl.o): + Use $(MAKE) instead of make for recursive make. + + * Makefile.in (.el.elc): Use $(SHELL) instead of /bin/sh. + (install-exec): Add missing dummy goal. + (install-data, uninstall): @ in multi-line shell command at + beginning, not in front of echo. Reported by Eric Backus. + +Sat Jul 15 00:21:28 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): + Rename libgettext.perl to gettext.perl to fit in 14 chars + file systems. + + * gettext.perl: + Rename to gettext.perl to fit in 14 chars file systems. + +Thu Jul 13 23:17:20 1995 Ulrich Drepper + + * cat-compat.c: If !STDC_HEADERS try to include malloc.h. + +Thu Jul 13 20:55:02 1995 Ulrich Drepper + + * po2tbl.sed.in: Pretty printing. + + * linux-msg.sed, xopen-msg.sed: + Correct bugs with handling substitute flags in branches. + + * hash-string.h (hash_string): + Old K&R compilers don't under stand `unsigned char'. + + * gettext.h (nls_uint32): + Some old K&R compilers (eg HP) don't understand `unsigned int'. + + * cat-compat.c (msg_to_cat_id): De-ANSI-fy prototypes. + +Thu Jul 13 01:34:33 1995 Ulrich Drepper + + * Makefile.in (ELCFILES): New variable. + (DISTFILES): Add elisp-comp. + Add implicit rule for .el -> .elc compilation. + (install-data): install $ELCFILES + (clean): renamed po-to-tbl and po-to-msg to po2tbl and po2msg resp. + + * elisp-comp: Initial revision + +Wed Jul 12 16:14:52 1995 Ulrich Drepper + + * Makefile.in: + cat-id-tbl.c is now found in po/. This enables us to use an identical + intl/ directory in all packages. + + * dcgettext.c (dcgettext): hashing does not work for table size <= 2. + + * textdomain.c: fix typo (#if def -> #if defined) + +Tue Jul 11 18:44:43 1995 Ulrich Drepper + + * Makefile.in (stamp-cat-id): use top_srcdir to address source files + (DISTFILES,distclean): move tupdate.perl to src/ + + * po-to-tbl.sed.in: + add additional jump to clear change flag to recognize multiline strings + +Tue Jul 11 01:32:50 1995 Ulrich Drepper + + * textdomain.c: Protect inclusion of stdlib.h and string.h. + + * loadmsgcat.c: Protect inclusion of stdlib.h. + + * libgettext.h: Protect inclusion of locale.h. + Allow use in C++ programs. + Define NULL is not happened already. + + * Makefile.in (DISTFILES): ship po-to-tbl.sed.in instead of + po-to-tbl.sed. + (distclean): remove po-to-tbl.sed and tupdate.perl. + + * tupdate.perl.in: Substitute Perl path even in exec line. + Don't include entries without translation from old .po file. + +Tue Jul 4 00:41:51 1995 Ulrich Drepper + + * tupdate.perl.in: use "Updated: " in msgid "". + + * cat-compat.c: Fix typo (LOCALDIR -> LOCALEDIR). + Define getenv if !__STDC__. + + * bindtextdom.c: Protect stdlib.h and string.h inclusion. + Define free if !__STDC__. + + * finddomain.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. + Define free if !__STDC__. + + * cat-compat.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. + +Mon Jul 3 23:56:30 1995 Ulrich Drepper + + * Makefile.in: Use LOCALEDIR instead of DEF_MSG_DOM_DIR. + Remove unneeded $(srcdir) from Makefile.in dependency. + + * makelinks: Add copyright and short description. + + * po-mode.el: Last version for 0.7. + + * tupdate.perl.in: Fix die message. + + * dcgettext.c: Protect include of string.h. + + * gettext.c: Protect include of stdlib.h and further tries to get NULL. + + * finddomain.c: Some corrections in includes. + + * Makefile.in (INCLUDES): Prune list correct path to Makefile.in. + + * po-to-tbl.sed: Adopt for new .po file format. + + * linux-msg.sed, xopen-msg.sed: Adopt for new .po file format. + +Sun Jul 2 23:55:03 1995 Ulrich Drepper + + * tupdate.perl.in: Complete rewrite for new .po file format. + +Sun Jul 2 02:06:50 1995 Ulrich Drepper + + * First official release. This directory contains all the code + needed to internationalize own packages. It provides functions + which allow to use the X/Open catgets function with an interface + like the Uniforum gettext function. For system which does not + have neither of those a complete implementation is provided. diff --git a/current/intl/Makefile.in b/current/intl/Makefile.in new file mode 100644 index 00000000..4bdb186d --- /dev/null +++ b/current/intl/Makefile.in @@ -0,0 +1,214 @@ +# Makefile for directory with message catalog handling in GNU NLS Utilities. +# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = .. +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +transform = @program_transform_name@ +libdir = $(exec_prefix)/lib +includedir = $(prefix)/include +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale +gnulocaledir = $(prefix)/share/locale +gettextsrcdir = @datadir@/gettext/intl +aliaspath = $(localedir):. +subdir = intl + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = @MKINSTALLDIRS@ + +l = @l@ + +AR = ar +CC = @CC@ +LIBTOOL = @LIBTOOL@ +RANLIB = @RANLIB@ + +DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \ +-DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +HEADERS = $(COMHDRS) libgettext.h loadinfo.h +COMHDRS = gettext.h gettextP.h hash-string.h +SOURCES = $(COMSRCS) intl-compat.c cat-compat.c +COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ +finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ +explodename.c +OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ +finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ +explodename.$lo +CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo +GETTOBJS = intl-compat.$lo +DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \ +xopen-msg.sed $(HEADERS) $(SOURCES) +DISTFILES.normal = VERSION +DISTFILES.gettext = libintl.glibc intlh.inst.in + +.SUFFIXES: +.SUFFIXES: .c .o .lo +.c.o: + $(COMPILE) $< +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) $< + +INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib + +all: all-@USE_INCLUDED_LIBINTL@ + +all-yes: libintl.$la intlh.inst +all-no: + +libintl.a: $(OBJECTS) + rm -f $@ + $(AR) cru $@ $(OBJECTS) + $(RANLIB) $@ + +libintl.la: $(OBJECTS) + $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \ + -version-info 1:0 -rpath $(libdir) + +../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot + cd ../po && $(MAKE) cat-id-tbl.$lo + +check: all + +# This installation goal is only used in GNU gettext. Packages which +# only use the library should use install instead. + +# We must not install the libintl.h/libintl.a files if we are on a +# system which has the gettext() function in its C library or in a +# separate library or use the catgets interface. A special case is +# where configure found a previously installed GNU gettext library. +# If you want to use the one which comes with this version of the +# package, you have to use `configure --with-included-gettext'. +install: install-exec install-data +install-exec: all + if test "$(PACKAGE)" = "gettext" \ + && test '@INTLOBJS@' = '$(GETTOBJS)'; then \ + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $(libdir) $(includedir); \ + else \ + $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \ + fi; \ + $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \ + $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \ + else \ + : ; \ + fi +install-data: all + if test "$(PACKAGE)" = "gettext"; then \ + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $(gettextsrcdir); \ + else \ + $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ + fi; \ + $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \ + dists="$(DISTFILES.common)"; \ + for file in $$dists; do \ + $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + dists="$(DISTFILES.common)"; \ + for file in $$dists; do \ + rm -f $(gettextsrcdir)/$$file; \ + done + +info dvi: + +$(OBJECTS): ../config.h libgettext.h +bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h +dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h + +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) + +id: ID + +ID: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) + + +mostlyclean: + rm -f *.a *.o *.lo core core.* + +clean: mostlyclean + +distclean: clean + rm -f Makefile ID TAGS po2msg.sed po2tbl.sed + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + + +# GNU gettext needs not contain the file `VERSION' but contains some +# other files which should not be distributed in other packages. +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: Makefile $(DISTFILES) + if test "$(PACKAGE)" = gettext; then \ + additional="$(DISTFILES.gettext)"; \ + else \ + additional="$(DISTFILES.normal)"; \ + fi; \ + for file in $(DISTFILES.common) $$additional; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +dist-libc: + tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc + +Makefile: Makefile.in ../config.status + cd .. \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +# The dependency for intlh.inst is different in gettext and all other +# packages. Because we cannot you GNU make features we have to solve +# the problem while rewriting Makefile.in. +@GT_YES@intlh.inst: intlh.inst.in ../config.status +@GT_YES@ cd .. \ +@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \ +@GT_YES@ $(SHELL) ./config.status +@GT_NO@.PHONY: intlh.inst +@GT_NO@intlh.inst: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/intl/VERSION b/current/intl/VERSION new file mode 100644 index 00000000..ee66b061 --- /dev/null +++ b/current/intl/VERSION @@ -0,0 +1 @@ +GNU gettext library from gettext-0.10.35 diff --git a/current/intl/bindtextdom.c b/current/intl/bindtextdom.c new file mode 100644 index 00000000..d9c3f349 --- /dev/null +++ b/current/intl/bindtextdom.c @@ -0,0 +1,203 @@ +/* Implementation of the bindtextdomain(3) function + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif +#include "gettext.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +/* Contains the default location of the message catalogs. */ +extern const char _nl_default_dirname[]; + +/* List with bindings of specific domains. */ +extern struct binding *_nl_domain_bindings; + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define BINDTEXTDOMAIN __bindtextdomain +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define BINDTEXTDOMAIN bindtextdomain__ +#endif + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +char * +BINDTEXTDOMAIN (domainname, dirname) + const char *domainname; + const char *dirname; +{ + struct binding *binding; + + /* Some sanity checks. */ + if (domainname == NULL || domainname[0] == '\0') + return NULL; + + for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) + { + int compare = strcmp (domainname, binding->domainname); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It is not in the list. */ + binding = NULL; + break; + } + } + + if (dirname == NULL) + /* The current binding has be to returned. */ + return binding == NULL ? (char *) _nl_default_dirname : binding->dirname; + + if (binding != NULL) + { + /* The domain is already bound. If the new value and the old + one are equal we simply do nothing. Otherwise replace the + old binding. */ + if (strcmp (dirname, binding->dirname) != 0) + { + char *new_dirname; + + if (strcmp (dirname, _nl_default_dirname) == 0) + new_dirname = (char *) _nl_default_dirname; + else + { +#if defined _LIBC || defined HAVE_STRDUP + new_dirname = strdup (dirname); + if (new_dirname == NULL) + return NULL; +#else + size_t len = strlen (dirname) + 1; + new_dirname = (char *) malloc (len); + if (new_dirname == NULL) + return NULL; + + memcpy (new_dirname, dirname, len); +#endif + } + + if (binding->dirname != _nl_default_dirname) + free (binding->dirname); + + binding->dirname = new_dirname; + } + } + else + { + /* We have to create a new binding. */ +#if !defined _LIBC && !defined HAVE_STRDUP + size_t len; +#endif + struct binding *new_binding = + (struct binding *) malloc (sizeof (*new_binding)); + + if (new_binding == NULL) + return NULL; + +#if defined _LIBC || defined HAVE_STRDUP + new_binding->domainname = strdup (domainname); + if (new_binding->domainname == NULL) + return NULL; +#else + len = strlen (domainname) + 1; + new_binding->domainname = (char *) malloc (len); + if (new_binding->domainname == NULL) + return NULL; + memcpy (new_binding->domainname, domainname, len); +#endif + + if (strcmp (dirname, _nl_default_dirname) == 0) + new_binding->dirname = (char *) _nl_default_dirname; + else + { +#if defined _LIBC || defined HAVE_STRDUP + new_binding->dirname = strdup (dirname); + if (new_binding->dirname == NULL) + return NULL; +#else + len = strlen (dirname) + 1; + new_binding->dirname = (char *) malloc (len); + if (new_binding->dirname == NULL) + return NULL; + memcpy (new_binding->dirname, dirname, len); +#endif + } + + /* Now enqueue it. */ + if (_nl_domain_bindings == NULL + || strcmp (domainname, _nl_domain_bindings->domainname) < 0) + { + new_binding->next = _nl_domain_bindings; + _nl_domain_bindings = new_binding; + } + else + { + binding = _nl_domain_bindings; + while (binding->next != NULL + && strcmp (domainname, binding->next->domainname) > 0) + binding = binding->next; + + new_binding->next = binding->next; + binding->next = new_binding; + } + + binding = new_binding; + } + + return binding->dirname; +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__bindtextdomain, bindtextdomain); +#endif diff --git a/current/intl/cat-compat.c b/current/intl/cat-compat.c new file mode 100644 index 00000000..867d901b --- /dev/null +++ b/current/intl/cat-compat.c @@ -0,0 +1,262 @@ +/* Compatibility code for gettext-using-catgets interface. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef STDC_HEADERS +# include +# include +#else +char *getenv (); +# ifdef HAVE_MALLOC_H +# include +# endif +#endif + +#ifdef HAVE_NL_TYPES_H +# include +#endif + +#include "libgettext.h" + +/* @@ end of prolog @@ */ + +/* XPG3 defines the result of `setlocale (category, NULL)' as: + ``Directs `setlocale()' to query `category' and return the current + setting of `local'.'' + However it does not specify the exact format. And even worse: POSIX + defines this not at all. So we can use this feature only on selected + system (e.g. those using GNU C Library). */ +#ifdef _LIBC +# define HAVE_LOCALE_NULL +#endif + +/* The catalog descriptor. */ +static nl_catd catalog = (nl_catd) -1; + +/* Name of the default catalog. */ +static const char default_catalog_name[] = "messages"; + +/* Name of currently used catalog. */ +static const char *catalog_name = default_catalog_name; + +/* Get ID for given string. If not found return -1. */ +static int msg_to_cat_id PARAMS ((const char *msg)); + +/* Substitution for systems lacking this function in their C library. */ +#if !_LIBC && !HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +#endif + + +/* Set currently used domain/catalog. */ +char * +textdomain (domainname) + const char *domainname; +{ + nl_catd new_catalog; + char *new_name; + size_t new_name_len; + char *lang; + +#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \ + && defined HAVE_LOCALE_NULL + lang = setlocale (LC_MESSAGES, NULL); +#else + lang = getenv ("LC_ALL"); + if (lang == NULL || lang[0] == '\0') + { + lang = getenv ("LC_MESSAGES"); + if (lang == NULL || lang[0] == '\0') + lang = getenv ("LANG"); + } +#endif + if (lang == NULL || lang[0] == '\0') + lang = "C"; + + /* See whether name of currently used domain is asked. */ + if (domainname == NULL) + return (char *) catalog_name; + + if (domainname[0] == '\0') + domainname = default_catalog_name; + + /* Compute length of added path element. */ + new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang) + + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1 + + sizeof (".cat"); + + new_name = (char *) malloc (new_name_len); + if (new_name == NULL) + return NULL; + + strcpy (new_name, PACKAGE); + new_catalog = catopen (new_name, 0); + + if (new_catalog == (nl_catd) -1) + { + /* NLSPATH search didn't work, try absolute path */ + sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang, + PACKAGE); + new_catalog = catopen (new_name, 0); + + if (new_catalog == (nl_catd) -1) + { + free (new_name); + return (char *) catalog_name; + } + } + + /* Close old catalog. */ + if (catalog != (nl_catd) -1) + catclose (catalog); + if (catalog_name != default_catalog_name) + free ((char *) catalog_name); + + catalog = new_catalog; + catalog_name = new_name; + + return (char *) catalog_name; +} + +char * +bindtextdomain (domainname, dirname) + const char *domainname; + const char *dirname; +{ +#if HAVE_SETENV || HAVE_PUTENV + char *old_val, *new_val, *cp; + size_t new_val_len; + + /* This does not make much sense here but to be compatible do it. */ + if (domainname == NULL) + return NULL; + + /* Compute length of added path element. If we use setenv we don't need + the first byts for NLSPATH=, but why complicate the code for this + peanuts. */ + new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname) + + sizeof ("/%L/LC_MESSAGES/%N.cat"); + + old_val = getenv ("NLSPATH"); + if (old_val == NULL || old_val[0] == '\0') + { + old_val = NULL; + new_val_len += 1 + sizeof (LOCALEDIR) - 1 + + sizeof ("/%L/LC_MESSAGES/%N.cat"); + } + else + new_val_len += strlen (old_val); + + new_val = (char *) malloc (new_val_len); + if (new_val == NULL) + return NULL; + +# if HAVE_SETENV + cp = new_val; +# else + cp = stpcpy (new_val, "NLSPATH="); +# endif + + cp = stpcpy (cp, dirname); + cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:"); + + if (old_val == NULL) + { +# if __STDC__ + stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat"); +# else + + cp = stpcpy (cp, LOCALEDIR); + stpcpy (cp, "/%L/LC_MESSAGES/%N.cat"); +# endif + } + else + stpcpy (cp, old_val); + +# if HAVE_SETENV + setenv ("NLSPATH", new_val, 1); + free (new_val); +# else + putenv (new_val); + /* Do *not* free the environment entry we just entered. It is used + from now on. */ +# endif + +#endif + + return (char *) domainname; +} + +#undef gettext +char * +gettext (msg) + const char *msg; +{ + int msgid; + + if (msg == NULL || catalog == (nl_catd) -1) + return (char *) msg; + + /* Get the message from the catalog. We always use set number 1. + The message ID is computed by the function `msg_to_cat_id' + which works on the table generated by `po-to-tbl'. */ + msgid = msg_to_cat_id (msg); + if (msgid == -1) + return (char *) msg; + + return catgets (catalog, 1, msgid, (char *) msg); +} + +/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries + for the one equal to msg. If it is found return the ID. In case when + the string is not found return -1. */ +static int +msg_to_cat_id (msg) + const char *msg; +{ + int cnt; + + for (cnt = 0; cnt < _msg_tbl_length; ++cnt) + if (strcmp (msg, _msg_tbl[cnt]._msg) == 0) + return _msg_tbl[cnt]._msg_number; + + return -1; +} + + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif diff --git a/current/intl/dcgettext.c b/current/intl/dcgettext.c new file mode 100644 index 00000000..0f7bb486 --- /dev/null +++ b/current/intl/dcgettext.c @@ -0,0 +1,655 @@ +/* Implementation of the dcgettext(3) function. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#if defined __GNUC__ && !defined C_ALLOCA +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# if (defined HAVE_ALLOCA_H || defined _LIBC) && !defined C_ALLOCA +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +#endif + +#include +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(val) errno = (val) +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +char *getenv (); +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# endif +# include +#else +# include +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include "gettext.h" +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif +#include "hash-string.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define getcwd __getcwd +# ifndef stpcpy +# define stpcpy __stpcpy +# endif +#else +# if !defined HAVE_GETCWD +char *getwd (); +# define getcwd(buf, max) getwd (buf) +# else +char *getcwd (); +# endif +# ifndef HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +# endif +#endif + +/* Amount to increase buffer size by in each try. */ +#define PATH_INCR 32 + +/* The following is from pathmax.h. */ +/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define + PATH_MAX but might cause redefinition warnings when sys/param.h is + later included (as on MORE/BSD 4.3). */ +#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__)) +# include +#endif + +#ifndef _POSIX_PATH_MAX +# define _POSIX_PATH_MAX 255 +#endif + +#if !defined(PATH_MAX) && defined(_PC_PATH_MAX) +# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) +#endif + +/* Don't include sys/param.h if it already has been. */ +#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN) +# include +#endif + +#if !defined(PATH_MAX) && defined(MAXPATHLEN) +# define PATH_MAX MAXPATHLEN +#endif + +#ifndef PATH_MAX +# define PATH_MAX _POSIX_PATH_MAX +#endif + +/* XPG3 defines the result of `setlocale (category, NULL)' as: + ``Directs `setlocale()' to query `category' and return the current + setting of `local'.'' + However it does not specify the exact format. And even worse: POSIX + defines this not at all. So we can use this feature only on selected + system (e.g. those using GNU C Library). */ +#ifdef _LIBC +# define HAVE_LOCALE_NULL +#endif + +/* Name of the default domain used for gettext(3) prior any call to + textdomain(3). The default value for this is "messages". */ +const char _nl_default_default_domain[] = "messages"; + +/* Value used as the default domain for gettext(3). */ +const char *_nl_current_default_domain = _nl_default_default_domain; + +/* Contains the default location of the message catalogs. */ +const char _nl_default_dirname[] = GNULOCALEDIR; + +/* List with bindings of specific domains created by bindtextdomain() + calls. */ +struct binding *_nl_domain_bindings; + +/* Prototypes for local functions. */ +static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file, + const char *msgid)) internal_function; +static const char *category_to_name PARAMS ((int category)) internal_function; +static const char *guess_category_value PARAMS ((int category, + const char *categoryname)) + internal_function; + + +/* For those loosing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +/* Nothing has to be done. */ +# define ADD_BLOCK(list, address) /* nothing */ +# define FREE_BLOCKS(list) /* nothing */ +#else +struct block_list +{ + void *address; + struct block_list *next; +}; +# define ADD_BLOCK(list, addr) \ + do { \ + struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ + /* If we cannot get a free block we cannot add the new element to \ + the list. */ \ + if (newp != NULL) { \ + newp->address = (addr); \ + newp->next = (list); \ + (list) = newp; \ + } \ + } while (0) +# define FREE_BLOCKS(list) \ + do { \ + while (list != NULL) { \ + struct block_list *old = list; \ + list = list->next; \ + free (old); \ + } \ + } while (0) +# undef alloca +# define alloca(size) (malloc (size)) +#endif /* have alloca */ + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DCGETTEXT __dcgettext +#else +# define DCGETTEXT dcgettext__ +#endif + +/* Checking whether the binaries runs SUID must be done and glibc provides + easier methods therefore we make a difference here. */ +#ifdef _LIBC +# define ENABLE_SECURE __libc_enable_secure +# define DETERMINE_SECURE +#else +static int enable_secure; +# define ENABLE_SECURE (enable_secure == 1) +# define DETERMINE_SECURE \ + if (enable_secure == 0) \ + { \ + if (getuid () != geteuid () || getgid () != getegid ()) \ + enable_secure = 1; \ + else \ + enable_secure = -1; \ + } +#endif + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +char * +DCGETTEXT (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ +#ifndef HAVE_ALLOCA + struct block_list *block_list = NULL; +#endif + struct loaded_l10nfile *domain; + struct binding *binding; + const char *categoryname; + const char *categoryvalue; + char *dirname, *xdomainname; + char *single_locale; + char *retval; + int saved_errno = errno; + + /* If no real MSGID is given return NULL. */ + if (msgid == NULL) + return NULL; + + /* See whether this is a SUID binary or not. */ + DETERMINE_SECURE; + + /* If DOMAINNAME is NULL, we are interested in the default domain. If + CATEGORY is not LC_MESSAGES this might not make much sense but the + definition left this undefined. */ + if (domainname == NULL) + domainname = _nl_current_default_domain; + + /* First find matching binding. */ + for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) + { + int compare = strcmp (domainname, binding->domainname); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It is not in the list. */ + binding = NULL; + break; + } + } + + if (binding == NULL) + dirname = (char *) _nl_default_dirname; + else if (binding->dirname[0] == '/') + dirname = binding->dirname; + else + { + /* We have a relative path. Make it absolute now. */ + size_t dirname_len = strlen (binding->dirname) + 1; + size_t path_max; + char *ret; + + path_max = (unsigned int) PATH_MAX; + path_max += 2; /* The getcwd docs say to do this. */ + + dirname = (char *) alloca (path_max + dirname_len); + ADD_BLOCK (block_list, dirname); + + __set_errno (0); + while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE) + { + path_max += PATH_INCR; + dirname = (char *) alloca (path_max + dirname_len); + ADD_BLOCK (block_list, dirname); + __set_errno (0); + } + + if (ret == NULL) + { + /* We cannot get the current working directory. Don't signal an + error but simply return the default string. */ + FREE_BLOCKS (block_list); + __set_errno (saved_errno); + return (char *) msgid; + } + + stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); + } + + /* Now determine the symbolic name of CATEGORY and its value. */ + categoryname = category_to_name (category); + categoryvalue = guess_category_value (category, categoryname); + + xdomainname = (char *) alloca (strlen (categoryname) + + strlen (domainname) + 5); + ADD_BLOCK (block_list, xdomainname); + + stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), + domainname), + ".mo"); + + /* Creating working area. */ + single_locale = (char *) alloca (strlen (categoryvalue) + 1); + ADD_BLOCK (block_list, single_locale); + + + /* Search for the given string. This is a loop because we perhaps + got an ordered list of languages to consider for the translation. */ + while (1) + { + /* Make CATEGORYVALUE point to the next element of the list. */ + while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') + ++categoryvalue; + if (categoryvalue[0] == '\0') + { + /* The whole contents of CATEGORYVALUE has been searched but + no valid entry has been found. We solve this situation + by implicitly appending a "C" entry, i.e. no translation + will take place. */ + single_locale[0] = 'C'; + single_locale[1] = '\0'; + } + else + { + char *cp = single_locale; + while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') + *cp++ = *categoryvalue++; + *cp = '\0'; + + /* When this is a SUID binary we must not allow accessing files + outside the dedicated directories. */ + if (ENABLE_SECURE + && (memchr (single_locale, '/', + _nl_find_language (single_locale) - single_locale) + != NULL)) + /* Ingore this entry. */ + continue; + } + + /* If the current locale value is C (or POSIX) we don't load a + domain. Return the MSGID. */ + if (strcmp (single_locale, "C") == 0 + || strcmp (single_locale, "POSIX") == 0) + { + FREE_BLOCKS (block_list); + __set_errno (saved_errno); + return (char *) msgid; + } + + + /* Find structure describing the message catalog matching the + DOMAINNAME and CATEGORY. */ + domain = _nl_find_domain (dirname, single_locale, xdomainname); + + if (domain != NULL) + { + retval = find_msg (domain, msgid); + + if (retval == NULL) + { + int cnt; + + for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) + { + retval = find_msg (domain->successor[cnt], msgid); + + if (retval != NULL) + break; + } + } + + if (retval != NULL) + { + FREE_BLOCKS (block_list); + __set_errno (saved_errno); + return retval; + } + } + } + /* NOTREACHED */ +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dcgettext, dcgettext); +#endif + + +static char * +internal_function +find_msg (domain_file, msgid) + struct loaded_l10nfile *domain_file; + const char *msgid; +{ + size_t act = 0; + size_t top, bottom; + struct loaded_domain *domain; + + if (domain_file->decided == 0) + _nl_load_domain (domain_file); + + if (domain_file->data == NULL) + return NULL; + + domain = (struct loaded_domain *) domain_file->data; + + /* Locate the MSGID and its translation. */ + if (domain->hash_size > 2 && domain->hash_tab != NULL) + { + /* Use the hashing table. */ + nls_uint32 len = strlen (msgid); + nls_uint32 hash_val = hash_string (msgid); + nls_uint32 idx = hash_val % domain->hash_size; + nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); + nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]); + + if (nstr == 0) + /* Hash table entry is empty. */ + return NULL; + + if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len + && strcmp (msgid, + domain->data + W (domain->must_swap, + domain->orig_tab[nstr - 1].offset)) == 0) + return (char *) domain->data + W (domain->must_swap, + domain->trans_tab[nstr - 1].offset); + + while (1) + { + if (idx >= domain->hash_size - incr) + idx -= domain->hash_size - incr; + else + idx += incr; + + nstr = W (domain->must_swap, domain->hash_tab[idx]); + if (nstr == 0) + /* Hash table entry is empty. */ + return NULL; + + if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len + && strcmp (msgid, + domain->data + W (domain->must_swap, + domain->orig_tab[nstr - 1].offset)) + == 0) + return (char *) domain->data + + W (domain->must_swap, domain->trans_tab[nstr - 1].offset); + } + /* NOTREACHED */ + } + + /* Now we try the default method: binary search in the sorted + array of messages. */ + bottom = 0; + top = domain->nstrings; + while (bottom < top) + { + int cmp_val; + + act = (bottom + top) / 2; + cmp_val = strcmp (msgid, domain->data + + W (domain->must_swap, + domain->orig_tab[act].offset)); + if (cmp_val < 0) + top = act; + else if (cmp_val > 0) + bottom = act + 1; + else + break; + } + + /* If an translation is found return this. */ + return bottom >= top ? NULL : (char *) domain->data + + W (domain->must_swap, + domain->trans_tab[act].offset); +} + + +/* Return string representation of locale CATEGORY. */ +static const char * +internal_function +category_to_name (category) + int category; +{ + const char *retval; + + switch (category) + { +#ifdef LC_COLLATE + case LC_COLLATE: + retval = "LC_COLLATE"; + break; +#endif +#ifdef LC_CTYPE + case LC_CTYPE: + retval = "LC_CTYPE"; + break; +#endif +#ifdef LC_MONETARY + case LC_MONETARY: + retval = "LC_MONETARY"; + break; +#endif +#ifdef LC_NUMERIC + case LC_NUMERIC: + retval = "LC_NUMERIC"; + break; +#endif +#ifdef LC_TIME + case LC_TIME: + retval = "LC_TIME"; + break; +#endif +#ifdef LC_MESSAGES + case LC_MESSAGES: + retval = "LC_MESSAGES"; + break; +#endif +#ifdef LC_RESPONSE + case LC_RESPONSE: + retval = "LC_RESPONSE"; + break; +#endif +#ifdef LC_ALL + case LC_ALL: + /* This might not make sense but is perhaps better than any other + value. */ + retval = "LC_ALL"; + break; +#endif + default: + /* If you have a better idea for a default value let me know. */ + retval = "LC_XXX"; + } + + return retval; +} + +/* Guess value of current locale from value of the environment variables. */ +static const char * +internal_function +guess_category_value (category, categoryname) + int category; + const char *categoryname; +{ + const char *retval; + + /* The highest priority value is the `LANGUAGE' environment + variable. This is a GNU extension. */ + retval = getenv ("LANGUAGE"); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* `LANGUAGE' is not set. So we have to proceed with the POSIX + methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some + systems this can be done by the `setlocale' function itself. */ +#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL + return setlocale (category, NULL); +#else + /* Setting of LC_ALL overwrites all other. */ + retval = getenv ("LC_ALL"); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* Next comes the name of the desired category. */ + retval = getenv (categoryname); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* Last possibility is the LANG environment variable. */ + retval = getenv ("LANG"); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* We use C as the default domain. POSIX says this is implementation + defined. */ + return "C"; +#endif +} + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif + + +#ifdef _LIBC +/* If we want to free all resources we have to do some work at + program's end. */ +static void __attribute__ ((unused)) +free_mem (void) +{ + struct binding *runp; + + for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next) + { + free (runp->domainname); + if (runp->dirname != _nl_default_dirname) + /* Yes, this is a pointer comparison. */ + free (runp->dirname); + } + + if (_nl_current_default_domain != _nl_default_default_domain) + /* Yes, again a pointer comparison. */ + free ((char *) _nl_current_default_domain); +} + +text_set_element (__libc_subfreeres, free_mem); +#endif diff --git a/current/intl/dgettext.c b/current/intl/dgettext.c new file mode 100644 index 00000000..0510c2b0 --- /dev/null +++ b/current/intl/dgettext.c @@ -0,0 +1,59 @@ +/* Implementation of the dgettext(3) function + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined HAVE_LOCALE_H || defined _LIBC +# include +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DGETTEXT __dgettext +# define DCGETTEXT __dcgettext +#else +# define DGETTEXT dgettext__ +# define DCGETTEXT dcgettext__ +#endif + +/* Look up MSGID in the DOMAINNAME message catalog of the current + LC_MESSAGES locale. */ +char * +DGETTEXT (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return DCGETTEXT (domainname, msgid, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dgettext, dgettext); +#endif diff --git a/current/intl/explodename.c b/current/intl/explodename.c new file mode 100644 index 00000000..80a3111c --- /dev/null +++ b/current/intl/explodename.c @@ -0,0 +1,197 @@ +/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +#endif +#include + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +char * +_nl_find_language (const char *name) +{ + while (name[0] != '\0' && name[0] != '_' && name[0] != '@' + && name[0] != '+' && name[0] != ',') + ++name; + + return (char *) name; +} + + +int +_nl_explode_name (name, language, modifier, territory, codeset, + normalized_codeset, special, sponsor, revision) + char *name; + const char **language; + const char **modifier; + const char **territory; + const char **codeset; + const char **normalized_codeset; + const char **special; + const char **sponsor; + const char **revision; +{ + enum { undecided, xpg, cen } syntax; + char *cp; + int mask; + + *modifier = NULL; + *territory = NULL; + *codeset = NULL; + *normalized_codeset = NULL; + *special = NULL; + *sponsor = NULL; + *revision = NULL; + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = 0; + syntax = undecided; + *language = cp = name; + cp = _nl_find_language (*language); + + if (*language == cp) + /* This does not make sense: language has to be specified. Use + this entry as it is without exploding. Perhaps it is an alias. */ + cp = strchr (*language, '\0'); + else if (cp[0] == '_') + { + /* Next is the territory. */ + cp[0] = '\0'; + *territory = ++cp; + + while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' + && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= TERRITORY; + + if (cp[0] == '.') + { + /* Next is the codeset. */ + syntax = xpg; + cp[0] = '\0'; + *codeset = ++cp; + + while (cp[0] != '\0' && cp[0] != '@') + ++cp; + + mask |= XPG_CODESET; + + if (*codeset != cp && (*codeset)[0] != '\0') + { + *normalized_codeset = _nl_normalize_codeset (*codeset, + cp - *codeset); + if (strcmp (*codeset, *normalized_codeset) == 0) + free ((char *) *normalized_codeset); + else + mask |= XPG_NORM_CODESET; + } + } + } + + if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) + { + /* Next is the modifier. */ + syntax = cp[0] == '@' ? xpg : cen; + cp[0] = '\0'; + *modifier = ++cp; + + while (syntax == cen && cp[0] != '\0' && cp[0] != '+' + && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= XPG_MODIFIER | CEN_AUDIENCE; + } + + if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) + { + syntax = cen; + + if (cp[0] == '+') + { + /* Next is special application (CEN syntax). */ + cp[0] = '\0'; + *special = ++cp; + + while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= CEN_SPECIAL; + } + + if (cp[0] == ',') + { + /* Next is sponsor (CEN syntax). */ + cp[0] = '\0'; + *sponsor = ++cp; + + while (cp[0] != '\0' && cp[0] != '_') + ++cp; + + mask |= CEN_SPONSOR; + } + + if (cp[0] == '_') + { + /* Next is revision (CEN syntax). */ + cp[0] = '\0'; + *revision = ++cp; + + mask |= CEN_REVISION; + } + } + + /* For CEN syntax values it might be important to have the + separator character in the file name, not for XPG syntax. */ + if (syntax == xpg) + { + if (*territory != NULL && (*territory)[0] == '\0') + mask &= ~TERRITORY; + + if (*codeset != NULL && (*codeset)[0] == '\0') + mask &= ~XPG_CODESET; + + if (*modifier != NULL && (*modifier)[0] == '\0') + mask &= ~XPG_MODIFIER; + } + + return mask; +} diff --git a/current/intl/finddomain.c b/current/intl/finddomain.c new file mode 100644 index 00000000..81ea29bf --- /dev/null +++ b/current/intl/finddomain.c @@ -0,0 +1,216 @@ +/* Handle list of needed message catalogs + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include "gettext.h" +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ +/* List of already loaded domains. */ +static struct loaded_l10nfile *_nl_loaded_domains; + + +/* Return a data structure describing the message catalog described by + the DOMAINNAME and CATEGORY parameters with respect to the currently + established bindings. */ +struct loaded_l10nfile * +internal_function +_nl_find_domain (dirname, locale, domainname) + const char *dirname; + char *locale; + const char *domainname; +{ + struct loaded_l10nfile *retval; + const char *language; + const char *modifier; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *special; + const char *sponsor; + const char *revision; + const char *alias_value; + int mask; + + /* LOCALE can consist of up to four recognized parts for the XPG syntax: + + language[_territory[.codeset]][@modifier] + + and six parts for the CEN syntax: + + language[_territory][+audience][+special][,[sponsor][_revision]] + + Beside the first part all of them are allowed to be missing. If + the full specified locale is not found, the less specific one are + looked for. The various parts will be stripped off according to + the following order: + (1) revision + (2) sponsor + (3) special + (4) codeset + (5) normalized codeset + (6) territory + (7) audience/modifier + */ + + /* If we have already tested for this locale entry there has to + be one data set in the list of loaded domains. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, 0, locale, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, domainname, 0); + if (retval != NULL) + { + /* We know something about this locale. */ + int cnt; + + if (retval->decided == 0) + _nl_load_domain (retval); + + if (retval->data != NULL) + return retval; + + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt]); + + if (retval->successor[cnt]->data != NULL) + break; + } + return cnt >= 0 ? retval : NULL; + /* NOTREACHED */ + } + + /* See whether the locale value is an alias. If yes its value + *overwrites* the alias name. No test for the original value is + done. */ + alias_value = _nl_expand_alias (locale); + if (alias_value != NULL) + { +#if defined _LIBC || defined HAVE_STRDUP + locale = strdup (alias_value); + if (locale == NULL) + return NULL; +#else + size_t len = strlen (alias_value) + 1; + locale = (char *) malloc (len); + if (locale == NULL) + return NULL; + + memcpy (locale, alias_value, len); +#endif + } + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = _nl_explode_name (locale, &language, &modifier, &territory, + &codeset, &normalized_codeset, &special, + &sponsor, &revision); + + /* Create all possible locale entries which might be interested in + generalization. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, mask, language, territory, + codeset, normalized_codeset, modifier, special, + sponsor, revision, domainname, 1); + if (retval == NULL) + /* This means we are out of core. */ + return NULL; + + if (retval->decided == 0) + _nl_load_domain (retval); + if (retval->data == NULL) + { + int cnt; + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt]); + if (retval->successor[cnt]->data != NULL) + break; + } + } + + /* The room for an alias was dynamically allocated. Free it now. */ + if (alias_value != NULL) + free (locale); + + return retval; +} + + +#ifdef _LIBC +static void __attribute__ ((unused)) +free_mem (void) +{ + struct loaded_l10nfile *runp = _nl_loaded_domains; + + while (runp != NULL) + { + struct loaded_l10nfile *here = runp; + if (runp->data != NULL) + _nl_unload_domain ((struct loaded_domain *) runp->data); + runp = runp->next; + free (here); + } +} + +text_set_element (__libc_subfreeres, free_mem); +#endif diff --git a/current/intl/gettext.c b/current/intl/gettext.c new file mode 100644 index 00000000..d929f98d --- /dev/null +++ b/current/intl/gettext.c @@ -0,0 +1,70 @@ +/* Implementation of gettext(3) function. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define __need_NULL +# include +#else +# ifdef STDC_HEADERS +# include /* Just for NULL. */ +# else +# ifdef HAVE_STRING_H +# include +# else +# define NULL ((void *) 0) +# endif +# endif +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define GETTEXT __gettext +# define DGETTEXT __dgettext +#else +# define GETTEXT gettext__ +# define DGETTEXT dgettext__ +#endif + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +char * +GETTEXT (msgid) + const char *msgid; +{ + return DGETTEXT (NULL, msgid); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__gettext, gettext); +#endif diff --git a/current/intl/gettext.h b/current/intl/gettext.h new file mode 100644 index 00000000..3cd23d7d --- /dev/null +++ b/current/intl/gettext.h @@ -0,0 +1,105 @@ +/* Internal header for GNU gettext internationalization functions. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETTEXT_H +#define _GETTEXT_H 1 + +#include + +#if HAVE_LIMITS_H || _LIBC +# include +#endif + +/* @@ end of prolog @@ */ + +/* The magic number of the GNU message catalog format. */ +#define _MAGIC 0x950412de +#define _MAGIC_SWAPPED 0xde120495 + +/* Revision number of the currently used .mo (binary) file format. */ +#define MO_REVISION_NUMBER 0 + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#if __STDC__ +# define UINT_MAX_32_BITS 4294967295U +#else +# define UINT_MAX_32_BITS 0xFFFFFFFF +#endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +#ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +#endif + +#if UINT_MAX == UINT_MAX_32_BITS +typedef unsigned nls_uint32; +#else +# if USHRT_MAX == UINT_MAX_32_BITS +typedef unsigned short nls_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS +typedef unsigned long nls_uint32; +# else + /* The following line is intended to throw an error. Using #error is + not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +#endif + + +/* Header for binary .mo file format. */ +struct mo_file_header +{ + /* The magic number. */ + nls_uint32 magic; + /* The revision number of the file format. */ + nls_uint32 revision; + /* The number of strings pairs. */ + nls_uint32 nstrings; + /* Offset of table with start offsets of original strings. */ + nls_uint32 orig_tab_offset; + /* Offset of table with start offsets of translation strings. */ + nls_uint32 trans_tab_offset; + /* Size of hashing table. */ + nls_uint32 hash_tab_size; + /* Offset of first hashing entry. */ + nls_uint32 hash_tab_offset; +}; + +struct string_desc +{ + /* Length of addressed string. */ + nls_uint32 length; + /* Offset of string in file. */ + nls_uint32 offset; +}; + +/* @@ begin of epilog @@ */ + +#endif /* gettext.h */ diff --git a/current/intl/gettextP.h b/current/intl/gettextP.h new file mode 100644 index 00000000..00c52031 --- /dev/null +++ b/current/intl/gettextP.h @@ -0,0 +1,89 @@ +/* Header describing internals of gettext library + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _GETTEXTP_H +#define _GETTEXTP_H + +#include "loadinfo.h" + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef internal_function +# define internal_function +#endif + +#ifndef W +# define W(flag, data) ((flag) ? SWAP (data) : (data)) +#endif + + +#ifdef _LIBC +# include +# define SWAP(i) bswap_32 (i) +#else +static nls_uint32 SWAP PARAMS ((nls_uint32 i)); + +static inline nls_uint32 +SWAP (i) + nls_uint32 i; +{ + return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); +} +#endif + + +struct loaded_domain +{ + const char *data; + int use_mmap; + size_t mmap_size; + int must_swap; + nls_uint32 nstrings; + struct string_desc *orig_tab; + struct string_desc *trans_tab; + nls_uint32 hash_size; + nls_uint32 *hash_tab; +}; + +struct binding +{ + struct binding *next; + char *domainname; + char *dirname; +}; + +struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, + char *__locale, + const char *__domainname)) + internal_function; +void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain)) + internal_function; +void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) + internal_function; + +/* @@ begin of epilog @@ */ + +#endif /* gettextP.h */ diff --git a/current/intl/hash-string.h b/current/intl/hash-string.h new file mode 100644 index 00000000..939e9582 --- /dev/null +++ b/current/intl/hash-string.h @@ -0,0 +1,59 @@ +/* Implements a string hashing function. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ +# define PARAMS(Args) Args +# else +# define PARAMS(Args) () +# endif +#endif + +/* We assume to have `unsigned long int' value with at least 32 bits. */ +#define HASHWORDBITS 32 + + +/* Defines the so called `hashpjw' function by P.J. Weinberger + [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, + 1986, 1987 Bell Telephone Laboratories, Inc.] */ +static unsigned long int hash_string PARAMS ((const char *__str_param)); + +static inline unsigned long int +hash_string (str_param) + const char *str_param; +{ + unsigned long int hval, g; + const char *str = str_param; + + /* Compute the hash value for the given string. */ + hval = 0; + while (*str != '\0') + { + hval <<= 4; + hval += (unsigned long int) *str++; + g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4)); + if (g != 0) + { + hval ^= g >> (HASHWORDBITS - 8); + hval ^= g; + } + } + return hval; +} diff --git a/current/intl/intl-compat.c b/current/intl/intl-compat.c new file mode 100644 index 00000000..503efa0f --- /dev/null +++ b/current/intl/intl-compat.c @@ -0,0 +1,76 @@ +/* intl-compat.c - Stub functions to call gettext functions from GNU gettext + Library. + Copyright (C) 1995 Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libgettext.h" + +/* @@ end of prolog @@ */ + + +#undef gettext +#undef dgettext +#undef dcgettext +#undef textdomain +#undef bindtextdomain + + +char * +bindtextdomain (domainname, dirname) + const char *domainname; + const char *dirname; +{ + return bindtextdomain__ (domainname, dirname); +} + + +char * +dcgettext (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ + return dcgettext__ (domainname, msgid, category); +} + + +char * +dgettext (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return dgettext__ (domainname, msgid); +} + + +char * +gettext (msgid) + const char *msgid; +{ + return gettext__ (msgid); +} + + +char * +textdomain (domainname) + const char *domainname; +{ + return textdomain__ (domainname); +} diff --git a/current/intl/l10nflist.c b/current/intl/l10nflist.c new file mode 100644 index 00000000..30f5f645 --- /dev/null +++ b/current/intl/l10nflist.c @@ -0,0 +1,411 @@ +/* Handle list of needed message catalogs + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#if defined HAVE_STRING_H || defined _LIBC +# ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# endif +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#if defined _LIBC || defined HAVE_ARGZ_H +# include +#endif +#include +#include + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# ifndef stpcpy +# define stpcpy(dest, src) __stpcpy(dest, src) +# endif +#else +# ifndef HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +# endif +#endif + +/* Define function which are usually not available. */ + +#if !defined _LIBC && !defined HAVE___ARGZ_COUNT +/* Returns the number of strings in ARGZ. */ +static size_t argz_count__ PARAMS ((const char *argz, size_t len)); + +static size_t +argz_count__ (argz, len) + const char *argz; + size_t len; +{ + size_t count = 0; + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len + 1; + len -= part_len + 1; + count++; + } + return count; +} +# undef __argz_count +# define __argz_count(argz, len) argz_count__ (argz, len) +#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ + +#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY +/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's + except the last into the character SEP. */ +static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); + +static void +argz_stringify__ (argz, len, sep) + char *argz; + size_t len; + int sep; +{ + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len; + len -= part_len + 1; + if (len > 0) + *argz++ = sep; + } +} +# undef __argz_stringify +# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) +#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ + +#if !defined _LIBC && !defined HAVE___ARGZ_NEXT +static char *argz_next__ PARAMS ((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next__ (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + if (entry) + { + if (entry < argz + argz_len) + entry = strchr (entry, '\0') + 1; + + return entry >= argz + argz_len ? NULL : (char *) entry; + } + else + if (argz_len > 0) + return argz; + else + return 0; +} +# undef __argz_next +# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) +#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ + + +/* Return number of bits set in X. */ +static int pop PARAMS ((int x)); + +static inline int +pop (x) + int x; +{ + /* We assume that no more than 16 bits are used. */ + x = ((x & ~0x5555) >> 1) + (x & 0x5555); + x = ((x & ~0x3333) >> 2) + (x & 0x3333); + x = ((x >> 4) + x) & 0x0f0f; + x = ((x >> 8) + x) & 0xff; + + return x; +} + + +struct loaded_l10nfile * +_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, + territory, codeset, normalized_codeset, modifier, special, + sponsor, revision, filename, do_allocate) + struct loaded_l10nfile **l10nfile_list; + const char *dirlist; + size_t dirlist_len; + int mask; + const char *language; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *modifier; + const char *special; + const char *sponsor; + const char *revision; + const char *filename; + int do_allocate; +{ + char *abs_filename; + struct loaded_l10nfile *last = NULL; + struct loaded_l10nfile *retval; + char *cp; + size_t entries; + int cnt; + + /* Allocate room for the full file name. */ + abs_filename = (char *) malloc (dirlist_len + + strlen (language) + + ((mask & TERRITORY) != 0 + ? strlen (territory) + 1 : 0) + + ((mask & XPG_CODESET) != 0 + ? strlen (codeset) + 1 : 0) + + ((mask & XPG_NORM_CODESET) != 0 + ? strlen (normalized_codeset) + 1 : 0) + + (((mask & XPG_MODIFIER) != 0 + || (mask & CEN_AUDIENCE) != 0) + ? strlen (modifier) + 1 : 0) + + ((mask & CEN_SPECIAL) != 0 + ? strlen (special) + 1 : 0) + + (((mask & CEN_SPONSOR) != 0 + || (mask & CEN_REVISION) != 0) + ? (1 + ((mask & CEN_SPONSOR) != 0 + ? strlen (sponsor) + 1 : 0) + + ((mask & CEN_REVISION) != 0 + ? strlen (revision) + 1 : 0)) : 0) + + 1 + strlen (filename) + 1); + + if (abs_filename == NULL) + return NULL; + + retval = NULL; + last = NULL; + + /* Construct file name. */ + memcpy (abs_filename, dirlist, dirlist_len); + __argz_stringify (abs_filename, dirlist_len, ':'); + cp = abs_filename + (dirlist_len - 1); + *cp++ = '/'; + cp = stpcpy (cp, language); + + if ((mask & TERRITORY) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, territory); + } + if ((mask & XPG_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, codeset); + } + if ((mask & XPG_NORM_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, normalized_codeset); + } + if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) + { + /* This component can be part of both syntaces but has different + leading characters. For CEN we use `+', else `@'. */ + *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; + cp = stpcpy (cp, modifier); + } + if ((mask & CEN_SPECIAL) != 0) + { + *cp++ = '+'; + cp = stpcpy (cp, special); + } + if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) + { + *cp++ = ','; + if ((mask & CEN_SPONSOR) != 0) + cp = stpcpy (cp, sponsor); + if ((mask & CEN_REVISION) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, revision); + } + } + + *cp++ = '/'; + stpcpy (cp, filename); + + /* Look in list of already loaded domains whether it is already + available. */ + last = NULL; + for (retval = *l10nfile_list; retval != NULL; retval = retval->next) + if (retval->filename != NULL) + { + int compare = strcmp (retval->filename, abs_filename); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It's not in the list. */ + retval = NULL; + break; + } + + last = retval; + } + + if (retval != NULL || do_allocate == 0) + { + free (abs_filename); + return retval; + } + + retval = (struct loaded_l10nfile *) + malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len) + * (1 << pop (mask)) + * sizeof (struct loaded_l10nfile *))); + if (retval == NULL) + return NULL; + + retval->filename = abs_filename; + retval->decided = (__argz_count (dirlist, dirlist_len) != 1 + || ((mask & XPG_CODESET) != 0 + && (mask & XPG_NORM_CODESET) != 0)); + retval->data = NULL; + + if (last == NULL) + { + retval->next = *l10nfile_list; + *l10nfile_list = retval; + } + else + { + retval->next = last->next; + last->next = retval; + } + + entries = 0; + /* If the DIRLIST is a real list the RETVAL entry corresponds not to + a real file. So we have to use the DIRLIST separation mechanism + of the inner loop. */ + cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask; + for (; cnt >= 0; --cnt) + if ((cnt & ~mask) == 0 + && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) + && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) + { + /* Iterate over all elements of the DIRLIST. */ + char *dir = NULL; + + while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) + != NULL) + retval->successor[entries++] + = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt, + language, territory, codeset, + normalized_codeset, modifier, special, + sponsor, revision, filename, 1); + } + retval->successor[entries] = NULL; + + return retval; +} + +/* Normalize codeset name. There is no standard for the codeset + names. Normalization allows the user to use any of the common + names. */ +const char * +_nl_normalize_codeset (codeset, name_len) + const char *codeset; + size_t name_len; +{ + int len = 0; + int only_digit = 1; + char *retval; + char *wp; + size_t cnt; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalnum (codeset[cnt])) + { + ++len; + + if (isalpha (codeset[cnt])) + only_digit = 0; + } + + retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); + + if (retval != NULL) + { + if (only_digit) + wp = stpcpy (retval, "iso"); + else + wp = retval; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalpha (codeset[cnt])) + *wp++ = tolower (codeset[cnt]); + else if (isdigit (codeset[cnt])) + *wp++ = codeset[cnt]; + + *wp = '\0'; + } + + return (const char *) retval; +} + + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif diff --git a/current/intl/libgettext.h b/current/intl/libgettext.h new file mode 100644 index 00000000..3a92960a --- /dev/null +++ b/current/intl/libgettext.h @@ -0,0 +1,182 @@ +/* Message catalogs for internationalization. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Because on some systems (e.g. Solaris) we sometimes have to include + the systems libintl.h as well as this file we have more complex + include protection above. But the systems header might perhaps also + define _LIBINTL_H and therefore we have to protect the definition here. */ + +#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H +#ifndef _LIBINTL_H +# define _LIBINTL_H 1 +#endif +#define _LIBGETTEXT_H 1 + +/* We define an additional symbol to signal that we use the GNU + implementation of gettext. */ +#define __USE_GNU_GETTEXT 1 + +#include + +#if HAVE_LOCALE_H +# include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ || defined __cplusplus +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef NULL +# if !defined __cplusplus || defined __GNUC__ +# define NULL ((void *) 0) +# else +# define NULL (0) +# endif +#endif + +#if !HAVE_LC_MESSAGES +/* This value determines the behaviour of the gettext() and dgettext() + function. But some system does not have this defined. Define it + to a default value. */ +# define LC_MESSAGES (-1) +#endif + + +/* Declarations for gettext-using-catgets interface. Derived from + Jim Meyering's libintl.h. */ +struct _msg_ent +{ + const char *_msg; + int _msg_number; +}; + + +#if HAVE_CATGETS +/* These two variables are defined in the automatically by po-to-tbl.sed + generated file `cat-id-tbl.c'. */ +extern const struct _msg_ent _msg_tbl[]; +extern int _msg_tbl_length; +#endif + + +/* For automatical extraction of messages sometimes no real + translation is needed. Instead the string itself is the result. */ +#define gettext_noop(Str) (Str) + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +extern char *gettext PARAMS ((const char *__msgid)); +extern char *gettext__ PARAMS ((const char *__msgid)); + +/* Look up MSGID in the DOMAINNAME message catalog for the current + LC_MESSAGES locale. */ +extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid)); +extern char *dgettext__ PARAMS ((const char *__domainname, + const char *__msgid)); + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid, + int __category)); +extern char *dcgettext__ PARAMS ((const char *__domainname, + const char *__msgid, int __category)); + + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +extern char *textdomain PARAMS ((const char *__domainname)); +extern char *textdomain__ PARAMS ((const char *__domainname)); + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +extern char *bindtextdomain PARAMS ((const char *__domainname, + const char *__dirname)); +extern char *bindtextdomain__ PARAMS ((const char *__domainname, + const char *__dirname)); + +#if ENABLE_NLS + +/* Solaris 2.3 has the gettext function but dcgettext is missing. + So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4 + has dcgettext. */ +# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT) + +# define gettext(Msgid) \ + dgettext (NULL, Msgid) + +# define dgettext(Domainname, Msgid) \ + dcgettext (Domainname, Msgid, LC_MESSAGES) + +# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7 +/* This global variable is defined in loadmsgcat.c. We need a sign, + whether a new catalog was loaded, which can be associated with all + translations. */ +extern int _nl_msg_cat_cntr; + +# define dcgettext(Domainname, Msgid, Category) \ + (__extension__ \ + ({ \ + char *__result; \ + if (__builtin_constant_p (Msgid)) \ + { \ + static char *__translation__; \ + static int __catalog_counter__; \ + if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \ + { \ + __translation__ = \ + dcgettext__ (Domainname, Msgid, Category); \ + __catalog_counter__ = _nl_msg_cat_cntr; \ + } \ + __result = __translation__; \ + } \ + else \ + __result = dcgettext__ (Domainname, Msgid, Category); \ + __result; \ + })) +# endif +# endif + +#else + +# define gettext(Msgid) (Msgid) +# define dgettext(Domainname, Msgid) (Msgid) +# define dcgettext(Domainname, Msgid, Category) (Msgid) +# define textdomain(Domainname) ((char *) Domainname) +# define bindtextdomain(Domainname, Dirname) ((char *) Dirname) + +#endif + +/* @@ begin of epilog @@ */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/current/intl/linux-msg.sed b/current/intl/linux-msg.sed new file mode 100644 index 00000000..5918e720 --- /dev/null +++ b/current/intl/linux-msg.sed @@ -0,0 +1,100 @@ +# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# The first directive in the .msg should be the definition of the +# message set number. We use always set number 1. +# +1 { + i\ +$set 1 # Automatically created by po2msg.sed + h + s/.*/0/ + x +} +# +# Mitch's old catalog format does not allow comments. +# +# We copy the original message as a comment into the .msg file. +# +/^msgid/ { + s/msgid[ ]*"// +# +# This does not work now with the new format. +# /"$/! { +# s/\\$// +# s/$/ ... (more lines following)"/ +# } + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x + G + s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p +} +# +# The .msg file contains, other then the .po file, only the translations +# but each given a unique ID. Starting from 1 and incrementing by 1 for +# each message we assign them to the messages. +# It is important that the .po file used to generate the cat-id-tbl.c file +# (with po-to-tbl) is the same as the one used here. (At least the order +# of declarations must not be changed.) +# +/^msgstr/ { + s/msgstr[ ]*"\(.*\)"/# \1/ +# Clear substitution flag. + tb +# Append the next line. + :b + N +# Look whether second part is continuation line. + s/\(.*\n\)"\(.*\)"/\1\2/ +# Yes, then branch. + ta + P + D +# Note that D includes a jump to the start!! +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use D here. + s/.*\n\(.*\)/\1/ + tb +} +d diff --git a/current/intl/loadinfo.h b/current/intl/loadinfo.h new file mode 100644 index 00000000..1c4524ab --- /dev/null +++ b/current/intl/loadinfo.h @@ -0,0 +1,78 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef PARAMS +# if __STDC__ +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +/* Encoding of locale name parts. */ +#define CEN_REVISION 1 +#define CEN_SPONSOR 2 +#define CEN_SPECIAL 4 +#define XPG_NORM_CODESET 8 +#define XPG_CODESET 16 +#define TERRITORY 32 +#define CEN_AUDIENCE 64 +#define XPG_MODIFIER 128 + +#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) +#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) + + +struct loaded_l10nfile +{ + const char *filename; + int decided; + + const void *data; + + struct loaded_l10nfile *next; + struct loaded_l10nfile *successor[1]; +}; + + +extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, + size_t name_len)); + +extern struct loaded_l10nfile * +_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, + const char *dirlist, size_t dirlist_len, int mask, + const char *language, const char *territory, + const char *codeset, + const char *normalized_codeset, + const char *modifier, const char *special, + const char *sponsor, const char *revision, + const char *filename, int do_allocate)); + + +extern const char *_nl_expand_alias PARAMS ((const char *name)); + +extern int _nl_explode_name PARAMS ((char *name, const char **language, + const char **modifier, + const char **territory, + const char **codeset, + const char **normalized_codeset, + const char **special, + const char **sponsor, + const char **revision)); + +extern char *_nl_find_language PARAMS ((const char *name)); diff --git a/current/intl/loadmsgcat.c b/current/intl/loadmsgcat.c new file mode 100644 index 00000000..2c6a5650 --- /dev/null +++ b/current/intl/loadmsgcat.c @@ -0,0 +1,220 @@ +/* Load needed message catalogs. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || (defined _LIBC && defined _POSIX_MAPPED_FILES) +# include +# undef HAVE_MMAP +# define HAVE_MMAP 1 +#else +# undef HAVE_MMAP +#endif + +#include "gettext.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ISO C functions. This is required by the standard + because some ISO C functions will require linking with this object + file and the name space must not be polluted. */ +# define open __open +# define close __close +# define read __read +# define mmap __mmap +# define munmap __munmap +#endif + +/* We need a sign, whether a new catalog was loaded, which can be associated + with all translations. This is important if the translations are + cached by one of GCC's features. */ +int _nl_msg_cat_cntr = 0; + + +/* Load the message catalogs specified by FILENAME. If it is no valid + message catalog do nothing. */ +void +internal_function +_nl_load_domain (domain_file) + struct loaded_l10nfile *domain_file; +{ + int fd; + size_t size; + struct stat st; + struct mo_file_header *data = (struct mo_file_header *) -1; + int use_mmap = 0; + struct loaded_domain *domain; + + domain_file->decided = 1; + domain_file->data = NULL; + + /* If the record does not represent a valid locale the FILENAME + might be NULL. This can happen when according to the given + specification the locale file name is different for XPG and CEN + syntax. */ + if (domain_file->filename == NULL) + return; + + /* Try to open the addressed file. */ + fd = open (domain_file->filename, O_RDONLY); + if (fd == -1) + return; + + /* We must know about the size of the file. */ + if (fstat (fd, &st) != 0 + || (size = (size_t) st.st_size) != st.st_size + || size < sizeof (struct mo_file_header)) + { + /* Something went wrong. */ + close (fd); + return; + } + +#ifdef HAVE_MMAP + /* Now we are ready to load the file. If mmap() is available we try + this first. If not available or it failed we try to load it. */ + data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, + MAP_PRIVATE, fd, 0); + + if (data != (struct mo_file_header *) -1) + { + /* mmap() call was successful. */ + close (fd); + use_mmap = 1; + } +#endif + + /* If the data is not yet available (i.e. mmap'ed) we try to load + it manually. */ + if (data == (struct mo_file_header *) -1) + { + size_t to_read; + char *read_ptr; + + data = (struct mo_file_header *) malloc (size); + if (data == NULL) + return; + + to_read = size; + read_ptr = (char *) data; + do + { + long int nb = (long int) read (fd, read_ptr, to_read); + if (nb == -1) + { + close (fd); + return; + } + + read_ptr += nb; + to_read -= nb; + } + while (to_read > 0); + + close (fd); + } + + /* Using the magic number we can test whether it really is a message + catalog file. */ + if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED) + { + /* The magic number is wrong: not a message catalog file. */ +#ifdef HAVE_MMAP + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + return; + } + + domain_file->data + = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); + if (domain_file->data == NULL) + return; + + domain = (struct loaded_domain *) domain_file->data; + domain->data = (char *) data; + domain->use_mmap = use_mmap; + domain->mmap_size = size; + domain->must_swap = data->magic != _MAGIC; + + /* Fill in the information about the available tables. */ + switch (W (domain->must_swap, data->revision)) + { + case 0: + domain->nstrings = W (domain->must_swap, data->nstrings); + domain->orig_tab = (struct string_desc *) + ((char *) data + W (domain->must_swap, data->orig_tab_offset)); + domain->trans_tab = (struct string_desc *) + ((char *) data + W (domain->must_swap, data->trans_tab_offset)); + domain->hash_size = W (domain->must_swap, data->hash_tab_size); + domain->hash_tab = (nls_uint32 *) + ((char *) data + W (domain->must_swap, data->hash_tab_offset)); + break; + default: + /* This is an invalid revision. */ +#ifdef HAVE_MMAP + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + free (domain); + domain_file->data = NULL; + return; + } + + /* Show that one domain is changed. This might make some cached + translations invalid. */ + ++_nl_msg_cat_cntr; +} + + +#ifdef _LIBC +void +internal_function +_nl_unload_domain (domain) + struct loaded_domain *domain; +{ +#ifdef _POSIX_MAPPED_FILES + if (domain->use_mmap) + munmap ((caddr_t) domain->data, domain->mmap_size); + else +#endif /* _POSIX_MAPPED_FILES */ + free ((void *) domain->data); + + free (domain); +} +#endif diff --git a/current/intl/localealias.c b/current/intl/localealias.c new file mode 100644 index 00000000..861020dd --- /dev/null +++ b/current/intl/localealias.c @@ -0,0 +1,438 @@ +/* Handle aliases for locale names. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#ifdef __GNUC__ +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +char *getenv (); +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# endif +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#include "gettext.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define strcasecmp __strcasecmp + +# ifndef mempcpy +# define mempcpy __mempcpy +# endif +# define HAVE_MEMPCPY 1 + +/* We need locking here since we can be called from different places. */ +# include + +__libc_lock_define_initialized (static, lock); +#endif + +#ifndef internal_function +# define internal_function +#endif + +/* For those loosing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +/* Nothing has to be done. */ +# define ADD_BLOCK(list, address) /* nothing */ +# define FREE_BLOCKS(list) /* nothing */ +#else +struct block_list +{ + void *address; + struct block_list *next; +}; +# define ADD_BLOCK(list, addr) \ + do { \ + struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ + /* If we cannot get a free block we cannot add the new element to \ + the list. */ \ + if (newp != NULL) { \ + newp->address = (addr); \ + newp->next = (list); \ + (list) = newp; \ + } \ + } while (0) +# define FREE_BLOCKS(list) \ + do { \ + while (list != NULL) { \ + struct block_list *old = list; \ + list = list->next; \ + free (old); \ + } \ + } while (0) +# undef alloca +# define alloca(size) (malloc (size)) +#endif /* have alloca */ + +#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED +# undef fgets +# define fgets(buf, len, s) fgets_unlocked (buf, len, s) +#endif +#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED +# undef feof +# define feof(s) feof_unlocked (s) +#endif + + +struct alias_map +{ + const char *alias; + const char *value; +}; + + +static char *string_space = NULL; +static size_t string_space_act = 0; +static size_t string_space_max = 0; +static struct alias_map *map; +static size_t nmap = 0; +static size_t maxmap = 0; + + +/* Prototypes for local functions. */ +static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) + internal_function; +static void extend_alias_table PARAMS ((void)); +static int alias_compare PARAMS ((const struct alias_map *map1, + const struct alias_map *map2)); + + +const char * +_nl_expand_alias (name) + const char *name; +{ + static const char *locale_alias_path = LOCALE_ALIAS_PATH; + struct alias_map *retval; + const char *result = NULL; + size_t added; + +#ifdef _LIBC + __libc_lock_lock (lock); +#endif + + do + { + struct alias_map item; + + item.alias = name; + + if (nmap > 0) + retval = (struct alias_map *) bsearch (&item, map, nmap, + sizeof (struct alias_map), + (int (*) PARAMS ((const void *, + const void *)) + ) alias_compare); + else + retval = NULL; + + /* We really found an alias. Return the value. */ + if (retval != NULL) + { + result = retval->value; + break; + } + + /* Perhaps we can find another alias file. */ + added = 0; + while (added == 0 && locale_alias_path[0] != '\0') + { + const char *start; + + while (locale_alias_path[0] == ':') + ++locale_alias_path; + start = locale_alias_path; + + while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':') + ++locale_alias_path; + + if (start < locale_alias_path) + added = read_alias_file (start, locale_alias_path - start); + } + } + while (added != 0); + +#ifdef _LIBC + __libc_lock_unlock (lock); +#endif + + return result; +} + + +static size_t +internal_function +read_alias_file (fname, fname_len) + const char *fname; + int fname_len; +{ +#ifndef HAVE_ALLOCA + struct block_list *block_list = NULL; +#endif + FILE *fp; + char *full_fname; + size_t added; + static const char aliasfile[] = "/locale.alias"; + + full_fname = (char *) alloca (fname_len + sizeof aliasfile); + ADD_BLOCK (block_list, full_fname); +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (full_fname, fname, fname_len), + aliasfile, sizeof aliasfile); +#else + memcpy (full_fname, fname, fname_len); + memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); +#endif + + fp = fopen (full_fname, "r"); + if (fp == NULL) + { + FREE_BLOCKS (block_list); + return 0; + } + + added = 0; + while (!feof (fp)) + { + /* It is a reasonable approach to use a fix buffer here because + a) we are only interested in the first two fields + b) these fields must be usable as file names and so must not + be that long + */ + char buf[BUFSIZ]; + char *alias; + char *value; + char *cp; + + if (fgets (buf, sizeof buf, fp) == NULL) + /* EOF reached. */ + break; + + /* Possibly not the whole line fits into the buffer. Ignore + the rest of the line. */ + if (strchr (buf, '\n') == NULL) + { + char altbuf[BUFSIZ]; + do + if (fgets (altbuf, sizeof altbuf, fp) == NULL) + /* Make sure the inner loop will be left. The outer loop + will exit at the `feof' test. */ + break; + while (strchr (altbuf, '\n') == NULL); + } + + cp = buf; + /* Ignore leading white space. */ + while (isspace (cp[0])) + ++cp; + + /* A leading '#' signals a comment line. */ + if (cp[0] != '\0' && cp[0] != '#') + { + alias = cp++; + while (cp[0] != '\0' && !isspace (cp[0])) + ++cp; + /* Terminate alias name. */ + if (cp[0] != '\0') + *cp++ = '\0'; + + /* Now look for the beginning of the value. */ + while (isspace (cp[0])) + ++cp; + + if (cp[0] != '\0') + { + size_t alias_len; + size_t value_len; + + value = cp++; + while (cp[0] != '\0' && !isspace (cp[0])) + ++cp; + /* Terminate value. */ + if (cp[0] == '\n') + { + /* This has to be done to make the following test + for the end of line possible. We are looking for + the terminating '\n' which do not overwrite here. */ + *cp++ = '\0'; + *cp = '\n'; + } + else if (cp[0] != '\0') + *cp++ = '\0'; + + if (nmap >= maxmap) + extend_alias_table (); + + alias_len = strlen (alias) + 1; + value_len = strlen (value) + 1; + + if (string_space_act + alias_len + value_len > string_space_max) + { + /* Increase size of memory pool. */ + size_t new_size = (string_space_max + + (alias_len + value_len > 1024 + ? alias_len + value_len : 1024)); + char *new_pool = (char *) realloc (string_space, new_size); + if (new_pool == NULL) + { + FREE_BLOCKS (block_list); + return added; + } + string_space = new_pool; + string_space_max = new_size; + } + + map[nmap].alias = memcpy (&string_space[string_space_act], + alias, alias_len); + string_space_act += alias_len; + + map[nmap].value = memcpy (&string_space[string_space_act], + value, value_len); + string_space_act += value_len; + + ++nmap; + ++added; + } + } + } + + /* Should we test for ferror()? I think we have to silently ignore + errors. --drepper */ + fclose (fp); + + if (added > 0) + qsort (map, nmap, sizeof (struct alias_map), + (int (*) PARAMS ((const void *, const void *))) alias_compare); + + FREE_BLOCKS (block_list); + return added; +} + + +static void +extend_alias_table () +{ + size_t new_size; + struct alias_map *new_map; + + new_size = maxmap == 0 ? 100 : 2 * maxmap; + new_map = (struct alias_map *) realloc (map, (new_size + * sizeof (struct alias_map))); + if (new_map == NULL) + /* Simply don't extend: we don't have any more core. */ + return; + + map = new_map; + maxmap = new_size; +} + + +#ifdef _LIBC +static void __attribute__ ((unused)) +free_mem (void) +{ + if (string_space != NULL) + free (string_space); + if (map != NULL) + free (map); +} +text_set_element (__libc_subfreeres, free_mem); +#endif + + +static int +alias_compare (map1, map2) + const struct alias_map *map1; + const struct alias_map *map2; +{ +#if defined _LIBC || defined HAVE_STRCASECMP + return strcasecmp (map1->alias, map2->alias); +#else + const unsigned char *p1 = (const unsigned char *) map1->alias; + const unsigned char *p2 = (const unsigned char *) map2->alias; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + /* I know this seems to be odd but the tolower() function in + some systems libc cannot handle nonalpha characters. */ + c1 = isupper (*p1) ? tolower (*p1) : *p1; + c2 = isupper (*p2) ? tolower (*p2) : *p2; + if (c1 == '\0') + break; + ++p1; + ++p2; + } + while (c1 == c2); + + return c1 - c2; +#endif +} diff --git a/current/intl/po2tbl.sed.in b/current/intl/po2tbl.sed.in new file mode 100644 index 00000000..b3bcca4d --- /dev/null +++ b/current/intl/po2tbl.sed.in @@ -0,0 +1,102 @@ +# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +1 { + i\ +/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\ +\ +#if HAVE_CONFIG_H\ +# include \ +#endif\ +\ +#include "libgettext.h"\ +\ +const struct _msg_ent _msg_tbl[] = { + h + s/.*/0/ + x +} +# +# Write msgid entries in C array form. +# +/^msgid/ { + s/msgid[ ]*\(".*"\)/ {\1/ + tb +# Append the next line + :b + N +# Look whether second part is continuation line. + s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/ +# Yes, then branch. + ta +# Because we assume that the input file correctly formed the line +# just read cannot be again be a msgid line. So it's safe to ignore +# it. + s/\(.*\)\n.*/\1/ + bc +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use D here. + s/.*\n\(.*\)/\1/ +# Some buggy seds do not clear the `successful substitution since last ``t''' +# flag on `N', so we do a `t' here to clear it. + tb +# Not reached + :c + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x + G + s/\(.*\)\n\([0-9]*\)/\1, \2},/ + s/\(.*\)"$/\1/ + p +} +# +# Last line. +# +$ { + i\ +};\ + + g + s/0*\(.*\)/int _msg_tbl_length = \1;/p +} +d diff --git a/current/intl/textdomain.c b/current/intl/textdomain.c new file mode 100644 index 00000000..88557460 --- /dev/null +++ b/current/intl/textdomain.c @@ -0,0 +1,108 @@ +/* Implementation of the textdomain(3) function. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ + +/* Name of the default text domain. */ +extern const char _nl_default_default_domain[]; + +/* Default text domain in which entries for gettext(3) are to be found. */ +extern const char *_nl_current_default_domain; + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define TEXTDOMAIN __textdomain +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define TEXTDOMAIN textdomain__ +#endif + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +char * +TEXTDOMAIN (domainname) + const char *domainname; +{ + char *old; + + /* A NULL pointer requests the current setting. */ + if (domainname == NULL) + return (char *) _nl_current_default_domain; + + old = (char *) _nl_current_default_domain; + + /* If domain name is the null string set to default domain "messages". */ + if (domainname[0] == '\0' + || strcmp (domainname, _nl_default_default_domain) == 0) + _nl_current_default_domain = _nl_default_default_domain; + else + { + /* If the following malloc fails `_nl_current_default_domain' + will be NULL. This value will be returned and so signals we + are out of core. */ +#if defined _LIBC || defined HAVE_STRDUP + _nl_current_default_domain = strdup (domainname); +#else + size_t len = strlen (domainname) + 1; + char *cp = (char *) malloc (len); + if (cp != NULL) + memcpy (cp, domainname, len); + _nl_current_default_domain = cp; +#endif + } + + if (old != _nl_default_default_domain) + free (old); + + return (char *) _nl_current_default_domain; +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__textdomain, textdomain); +#endif diff --git a/current/intl/xopen-msg.sed b/current/intl/xopen-msg.sed new file mode 100644 index 00000000..b19c0bbd --- /dev/null +++ b/current/intl/xopen-msg.sed @@ -0,0 +1,104 @@ +# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# The first directive in the .msg should be the definition of the +# message set number. We use always set number 1. +# +1 { + i\ +$set 1 # Automatically created by po2msg.sed + h + s/.*/0/ + x +} +# +# We copy all comments into the .msg file. Perhaps they can help. +# +/^#/ s/^#[ ]*/$ /p +# +# We copy the original message as a comment into the .msg file. +# +/^msgid/ { +# Does not work now +# /"$/! { +# s/\\$// +# s/$/ ... (more lines following)"/ +# } + s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/ + p +} +# +# The .msg file contains, other then the .po file, only the translations +# but each given a unique ID. Starting from 1 and incrementing by 1 for +# each message we assign them to the messages. +# It is important that the .po file used to generate the cat-id-tbl.c file +# (with po-to-tbl) is the same as the one used here. (At least the order +# of declarations must not be changed.) +# +/^msgstr/ { + s/msgstr[ ]*"\(.*\)"/\1/ + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x +# Bring the line in the format ` ' + G + s/^[^\n]*$/& / + s/\(.*\)\n\([0-9]*\)/\2 \1/ +# Clear flag from last substitution. + tb +# Append the next line. + :b + N +# Look whether second part is a continuation line. + s/\(.*\n\)"\(.*\)"/\1\2/ +# Yes, then branch. + ta + P + D +# Note that `D' includes a jump to the start!! +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use the sed command `D' here + s/.*\n\(.*\)/\1/ + tb +} +d diff --git a/current/lib/Makefile.am b/current/lib/Makefile.am new file mode 100644 index 00000000..f3de6fe0 --- /dev/null +++ b/current/lib/Makefile.am @@ -0,0 +1,57 @@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h \ + faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h \ + pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h \ + tcfsio.h + +localedir = $(datadir)/locale +DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@ + +# These files are unneeded for some reason, listed in +# order of appearance: +# +# sources which are not really needed (are they in libc???) +# sources for dbm support (not yet used) +# sources for LIBOBJS (which are normally in libc) +# misc header sources + +EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c \ + grpack.c gspack.c pwpack.c sppack.c \ + gshadow_.h shadow_.h lastlog_.h snprintf.h + +EXTRA_libshadow_a_SOURCESS = grent.c pwent.c \ + mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c \ + putgrent.c putpwent.c putspent.c \ + sgetgrent.c sgetpwent.c sgetspent.c snprintf.c \ + md5.c md5crypt.c + +# We build libshadow for our tools. + +noinst_LIBRARIES = libshadow.a + +libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c \ + fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c \ + pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c \ + tcfsio.c + +libshadow_a_LIBADD = @LIBOBJS@ + +INCLUDES = -I$(top_srcdir)/lib + +# shared library support +libdir = ${exec_prefix}/lib +#lib_PROGRAMS = libshadow.la +lib_LTLIBRARIES = libshadow.la +libshadow_la_SOURCES = ${libshadow_a_SOURCES} +libshadow_la_LIBADD = @LTLIBOBJS@ +#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir) +libshadow_la_LDFLAGS = -version-info 0:0:0 + +# remove the libshadow.so -> libshadow.so.x.x symlink, because this +# library is for internal use by this package only. Shadow support +# is in libc and no one should be using -lshadow anymore. +install-exec-hook: + rm -f $(libdir)/libshadow.so + diff --git a/current/lib/Makefile.in b/current/lib/Makefile.in new file mode 100644 index 00000000..d28a1db4 --- /dev/null +++ b/current/lib/Makefile.in @@ -0,0 +1,448 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h tcfsio.h + + +localedir = $(datadir)/locale +DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@ + +# These files are unneeded for some reason, listed in +# order of appearance: +# +# sources which are not really needed (are they in libc???) +# sources for dbm support (not yet used) +# sources for LIBOBJS (which are normally in libc) +# misc header sources + +EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c grpack.c gspack.c pwpack.c sppack.c gshadow_.h shadow_.h lastlog_.h snprintf.h + + +EXTRA_libshadow_a_SOURCESS = grent.c pwent.c mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c putgrent.c putpwent.c putspent.c sgetgrent.c sgetpwent.c sgetspent.c snprintf.c md5.c md5crypt.c + + +# We build libshadow for our tools. + +noinst_LIBRARIES = libshadow.a + +libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c tcfsio.c + + +libshadow_a_LIBADD = @LIBOBJS@ + +INCLUDES = -I$(top_srcdir)/lib + +# shared library support +libdir = ${exec_prefix}/lib +#lib_PROGRAMS = libshadow.la +lib_LTLIBRARIES = libshadow.la +libshadow_la_SOURCES = ${libshadow_a_SOURCES} +libshadow_la_LIBADD = @LTLIBOBJS@ +#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir) +libshadow_la_LDFLAGS = -version-info 0:0:0 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libshadow_a_DEPENDENCIES = @LIBOBJS@ +libshadow_a_OBJECTS = commonio.o dialchk.o dialup.o encrypt.o fputsx.o \ +getdef.o getpass.o groupio.o gshadow.o lockpw.o port.o pwauth.o pwio.o \ +rad64.o sgroupio.o shadow.o shadowio.o utent.o tcfsio.o +AR = ar +LTLIBRARIES = $(lib_LTLIBRARIES) + +libshadow_la_DEPENDENCIES = @LTLIBOBJS@ +libshadow_la_OBJECTS = commonio.lo dialchk.lo dialup.lo encrypt.lo \ +fputsx.lo getdef.lo getpass.lo groupio.lo gshadow.lo lockpw.lo port.lo \ +pwauth.lo pwio.lo rad64.lo sgroupio.lo shadow.lo shadowio.lo utent.lo \ +tcfsio.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in md5.c md5crypt.c mkdir.c \ +putgrent.c putpwent.c putspent.c rename.c rmdir.c sgetgrent.c \ +sgetpwent.c sgetspent.c snprintf.c strcasecmp.c strdup.c strerror.c \ +strstr.c + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(libshadow_a_SOURCES) $(libshadow_la_SOURCES) +OBJECTS = $(libshadow_a_OBJECTS) $(libshadow_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps lib/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libshadow.a: $(libshadow_a_OBJECTS) $(libshadow_a_DEPENDENCIES) + -rm -f libshadow.a + $(AR) cru libshadow.a $(libshadow_a_OBJECTS) $(libshadow_a_LIBADD) + $(RANLIB) libshadow.a + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +libshadow.la: $(libshadow_la_OBJECTS) $(libshadow_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libshadow_la_LDFLAGS) $(libshadow_la_OBJECTS) $(libshadow_la_LIBADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = lib + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +commonio.lo commonio.o : commonio.c ../config.h rcsid.h defines.h \ + gshadow_.h commonio.h +dialchk.lo dialchk.o : dialchk.c ../config.h rcsid.h defines.h \ + gshadow_.h prototypes.h dialup.h dialchk.h +dialup.lo dialup.o : dialup.c ../config.h rcsid.h prototypes.h defines.h \ + gshadow_.h dialup.h +encrypt.lo encrypt.o : encrypt.c ../config.h rcsid.h prototypes.h \ + defines.h gshadow_.h +fputsx.lo fputsx.o : fputsx.c ../config.h defines.h gshadow_.h rcsid.h +getdef.lo getdef.o : getdef.c ../config.h rcsid.h prototypes.h defines.h \ + gshadow_.h getdef.h +getpass.lo getpass.o : getpass.c ../config.h rcsid.h defines.h \ + gshadow_.h getdef.h +groupio.lo groupio.o : groupio.c ../config.h rcsid.h prototypes.h \ + defines.h gshadow_.h commonio.h groupio.h +gshadow.lo gshadow.o : gshadow.c ../config.h rcsid.h prototypes.h \ + defines.h gshadow_.h +lockpw.lo lockpw.o : lockpw.c ../config.h +port.lo port.o : port.c ../config.h rcsid.h defines.h gshadow_.h port.h +putgrent.lo putgrent.o : putgrent.c ../config.h prototypes.h defines.h \ + gshadow_.h +pwauth.lo pwauth.o : pwauth.c ../config.h rcsid.h prototypes.h defines.h \ + gshadow_.h pwauth.h getdef.h +pwio.lo pwio.o : pwio.c ../config.h rcsid.h prototypes.h defines.h \ + gshadow_.h commonio.h pwio.h +rad64.lo rad64.o : rad64.c ../config.h rcsid.h +sgetgrent.lo sgetgrent.o : sgetgrent.c ../config.h rcsid.h defines.h \ + gshadow_.h +sgetpwent.lo sgetpwent.o : sgetpwent.c ../config.h rcsid.h defines.h \ + gshadow_.h +sgroupio.lo sgroupio.o : sgroupio.c ../config.h rcsid.h prototypes.h \ + defines.h gshadow_.h commonio.h sgroupio.h +shadowio.lo shadowio.o : shadowio.c ../config.h rcsid.h prototypes.h \ + defines.h gshadow_.h commonio.h shadowio.h +shadow.lo shadow.o : shadow.c ../config.h +tcfsio.lo tcfsio.o : tcfsio.c ../config.h +utent.lo utent.o : utent.c ../config.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-libLTLIBRARIES \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-libtool \ + clean-libLTLIBRARIES clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-libtool distclean-libLTLIBRARIES \ + distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-libLTLIBRARIES maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool mostlyclean-libLTLIBRARIES \ +distclean-libLTLIBRARIES clean-libLTLIBRARIES \ +maintainer-clean-libLTLIBRARIES uninstall-libLTLIBRARIES \ +install-libLTLIBRARIES tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# remove the libshadow.so -> libshadow.so.x.x symlink, because this +# library is for internal use by this package only. Shadow support +# is in libc and no one should be using -lshadow anymore. +install-exec-hook: + rm -f $(libdir)/libshadow.so + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/lib/commonio.c b/current/lib/commonio.c new file mode 100644 index 00000000..4adb8eee --- /dev/null +++ b/current/lib/commonio.c @@ -0,0 +1,803 @@ + +#include + +#include "rcsid.h" +RCSID("$Id: commonio.c,v 1.16 2000/09/02 18:40:42 marekm Exp $") + +#include "defines.h" +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SHADOW_H +#include +#endif + +#include "commonio.h" + +/* local function prototypes */ +static int check_link_count(const char *); +static int do_lock_file(const char *, const char *); +static FILE *fopen_set_perms(const char *, const char *, const struct stat *); +static int create_backup(const char *, FILE *); +static void free_linked_list(struct commonio_db *); +static void add_one_entry(struct commonio_db *, struct commonio_entry *); +static int name_is_nis(const char *); +static int write_all(const struct commonio_db *); +static struct commonio_entry *find_entry_by_name(struct commonio_db *, const char *); + +static int lock_count = 0; +static int nscd_need_reload = 0; + +static int +check_link_count(const char *file) +{ + struct stat sb; + + if (stat(file, &sb) != 0) + return 0; + + if (sb.st_nlink != 2) + return 0; + + return 1; +} + + +static int +do_lock_file(const char *file, const char *lock) +{ + int fd; + int pid; + int len; + int retval; + char buf[32]; + + if ((fd = open(file, O_CREAT|O_EXCL|O_WRONLY, 0600)) == -1) + return 0; + + pid = getpid(); + snprintf(buf, sizeof buf, "%d", pid); + len = strlen(buf) + 1; + if (write(fd, buf, len) != len) { + close(fd); + unlink(file); + return 0; + } + close(fd); + + if (link(file, lock) == 0) { + retval = check_link_count(file); + unlink(file); + return retval; + } + + if ((fd = open(lock, O_RDWR)) == -1) { + unlink(file); + errno = EINVAL; + return 0; + } + len = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (len <= 0) { + unlink(file); + errno = EINVAL; + return 0; + } + buf[len] = '\0'; + if ((pid = strtol(buf, (char **) 0, 10)) == 0) { + unlink(file); + errno = EINVAL; + return 0; + } + if (kill(pid, 0) == 0) { + unlink(file); + errno = EEXIST; + return 0; + } + if (unlink(lock) != 0) { + unlink(file); + return 0; + } + + retval = 0; + if (link(file, lock) == 0 && check_link_count(file)) + retval = 1; + + unlink(file); + return retval; +} + + +static FILE * +fopen_set_perms(const char *name, const char *mode, const struct stat *sb) +{ + FILE *fp; + mode_t mask; + + mask = umask(0777); + fp = fopen(name, mode); + umask(mask); + if (!fp) + return NULL; + +#ifdef HAVE_FCHOWN + if (fchown(fileno(fp), sb->st_uid, sb->st_gid)) + goto fail; +#else + if (chown(name, sb->st_mode)) + goto fail; +#endif + +#ifdef HAVE_FCHMOD + if (fchmod(fileno(fp), sb->st_mode & 0664)) + goto fail; +#else + if (chmod(name, sb->st_mode & 0664)) + goto fail; +#endif + return fp; + +fail: + fclose(fp); + unlink(name); + return NULL; +} + + +static int +create_backup(const char *backup, FILE *fp) +{ + struct stat sb; + struct utimbuf ub; + FILE *bkfp; + int c; + mode_t mask; + + if (fstat(fileno(fp), &sb)) + return -1; + + mask = umask(077); + bkfp = fopen(backup, "w"); + umask(mask); + if (!bkfp) + return -1; + + /* TODO: faster copy, not one-char-at-a-time. --marekm */ + rewind(fp); + while ((c = getc(fp)) != EOF) { + if (putc(c, bkfp) == EOF) + break; + } + if (c != EOF || fflush(bkfp)) { + fclose(bkfp); + return -1; + } + if (fclose(bkfp)) + return -1; + + ub.actime = sb.st_atime; + ub.modtime = sb.st_mtime; + utime(backup, &ub); + return 0; +} + + +static void +free_linked_list(struct commonio_db *db) +{ + struct commonio_entry *p; + + while (db->head) { + p = db->head; + db->head = p->next; + + if (p->line) + free(p->line); + + if (p->eptr) + db->ops->free(p->eptr); + + free(p); + } + db->tail = NULL; +} + + +int +commonio_setname(struct commonio_db *db, const char *name) +{ + strcpy(db->filename, name); + return 1; +} + + +int +commonio_present(const struct commonio_db *db) +{ + return (access(db->filename, F_OK) == 0); +} + + +int +commonio_lock_nowait(struct commonio_db *db) +{ + char file[1024]; + char lock[1024]; + + if (db->locked) + return 1; + + snprintf(file, sizeof file, "%s.%ld", db->filename, (long) getpid()); + snprintf(lock, sizeof lock, "%s.lock", db->filename); + if (do_lock_file(file, lock)) { + db->locked = 1; + lock_count++; + return 1; + } + return 0; +} + + +int +commonio_lock(struct commonio_db *db) +{ +#ifdef HAVE_LCKPWDF + /* + * only if the system libc has a real lckpwdf() - the one from + * lockpw.c calls us and would cause infinite recursion! + */ + + /* + * Call lckpwdf() on the first lock. + * If it succeeds, call *_lock() only once + * (no retries, it should always succeed). + */ + if (lock_count == 0) { + if (lckpwdf() == -1) + return 0; /* failure */ + } + + if (commonio_lock_nowait(db)) + return 1; /* success */ + + ulckpwdf(); + return 0; /* failure */ +#else + int i; + + /* + * lckpwdf() not used - do it the old way. + */ +#ifndef LOCK_TRIES +#define LOCK_TRIES 15 +#endif + +#ifndef LOCK_SLEEP +#define LOCK_SLEEP 1 +#endif + for (i = 0; i < LOCK_TRIES; i++) { + if (i > 0) + sleep(LOCK_SLEEP); /* delay between retries */ + if (commonio_lock_nowait(db)) + return 1; /* success */ + /* no unnecessary retries on "permission denied" errors */ + if (geteuid() != 0) + return 0; + } + return 0; /* failure */ +#endif +} + +#ifndef NSCD_PID_FILE +#define NSCD_PID_FILE "/var/run/nscd.pid" +#endif + +/* + reload_nscd() is called after updating all of the password files, + to tell the "nscd" caching daemon to clear its cache. + Very loosely based on a shadow-utils patch from Red Hat. + */ + +static void +reload_nscd(void) +{ + FILE *pidfile; + int pid; + + pidfile = fopen(NSCD_PID_FILE, "r"); + if (pidfile) { + pid = 0; + fscanf(pidfile, "%d", &pid); + if (pid > 0) + kill(pid, SIGHUP); + fclose(pidfile); + } +} + + +static void +dec_lock_count(void) +{ + if (lock_count > 0) { + lock_count--; + if (lock_count == 0) { + /* Tell nscd when lock count goes to zero, + if any of the files were changed. */ + if (nscd_need_reload) { + reload_nscd(); + nscd_need_reload = 0; + } +#ifdef HAVE_LCKPWDF + ulckpwdf(); +#endif + } + } +} + + +int +commonio_unlock(struct commonio_db *db) +{ + char lock[1024]; + + if (db->isopen) { + db->readonly = 1; + if (!commonio_close(db)) { + if (db->locked) + dec_lock_count(); + return 0; + } + } + if (db->locked) { + /* + * Unlock in reverse order: remove the lock file, + * then call ulckpwdf() (if used) on last unlock. + */ + db->locked = 0; + snprintf(lock, sizeof lock, "%s.lock", db->filename); + unlink(lock); + dec_lock_count(); + return 1; + } + return 0; +} + + +static void +add_one_entry(struct commonio_db *db, struct commonio_entry *p) +{ + p->next = NULL; + p->prev = db->tail; + if (!db->head) + db->head = p; + if (db->tail) + db->tail->next = p; + db->tail = p; +} + + +static int +name_is_nis(const char *n) +{ + return (n[0] == '+' || n[0] == '-'); +} + + +/* + * New entries are inserted before the first NIS entry. Order is preserved + * when db is written out. + */ +#ifndef KEEP_NIS_AT_END +#define KEEP_NIS_AT_END 1 +#endif + +#if KEEP_NIS_AT_END +static void add_one_entry_nis(struct commonio_db *, struct commonio_entry *); + +static void +add_one_entry_nis(struct commonio_db *db, struct commonio_entry *newp) +{ + struct commonio_entry *p; + + for (p = db->head; p; p = p->next) { + if (name_is_nis(p->eptr ? db->ops->getname(p->eptr) : p->line)) { + newp->next = p; + newp->prev = p->prev; + if (p->prev) + p->prev->next = newp; + else + db->head = newp; + p->prev = newp; + return; + } + } + add_one_entry(db, newp); +} +#endif /* KEEP_NIS_AT_END */ + +/* Initial buffer size, as well as increment if not sufficient + (for reading very long lines in group files). */ +#define BUFLEN 4096 + +int +commonio_open(struct commonio_db *db, int mode) +{ + char *buf; + char *cp; + char *line; + struct commonio_entry *p; + void *eptr; + int flags = mode; + int buflen; + + mode &= ~O_CREAT; + + if (db->isopen || (mode != O_RDONLY && mode != O_RDWR)) { + errno = EINVAL; + return 0; + } + db->readonly = (mode == O_RDONLY); + if (!db->readonly && !db->locked) { + errno = EACCES; + return 0; + } + + db->head = db->tail = db->cursor = NULL; + db->changed = 0; + + db->fp = fopen(db->filename, db->readonly ? "r" : "r+"); + + /* + * If O_CREAT was specified and the file didn't exist, it will be + * created by commonio_close(). We have no entries to read yet. --marekm + */ + if (!db->fp) { + if ((flags & O_CREAT) && errno == ENOENT) { + db->isopen = 1; + return 1; + } + return 0; + } + + buflen = BUFLEN; + buf = (char *) malloc(buflen); + if (!buf) + goto cleanup; + + while (db->ops->fgets(buf, buflen, db->fp)) { + while (!(cp = strrchr(buf, '\n')) && !feof(db->fp)) { + buflen += BUFLEN; + cp = (char *) realloc(buf, buflen); + if (!cp) + goto cleanup_buf; + buf = cp; + db->ops->fgets(buf + buflen - BUFLEN, BUFLEN, db->fp); + } + if ((cp = strrchr(buf, '\n'))) + *cp = '\0'; + + if (!(line = strdup(buf))) + goto cleanup_buf; + + if (name_is_nis(line)) { + eptr = NULL; + } else if ((eptr = db->ops->parse(line))) { + eptr = db->ops->dup(eptr); + if (!eptr) + goto cleanup_line; + } + + p = (struct commonio_entry *) malloc(sizeof *p); + if (!p) + goto cleanup_entry; + + p->eptr = eptr; + p->line = line; + p->changed = 0; + + add_one_entry(db, p); + } + + db->isopen = 1; + free(buf); + return 1; + +cleanup_entry: + if (eptr) + db->ops->free(eptr); +cleanup_line: + free(line); +cleanup_buf: + free(buf); +cleanup: + free_linked_list(db); + fclose(db->fp); + db->fp = NULL; + errno = ENOMEM; + return 0; +} + + +static int +write_all(const struct commonio_db *db) +{ + const struct commonio_entry *p; + void *eptr; + + for (p = db->head; p; p = p->next) { + if (p->changed) { + eptr = p->eptr; + if (db->ops->put(eptr, db->fp)) + return -1; + } else if (p->line) { + if (db->ops->fputs(p->line, db->fp) == EOF) + return -1; + if (putc('\n', db->fp) == EOF) + return -1; + } + } + return 0; +} + + +int +commonio_close(struct commonio_db *db) +{ + char buf[1024]; + int errors = 0; + struct stat sb; + + if (!db->isopen) { + errno = EINVAL; + return 0; + } + db->isopen = 0; + + if (!db->changed || db->readonly) { + fclose(db->fp); + db->fp = NULL; + goto success; + } + + memzero(&sb, sizeof sb); + if (db->fp) { + if (fstat(fileno(db->fp), &sb)) { + fclose(db->fp); + db->fp = NULL; + goto fail; + } + + /* + * Create backup file. + */ + snprintf(buf, sizeof buf, "%s-", db->filename); + + if (create_backup(buf, db->fp)) + errors++; + + if (fclose(db->fp)) + errors++; + + if (errors) { + db->fp = NULL; + goto fail; + } + } else { + /* + * Default permissions for new [g]shadow files. + * (passwd and group always exist...) + */ + sb.st_mode = 0400; + sb.st_uid = 0; + sb.st_gid = 0; + } + + snprintf(buf, sizeof buf, "%s+", db->filename); + + db->fp = fopen_set_perms(buf, "w", &sb); + if (!db->fp) + goto fail; + + if (write_all(db)) + errors++; + + if (fflush(db->fp)) + errors++; +#ifdef HAVE_FSYNC + if (fsync(fileno(db->fp))) + errors++; +#else + sync(); +#endif + if (fclose(db->fp)) + errors++; + + db->fp = NULL; + + if (errors) { + unlink(buf); + goto fail; + } + + if (rename(buf, db->filename)) + goto fail; + + nscd_need_reload = 1; + +success: + free_linked_list(db); + return 1; + +fail: + free_linked_list(db); + return 0; +} + + +static struct commonio_entry * +find_entry_by_name(struct commonio_db *db, const char *name) +{ + struct commonio_entry *p; + void *ep; + + for (p = db->head; p; p = p->next) { + ep = p->eptr; + if (ep && strcmp(db->ops->getname(ep), name) == 0) + break; + } + return p; +} + + +int +commonio_update(struct commonio_db *db, const void *eptr) +{ + struct commonio_entry *p; + void *nentry; + + if (!db->isopen || db->readonly) { + errno = EINVAL; + return 0; + } + if (!(nentry = db->ops->dup(eptr))) { + errno = ENOMEM; + return 0; + } + p = find_entry_by_name(db, db->ops->getname(eptr)); + if (p) { + db->ops->free(p->eptr); + p->eptr = nentry; + p->changed = 1; + db->cursor = p; + + db->changed = 1; + return 1; + } + /* not found, new entry */ + p = (struct commonio_entry *) malloc(sizeof *p); + if (!p) { + db->ops->free(nentry); + errno = ENOMEM; + return 0; + } + + p->eptr = nentry; + p->line = NULL; + p->changed = 1; + +#if KEEP_NIS_AT_END + add_one_entry_nis(db, p); +#else + add_one_entry(db, p); +#endif + + db->changed = 1; + return 1; +} + + +void +commonio_del_entry(struct commonio_db *db, const struct commonio_entry *p) +{ + if (p == db->cursor) + db->cursor = p->next; + + if (p->prev) + p->prev->next = p->next; + else + db->head = p->next; + + if (p->next) + p->next->prev = p->prev; + else + db->tail = p->prev; + + db->changed = 1; +} + + +int +commonio_remove(struct commonio_db *db, const char *name) +{ + struct commonio_entry *p; + + if (!db->isopen || db->readonly) { + errno = EINVAL; + return 0; + } + p = find_entry_by_name(db, name); + if (!p) { + errno = ENOENT; + return 0; + } + + commonio_del_entry(db, p); + + if (p->line) + free(p->line); + + if (p->eptr) + db->ops->free(p->eptr); + + return 1; +} + + +const void * +commonio_locate(struct commonio_db *db, const char *name) +{ + struct commonio_entry *p; + + if (!db->isopen) { + errno = EINVAL; + return NULL; + } + p = find_entry_by_name(db, name); + if (!p) { + errno = ENOENT; + return NULL; + } + db->cursor = p; + return p->eptr; +} + + +int +commonio_rewind(struct commonio_db *db) +{ + if (!db->isopen) { + errno = EINVAL; + return 0; + } + db->cursor = NULL; + return 1; +} + + +const void * +commonio_next(struct commonio_db *db) +{ + void *eptr; + + if (!db->isopen) { + errno = EINVAL; + return 0; + } + if (db->cursor == NULL) + db->cursor = db->head; + else + db->cursor = db->cursor->next; + + while (db->cursor) { + eptr = db->cursor->eptr; + if (eptr) + return eptr; + + db->cursor = db->cursor->next; + } + return NULL; +} diff --git a/current/lib/commonio.h b/current/lib/commonio.h new file mode 100644 index 00000000..f25883b8 --- /dev/null +++ b/current/lib/commonio.h @@ -0,0 +1,100 @@ +/* $Id: commonio.h,v 1.6 2000/09/02 18:40:43 marekm Exp $ */ + +/* + * Linked list entry. + */ +struct commonio_entry { + char *line; + void *eptr; /* struct passwd, struct spwd, ... */ + struct commonio_entry *prev, *next; + int changed:1; +}; + +/* + * Operations depending on database type: passwd, group, shadow etc. + */ +struct commonio_ops { + /* + * Make a copy of the object (for example, struct passwd) + * and all strings pointed by it, in malloced memory. + */ + void *(*dup)(const void *); + + /* + * free() the object including any strings pointed by it. + */ + void (*free)(void *); + + /* + * Return the name of the object (for example, pw_name + * for struct passwd). + */ + const char *(*getname)(const void *); + + /* + * Parse a string, return object (in static area - + * should be copied using the dup operation above). + */ + void *(*parse)(const char *); + + /* + * Write the object to the file (this calls putpwent() + * for struct passwd, for example). + */ + int (*put)(const void *, FILE *); + + /* + * fgets and fputs (can be replaced by versions that + * understand line continuation conventions). + */ + char *(*fgets)(char *, int, FILE *); + int (*fputs)(const char *, FILE *); +}; + +/* + * Database structure. + */ +struct commonio_db { + /* + * Name of the data file. + */ + char filename[1024]; + + /* + * Operations from above. + */ + struct commonio_ops *ops; + + /* + * Currently open file stream. + */ + FILE *fp; + + /* + * Head, tail, current position in linked list. + */ + struct commonio_entry *head, *tail, *cursor; + + /* + * Various flags. + */ + int changed:1; + int isopen:1; + int locked:1; + int readonly:1; +}; + +extern int commonio_setname(struct commonio_db *, const char *); +extern int commonio_present(const struct commonio_db *); +extern int commonio_lock(struct commonio_db *); +extern int commonio_lock_nowait(struct commonio_db *); +extern int commonio_open(struct commonio_db *, int); +extern const void *commonio_locate(struct commonio_db *, const char *); +extern int commonio_update(struct commonio_db *, const void *); +extern int commonio_remove(struct commonio_db *, const char *); +extern int commonio_rewind(struct commonio_db *); +extern const void *commonio_next(struct commonio_db *); +extern int commonio_close(struct commonio_db *); +extern int commonio_unlock(struct commonio_db *); +extern void commonio_del_entry(struct commonio_db *, const struct commonio_entry *); + diff --git a/current/lib/defines.h b/current/lib/defines.h new file mode 100644 index 00000000..c020f9e5 --- /dev/null +++ b/current/lib/defines.h @@ -0,0 +1,348 @@ +/* $Id: defines.h,v 1.17 2000/09/02 18:40:43 marekm Exp $ */ +/* some useful defines */ + +#ifndef _DEFINES_H_ +#define _DEFINES_H_ + +#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) + +/* Take care of NLS matters. */ + +#if HAVE_LOCALE_H +# include +#endif +#if !HAVE_SETLOCALE +# define setlocale(Category, Locale) /* empty */ +#endif + +#define gettext_noop(String) (String) +/* #define gettext_def(String) "#define String" */ + +#if ENABLE_NLS +# include +# define _(Text) gettext (Text) +#else +# undef bindtextdomain +# define bindtextdomain(Domain, Directory) /* empty */ +# undef textdomain +# define textdomain(Domain) /* empty */ +# define _(Text) Text +#endif + +#if STDC_HEADERS +# include +# include +#else /* not STDC_HEADERS */ +# ifndef HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +char *strchr(), *strrchr(), *strtok(); +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy((s), (d), (n)) +# endif +#endif /* not STDC_HEADERS */ + +/* Solaris 2.4 defines __SVR4, but not SVR4 -j. */ + +#ifdef __SVR4 +# ifndef SVR4 +# define SVR4 __SVR4 +# endif +#endif + +#include +#include +#if HAVE_SYS_WAIT_H +# include +#endif +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +#if HAVE_UNISTD_H +# include +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else /* not TIME_WITH_SYS_TIME */ +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif /* not TIME_WITH_SYS_TIME */ + +#ifdef HAVE_MEMSET +# define memzero(ptr, size) memset((void *)(ptr), 0, (size)) +#else +# define memzero(ptr, size) bzero((char *)(ptr), (size)) +#endif +#define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */ + +#ifdef HAVE_DIRENT_H /* DIR_SYSV */ +# include +# define DIRECT dirent +#else +# ifdef HAVE_SYS_NDIR_H /* DIR_XENIX */ +# include +# endif +# ifdef HAVE_SYS_DIR_H /* DIR_??? */ +# include +# endif +# ifdef HAVE_NDIR_H /* DIR_BSD */ +# include +# endif +# define DIRECT direct +#endif + +#ifdef SHADOWPWD +/* + * Possible cases: + * - /usr/include/shadow.h exists and includes the shadow group stuff. + * - /usr/include/shadow.h exists, but we use our own gshadow.h. + * - /usr/include/shadow.h doesn't exist, use our own shadow.h and gshadow.h. + */ +#if HAVE_SHADOW_H +#include +#if defined(SHADOWGRP) && !defined(GSHADOW) +#include "gshadow_.h" +#endif +#else /* not HAVE_SHADOW_H */ +#include "shadow_.h" +#ifdef SHADOWGRP +#include "gshadow_.h" +#endif +#endif /* not HAVE_SHADOW_H */ +#endif /* SHADOWPWD */ + +#include + +#ifndef NGROUPS_MAX +#ifdef NGROUPS +#define NGROUPS_MAX NGROUPS +#else +#define NGROUPS_MAX 64 +#endif +#endif + +#ifdef USE_SYSLOG +#include + +#ifndef LOG_WARN +#define LOG_WARN LOG_WARNING +#endif + +/* LOG_NOWAIT is deprecated */ +#ifndef LOG_NOWAIT +#define LOG_NOWAIT 0 +#endif + +/* LOG_AUTH is deprecated, use LOG_AUTHPRIV instead */ +#ifndef LOG_AUTHPRIV +#define LOG_AUTHPRIV LOG_AUTH +#endif + +/* cleaner than lots of #ifdefs everywhere - use this as follows: + SYSLOG((LOG_CRIT, "user %s cracked root", user)); */ +#if HAVE_SETLOCALE +/* Temporarily set LC_TIME to "C" to avoid strange dates in syslog. + This is a workaround for a more general syslog(d) design problem - + syslogd should log the current system time for each event, and not + trust the formatted time received from the unix domain (or worse, + UDP) socket. -MM */ +#define SYSLOG(x) \ + do { \ + char *saved_locale = setlocale(LC_ALL, NULL); \ + if (saved_locale) \ + saved_locale = strdup(saved_locale); \ + if (saved_locale) \ + setlocale(LC_TIME, "C"); \ + syslog x ; \ + if (saved_locale) { \ + setlocale(LC_ALL, saved_locale); \ + free(saved_locale); \ + } \ + } while (0) +#else /* !HAVE_SETLOCALE */ +#define SYSLOG(x) syslog x +#endif /* !HAVE_SETLOCALE */ + +#else /* !USE_SYSLOG */ + +#define SYSLOG(x) /* empty */ +#define openlog(a,b,c) /* empty */ +#define closelog() /* empty */ + +#endif /* !USE_SYSLOG */ + +/* The default syslog settings can now be changed here, + in just one place. */ + +#ifndef SYSLOG_OPTIONS +/* #define SYSLOG_OPTIONS (LOG_PID | LOG_CONS | LOG_NOWAIT) */ +#define SYSLOG_OPTIONS (LOG_PID) +#endif + +#ifndef SYSLOG_FACILITY +#define SYSLOG_FACILITY LOG_AUTHPRIV +#endif + +#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY) + +#ifndef F_OK +# define F_OK 0 +# define X_OK 1 +# define W_OK 2 +# define R_OK 4 +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 +# define SEEK_CUR 1 +# define SEEK_END 2 +#endif + +#ifdef STAT_MACROS_BROKEN +# define S_ISDIR(x) ((x) & S_IFMT) == S_IFDIR) +# define S_ISREG(x) ((x) & S_IFMT) == S_IFREG) +# ifdef S_IFLNK +# define S_ISLNK(x) ((x) & S_IFMT) == S_IFLNK) +# endif +#endif + +#ifndef S_ISLNK +#define S_ISLNK(x) (0) +#endif + +#if HAVE_LCHOWN +#define LCHOWN lchown +#else +#define LCHOWN chown +#endif + +#if HAVE_LSTAT +#define LSTAT lstat +#else +#define LSTAT stat +#endif + +#if HAVE_TERMIOS_H +# include +# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio) +# define GTTY(fd, termio) tcgetattr(fd, termio) +# define TERMIO struct termios +# define USE_TERMIOS +#else /* assumed HAVE_TERMIO_H */ +# include +# include +# define STTY(fd, termio) ioctl(fd, TCSETA, termio) +# define GTTY(fd, termio) ioctl(fd, TCGETA, termio) +# define TEMRIO struct termio +# define USE_TERMIO +#endif + +/* + * Password aging constants + * + * DAY - seconds / day + * WEEK - seconds / week + * SCALE - seconds / aging unit + */ + +/* Solaris defines this in shadow.h */ +#ifndef DAY +#define DAY (24L*3600L) +#endif + +#define WEEK (7*DAY) + +#ifdef ITI_AGING +#define SCALE 1 +#else +#define SCALE DAY +#endif + +/* Copy string pointed by B to array A with size checking. It was originally + in lmain.c but is _very_ useful elsewhere. Some setuid root programs with + very sloppy coding used to assume that BUFSIZ will always be enough... */ + + /* danger - side effects */ +#define STRFCPY(A,B) \ + (strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0') + +/* get rid of a few ugly repeated #ifdefs in pwent.c and grent.c */ +/* XXX - this is ugly too, configure should test it and not check for + any hardcoded system names, if possible. --marekm */ +#if defined(SVR4) || defined(AIX) || defined(__linux__) +#define SETXXENT_TYPE void +#define SETXXENT_RET(x) return +#define SETXXENT_TEST(x) x; if (0) /* compiler should optimize this away */ +#else +#define SETXXENT_TYPE int +#define SETXXENT_RET(x) return(x) +#define SETXXENT_TEST(x) if (x) +#endif + +#ifndef PASSWD_FILE +#define PASSWD_FILE "/etc/passwd" +#endif + +#ifndef GROUP_FILE +#define GROUP_FILE "/etc/group" +#endif + +#ifdef SHADOWPWD +#ifndef SHADOW_FILE +#define SHADOW_FILE "/etc/shadow" +#endif +#endif + +#ifdef SHADOWGRP +#ifndef SGROUP_FILE +#define SGROUP_FILE "/etc/gshadow" +#endif +#endif + +#define PASSWD_PAG_FILE PASSWD_FILE ".pag" +#define GROUP_PAG_FILE GROUP_FILE ".pag" +#define SHADOW_PAG_FILE SHADOW_FILE ".pag" +#define SGROUP_PAG_FILE SGROUP_FILE ".pag" + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#ifdef sun /* hacks for compiling on SunOS */ +# ifndef SOLARIS +extern int fputs(); +extern char *strdup(); +extern char *strerror(); +# endif +#endif + +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif + +/* + * string to use for the pw_passwd field in /etc/passwd when using + * shadow passwords - most systems use "x" but there are a few + * exceptions, so it can be changed here if necessary. --marekm + */ +#ifndef SHADOW_PASSWD_STRING +#define SHADOW_PASSWD_STRING "x" +#endif + +#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */ +#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err) +#else +#define PAM_STRERROR(pamh, err) pam_strerror(err) +#endif + +#endif /* _DEFINES_H_ */ diff --git a/current/lib/dialchk.c b/current/lib/dialchk.c new file mode 100644 index 00000000..92b4ce7e --- /dev/null +++ b/current/lib/dialchk.c @@ -0,0 +1,77 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: dialchk.c,v 1.6 1999/08/27 19:02:51 marekm Exp $") + +#include +#include "defines.h" +#include "prototypes.h" +#include "dialup.h" +#include "dialchk.h" + +/* + * Check for dialup password + * + * dialcheck tests to see if tty is listed as being a dialup + * line. If so, a dialup password may be required if the shell + * is listed as one which requires a second password. + */ + +int +dialcheck(const char *tty, const char *sh) +{ + struct dialup *dialup; + char *pass; + char *cp; + + setduent (); + + if (! isadialup (tty)) { + endduent (); + return (1); + } + if (! (dialup = getdushell (sh))) { + endduent (); + return (1); + } + endduent (); + + if (dialup->du_passwd[0] == '\0') + return (1); + + if (! (pass = getpass(_("Dialup Password: ")))) + return (0); + + cp = pw_encrypt (pass, dialup->du_passwd); + strzero(pass); + return (strcmp (cp, dialup->du_passwd) == 0); +} diff --git a/current/lib/dialchk.h b/current/lib/dialchk.h new file mode 100644 index 00000000..75f1829e --- /dev/null +++ b/current/lib/dialchk.h @@ -0,0 +1,16 @@ +/* $Id: dialchk.h,v 1.2 2000/08/26 18:27:17 marekm Exp $ */ +#ifndef _DIALCHK_H_ +#define _DIALCHK_H_ + +#include "defines.h" + +/* + * Check for dialup password + * + * dialcheck tests to see if tty is listed as being a dialup + * line. If so, a dialup password may be required if the shell + * is listed as one which requires a second password. + */ +extern int dialcheck(const char *, const char *); + +#endif diff --git a/current/lib/dialup.c b/current/lib/dialup.c new file mode 100644 index 00000000..7965c1ae --- /dev/null +++ b/current/lib/dialup.c @@ -0,0 +1,169 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: dialup.c,v 1.3 1997/12/07 23:26:50 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include "dialup.h" + +static FILE *dialpwd; + +void +setduent(void) +{ + if (dialpwd) + rewind (dialpwd); + else + dialpwd = fopen (DIALPWD, "r"); +} + +void +endduent(void) +{ + if (dialpwd) + fclose (dialpwd); + + dialpwd = (FILE *) 0; +} + +struct dialup * +fgetduent(FILE *fp) +{ + static struct dialup dialup; /* static structure to point to */ + static char sh[128]; /* some space for a login shell */ + static char passwd[128]; /* some space for dialup password */ + char buf[BUFSIZ]; + char *cp; + char *cp2; + + if (! fp) + return 0; + + if (! fp || feof (fp)) + return ((struct dialup *) 0); + + while (fgets (buf, sizeof buf, fp) == buf && buf[0] == '#') + ; + + if (feof (fp)) + return ((struct dialup *) 0); + + if ((cp = strchr (buf, '\n'))) + *cp = '\0'; + + if (! (cp = strchr (buf, ':'))) + return ((struct dialup *) 0); + + if (cp - buf > sizeof sh) /* something is fishy ... */ + return ((struct dialup *) 0); + + *cp++ = '\0'; + (void) strcpy (sh, buf); + sh[cp - buf] = '\0'; + + if ((cp2 = strchr (cp, ':'))) + *cp2 = '\0'; + + if (strlen (cp) + 1 > sizeof passwd) /* something is REALLY fishy */ + return ((struct dialup *) 0); + + (void) strcpy (passwd, cp); + + dialup.du_shell = sh; + dialup.du_passwd = passwd; + + return (&dialup); +} + +struct dialup * +getduent(void) +{ + if (! dialpwd) + setduent (); + + return fgetduent (dialpwd); +} + +struct dialup * +getdushell(const char *sh) +{ + struct dialup *dialup; + + while ((dialup = getduent ())) { + if (strcmp (sh, dialup->du_shell) == 0) + return (dialup); + + if (strcmp (dialup->du_shell, "*") == 0) + return (dialup); + } + return ((struct dialup *) 0); +} + +int +isadialup(const char *tty) +{ + FILE *fp; + char buf[BUFSIZ]; + int dialup = 0; + + if (! (fp = fopen (DIALUPS, "r"))) + return (0); + + while (fgets (buf, sizeof buf, fp) == buf) { + if (buf[0] == '#') + continue; + + buf[strlen (buf) - 1] = '\0'; + + if (strcmp (buf, tty) == 0) { + dialup = 1; + break; + } + } + fclose (fp); + + return (dialup); +} + +int +putduent(const struct dialup *dial, FILE *fp) +{ + if (! fp || ! dial) + return -1; + + if (fprintf (fp, "%s:%s\n", dial->du_shell, dial->du_passwd) == EOF) + return -1; + + return 0; +} diff --git a/current/lib/dialup.h b/current/lib/dialup.h new file mode 100644 index 00000000..2b3892bd --- /dev/null +++ b/current/lib/dialup.h @@ -0,0 +1,66 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * Structure of the /etc/d_passwd file + * + * The d_passwd file contains the names of login shells which require + * dialup passwords. Each line contains the fully qualified path name + * for the shell, followed by an optional password. Each field is + * separated by a ':'. + * + * Structure of the /etc/dialups file + * + * The dialups file contains the names of ports which may be dialup + * lines. Each line consists of the last component of the path + * name. The leading "/dev/" string is removed. + * + * $Id: dialup.h,v 1.3 2000/08/26 18:27:17 marekm Exp $ + */ + +#ifndef _DIALUP_H +#define _DIALUP_H + +struct dialup { + char *du_shell; + char *du_passwd; +}; + +extern void setduent(void); +extern void endduent(void); +extern struct dialup *fgetduent(FILE *); +extern struct dialup *getduent(void); +extern struct dialup *getdushell(const char *); +extern int putduent(const struct dialup *, FILE *); +extern int isadialup(const char *); + +#define DIALPWD "/etc/d_passwd" +#define DIALUPS "/etc/dialups" + +#endif diff --git a/current/lib/encrypt.c b/current/lib/encrypt.c new file mode 100644 index 00000000..51c16e7a --- /dev/null +++ b/current/lib/encrypt.c @@ -0,0 +1,123 @@ +/* + * Copyright 1990 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: encrypt.c,v 1.7 2000/08/26 18:27:17 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" + +extern char *crypt(); +extern char *libshadow_md5_crypt(const char *, const char *); + +char * +pw_encrypt(const char *clear, const char *salt) +{ + static char cipher[128]; + char *cp; +#ifdef SW_CRYPT + static int count; +#endif + +#ifdef MD5_CRYPT + /* + * If the salt string from the password file or from crypt_make_salt() + * begins with the magic string, use the new algorithm. + */ + if (strncmp(salt, "$1$", 3) == 0) + return libshadow_md5_crypt(clear, salt); +#endif + +#ifdef SW_CRYPT + /* + * Copy over the salt. It is always the first two + * characters of the string. + */ + + cipher[0] = salt[0]; + cipher[1] = salt[1]; + cipher[2] = '\0'; + + /* + * Loop up to ten times on the cleartext password. + * This is because the input limit for passwords is + * 80 characters. + * + * The initial salt is that provided by the user, or the + * one generated above. The subsequent salts are gotten + * from the first two characters of the previous encrypted + * block of characters. + */ + + for (count = 0;count < 10;count++) { + cp = crypt(clear, salt); + if (!cp) { + perror("crypt"); + exit(1); + } + if (strlen(cp) != 13) + return cp; + strcat(cipher, cp + 2); + salt = cipher + 11 * count + 2; + + if (strlen(clear) > 8) + clear += 8; + else + break; + } +#else + cp = crypt(clear, salt); + if (!cp) { + /* + * Single Unix Spec: crypt() may return a null pointer, + * and set errno to indicate an error. The caller doesn't + * expect us to return NULL, so... + */ + perror("crypt"); + exit(1); + } + if (strlen(cp) != 13) + return cp; /* nonstandard crypt() in libc, better bail out */ + strcpy(cipher, cp); + +#ifdef DOUBLESIZE + if (strlen (clear) > 8) { + cp = crypt(clear + 8, salt); + if (!cp) { + perror("crypt"); + exit(1); + } + strcat(cipher, cp + 2); + } +#endif /* DOUBLESIZE */ +#endif /* SW_CRYPT */ + return cipher; +} diff --git a/current/lib/faillog.h b/current/lib/faillog.h new file mode 100644 index 00000000..028012c8 --- /dev/null +++ b/current/lib/faillog.h @@ -0,0 +1,55 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * faillog.h - login failure logging file format + * + * $Id: faillog.h,v 1.3 1997/05/01 23:14:39 marekm Exp $ + * + * The login failure file is maintained by login(1) and faillog(8) + * Each record in the file represents a separate UID and the file + * is indexed in that fashion. + */ + +#ifndef _FAILLOG_H +#define _FAILLOG_H + +struct faillog { + short fail_cnt; /* failures since last success */ + short fail_max; /* failures before turning account off */ + char fail_line[12]; /* last failure occured here */ + time_t fail_time; /* last failure occured then */ + /* + * If nonzero, the account will be re-enabled if there are no + * failures for fail_locktime seconds since last failure. + */ + long fail_locktime; +}; + +#endif diff --git a/current/lib/fputsx.c b/current/lib/fputsx.c new file mode 100644 index 00000000..17846110 --- /dev/null +++ b/current/lib/fputsx.c @@ -0,0 +1,80 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include +#include "defines.h" + +#include "rcsid.h" +RCSID("$Id: fputsx.c,v 1.5 1999/06/07 16:40:44 marekm Exp $") + +char * +fgetsx(char *buf, int cnt, FILE *f) +{ + char *cp = buf; + char *ep; + + while (cnt > 0) { + if (fgets (cp, cnt, f) == 0) { + if (cp == buf) + return 0; + else + break; + } + if ((ep = strrchr (cp, '\\')) && *(ep + 1) == '\n') { + if ((cnt -= ep - cp) > 0) + *(cp = ep) = '\0'; + } else + break; + } + return buf; +} + +int +fputsx(const char *s, FILE *stream) +{ + int i; + + for (i = 0;*s;i++, s++) { + if (putc (*s, stream) == EOF) + return EOF; + +#if 0 /* The standard getgr*() can't handle that. --marekm */ + if (i > (BUFSIZ/2)) { + if (putc ('\\', stream) == EOF || + putc ('\n', stream) == EOF) + return EOF; + + i = 0; + } +#endif + } + return 0; +} diff --git a/current/lib/getdef.c b/current/lib/getdef.c new file mode 100644 index 00000000..12ce99e8 --- /dev/null +++ b/current/lib/getdef.c @@ -0,0 +1,406 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh and Chip Rosenthal + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: getdef.c,v 1.14 2000/08/26 18:27:17 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include +#include +#include "getdef.h" + +/* + * A configuration item definition. + */ + +struct itemdef { + const char *name; /* name of the item */ + char *value; /* value given, or NULL if no value */ +}; + +/* + * This list *must* be sorted by the "name" member. + */ + +#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0])) +static struct itemdef def_table[] = { + { "CHFN_AUTH", NULL }, + { "CHFN_RESTRICT", NULL }, +#ifdef USE_PAM + { "CLOSE_SESSIONS", NULL }, +#endif + { "CONSOLE", NULL }, + { "CONSOLE_GROUPS", NULL }, + { "CRACKLIB_DICTPATH", NULL }, + { "CREATE_HOME", NULL }, + { "DEFAULT_HOME", NULL }, + { "DIALUPS_CHECK_ENAB", NULL }, + { "ENVIRON_FILE", NULL }, + { "ENV_HZ", NULL }, + { "ENV_PATH", NULL }, + { "ENV_ROOTPATH", NULL }, /* SuSE compatibility? */ + { "ENV_SUPATH", NULL }, + { "ENV_TZ", NULL }, + { "ERASECHAR", NULL }, + { "FAILLOG_ENAB", NULL }, + { "FAIL_DELAY", NULL }, + { "FAKE_SHELL", NULL }, + { "FTMP_FILE", NULL }, + { "GETPASS_ASTERISKS", NULL }, + { "GID_MAX", NULL }, + { "GID_MIN", NULL }, + { "HUSHLOGIN_FILE", NULL }, + { "ISSUE_FILE", NULL }, + { "KILLCHAR", NULL }, + { "LASTLOG_ENAB", NULL }, + { "LOGIN_RETRIES", NULL }, + { "LOGIN_STRING", NULL }, + { "LOGIN_TIMEOUT", NULL }, + { "LOG_OK_LOGINS", NULL }, + { "LOG_UNKFAIL_ENAB", NULL }, + { "MAIL_CHECK_ENAB", NULL }, + { "MAIL_DIR", NULL }, + { "MAIL_FILE", NULL }, + { "MD5_CRYPT_ENAB", NULL }, + { "MOTD_FILE", NULL }, + { "NOLOGINS_FILE", NULL }, + { "NOLOGIN_STR", NULL }, + { "NO_PASSWORD_CONSOLE", NULL }, + { "OBSCURE_CHECKS_ENAB", NULL }, + { "PASS_ALWAYS_WARN", NULL }, + { "PASS_CHANGE_TRIES", NULL }, + { "PASS_MAX_DAYS", NULL }, + { "PASS_MAX_LEN", NULL }, + { "PASS_MIN_DAYS", NULL }, + { "PASS_MIN_LEN", NULL }, + { "PASS_WARN_AGE", NULL }, + { "PORTTIME_CHECKS_ENAB", NULL }, + { "QMAIL_DIR", NULL }, + { "QUOTAS_ENAB", NULL }, + { "SULOG_FILE", NULL }, + { "SU_NAME", NULL }, + { "SU_WHEEL_ONLY", NULL }, +#ifdef USE_SYSLOG + { "SYSLOG_SG_ENAB", NULL }, + { "SYSLOG_SU_ENAB", NULL }, +#endif + { "TTYGROUP", NULL }, + { "TTYPERM", NULL }, + { "TTYTYPE_FILE", NULL }, + { "UID_MAX", NULL }, + { "UID_MIN", NULL }, + { "ULIMIT", NULL }, + { "UMASK", NULL }, + { "USERDEL_CMD", NULL }, + { "USERGROUPS_ENAB", NULL } +}; + +#ifndef LOGINDEFS +#define LOGINDEFS "/etc/login.defs" +#endif + +static char def_fname[] = LOGINDEFS; /* login config defs file */ +static int def_loaded = 0; /* are defs already loaded? */ + +extern long strtol(); + +/* local function prototypes */ +static struct itemdef *def_find(const char *); +static void def_load(void); + + +/* + * getdef_str - get string value from table of definitions. + * + * Return point to static data for specified item, or NULL if item is not + * defined. First time invoked, will load definitions from the file. + */ + +char * +getdef_str(const char *item) +{ + struct itemdef *d; + + if (!def_loaded) + def_load(); + + return ((d = def_find(item)) == NULL ? (char *)NULL : d->value); +} + + +/* + * getdef_bool - get boolean value from table of definitions. + * + * Return TRUE if specified item is defined as "yes", else FALSE. + */ + +int +getdef_bool(const char *item) +{ + struct itemdef *d; + + if (!def_loaded) + def_load(); + + if ((d = def_find(item)) == NULL || d->value == NULL) + return 0; + + return (strcasecmp(d->value, "yes") == 0); +} + + +/* + * getdef_num - get numerical value from table of definitions + * + * Returns numeric value of specified item, else the "dflt" value if + * the item is not defined. Octal (leading "0") and hex (leading "0x") + * values are handled. + */ + +int +getdef_num(const char *item, int dflt) +{ + struct itemdef *d; + + if (!def_loaded) + def_load(); + + if ((d = def_find(item)) == NULL || d->value == NULL) + return dflt; + + return (int) strtol(d->value, (char **)NULL, 0); +} + + +/* + * getdef_long - get long integer value from table of definitions + * + * Returns numeric value of specified item, else the "dflt" value if + * the item is not defined. Octal (leading "0") and hex (leading "0x") + * values are handled. + */ + +long +getdef_long(const char *item, long dflt) +{ + struct itemdef *d; + + if (!def_loaded) + def_load(); + + if ((d = def_find(item)) == NULL || d->value == NULL) + return dflt; + + return strtol(d->value, (char **)NULL, 0); +} + + +/* + * putdef_str - override the value read from /etc/login.defs + * (also used when loading the initial defaults) + */ + +int +putdef_str(const char *name, const char *value) +{ + struct itemdef *d; + char *cp; + + if (!def_loaded) + def_load(); + + /* + * Locate the slot to save the value. If this parameter + * is unknown then "def_find" will print an err message. + */ + if ((d = def_find(name)) == NULL) + return -1; + + /* + * Save off the value. + */ + if ((cp = strdup(value)) == NULL) { + fprintf(stderr, + _("Could not allocate space for config info.\n")); + SYSLOG((LOG_ERR, + "could not allocate space for config info")); + return -1; + } + + if (d->value) + free(d->value); + + d->value = cp; + return 0; +} + + +/* + * def_find - locate named item in table + * + * Search through a sorted table of configurable items to locate the + * specified configuration option. + */ + +static struct itemdef * +def_find(const char *name) +{ + int min, max, curr, n; + + /* + * Invariant - desired item in range [min:max]. + */ + + min = 0; + max = NUMDEFS-1; + + /* + * Binary search into the table. Relies on the items being + * sorted by name. + */ + + while (min <= max) { + curr = (min+max)/2; + + if (! (n = strcmp(def_table[curr].name, name))) + return &def_table[curr]; + + if (n < 0) + min = curr+1; + else + max = curr-1; + } + + /* + * Item was never found. + */ + + fprintf(stderr, _("configuration error - unknown item '%s' (notify administrator)\n"), name); + SYSLOG((LOG_CRIT, "unknown configuration item `%s'", name)); + return (struct itemdef *) NULL; +} + +/* + * def_load - load configuration table + * + * Loads the user-configured options from the default configuration file + */ + +static void +def_load(void) +{ + int i; + FILE *fp; + char buf[1024], *name, *value, *s; + + /* + * Open the configuration definitions file. + */ + if ((fp = fopen(def_fname, "r")) == NULL) { + SYSLOG((LOG_CRIT, "cannot open login definitions %s [%m]", + def_fname)); + return; + } + + /* + * Set the initialized flag. + * (do it early to prevent recursion in putdef_str()) + */ + ++def_loaded; + + /* + * Go through all of the lines in the file. + */ + while (fgets(buf, sizeof(buf), fp) != NULL) { + + /* + * Trim trailing whitespace. + */ + for (i = strlen(buf)-1 ; i >= 0 ; --i) { + if (!isspace(buf[i])) + break; + } + buf[++i] = '\0'; + + /* + * Break the line into two fields. + */ + name = buf + strspn(buf, " \t"); /* first nonwhite */ + if (*name == '\0' || *name == '#') + continue; /* comment or empty */ + + s = name + strcspn(name, " \t"); /* end of field */ + if (*s == '\0') + continue; /* only 1 field?? */ + + *s++ = '\0'; + value = s + strspn(s, " \"\t"); /* next nonwhite */ + *(value + strcspn(value, "\"")) = '\0'; + + /* + * Store the value in def_table. + */ + putdef_str(name, value); + } + (void) fclose(fp); +} + + +#ifdef CKDEFS +int +main(int argc, char **argv) +{ + int i; + char *cp; + struct itemdef *d; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + def_load (); + + for (i = 0 ; i < NUMDEFS ; ++i) { + if ((d = def_find(def_table[i].name)) == NULL) + printf(_("error - lookup '%s' failed\n"), def_table[i].name); + else + printf("%4d %-24s %s\n", i+1, d->name, d->value); + } + for (i = 1;i < argc;i++) { + if ((cp = getdef_str (argv[1])) != NULL) + printf ("%s `%s'\n", argv[1], cp); + else + printf (_("%s not found\n"), argv[1]); + } + exit(0); +} +#endif diff --git a/current/lib/getdef.h b/current/lib/getdef.h new file mode 100644 index 00000000..304e1096 --- /dev/null +++ b/current/lib/getdef.h @@ -0,0 +1,11 @@ +#ifndef _GETDEF_H +#define _GETDEF_H + +/* getdef.c */ +extern int getdef_bool(const char *); +extern long getdef_long(const char *, long); +extern int getdef_num(const char *, int); +extern char *getdef_str(const char *); +extern int putdef_str(const char *, const char *); + +#endif /* _GETDEF_H */ diff --git a/current/lib/getpass.c b/current/lib/getpass.c new file mode 100644 index 00000000..cc4b4585 --- /dev/null +++ b/current/lib/getpass.c @@ -0,0 +1,296 @@ +/* + * Copyright 1990 - 1995, Julianne Frances Haugh + * Copyright 1998, Pavel Machek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: getpass.c,v 1.10 1999/08/27 19:02:51 marekm Exp $") + +#include "defines.h" + +#include +#include + +#include "getdef.h" + +/* new code, #undef if there are any problems... */ +#define USE_SETJMP 1 + +#ifdef USE_SETJMP +#include + +static sigjmp_buf intr; /* where to jump on SIGINT */ +#endif + +static int sig_caught; +#ifdef HAVE_SIGACTION +static struct sigaction sigact; +#endif + +/*ARGSUSED*/ +static RETSIGTYPE +sig_catch(int sig) +{ + sig_caught = 1; +#ifdef USE_SETJMP + siglongjmp(intr, 1); +#endif +} + +#define MAXLEN 127 + + +static char * +readpass(FILE *ifp, FILE *ofp, int with_echo, int max_asterisks) +{ + static char input[MAXLEN + 1], asterix[MAXLEN + 1]; + static char once; + char *cp, *ap, c; + int i; + + if (max_asterisks < 0) { + /* traditional code using fgets() */ + if (fgets(input, sizeof input, ifp) != input) + return NULL; + cp = strrchr(input, '\n'); + if (cp) + *cp = '\0'; + else + input[sizeof input - 1] = '\0'; + return input; + } + if (!once) { + srandom(time(0)*getpid()); + once = 1; + } + cp = input; + ap = asterix; + while (read(fileno(ifp), &c, 1)) { + switch (c) { + case '\n': + case '\r': + goto endwhile; + case '\b': + case 127: + if (cp > input) { + cp--; + ap--; + for (i = *ap; i > 0; i--) + fputs("\b \b", ofp); + *cp = '\0'; + *ap = 0; + } else { + putc('\a', ofp); /* BEL */ + } + break; + case '\025': /* Ctrl-U = erase everything typed so far */ + if (cp == input) { + putc('\a', ofp); /* BEL */ + } else while (cp > input) { + cp--; + ap--; + for (i = *ap; i > 0; i--) + fputs("\b \b", ofp); + *cp = '\0'; + *ap = 0; + } + break; + default: + *cp++ = c; + if (with_echo) { + *ap = 1; + putc(c, ofp); + } else if (max_asterisks > 0) { + *ap = (random() % max_asterisks) + 1; + for (i = *ap; i > 0; i--) + putc('*', ofp); + } else { + *ap = 0; + } + ap++; + break; + } + fflush(ofp); + if (cp >= input + MAXLEN) { + putc('\a', ofp); /* BEL */ + break; + } + } +endwhile: + *cp = '\0'; + putc('\n', ofp); + return input; +} + +static char * +prompt_password(const char *prompt, int with_echo) +{ + static char nostring[1] = ""; + static char *return_value; + volatile int tty_opened; + static FILE *ifp, *ofp; + volatile int is_tty; +#ifdef HAVE_SIGACTION + struct sigaction old_sigact; +#else + RETSIGTYPE (*old_signal)(); +#endif + TERMIO old_modes; + int max_asterisks = getdef_num("GETPASS_ASTERISKS", -1); + + /* + * set a flag so the SIGINT signal can be re-sent if it + * is caught + */ + + sig_caught = 0; + return_value = NULL; + tty_opened = 0; + + /* + * if /dev/tty can't be opened, getpass() needs to read + * from stdin and write to stderr instead. + */ + + if (!(ifp = fopen("/dev/tty", "r+"))) { + ifp = stdin; + ofp = stderr; + } else { + ofp = ifp; + tty_opened = 1; + } + setbuf(ifp, (char *) 0); + + /* + * the current tty modes must be saved so they can be + * restored later on. echo will be turned off, except + * for the newline character + */ + + is_tty = 1; + if (GTTY(fileno(ifp), &old_modes)) { + is_tty = 0; +#if 0 /* to make getpass work with redirected stdin */ + return_value = NULL; + goto out2; +#endif + } + +#ifdef USE_SETJMP + /* + * If we get a SIGINT, sig_catch() will jump here - + * no need to press Enter after Ctrl-C. + */ + if (sigsetjmp(intr, 1)) + goto out; +#endif + +#ifdef HAVE_SIGACTION + sigact.sa_handler = sig_catch; + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = 0; + sigaction(SIGINT, &sigact, &old_sigact); +#else + old_signal = signal(SIGINT, sig_catch); +#endif + + if (is_tty) { + TERMIO new_modes = old_modes; + + if (max_asterisks < 0) + new_modes.c_lflag |= ICANON; + else + new_modes.c_lflag &= ~(ICANON); + + if (with_echo) + new_modes.c_lflag |= (ECHO | ECHOE | ECHOK); + else + new_modes.c_lflag &= ~(ECHO | ECHOE | ECHOK); + + new_modes.c_lflag |= ECHONL; + + if (STTY(fileno(ifp), &new_modes)) + goto out; + } + + /* + * the prompt is output, and the response read without + * echoing. the trailing newline must be removed. if + * the fgets() returns an error, a NULL pointer is + * returned. + */ + + if ((fputs(prompt, ofp) != EOF) && (fflush(ofp) != EOF)) + return_value = readpass(ifp, ofp, with_echo, max_asterisks); +out: + /* + * the old SIGINT handler is restored after the tty + * modes. then /dev/tty is closed if it was opened in + * the beginning. finally, if a signal was caught it + * is sent to this process for normal processing. + */ + + if (is_tty) { + if (STTY(fileno(ifp), &old_modes)) + return_value = NULL; + } + +#ifdef HAVE_SIGACTION + (void) sigaction (SIGINT, &old_sigact, NULL); +#else + (void) signal (SIGINT, old_signal); +#endif +out2: + if (tty_opened) + (void) fclose(ifp); + + if (sig_caught) { + kill(getpid(), SIGINT); + return_value = NULL; + } + if (!return_value) { + nostring[0] = '\0'; + return_value = nostring; + } + return return_value; +} + +char * +libshadow_getpass(const char *prompt) +{ + return prompt_password(prompt, 0); +} + +char * +getpass_with_echo(const char *prompt) +{ + return prompt_password(prompt, 1); +} + diff --git a/current/lib/grdbm.c b/current/lib/grdbm.c new file mode 100644 index 00000000..b08c0f58 --- /dev/null +++ b/current/lib/grdbm.c @@ -0,0 +1,211 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifdef NDBM + +#include "rcsid.h" +RCSID("$Id: grdbm.c,v 1.3 1997/12/07 23:26:52 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" + +#include +extern DBM *gr_dbm; + +#define GRP_FRAG 256 + +/* + * gr_dbm_update + * + * Updates the DBM password files, if they exist. + */ + +int +gr_dbm_update(const struct group *gr) +{ + datum key; + datum content; + char data[BUFSIZ*8]; + char grpkey[60]; + char *cp; + int len; + int i; + int cnt; + static int once; + + if (! once) { + if (! gr_dbm) + setgrent (); + + once++; + } + if (! gr_dbm) + return 0; + + len = gr_pack (gr, data); + + if (len <= GRP_FRAG) { + content.dsize = len; + content.dptr = data; + + key.dsize = strlen (gr->gr_name); + key.dptr = gr->gr_name; + if (dbm_store (gr_dbm, key, content, DBM_REPLACE)) + return 0; + + key.dsize = sizeof gr->gr_gid; + key.dptr = (char *) &gr->gr_gid; + if (dbm_store (gr_dbm, key, content, DBM_REPLACE)) + return 0; + + } else { + content.dsize = sizeof cnt; + content.dptr = (char *) &cnt; + cnt = (len + (GRP_FRAG-1)) / GRP_FRAG; + + key.dsize = strlen (gr->gr_name); + key.dptr = gr->gr_name; + if (dbm_store (gr_dbm, key, content, DBM_REPLACE)) + return 0; + + key.dsize = sizeof gr->gr_gid; + key.dptr = (char *) &gr->gr_gid; + if (dbm_store (gr_dbm, key, content, DBM_REPLACE)) + return 0; + + for (cp = data, i = 0;i < cnt;i++) { + content.dsize = len > GRP_FRAG ? GRP_FRAG:len; + len -= content.dsize; + content.dptr = cp; + cp += content.dsize; + + key.dsize = sizeof i + strlen (gr->gr_name); + key.dptr = grpkey; + memcpy (grpkey, (char *) &i, sizeof i); + strcpy (grpkey + sizeof i, gr->gr_name); + if (dbm_store (gr_dbm, key, content, DBM_REPLACE)) + return 0; + + key.dsize = sizeof i + sizeof gr->gr_gid; + key.dptr = grpkey; + memcpy (grpkey, (char *) &i, sizeof i); + memcpy (grpkey + sizeof i, (char *) &gr->gr_gid, + sizeof gr->gr_gid); + if (dbm_store (gr_dbm, key, content, DBM_REPLACE)) + return 0; + } + } + return 1; +} + +/* + * gr_dbm_remove + * + * Deletes the DBM group file entries, if they exist. + */ + +int +gr_dbm_remove(const struct group *gr) +{ + datum key; + datum content; + char grpkey[60]; + int i; + int cnt; + int errors = 0; + static int once; + + if (! once) { + if (! gr_dbm) + setgrent (); + + once++; + } + if (! gr_dbm) + return 0; + + key.dsize = strlen (gr->gr_name); + key.dptr = (char *) gr->gr_name; + content = dbm_fetch (gr_dbm, key); + if (content.dptr == 0) + ++errors; + else { + if (content.dsize == sizeof (int)) { + memcpy ((char *) &cnt, content.dptr, sizeof cnt); + + for (i = 0;i < cnt;i++) { + key.dsize = sizeof i + strlen (gr->gr_name); + key.dptr = grpkey; + memcpy (grpkey, (char *) &i, sizeof i); + strcpy (grpkey + sizeof i, gr->gr_name); + if (dbm_delete (gr_dbm, key)) + ++errors; + } + } else { + if (dbm_delete (gr_dbm, key)) + ++errors; + } + } + key.dsize = sizeof gr->gr_gid; + key.dptr = (char *) &gr->gr_gid; + content = dbm_fetch (gr_dbm, key); + if (content.dptr == 0) + ++errors; + else { + if (content.dsize == sizeof (int)) { + memcpy ((char *) &cnt, content.dptr, sizeof cnt); + + for (i = 0;i < cnt;i++) { + key.dsize = sizeof i + sizeof gr->gr_gid; + key.dptr = grpkey; + memcpy (grpkey, (char *) &i, sizeof i); + memcpy (grpkey + sizeof i, (char *) &gr->gr_gid, + sizeof gr->gr_gid); + + if (dbm_delete (gr_dbm, key)) + ++errors; + } + } else { + if (dbm_delete (gr_dbm, key)) + ++errors; + } + } + return errors ? 0:1; +} + +int +gr_dbm_present(void) +{ + return (access(GROUP_PAG_FILE, F_OK) == 0); +} +#endif diff --git a/current/lib/groupio.c b/current/lib/groupio.c new file mode 100644 index 00000000..a59faadd --- /dev/null +++ b/current/lib/groupio.c @@ -0,0 +1,184 @@ + +#include + +#include "rcsid.h" +RCSID("$Id: groupio.c,v 1.9 2000/09/02 18:40:43 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" + +#include "commonio.h" +#include "groupio.h" + +extern int putgrent(const struct group *, FILE *); +extern struct group *sgetgrent(const char *); + +struct group * +__gr_dup(const struct group *grent) +{ + struct group *gr; + int i; + + if (!(gr = (struct group *) malloc(sizeof *gr))) + return NULL; + *gr = *grent; + if (!(gr->gr_name = strdup(grent->gr_name))) + return NULL; + if (!(gr->gr_passwd = strdup(grent->gr_passwd))) + return NULL; + + for (i = 0; grent->gr_mem[i]; i++) + ; + gr->gr_mem = (char **) malloc((i + 1) * sizeof(char *)); + if (!gr->gr_mem) + return NULL; + for (i = 0; grent->gr_mem[i]; i++) { + gr->gr_mem[i] = strdup(grent->gr_mem[i]); + if (!gr->gr_mem[i]) + return NULL; + } + gr->gr_mem[i] = NULL; + return gr; +} + +static void * +group_dup(const void *ent) +{ + const struct group *gr = ent; + return __gr_dup(gr); +} + +static void +group_free(void *ent) +{ + struct group *gr = ent; + + free(gr->gr_name); + free(gr->gr_passwd); + while(*(gr->gr_mem)) { + free(*(gr->gr_mem)); + gr->gr_mem++; + } + free(gr); +} + +static const char * +group_getname(const void *ent) +{ + const struct group *gr = ent; + return gr->gr_name; +} + +static void * +group_parse(const char *line) +{ + return (void *) sgetgrent(line); +} + +static int +group_put(const void *ent, FILE *file) +{ + const struct group *gr = ent; + return (putgrent(gr, file) == -1) ? -1 : 0; +} + +static struct commonio_ops group_ops = { + group_dup, + group_free, + group_getname, + group_parse, + group_put, + fgetsx, + fputsx +}; + +static struct commonio_db group_db = { + GROUP_FILE, /* filename */ + &group_ops, /* ops */ + NULL, /* fp */ + NULL, /* head */ + NULL, /* tail */ + NULL, /* cursor */ + 0, /* changed */ + 0, /* isopen */ + 0, /* locked */ + 0 /* readonly */ +}; + +int +gr_name(const char *filename) +{ + return commonio_setname(&group_db, filename); +} + +int +gr_lock(void) +{ + return commonio_lock(&group_db); +} + +int +gr_open(int mode) +{ + return commonio_open(&group_db, mode); +} + +const struct group * +gr_locate(const char *name) +{ + return commonio_locate(&group_db, name); +} + +int +gr_update(const struct group *gr) +{ + return commonio_update(&group_db, (const void *) gr); +} + +int +gr_remove(const char *name) +{ + return commonio_remove(&group_db, name); +} + +int +gr_rewind(void) +{ + return commonio_rewind(&group_db); +} + +const struct group * +gr_next(void) +{ + return commonio_next(&group_db); +} + +int +gr_close(void) +{ + return commonio_close(&group_db); +} + +int +gr_unlock(void) +{ + return commonio_unlock(&group_db); +} + +void +__gr_set_changed(void) +{ + group_db.changed = 1; +} + +struct commonio_entry * +__gr_get_head(void) +{ + return group_db.head; +} + +void +__gr_del_entry(const struct commonio_entry *ent) +{ + commonio_del_entry(&group_db, ent); +} diff --git a/current/lib/groupio.h b/current/lib/groupio.h new file mode 100644 index 00000000..7c083cea --- /dev/null +++ b/current/lib/groupio.h @@ -0,0 +1,12 @@ +extern struct group *__gr_dup(const struct group *); +extern void __gr_set_changed(void); +extern int gr_close(void); +extern const struct group *gr_locate(const char *); +extern int gr_lock(void); +extern int gr_name(const char *); +extern const struct group *gr_next(void); +extern int gr_open(int); +extern int gr_remove(const char *); +extern int gr_rewind(void); +extern int gr_unlock(void); +extern int gr_update(const struct group *); diff --git a/current/lib/grpack.c b/current/lib/grpack.c new file mode 100644 index 00000000..9f4a1803 --- /dev/null +++ b/current/lib/grpack.c @@ -0,0 +1,95 @@ +/* + * Copyright 1990, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: grpack.c,v 1.3 1997/12/07 23:26:52 marekm Exp $") + +#include +#include + +#include "defines.h" + +int +gr_pack(const struct group *group, char *buf) +{ + char *cp; + int i; + + cp = buf; + strcpy (cp, group->gr_name); + cp += strlen (cp) + 1; + + strcpy (cp, group->gr_passwd); + cp += strlen (cp) + 1; + + memcpy (cp, (const char *) &group->gr_gid, sizeof group->gr_gid); + cp += sizeof group->gr_gid; + + for (i = 0;group->gr_mem[i];i++) { + strcpy (cp, group->gr_mem[i]); + cp += strlen (cp) + 1; + } + *cp++ = '\0'; + + return cp - buf; +} + +int +gr_unpack(char *buf, int len, struct group *group) +{ + char *org = buf; + int i; + + group->gr_name = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + group->gr_passwd = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + memcpy ((char *) &group->gr_gid, (char *) buf, sizeof group->gr_gid); + buf += sizeof group->gr_gid; + if (buf - org > len) + return -1; + + for (i = 0;*buf && i < 1024;i++) { + group->gr_mem[i] = buf; + buf += strlen (buf) + 1; + + if (buf - org > len) + return -1; + } + group->gr_mem[i] = (char *) 0; + return 0; +} diff --git a/current/lib/gsdbm.c b/current/lib/gsdbm.c new file mode 100644 index 00000000..a6da67ae --- /dev/null +++ b/current/lib/gsdbm.c @@ -0,0 +1,167 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#if defined(NDBM) && defined(SHADOWGRP) /*{*/ + +#include +#include +#include "prototypes.h" + +#include "rcsid.h" +RCSID("$Id: gsdbm.c,v 1.3 1997/12/07 23:26:53 marekm Exp $") + +#include +extern DBM *sg_dbm; + +#define GRP_FRAG 256 + +/* + * sg_dbm_update + * + * Updates the DBM password files, if they exist. + */ + +int +sg_dbm_update(const struct sgrp *sgr) +{ + datum key; + datum content; + char data[BUFSIZ*8]; + char sgrpkey[60]; + char *cp; + int len; + int i; + int cnt; + static int once; + + if (! once) { + if (! sg_dbm) + setsgent (); + + once++; + } + if (! sg_dbm) + return 0; + + len = sgr_pack (sgr, data); + + if (len <= GRP_FRAG) { + content.dsize = len; + content.dptr = data; + + key.dsize = strlen (sgr->sg_name); + key.dptr = sgr->sg_name; + if (dbm_store (sg_dbm, key, content, DBM_REPLACE)) + return 0; + } else { + content.dsize = sizeof cnt; + content.dptr = (char *) &cnt; + cnt = (len + (GRP_FRAG-1)) / GRP_FRAG; + + key.dsize = strlen (sgr->sg_name); + key.dptr = sgr->sg_name; + if (dbm_store (sg_dbm, key, content, DBM_REPLACE)) + return 0; + + for (cp = data, i = 0;i < cnt;i++) { + content.dsize = len > GRP_FRAG ? GRP_FRAG:len; + len -= content.dsize; + content.dptr = cp; + cp += content.dsize; + + key.dsize = sizeof i + strlen (sgr->sg_name); + key.dptr = sgrpkey; + memcpy (sgrpkey, (char *) &i, sizeof i); + strcpy (sgrpkey + sizeof i, sgr->sg_name); + if (dbm_store (sg_dbm, key, content, DBM_REPLACE)) + return 0; + } + } + return 1; +} + +/* + * sg_dbm_remove + * + * Deletes the DBM shadow group file entries, if they exist. + */ + +int +sg_dbm_remove(const char *name) +{ + datum key; + datum content; + char grpkey[60]; + int i; + int cnt; + int errors = 0; + static int once; + + if (! once) { + if (! sg_dbm) + setsgent (); + + once++; + } + if (! sg_dbm) + return 0; + + key.dsize = strlen (name); + key.dptr = name; + content = dbm_fetch (sg_dbm, key); + if (content.dptr == 0) + ++errors; + else { + if (content.dsize == sizeof (int)) { + memcpy ((char *) &cnt, content.dptr, sizeof cnt); + + for (i = 0;i < cnt;i++) { + key.dsize = sizeof i + strlen (name); + key.dptr = grpkey; + memcpy (grpkey, (char *) &i, sizeof i); + strcpy (grpkey + sizeof i, name); + if (dbm_delete (sg_dbm, key)) + ++errors; + } + } else { + if (dbm_delete (sg_dbm, key)) + ++errors; + } + } + return errors ? 0:1; +} + +int +sg_dbm_present(void) +{ + return (access(SGROUP_PAG_FILE, F_OK) == 0); +} +#endif /*} SHADOWGRP && NDBM */ diff --git a/current/lib/gshadow.c b/current/lib/gshadow.c new file mode 100644 index 00000000..8de925b8 --- /dev/null +++ b/current/lib/gshadow.c @@ -0,0 +1,528 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +/* Newer versions of Linux libc already have shadow support. */ +#if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP) /*{*/ + +#include "rcsid.h" +RCSID("$Id: gshadow.c,v 1.6 1998/04/02 21:51:43 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" + +#ifdef NDBM +#include +#include +DBM *sg_dbm; +int sg_dbm_mode = -1; +static int dbmopened; +static int dbmerror; +#endif + +#define MAXMEM 1024 + +static FILE *shadow; +static char sgrbuf[BUFSIZ*4]; +static char *members[MAXMEM+1]; +static char *admins[MAXMEM+1]; +static struct sgrp sgroup; + +extern char *fgetsx(); +extern int fputsx(); + +#define FIELDS 4 + +#ifdef USE_NIS +static int nis_used; +static int nis_ignore; +static enum { native, start, middle, native2 } nis_state; +static int nis_bound; +static char *nis_domain; +static char *nis_key; +static int nis_keylen; +static char *nis_val; +static int nis_vallen; +#define IS_NISCHAR(c) ((c)=='+') +#endif + +#ifdef USE_NIS + +/* + * __setsgNIS - turn on or off NIS searches + */ + +void +__setsgNIS(int flag) +{ + nis_ignore = ! flag; + + if (nis_ignore) + nis_used = 0; +} + +/* + * bind_nis - bind to NIS server + */ + +static int +bind_nis(void) +{ + if (yp_get_default_domain (&nis_domain)) + return -1; + + nis_bound = 1; + return 0; +} +#endif + +static char ** +list(char *s, char **l) +{ + int nmembers = 0; + + while (s && *s) { + l[nmembers++] = s; + if ((s = strchr (s, ','))) + *s++ = '\0'; + } + l[nmembers] = (char *) 0; + return l; +} + +void +setsgent(void) +{ +#ifdef NDBM + int mode; +#endif /* NDBM */ + +#ifdef USE_NIS + nis_state = native; +#endif + if (shadow) + rewind (shadow); + else + shadow = fopen(SGROUP_FILE, "r"); + + /* + * Attempt to open the DBM files if they have never been opened + * and an error has never been returned. + */ + +#ifdef NDBM + if (! dbmerror && ! dbmopened) { + char dbmfiles[BUFSIZ]; + + strcpy (dbmfiles, SGROUP_PAG_FILE); + + if (sg_dbm_mode == -1) + mode = O_RDWR; + else + mode = (sg_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY; + + if (access(dbmfiles, F_OK) || + (! (sg_dbm = dbm_open(SGROUP_FILE, mode, 0)))) + dbmerror = 1; + else + dbmopened = 1; + } +#endif /* NDBM */ +} + +void +endsgent(void) +{ + if (shadow) + (void) fclose (shadow); + + shadow = (FILE *) 0; +#ifdef NDBM + if (dbmopened && sg_dbm) { + dbm_close (sg_dbm); + dbmopened = 0; + sg_dbm = 0; + } +#endif +} + +struct sgrp * +sgetsgent(const char *string) +{ + char *fields[FIELDS]; + char *cp; + int i; + + strncpy (sgrbuf, string, (int) sizeof sgrbuf - 1); + sgrbuf[sizeof sgrbuf - 1] = '\0'; + + if ((cp = strrchr (sgrbuf, '\n'))) + *cp = '\0'; + + /* + * There should be exactly 4 colon separated fields. Find + * all 4 of them and save the starting addresses in fields[]. + */ + + for (cp = sgrbuf, i = 0;i < FIELDS && cp;i++) { + fields[i] = cp; + if ((cp = strchr (cp, ':'))) + *cp++ = '\0'; + } + + /* + * If there was an extra field somehow, or perhaps not enough, + * the line is invalid. + */ + + if (cp || i != FIELDS) +#ifdef USE_NIS + if (! IS_NISCHAR (fields[0][0])) + return 0; + else + nis_used = 1; +#else + return 0; +#endif + + sgroup.sg_name = fields[0]; + sgroup.sg_passwd = fields[1]; + sgroup.sg_adm = list (fields[2], admins); + sgroup.sg_mem = list (fields[3], members); + + return &sgroup; +} + +/* + * fgetsgent - convert next line in stream to (struct sgrp) + * + * fgetsgent() reads the next line from the provided stream and + * converts it to a (struct sgrp). NULL is returned on EOF. + */ + +struct sgrp * +fgetsgent(FILE *fp) +{ + char buf[sizeof sgrbuf]; + char *cp; + + if (! fp) + return (0); + +#ifdef USE_NIS + while (fgetsx (buf, sizeof buf, fp) != (char *) 0) +#else + if (fgetsx (buf, sizeof buf, fp) != (char *) 0) +#endif + { + if ((cp = strchr (buf, '\n'))) + *cp = '\0'; +#ifdef USE_NIS + if (nis_ignore && IS_NISCHAR (buf[0])) + continue; +#endif + return (sgetsgent (buf)); + } + return 0; +} + +/* + * getsgent - get a single shadow group entry + */ + +struct sgrp * +getsgent(void) +{ +#ifdef USE_NIS + int nis_1_group = 0; + struct sgrp *val; + char buf[BUFSIZ]; +#endif + if (! shadow) + setsgent (); + +#ifdef USE_NIS +again: + /* + * See if we are reading from the local file. + */ + + if (nis_state == native || nis_state == native2) { + + /* + * Get the next entry from the shadow group file. Return + * NULL right away if there is none. + */ + + if (! (val = fgetsgent (shadow))) + return 0; + + /* + * If this entry began with a NIS escape character, we have + * to see if this is just a single group, or if the entire + * map is being asked for. + */ + + if (IS_NISCHAR (val->sg_name[0])) { + if (val->sg_name[1]) + nis_1_group = 1; + else + nis_state = start; + } + + /* + * If this isn't a NIS group and this isn't an escape to go + * use a NIS map, it must be a regular local group. + */ + + if (nis_1_group == 0 && nis_state != start) + return val; + + /* + * If this is an escape to use an NIS map, switch over to + * that bunch of code. + */ + + if (nis_state == start) + goto again; + + /* + * NEEDSWORK. Here we substitute pieces-parts of this entry. + */ + + return 0; + } else { + if (nis_bound == 0) { + if (bind_nis ()) { + nis_state = native2; + goto again; + } + } + if (nis_state == start) { + if (yp_first (nis_domain, "gshadow.byname", &nis_key, + &nis_keylen, &nis_val, &nis_vallen)) { + nis_state = native2; + goto again; + } + nis_state = middle; + } else if (nis_state == middle) { + if (yp_next (nis_domain, "gshadow.byname", nis_key, + nis_keylen, &nis_key, &nis_keylen, + &nis_val, &nis_vallen)) { + nis_state = native2; + goto again; + } + } + return sgetsgent (nis_val); + } +#else + return (fgetsgent (shadow)); +#endif +} + +/* + * getsgnam - get a shadow group entry by name + */ + +struct sgrp * +getsgnam(const char *name) +{ + struct sgrp *sgrp; +#ifdef NDBM + datum key; + datum content; +#endif +#ifdef USE_NIS + char buf[BUFSIZ]; + static char save_name[16]; + int nis_disabled = 0; +#endif + + setsgent (); + +#ifdef NDBM + + /* + * If the DBM file are now open, create a key for this group and + * try to fetch the entry from the database. A matching record + * will be unpacked into a static structure and returned to + * the user. + */ + + if (dbmopened) { + key.dsize = strlen (name); + key.dptr = (void *) name; + + content = dbm_fetch (sg_dbm, key); + if (content.dptr != 0) { + memcpy (sgrbuf, content.dptr, content.dsize); + sgroup.sg_mem = members; + sgroup.sg_adm = admins; + sgr_unpack (sgrbuf, content.dsize, &sgroup); + return &sgroup; + } + } +#endif +#ifdef USE_NIS + if (nis_used) { +again: + + /* + * Search the gshadow.byname map for this group. + */ + + if (! nis_bound) + bind_nis (); + + if (nis_bound) { + char *cp; + + if (yp_match (nis_domain, "gshadow.byname", name, + strlen (name), &nis_val, &nis_vallen) == 0) { + if (cp = strchr (nis_val, '\n')) + *cp = '\0'; + + nis_state = middle; + if (sgrp = sgetsgent (nis_val)) { + strcpy (save_name, sgrp->sg_name); + nis_key = save_name; + nis_keylen = strlen (save_name); + } + return sgrp; + } + } + nis_state = native2; + } +#endif +#ifdef USE_NIS + if (nis_used) { + nis_ignore++; + nis_disabled++; + } +#endif + while ((sgrp = getsgent ()) != (struct sgrp *) 0) { + if (strcmp (name, sgrp->sg_name) == 0) + break; + } +#ifdef USE_NIS + nis_ignore--; +#endif + if (sgrp) + return sgrp; + return (0); +} + +/* + * putsgent - output shadow group entry in text form + * + * putsgent() converts the contents of a (struct sgrp) to text and + * writes the result to the given stream. This is the logical + * opposite of fgetsgent. + */ + +int +putsgent(const struct sgrp *sgrp, FILE *fp) +{ + char *buf, *cp; + int i; + size_t size; + + if (! fp || ! sgrp) + return -1; + + /* calculate the required buffer size */ + size = strlen(sgrp->sg_name) + strlen(sgrp->sg_passwd) + 10; + for (i = 0; sgrp->sg_adm && sgrp->sg_adm[i]; i++) + size += strlen(sgrp->sg_adm[i]) + 1; + for (i = 0; sgrp->sg_mem && sgrp->sg_mem[i]; i++) + size += strlen(sgrp->sg_mem[i]) + 1; + + buf = malloc(size); + if (!buf) + return -1; + cp = buf; + + /* + * Copy the group name and passwd. + */ + + strcpy (cp, sgrp->sg_name); + cp += strlen (cp); + *cp++ = ':'; + + strcpy (cp, sgrp->sg_passwd); + cp += strlen (cp); + *cp++ = ':'; + + /* + * Copy the administrators, separating each from the other + * with a ",". + */ + + for (i = 0;sgrp->sg_adm[i];i++) { + if (i > 0) + *cp++ = ','; + + strcpy (cp, sgrp->sg_adm[i]); + cp += strlen (cp); + } + *cp++ = ':'; + + /* + * Now do likewise with the group members. + */ + + for (i = 0;sgrp->sg_mem[i];i++) { + if (i > 0) + *cp++ = ','; + + strcpy (cp, sgrp->sg_mem[i]); + cp += strlen (cp); + } + *cp++ = '\n'; + *cp = '\0'; + + /* + * Output using the function which understands the line + * continuation conventions. + */ + + if (fputsx(buf, fp) == EOF) { + free(buf); + return -1; + } + + free(buf); + return 0; +} +#else +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /*} SHADOWGRP */ diff --git a/current/lib/gshadow_.h b/current/lib/gshadow_.h new file mode 100644 index 00000000..b1cac557 --- /dev/null +++ b/current/lib/gshadow_.h @@ -0,0 +1,71 @@ +/* + * Copyright 1988 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + * + * $Id: gshadow_.h,v 1.2 1997/05/01 23:14:41 marekm Exp $ + */ + +#ifndef _H_GSHADOW +#define _H_GSHADOW + +/* + * Shadow group security file structure + */ + +struct sgrp { + char *sg_name; /* group name */ + char *sg_passwd; /* group password */ + char **sg_adm; /* group administator list */ + char **sg_mem; /* group membership list */ +}; + +/* + * Shadow group security file functions. + */ + +#include /* for FILE */ + +#if __STDC__ +struct sgrp *getsgent (void); +struct sgrp *getsgnam (const char *); +struct sgrp *sgetsgent (const char *); +struct sgrp *fgetsgent (FILE *); +void setsgent (void); +void endsgent (void); +int putsgent (const struct sgrp *, FILE *); +#else +struct sgrp *getsgent (); +struct sgrp *getsgnam (); +struct sgrp *sgetsgent (); +struct sgrp *fgetsgent (); +void setsgent (); +void endsgent (); +int putsgent (); +#endif + +#define GSHADOW "/etc/gshadow" +#endif /* ifndef _H_GSHADOW */ diff --git a/current/lib/gspack.c b/current/lib/gspack.c new file mode 100644 index 00000000..fe76060b --- /dev/null +++ b/current/lib/gspack.c @@ -0,0 +1,150 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifdef SHADOWGRP /*{*/ + +#include "rcsid.h" +RCSID("$Id: gspack.c,v 1.3 1997/12/07 23:26:53 marekm Exp $") + +#include +#include "defines.h" + +/* + * sgr_pack - convert a shadow group structure to a packed + * shadow group record + * + * sgr_pack takes the shadow group structure and packs + * the components in a record. this record will be + * unpacked later by sgr_unpack. + */ + +int +sgr_pack(const struct sgrp *sgrp, char *buf) +{ + char *cp; + int i; + + /* + * The name and password are both easy - append each string + * to the buffer. These are always the first two strings + * in a record. + */ + + cp = buf; + strcpy (cp, sgrp->sg_name); + cp += strlen (cp) + 1; + + strcpy (cp, sgrp->sg_passwd); + cp += strlen (cp) + 1; + + /* + * The arrays of administrators and members are slightly + * harder. Each element is appended as a string, with a + * final '\0' appended to serve as a blank string. The + * number of elements is not known in advance, so the + * entire collection of administrators must be scanned to + * find the start of the members. + */ + + for (i = 0;sgrp->sg_adm[i];i++) { + strcpy (cp, sgrp->sg_adm[i]); + cp += strlen (cp) + 1; + } + *cp++ = '\0'; + + for (i = 0;sgrp->sg_mem[i];i++) { + strcpy (cp, sgrp->sg_mem[i]); + cp += strlen (cp) + 1; + } + *cp++ = '\0'; + + return cp - buf; +} + +/* + * sgr_unpack - convert a packed shadow group record to an + * unpacked record + * + * sgr_unpack converts a record which was packed by sgr_pack + * into the normal shadow group structure format. + */ + +int +sgr_unpack(char *buf, int len, struct sgrp *sgrp) +{ + char *org = buf; + int i; + + /* + * The name and password are both easy - they are the first + * two strings in the record. + */ + + sgrp->sg_name = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + sgrp->sg_passwd = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + /* + * The administrators and members are slightly more difficult. + * The arrays are lists of strings. Each list is terminated + * by a string of length zero. This string is detected by + * looking for an initial character of '\0'. + */ + + for (i = 0;*buf && i < 1024;i++) { + sgrp->sg_adm[i] = buf; + buf += strlen (buf) + 1; + + if (buf - org > len) + return -1; + } + sgrp->sg_adm[i] = (char *) 0; + if (! *buf) + buf++; + + for (i = 0;*buf && i < 1024;i++) { + sgrp->sg_mem[i] = buf; + buf += strlen (buf) + 1; + + if (buf - org > len) + return -1; + } + sgrp->sg_mem[i] = (char *) 0; + + return 0; +} +#endif /*}*/ diff --git a/current/lib/lastlog_.h b/current/lib/lastlog_.h new file mode 100644 index 00000000..8d459de6 --- /dev/null +++ b/current/lib/lastlog_.h @@ -0,0 +1,50 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * lastlog.h - structure of lastlog file + * + * $Id: lastlog_.h,v 1.2 1997/05/01 23:14:42 marekm Exp $ + * + * This file defines a lastlog file structure which should be sufficient + * to hold the information required by login. It should only be used if + * there is no real lastlog.h file. + */ + +#ifndef __LASTLOG_H +#define __LASTLOG_H + +struct lastlog { + time_t ll_time; + char ll_line[12]; + char ll_host[16]; +}; + +#define HAVE_LL_HOST +#endif /* _LASTLOG_H */ diff --git a/current/lib/lockpw.c b/current/lib/lockpw.c new file mode 100644 index 00000000..879dc983 --- /dev/null +++ b/current/lib/lockpw.c @@ -0,0 +1,114 @@ +/* + * Copyright 1992, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifndef HAVE_LCKPWDF + +#include "rcsid.h" +RCSID("$Id: lockpw.c,v 1.4 1998/01/29 23:22:28 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" + +#include "pwio.h" +#ifdef SHADOWPWD +#include "shadowio.h" +#endif + +/* + * lckpwdf - lock the password files + */ + +int +lckpwdf(void) +{ + int i; + + /* + * We have 15 seconds to lock the whole mess + */ + + for (i = 0;i < 15;i++) + if (pw_lock ()) + break; + else + sleep (1); + + /* + * Did we run out of time? + */ + + if (i == 15) + return -1; + + /* + * Nope, use any remaining time to lock the shadow password + * file. + */ + + for (;i < 15;i++) + if (spw_lock ()) + break; + else + sleep (1); + + /* + * Out of time yet? + */ + + if (i == 15) { + pw_unlock (); + return -1; + } + + /* + * Nope - and both files are now locked. + */ + + return 0; +} + +/* + * ulckpwdf - unlock the password files + */ + +int +ulckpwdf(void) +{ + + /* + * Unlock both files. + */ + + return (pw_unlock () && spw_unlock ()) ? 0:-1; +} +#else +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif diff --git a/current/lib/md5.c b/current/lib/md5.c new file mode 100644 index 00000000..766fafe8 --- /dev/null +++ b/current/lib/md5.c @@ -0,0 +1,261 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ +#include + +#ifdef MD5_CRYPT +#include /* for memcpy() */ +#include "md5.h" + +#ifndef HIGHFIRST +#define byteReverse(buf, len) /* Nothing */ +#else +void byteReverse(unsigned char *buf, unsigned longs); + +#ifndef ASM_MD5 +/* + * Note: this code is harmless on little-endian machines. + */ +void +byteReverse(unsigned char *buf, unsigned longs) +{ + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); +} +#endif +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32 *) ctx->in)[14] = ctx->bits[0]; + ((uint32 *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +MD5Transform(uint32 buf[4], uint32 const in[16]) +{ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif +#endif /* MD5_CRYPT */ diff --git a/current/lib/md5.h b/current/lib/md5.h new file mode 100644 index 00000000..e264f686 --- /dev/null +++ b/current/lib/md5.h @@ -0,0 +1,27 @@ +#ifndef MD5_H +#define MD5_H + +#ifdef __alpha +typedef unsigned int uint32; +#else +typedef unsigned long uint32; +#endif + +struct MD5Context { + uint32 buf[4]; + uint32 bits[2]; + unsigned char in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); +void MD5Transform(uint32 buf[4], uint32 const in[16]); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct MD5Context MD5_CTX; + +#endif /* !MD5_H */ diff --git a/current/lib/md5crypt.c b/current/lib/md5crypt.c new file mode 100644 index 00000000..e1595aa2 --- /dev/null +++ b/current/lib/md5crypt.c @@ -0,0 +1,151 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* + * Ported from FreeBSD to Linux, only minimal changes. --marekm + */ + +#include + +#ifdef MD5_CRYPT + +#include "rcsid.h" +RCSID("$Id: md5crypt.c,v 1.3 1998/01/29 23:22:29 marekm Exp $") + +#include +/* #include */ +#include +#include "md5.h" + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static void +to64(char *s, unsigned long v, int n) +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +/* + * UNIX password + * + * Use MD5 for what it is best at... + */ + +char * +libshadow_md5_crypt(const char *pw, const char *salt) +{ + static char *magic = "$1$"; /* + * This string is magic for + * this algorithm. Having + * it this way, we can get + * get better later on + */ + static char passwd[120], *p; + static const char *sp,*ep; + unsigned char final[16]; + int sl,pl,i,j; + MD5_CTX ctx,ctx1; + unsigned long l; + + /* Refine the Salt first */ + sp = salt; + + /* If it starts with the magic string, then skip that */ + if(!strncmp(sp,magic,strlen(magic))) + sp += strlen(magic); + + /* It stops at the first '$', max 8 chars */ + for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) + continue; + + /* get the length of the true salt */ + sl = ep - sp; + + MD5Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5Update(&ctx,pw,strlen(pw)); + + /* Then our magic string */ + MD5Update(&ctx,magic,strlen(magic)); + + /* Then the raw salt */ + MD5Update(&ctx,sp,sl); + + /* Then just as many characters of the MD5(pw,salt,pw) */ + MD5Init(&ctx1); + MD5Update(&ctx1,pw,strlen(pw)); + MD5Update(&ctx1,sp,sl); + MD5Update(&ctx1,pw,strlen(pw)); + MD5Final(final,&ctx1); + for(pl = strlen(pw); pl > 0; pl -= 16) + MD5Update(&ctx,final,pl>16 ? 16 : pl); + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + /* Then something really weird... */ + for (j=0,i = strlen(pw); i ; i >>= 1) + if(i&1) + MD5Update(&ctx, final+j, 1); + else + MD5Update(&ctx, pw+j, 1); + + /* Now make the output string */ + strcpy(passwd,magic); + strncat(passwd,sp,sl); + strcat(passwd,"$"); + + MD5Final(final,&ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for(i=0;i<1000;i++) { + MD5Init(&ctx1); + if(i & 1) + MD5Update(&ctx1,pw,strlen(pw)); + else + MD5Update(&ctx1,final,16); + + if(i % 3) + MD5Update(&ctx1,sp,sl); + + if(i % 7) + MD5Update(&ctx1,pw,strlen(pw)); + + if(i & 1) + MD5Update(&ctx1,final,16); + else + MD5Update(&ctx1,pw,strlen(pw)); + MD5Final(final,&ctx1); + } + + p = passwd + strlen(passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; + l = final[11] ; to64(p,l,2); p += 2; + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + return passwd; +} +#endif diff --git a/current/lib/mkdir.c b/current/lib/mkdir.c new file mode 100644 index 00000000..9e26b22a --- /dev/null +++ b/current/lib/mkdir.c @@ -0,0 +1,60 @@ +/* + * Copyright 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include +#include + +#include "rcsid.h" +RCSID("$Id: mkdir.c,v 1.4 1998/01/29 23:22:30 marekm Exp $") + +/* + * mkdir - create a directory + * + * mkdir is provided for systems which do not include the mkdir() + * system call. + */ + +int +mkdir(const char *dir, int mode) +{ + int status; + + if (fork()) { + while (wait(&status) != -1) + ; + + return status >> 8; + } + close(2); + open("/dev/null", O_WRONLY); + umask(0777 & ~ mode); + execl("/bin/mkdir", "mkdir", dir, 0); + _exit(127); + /*NOTREACHED*/ +} diff --git a/current/lib/pam_defs.h b/current/lib/pam_defs.h new file mode 100644 index 00000000..58d25c5c --- /dev/null +++ b/current/lib/pam_defs.h @@ -0,0 +1,21 @@ +#include +#include + +/* compatibility with different versions of Linux-PAM */ +#ifndef PAM_ESTABLISH_CRED +#define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH +#endif +#ifndef PAM_DELETE_CRED +#define PAM_DELETE_CRED PAM_CRED_DELETE +#endif +#ifndef PAM_NEW_AUTHTOK_REQD +#define PAM_NEW_AUTHTOK_REQD PAM_AUTHTOKEN_REQD +#endif +#ifndef PAM_DATA_SILENT +#define PAM_DATA_SILENT 0 +#endif +#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */ +#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err) +#else +#define PAM_STRERROR(pamh, err) pam_strerror(err) +#endif diff --git a/current/lib/port.c b/current/lib/port.c new file mode 100644 index 00000000..6ffb9125 --- /dev/null +++ b/current/lib/port.c @@ -0,0 +1,439 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: port.c,v 1.3 1997/12/07 23:26:54 marekm Exp $") + +#include +#include +#include +#include "defines.h" +#include "port.h" + +extern int errno; + +static FILE *ports; + +/* + * portcmp - compare the name of a port to a /etc/porttime entry + * + * portcmp works like strcmp, except that if the last character + * in a failing match is a '*', the match is considered to have + * passed. The "*" match is suppressed whenever the port is "SU", + * which is the token the "su" command uses to validate access. + * A match returns 0, failure returns non-zero. + */ + +static int +portcmp(const char *pattern, const char *port) +{ + const char *orig = port; + + while (*pattern && *pattern == *port) + pattern++, port++; + + if (*pattern == 0 && *port == 0) + return 0; + if (orig[0] == 'S' && orig[1] == 'U' && orig[2] == '\0') + return 1; + + return *pattern == '*' ? 0:1; +} + +/* + * setportent - open /etc/porttime file or rewind + * + * the /etc/porttime file is rewound if already open, or + * opened for reading. + */ + +static void +setportent(void) +{ + if (ports) + rewind (ports); + else + ports = fopen (PORTS, "r"); +} + +/* + * endportent - close the /etc/porttime file + * + * the /etc/porttime file is closed and the ports variable set + * to NULL to indicate that the /etc/porttime file is no longer + * open. + */ + +static void +endportent(void) +{ + if (ports) + fclose (ports); + + ports = (FILE *) 0; +} + +/* + * getportent - read a single entry from /etc/porttime + * + * the next line in /etc/porttime is converted to a (struct port) + * and a pointer to a static (struct port) is returned to the + * invoker. NULL is returned on either EOF or error. errno is + * set to EINVAL on error to distinguish the two conditions. + */ + +static struct port * +getportent(void) +{ + static struct port port; /* static struct to point to */ + static char buf[BUFSIZ]; /* some space for stuff */ + static char *ttys[PORT_TTY+1]; /* some pointers to tty names */ + static char *users[PORT_IDS+1]; /* some pointers to user ids */ + static struct pt_time ptimes[PORT_TIMES+1]; /* time ranges */ + char *cp; /* pointer into line */ + int dtime; /* scratch time of day */ + int i, j; + int saveerr = errno; /* errno value on entry */ + + /* + * If the ports file is not open, open the file. Do not rewind + * since we want to search from the beginning each time. + */ + + if (! ports) + setportent (); + + if (! ports) { + errno = saveerr; + return 0; + } + + /* + * Common point for beginning a new line - + * + * - read a line, and NUL terminate + * - skip lines which begin with '#' + * - parse off the tty names + * - parse off a list of user names + * - parse off a list of days and times + */ + +again: + + /* + * Get the next line and remove the last character, which + * is a '\n'. Lines which begin with '#' are all ignored. + */ + + if (fgets (buf, sizeof buf, ports) == 0) { + errno = saveerr; + return 0; + } + if (buf[0] == '#') + goto again; + + /* + * Get the name of the TTY device. It is the first colon + * separated field, and is the name of the TTY with no + * leading "/dev". The entry '*' is used to specify all + * TTY devices. + */ + + buf[strlen (buf) - 1] = 0; + + port.pt_names = ttys; + for (cp = buf, j = 0;j < PORT_TTY;j++) { + port.pt_names[j] = cp; + while (*cp && *cp != ':' && *cp != ',') + cp++; + + if (! *cp) + goto again; /* line format error */ + + if (*cp == ':') /* end of tty name list */ + break; + + if (*cp == ',') /* end of current tty name */ + *cp++ = '\0'; + } + *cp++ = 0; + port.pt_names[j + 1] = (char *) 0; + + /* + * Get the list of user names. It is the second colon + * separated field, and is a comma separated list of user + * names. The entry '*' is used to specify all usernames. + * The last entry in the list is a (char *) 0 pointer. + */ + + if (*cp != ':') { + port.pt_users = users; + port.pt_users[0] = cp; + + for (j = 1;*cp != ':';cp++) { + if (*cp == ',' && j < PORT_IDS) { + *cp++ = 0; + port.pt_users[j++] = cp; + } + } + port.pt_users[j] = 0; + } else + port.pt_users = 0; + + if (*cp != ':') + goto again; + + *cp++ = 0; + + /* + * Get the list of valid times. The times field is the third + * colon separated field and is a list of days of the week and + * times during which this port may be used by this user. The + * valid days are 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', and 'Sa'. + * + * In addition, the value 'Al' represents all 7 days, and 'Wk' + * represents the 5 weekdays. + * + * Times are given as HHMM-HHMM. The ending time may be before + * the starting time. Days are presumed to wrap at 0000. + */ + + if (*cp == '\0') { + port.pt_times = 0; + return &port; + } + + port.pt_times = ptimes; + + /* + * Get the next comma separated entry + */ + + for (j = 0;*cp && j < PORT_TIMES;j++) { + + /* + * Start off with no days of the week + */ + + port.pt_times[j].t_days = 0; + + /* + * Check each two letter sequence to see if it is + * one of the abbreviations for the days of the + * week or the other two values. + */ + + for (i = 0;cp[i] && cp[i + 1] && isalpha (cp[i]);i += 2) { + switch ((cp[i] << 8) | (cp[i + 1])) { + case ('S' << 8) | 'u': + port.pt_times[j].t_days |= 01; + break; + case ('M' << 8) | 'o': + port.pt_times[j].t_days |= 02; + break; + case ('T' << 8) | 'u': + port.pt_times[j].t_days |= 04; + break; + case ('W' << 8) | 'e': + port.pt_times[j].t_days |= 010; + break; + case ('T' << 8) | 'h': + port.pt_times[j].t_days |= 020; + break; + case ('F' << 8) | 'r': + port.pt_times[j].t_days |= 040; + break; + case ('S' << 8) | 'a': + port.pt_times[j].t_days |= 0100; + break; + case ('W' << 8) | 'k': + port.pt_times[j].t_days |= 076; + break; + case ('A' << 8) | 'l': + port.pt_times[j].t_days |= 0177; + break; + default: + errno = EINVAL; + return 0; + } + } + + /* + * The default is 'Al' if no days were seen. + */ + + if (i == 0) + port.pt_times[j].t_days = 0177; + + /* + * The start and end times are separated from each + * other by a '-'. The times are four digit numbers + * representing the times of day. + */ + + for (dtime = 0;cp[i] && isdigit (cp[i]);i++) + dtime = dtime * 10 + cp[i] - '0'; + + if (cp[i] != '-' || dtime > 2400 || dtime % 100 > 59) + goto again; + port.pt_times[j].t_start = dtime; + cp = cp + i + 1; + + for (dtime = i = 0;cp[i] && isdigit (cp[i]);i++) + dtime = dtime * 10 + cp[i] - '0'; + + if ((cp[i] != ',' && cp[i]) || + dtime > 2400 || dtime % 100 > 59) + goto again; + + port.pt_times[j].t_end = dtime; + cp = cp + i + 1; + } + + /* + * The end of the list is indicated by a pair of -1's for the + * start and end times. + */ + + port.pt_times[j].t_start = port.pt_times[j].t_end = -1; + + return &port; +} + +/* + * getttyuser - get ports information for user and tty + * + * getttyuser() searches the ports file for an entry with a TTY + * and user field both of which match the supplied TTY and + * user name. The file is searched from the beginning, so the + * entries are treated as an ordered list. + */ + +static struct port * +getttyuser(const char *tty, const char *user) +{ + int i, j; + struct port *port; + + setportent (); + + while ((port = getportent ())) { + if (port->pt_names == 0 || port->pt_users == 0) + continue; + + for (i = 0;port->pt_names[i];i++) + if (portcmp (port->pt_names[i], tty) == 0) + break; + + if (port->pt_names[i] == 0) + continue; + + for (j = 0;port->pt_users[j];j++) + if (strcmp (user, port->pt_users[j]) == 0 || + strcmp (port->pt_users[j], "*") == 0) + break; + + if (port->pt_users[j] != 0) + break; + } + endportent (); + return port; +} + +/* + * isttytime - tell if a given user may login at a particular time + * + * isttytime searches the ports file for an entry which matches + * the user name and TTY given. + */ + +int +isttytime(const char *id, const char *port, time_t when) +{ + int i; + int dtime; + struct port *pp; + struct tm *tm; + + /* + * Try to find a matching entry for this user. Default to + * letting the user in - there are pleny of ways to have an + * entry to match all users. + */ + + if (! (pp = getttyuser (port, id))) + return 1; + + /* + * The entry is there, but has no time entries - don't + * ever let them login. + */ + + if (pp->pt_times == 0) + return 0; + + /* + * The current time is converted to HHMM format for + * comparision against the time values in the TTY entry. + */ + + tm = localtime (&when); + dtime = tm->tm_hour * 100 + tm->tm_min; + + /* + * Each time entry is compared against the current + * time. For entries with the start after the end time, + * the comparision is made so that the time is between + * midnight and either the start or end time. + */ + + for (i = 0;pp->pt_times[i].t_start != -1;i++) { + if (! (pp->pt_times[i].t_days & PORT_DAY(tm->tm_wday))) + continue; + + if (pp->pt_times[i].t_start <= pp->pt_times[i].t_end) { + if (dtime >= pp->pt_times[i].t_start && + dtime <= pp->pt_times[i].t_end) + return 1; + } else { + if (dtime >= pp->pt_times[i].t_start || + dtime <= pp->pt_times[i].t_end) + return 1; + } + } + + /* + * No matching time entry was found, user shouldn't + * be let in right now. + */ + + return 0; +} diff --git a/current/lib/port.h b/current/lib/port.h new file mode 100644 index 00000000..a02d6728 --- /dev/null +++ b/current/lib/port.h @@ -0,0 +1,81 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * port.h - structure of /etc/porttime + * + * $Id: port.h,v 1.2 1997/05/01 23:14:43 marekm Exp $ + * + * Each entry in /etc/porttime consists of a TTY device + * name or "*" to indicate all TTY devices, followed by + * a list of 1 or more user IDs or "*" to indicate all + * user names, followed by a list of zero or more valid + * login times. Login time entries consist of zero or + * more day names (Su, Mo, Tu, We, Th, Fr, Sa, Wk, Al) + * followed by a pair of time values in HHMM format + * separated by a "-". + */ + +/* + * PORTS - Name of system port access time file. + * PORT_IDS - Allowable number of IDs per entry. + * PORT_TTY - Allowable number of TTYs per entry. + * PORT_TIMES - Allowable number of time entries per entry. + * PORT_DAY - Day of the week to a bit value (0 = Sunday). + */ + +#define PORTS "/etc/porttime" +#define PORT_IDS 64 +#define PORT_TTY 64 +#define PORT_TIMES 24 +#define PORT_DAY(day) (1<<(day)) + +/* + * pt_names - pointer to array of device names in /dev/ + * pt_users - pointer to array of applicable user IDs. + * pt_times - pointer to list of allowable time periods. + */ + +struct port { + char **pt_names; + char **pt_users; + struct pt_time *pt_times; +}; + +/* + * t_days - bit array for each day of the week (0 = Sunday) + * t_start - starting time for this entry + * t_end - ending time for this entry + */ + +struct pt_time { + short t_days; + short t_start; + short t_end; +}; diff --git a/current/lib/prototypes.h b/current/lib/prototypes.h new file mode 100644 index 00000000..20436dcf --- /dev/null +++ b/current/lib/prototypes.h @@ -0,0 +1,228 @@ +/* + * prototypes.h + * + * Missing function prototypes + * + * Juha Virtanen, ; November 1995 + */ +/* + * $Id: prototypes.h,v 1.14 2000/08/26 18:27:17 marekm Exp $ + * + * Added a macro to work around ancient (non-ANSI) compilers, just in case + * someone ever tries to compile this with SunOS cc... --marekm + */ + +#ifndef _PROTOTYPES_H +#define _PROTOTYPES_H + +#include +#include +#include +#include + +#include "defines.h" + +/* addgrps.c */ +extern int add_groups(const char *); +extern void add_cons_grps(void); + +/* age.c */ +#ifdef SHADOWPWD +extern void agecheck(const struct passwd *, const struct spwd *); +extern int expire(const struct passwd *, const struct spwd *); +extern int isexpired(const struct passwd *, const struct spwd *); +#else +extern void agecheck(const struct passwd *); +extern int expire(const struct passwd *); +extern int isexpired(const struct passwd *); +#endif + +/* basename() renamed to Basename() to avoid libc name space confusion */ +/* basename.c */ +extern char *Basename(char *str); + +/* chkshell.c */ +extern int check_shell(const char *); + +/* chowndir.c */ +extern int chown_tree(const char *, uid_t, uid_t, gid_t, gid_t); + +/* chowntty.c */ +extern void chown_tty(const char *, const struct passwd *); + +/* console.c */ +extern int console(const char *); +extern int is_listed(const char *, const char *, int); + +/* copydir.c */ +extern int copy_tree(const char *, const char *, uid_t, gid_t); +extern int remove_tree(const char *); + +/* encrypt.c */ +extern char *pw_encrypt(const char *, const char *); + +/* entry.c */ +extern void pw_entry(const char *, struct passwd *); + +/* env.c */ +extern void addenv(const char *, const char *); +extern void initenv(void); +extern void set_env(int, char * const *); +extern void sanitize_env(void); + +/* fields.c */ +extern void change_field(char *, size_t, const char *); +extern int valid_field(const char *, const char *); + +/* fputsx.c */ +extern char *fgetsx(char *, int, FILE *); +extern int fputsx(const char *, FILE *); + +/* grdbm.c */ +extern int gr_dbm_remove(const struct group *); +extern int gr_dbm_update(const struct group *); +extern int gr_dbm_present(void); + +/* grent.c */ +extern int putgrent(const struct group *, FILE *); + +/* grpack.c */ +extern int gr_pack(const struct group *, char *); +extern int gr_unpack(char *, int, struct group *); + +#ifdef SHADOWGRP +/* gsdbm.c */ +extern int sg_dbm_remove(const char *); +extern int sg_dbm_update(const struct sgrp *); +extern int sg_dbm_present(void); + +/* gspack.c */ +extern int sgr_pack(const struct sgrp *, char *); +extern int sgr_unpack(char *, int, struct sgrp *); +#endif + +/* hushed.c */ +extern int hushed(const struct passwd *); + +/* limits.c */ +extern void setup_limits(const struct passwd *); + +/* list.c */ +extern char **add_list(char **, const char *); +extern char **del_list(char **, const char *); +extern char **dup_list(char * const *); +extern int is_on_list(char * const *, const char *); +extern char **comma_to_list(const char *); + +/* login.c */ +extern void login_prompt(const char *, char *, int); + +/* login_desrpc.c */ +extern int login_desrpc(const char *); + +/* mail.c */ +extern void mailcheck(void); + +/* motd.c */ +extern void motd(void); + +/* myname.c */ +extern struct passwd *get_my_pwent(void); + +/* obscure.c */ +extern int obscure(const char *, const char *, const struct passwd *); + +/* pam_pass.c */ +extern int do_pam_passwd(const char *, int, int); + +/* port.c */ +extern int isttytime(const char *, const char *, time_t); + +/* pwd2spwd.c */ +#ifdef SHADOWPWD +extern struct spwd *pwd_to_spwd(const struct passwd *); +#endif + +/* pwdcheck.c */ +extern void passwd_check(const char *, const char *, const char *); + +/* pwd_init.c */ +extern void pwd_init(void); + +/* pwdbm.c */ +extern int pw_dbm_remove(const struct passwd *); +extern int pw_dbm_update(const struct passwd *); +extern int pw_dbm_present(void); + +/* pwpack.c */ +extern int pw_pack(const struct passwd *, char *); +extern int pw_unpack(char *, int, struct passwd *); + +/* rad64.c */ +extern int c64i(int); +extern int i64c(int); + +/* rlogin.c */ +extern int do_rlogin(const char *, char *, int, char *, int); + +/* salt.c */ +extern char *crypt_make_salt(void); + +/* setugid.c */ +extern int setup_groups(const struct passwd *); +extern int change_uid(const struct passwd *); +extern int setup_uid_gid(const struct passwd *, int); + +/* setup.c */ +extern void setup(struct passwd *); + +/* setupenv.c */ +extern void setup_env(struct passwd *); + +/* shell.c */ +extern void shell(const char *, const char *); + +#ifdef SHADOWPWD +/* spdbm.c */ +extern int sp_dbm_remove(const char *); +extern int sp_dbm_update(const struct spwd *); +extern int sp_dbm_present(void); + +/* sppack.c */ +extern int spw_pack(const struct spwd *, char *); +extern int spw_unpack(char *, int, struct spwd *); +#endif + +/* strtoday.c */ +extern long strtoday(const char *); + +/* suauth.c */ +extern int check_su_auth(const char *, const char *); + +/* sulog.c */ +extern void sulog(const char *, int, const char *, const char *); + +/* sub.c */ +extern void subsystem(const struct passwd *); + +/* ttytype.c */ +extern void ttytype(const char *); + +/* tz.c */ +extern char *tz(const char *); + +/* ulimit.c */ +extern void set_filesize_limit(int); + +/* utmp.c */ +extern void checkutmp(int); +extern void setutmp(const char *, const char *, const char *); + +/* valid.c */ +extern int valid(const char *, const struct passwd *); + +/* xmalloc.c */ +extern char *xmalloc(size_t); +extern char *xstrdup(const char *); + +#endif /* _PROTOTYPES_H */ diff --git a/current/lib/putgrent.c b/current/lib/putgrent.c new file mode 100644 index 00000000..6559cd92 --- /dev/null +++ b/current/lib/putgrent.c @@ -0,0 +1,75 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include +#include +#include "prototypes.h" +#include "defines.h" + +int +putgrent(const struct group *g, FILE *f) +{ + char *buf, *cp; + int i; + size_t size; + + if (!g || !f) + return -1; + + /* calculate the required buffer size (40 is added for the + numeric GID, colons, newline, and terminating NUL). */ + size = strlen(g->gr_name) + strlen(g->gr_passwd) + 40; + for (i = 0; g->gr_mem && g->gr_mem[i]; i++) + size += strlen(g->gr_mem[i]) + 1; + + buf = malloc(size); + if (!buf) + return -1; + + sprintf(buf, "%s:%s:%ld:", g->gr_name, g->gr_passwd, (long) g->gr_gid); + cp = buf + strlen(buf); + for (i = 0; g->gr_mem && g->gr_mem[i]; i++) { + if (i > 0) + *cp++ = ','; + strcpy(cp, g->gr_mem[i]); + cp += strlen(cp); + } + *cp++ = '\n'; + *cp = '\0'; + + if (fputsx(buf, f) == EOF || ferror(f)) { + free(buf); + return -1; + } + + free(buf); + return 0; +} diff --git a/current/lib/putpwent.c b/current/lib/putpwent.c new file mode 100644 index 00000000..bdc011c3 --- /dev/null +++ b/current/lib/putpwent.c @@ -0,0 +1,72 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: putpwent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $") + +#include "defines.h" +#include +#include + +/* + * putpwent - Output a (struct passwd) in character format + * + * putpwent() writes out a (struct passwd) in the format it appears + * in in flat ASCII files. + * + * (Author: Dr. Micheal Newberry) + */ + +int +putpwent(const struct passwd *p, FILE *f) +{ + int status; + +#if defined(SUN) || defined(BSD) || defined(SUN4) + status = fprintf (f, "%s:%s:%d:%d:%s,%s:%s:%s\n", + p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid, + p->pw_gecos, p->pw_comment, p->pw_dir, p->pw_shell) == EOF; +#else + status = fprintf (f, "%s:%s", p->pw_name, p->pw_passwd) == EOF; +#ifdef ATT_AGE + if (p->pw_age && p->pw_age[0]) + status |= fprintf (f, ",%s", p->pw_age) == EOF; +#endif + status |= fprintf (f, ":%d:%d:%s", p->pw_uid, p->pw_gid, + p->pw_gecos) == EOF; +#ifdef ATT_COMMENT + if (p->pw_comment && p->pw_comment[0]) + status |= fprintf (f, ",%s", p->pw_comment) == EOF; +#endif + status |= fprintf (f, ":%s:%s\n", p->pw_dir, p->pw_shell) == EOF; +#endif + return status; +} diff --git a/current/lib/putspent.c b/current/lib/putspent.c new file mode 100644 index 00000000..941d76bc --- /dev/null +++ b/current/lib/putspent.c @@ -0,0 +1,103 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifdef SHADOWPWD /*{*/ +#ifndef HAVE_PUTSPENT + +#include "rcsid.h" +RCSID("$Id: putspent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include + +int +putspent(const struct spwd *sp, FILE *fp) +{ + int errors = 0; + + if (! fp || ! sp) + return -1; + + if (fprintf (fp, "%s:%s:", sp->sp_namp, sp->sp_pwdp) < 0) + errors++; + + if (sp->sp_lstchg != -1) { + if (fprintf (fp, "%ld:", sp->sp_lstchg) < 0) + errors++; + } else if (putc (':', fp) == EOF) + errors++; + + if (sp->sp_min != -1) { + if (fprintf (fp, "%ld:", sp->sp_min) < 0) + errors++; + } else if (putc (':', fp) == EOF) + errors++; + + if (sp->sp_max != -1) { + if (fprintf (fp, "%ld:", sp->sp_max) < 0) + errors++; + } else if (putc (':', fp) == EOF) + errors++; + + if (sp->sp_warn != -1) { + if (fprintf (fp, "%ld:", sp->sp_warn) < 0) + errors++; + } else if (putc (':', fp) == EOF) + errors++; + + if (sp->sp_inact != -1) { + if (fprintf (fp, "%ld:", sp->sp_inact) < 0) + errors++; + } else if (putc (':', fp) == EOF) + errors++; + + if (sp->sp_expire != -1) { + if (fprintf (fp, "%ld:", sp->sp_expire) < 0) + errors++; + } else if (putc (':', fp) == EOF) + errors++; + + if (sp->sp_flag != -1) { + if (fprintf (fp, "%ld", sp->sp_flag) < 0) + errors++; + } + if (putc ('\n', fp) == EOF) + errors++; + + if (errors) + return -1; + else + return 0; +} +#endif +#endif /*}*/ diff --git a/current/lib/pwauth.c b/current/lib/pwauth.c new file mode 100644 index 00000000..bce32f22 --- /dev/null +++ b/current/lib/pwauth.c @@ -0,0 +1,578 @@ +/* + * Copyright 1992 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: pwauth.c,v 1.11 2000/08/26 18:27:17 marekm Exp $") + +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" +#include "pwauth.h" +#include "getdef.h" + +#ifdef SKEY +#include +#endif + +#ifdef OPIE +#include +#endif + +#ifdef __linux__ /* standard password prompt by default */ +static const char *PROMPT = gettext_noop("Password: "); +#else +static const char *PROMPT = gettext_noop("%s's Password: "); +#endif + +extern char *getpass(); +extern char *getpass_with_echo(); + +#ifdef AUTH_METHODS +/* + * Look-up table for bound-in methods. Put the name that the + * method is known by in the password field as "name" and a + * pointer to the function + */ + +struct method { + char *name; + int (*func)(const char *, int, const char *); +}; + +#ifdef PAD_AUTH +int pad_auth(); +#endif +static struct method methods[] = { +#ifdef PAD_AUTH + { "pad", pad_auth }, +#endif + { "", 0 } +}; +#endif /* AUTH_METHODS */ + +int wipe_clear_pass = 1; +char *clear_pass = NULL; + +/* + * _old_auth - perform getpass/crypt authentication + * + * _old_auth gets the user's cleartext password and encrypts it + * using the salt in the encrypted password. The results are + * compared. + */ + +static int +_old_auth(const char *cipher, const char *user, int reason, const char *input) +{ + char prompt[1024]; + char *clear = NULL; + const char *cp; + int retval; +#ifdef SKEY + int use_skey = 0; + char challenge_info[40]; + struct skey skey; +#endif + +#ifdef OPIE + int use_opie = 0; + char o_challenge_info[OPIE_CHALLENGE_MAX + 1]; + struct opie opie; + /* + * This implementation is based almost entirely on the SKEY code + * above. Thus the opie struct is called skey, etc. I am unaware + * if the system works at the same time, but I cannot imagine why + * anyone would want to do this.... + * -- A.R. + * Mod: 5/14/98 A.R. + * Made the OPIE code separate from the S/Key code. Now + * (conceivably) both can be compiled in and function apart from + * one another (assuming a sysadmin really wants to maintain OPIE + * and an S/Key databases....). + * + * Also cleaned up the code a bit. Will be adding second-prompt + * support (the traditional Echo-on S/Key/OPIE-only prompts to let + * the users see the one-time passwords they are typing/pasting + * in.... + * -- A.R. + */ +#endif + + /* + * There are programs for adding and deleting authentication data. + */ + + if (reason == PW_ADD || reason == PW_DELETE) + return 0; + + /* + * There are even programs for changing the user name ... + */ + + if (reason == PW_CHANGE && input != (char *) 0) + return 0; + + /* + * WARNING: + * + * When we change a password and we are root, we don't prompt. + * This is so root can change any password without having to + * know it. This is a policy decision that might have to be + * revisited. + */ + + if (reason == PW_CHANGE && getuid () == 0) + return 0; + + /* + * WARNING: + * + * When we are logging in a user with no ciphertext password, + * we don't prompt for the password or anything. In reality + * the user could just hit , so it doesn't really + * matter. + */ + + if (cipher == (char *) 0 || *cipher == '\0') + return 0; + +#ifdef SKEY + /* + * If the user has an S/KEY entry show them the pertinent info + * and then we can try validating the created cyphertext and the SKEY. + * If there is no SKEY information we default to not using SKEY. + */ + + if (skeychallenge (&skey, user, challenge_info) == 0) + use_skey = 1; +#endif + +#ifdef OPIE + /* + * Ditto above, for OPIE passwords. + * -- AR + */ + + o_challenge_info[0] = '\0'; + if (opiechallenge(&opie, user, o_challenge_info) == 0) + use_opie = 1; + + if (use_opie == 0) + opieverify(&opie, (char *)NULL); + /* + * This call to opieverify is necessary within OPIE's interface: + * Every call to opiechallenge(), which checks to see if the user + * has an OPIE password, and if so get the challenge, must be + * accompanied by exactly one call to opieverify, which clears + * any outstanding locks, and otherwise cleans up. + * -- AR + */ +#endif + + /* + * Prompt for the password as required. FTPD and REXECD both + * get the cleartext password for us. + */ + + if (reason != PW_FTP && reason != PW_REXEC && !input) { + if (! (cp = getdef_str ("LOGIN_STRING"))) + cp = _(PROMPT); +#ifdef SKEY + if (use_skey) + printf ("[%s]\n", challenge_info); +#endif + +#ifdef OPIE + if (use_opie) + printf("[ %s ]\n", o_challenge_info); +#endif + + snprintf(prompt, sizeof prompt, cp, user); + clear = getpass(prompt); + if (!clear) { + static char c[1]; + c[0] = '\0'; + clear = c; + } + input = clear; + } + + /* + * Convert the cleartext password into a ciphertext string. + * If the two match, the return value will be zero, which is + * SUCCESS. Otherwise we see if SKEY is being used and check + * the results there as well. + */ + + retval = strcmp(pw_encrypt(input, cipher), cipher); + +#ifdef OPIE + /* + * This is required because using OPIE, opieverify() MUST be called + * opiechallenge() above even if OPIE isn't being used in this case, + * so locks get released, etc. + * -- AR + */ + + if ((retval == 0) && use_opie) + opieverify(&opie, (char *)NULL); +#endif + +#if (defined(SKEY) || defined(OPIE)) + /* + * If (1) The password fails to match, and + * (2) The password is empty and + * (3) We are using OPIE or S/Key, then + * ...Re-prompt, with echo on. + * -- AR 8/22/1999 + */ + if (retval && !input[0] && + (0 +#ifdef SKEY + || use_skey +#endif +#ifdef OPIE + || use_opie +#endif + )) { + strncat(prompt, _("(Echo on) "), + (sizeof(prompt) - strlen(prompt))); + clear = getpass_with_echo(prompt); + if (!clear) { + static char c[1]; + c[0] = '\0'; + clear = c; + } + input = clear; + } +#endif + +#ifdef SKEY + if (retval && use_skey) { + int passcheck = -1; + +#if 0 /* some skey libs don't have skey_passcheck. --marekm */ + passcheck = skey_passcheck(user, input); +#else + if (skeyverify(&skey, input) == 0) + passcheck = skey.n; +#endif /* if 0 */ + if (passcheck > 0) + retval = 0; + } +#endif + +#ifdef OPIE + if (retval && use_opie) { + if (opieverify(&opie, input) == 0) + retval = 0; + } +#endif /* OPIE */ + + /* + * Things like RADIUS authentication may need the password - + * if the external variable wipe_clear_pass is zero, we will + * not wipe it (the caller should wipe clear_pass when it is + * no longer needed). --marekm + */ + + clear_pass = clear; + if (wipe_clear_pass && clear && *clear) + strzero(clear); + return retval; +} + +#ifdef AUTH_METHODS +/* + * _pw_auth - perform alternate password authentication + * + * pw_auth executes the alternate password authentication method + * described in the user's password entry. _pw_auth does the real + * work, pw_auth splits the authentication string into individual + * command names. + */ + +static int +_pw_auth(const char *command, const char *user, int reason, const char *input) +{ + RETSIGTYPE (*sigint)(); + RETSIGTYPE (*sigquit)(); +#ifdef SIGTSTP + RETSIGTYPE (*sigtstp)(); +#endif + int pid; + int status; + int i; + char * const argv[5]; + int argc = 0; + int pipes[2]; + char *empty_env = NULL; + int use_pipe; + + /* + * Start with a quick sanity check. ALL command names must + * be fully-qualified path names. + */ + + if (command[0] != '/') + return -1; + + /* + * Set the keyboard signals to be ignored. When the user kills + * the child we don't want the parent dying as well. + */ + + sigint = signal (SIGINT, SIG_IGN); + sigquit = signal (SIGQUIT, SIG_IGN); +#ifdef SIGTSTP + sigtstp = signal (SIGTSTP, SIG_IGN); +#endif + + /* + * FTP and REXEC reasons don't give the program direct access + * to the user. This means that the program can only get input + * from this function. So we set up a pipe for that purpose. + */ + + use_pipe = (reason == PW_FTP || reason == PW_REXEC); + if (use_pipe) + if (pipe (pipes)) + return -1; + + /* + * The program will be forked off with the parent process waiting + * on the child to tell it how successful it was. + */ + + switch (pid = fork ()) { + + /* + * The fork() failed completely. Clean up as needed and + * return to the caller. + */ + case -1: + if (use_pipe) { + close (pipes[0]); + close (pipes[1]); + } + return -1; + case 0: + + /* + * Let the child catch the SIGINT and SIGQUIT + * signals. The parent, however, will continue + * to ignore them. + */ + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + + /* + * Set up the command line. The first argument is + * the name of the command being executed. The + * second is the command line option for the reason, + * and the third is the user name. + */ + argv[argc++] = command; + switch (reason) { + case PW_SU: argv[argc++] = "-s"; break; + case PW_LOGIN: argv[argc++] = "-l"; break; + case PW_ADD: argv[argc++] = "-a"; break; + case PW_CHANGE: argv[argc++] = "-c"; break; + case PW_DELETE: argv[argc++] = "-d"; break; + case PW_TELNET: argv[argc++] = "-t"; break; + case PW_RLOGIN: argv[argc++] = "-r"; break; + case PW_FTP: argv[argc++] = "-f"; break; + case PW_REXEC: argv[argc++] = "-x"; break; + } + if (reason == PW_CHANGE && input) + argv[argc++] = input; + + argv[argc++] = user; + argv[argc] = (char *) 0; + + /* + * The FTP and REXEC reasons use a pipe to communicate + * with the parent. The other standard I/O descriptors + * are closed and re-opened as /dev/null. + */ + if (use_pipe) { + close (0); + close (1); + close (2); + + if (dup (pipes[0]) != 0) + exit (1); + + close (pipes[0]); + close (pipes[1]); + + if (open ("/dev/null", O_WRONLY) != 1) + exit (1); + + if (open ("/dev/null", O_WRONLY) != 2) + exit (1); + } + + /* + * Now we execute the command directly. + * Do it with empty environment for safety. --marekm + */ + execve(command, argv, &empty_env); + _exit((errno == ENOENT) ? 127 : 126); + /*NOTREACHED*/ + default: + /* + * FTP and REXEC cause a single line of text to be + * sent to the child over a pipe that was set up + * earlier. + */ + if (use_pipe) { + close (pipes[0]); + + if (input) + write (pipes[1], input, strlen (input)); + + write (pipes[1], "\n", 1); + close (pipes[1]); + } + + /* + * Wait on the child to die. When it does you will + * get the exit status and use that to determine if + * the authentication program was successful. + */ + while ((i = wait (&status)) != pid && i != -1) + ; + + /* + * Re-set the signals to their earlier values. + */ + signal (SIGINT, sigint); + signal (SIGQUIT, sigquit); +#ifdef SIGTSTP + signal (SIGTSTP, sigtstp); +#endif + + /* + * Make sure we found the right process! + */ + if (i == -1) + return -1; + + if (status == 0) + return 0; + else + return -1; + } + /*NOTREACHED*/ +} + +/* + * _builtin_auth - lookup routine in table and execute + */ + +static int +_builtin_auth(const char *command, const char *user, int reason, const char *input) +{ + int i; + + /* + * Scan the table, looking for a match. If we fall off + * the end, it must mean that this method isn't supported, + * so we fail the authentication. + */ + + for (i = 0;methods[i].name[0];i++) { + if (! strcmp (command, methods[i].name)) + break; + } + if (methods[i].name[0] == '\0') + return -1; + + /* + * Call the pointed to function with the other three + * arguments. + */ + + return (methods[i].func) (user, reason, input); +} +#endif /* AUTH_METHODS */ + +/* + * This function does the real work. It splits the list of program names + * up into individual programs and executes them one at a time. + */ + +int +pw_auth(const char *command, const char *user, int reason, const char *input) +{ +#ifdef AUTH_METHODS + char buf[256]; + char *cmd, *end; + int rc; + + /* + * Quick little sanity check ... + */ + + if (strlen (command) >= sizeof buf) + return -1; + + strcpy(buf, command); /* safe (because of the above check) --marekm */ + + /* + * Find each command and make sure it is NUL-terminated. Then + * invoke _pw_auth to actually run the program. The first + * failing program ends the whole mess. + */ + + for (cmd = buf;cmd;cmd = end) { + if ((end = strchr (cmd, ';'))) + *end++ = '\0'; + + if (cmd[0] != '@') + rc = _old_auth (cmd, user, reason, input); + else if (cmd[1] == '/') + rc = _pw_auth (cmd + 1, user, reason, input); + else + rc = _builtin_auth (cmd + 1, user, reason, input); + if (rc) + return -1; + } + return 0; +#else + return _old_auth(command, user, reason, input); +#endif +} diff --git a/current/lib/pwauth.h b/current/lib/pwauth.h new file mode 100644 index 00000000..ab6017b4 --- /dev/null +++ b/current/lib/pwauth.h @@ -0,0 +1,60 @@ +/* + * Copyright 1992 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + * + * $Id: pwauth.h,v 1.2 1997/05/01 23:14:44 marekm Exp $ + */ + +#if __STDC__ +int pw_auth(const char *program,const char *user,int flag,const char *input); +#else +int pw_auth (); +#endif + +/* + * Local access + */ + +#define PW_SU 1 +#define PW_LOGIN 2 + +/* + * Administrative functions + */ + +#define PW_ADD 101 +#define PW_CHANGE 102 +#define PW_DELETE 103 + +/* + * Network access + */ + +#define PW_TELNET 201 +#define PW_RLOGIN 202 +#define PW_FTP 203 +#define PW_REXEC 204 diff --git a/current/lib/pwdbm.c b/current/lib/pwdbm.c new file mode 100644 index 00000000..c0de8460 --- /dev/null +++ b/current/lib/pwdbm.c @@ -0,0 +1,143 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifdef NDBM /*{*/ + +#include "rcsid.h" +RCSID("$Id: pwdbm.c,v 1.4 1997/12/14 20:07:19 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +#include +extern DBM *pw_dbm; + +/* + * pw_dbm_update + * + * Updates the DBM password files, if they exist. + */ + +int +pw_dbm_update(const struct passwd *pw) +{ + datum key; + datum content; + char data[BUFSIZ]; + int len; + static int once; + + if (! once) { + if (! pw_dbm) + setpwent (); + once++; + } + if (! pw_dbm) + return 0; + + len = pw_pack (pw, data); + content.dsize = len; + content.dptr = data; + + key.dsize = strlen (pw->pw_name); + key.dptr = pw->pw_name; + + if (dbm_store(pw_dbm, key, content, DBM_REPLACE)) + return 0; + + /* + * XXX - on systems with 16-bit UIDs (such as Linux/x86) + * name "aa" and UID 24929 will give the same key. This + * happens only rarely, but code which only "works most + * of the time" is not good enough... + * + * This needs to be fixed in several places (pwdbm.c, + * grdbm.c, pwent.c, grent.c). Fixing it will cause + * incompatibility with existing dbm files. + * + * Summary: don't use this stuff for now. --marekm + */ + + key.dsize = sizeof pw->pw_uid; + key.dptr = (char *) &pw->pw_uid; + + if (dbm_store(pw_dbm, key, content, DBM_REPLACE)) + return 0; + + return 1; +} + +/* + * pw_dbm_remove + * + * Removes the DBM password entry, if it exists. + */ + +int +pw_dbm_remove(const struct passwd *pw) +{ + datum key; + static int once; + char data[BUFSIZ]; + + if (! once) { + if (! pw_dbm) + setpwent (); + once++; + } + if (! pw_dbm) + return 0; + + key.dsize = strlen (pw->pw_name); + key.dptr = pw->pw_name; + + if (dbm_delete (pw_dbm, key)) + return 0; + + key.dsize = sizeof pw->pw_uid; + key.dptr = (char *) &pw->pw_uid; + + if (dbm_delete (pw_dbm, key)) + return 0; + + return 1; +} + + +int +pw_dbm_present(void) +{ + return (access(PASSWD_PAG_FILE, F_OK) == 0); +} +#endif /* NDBM */ diff --git a/current/lib/pwio.c b/current/lib/pwio.c new file mode 100644 index 00000000..70b3d9ab --- /dev/null +++ b/current/lib/pwio.c @@ -0,0 +1,186 @@ + +#include + +#include "rcsid.h" +RCSID("$Id: pwio.c,v 1.11 2000/09/02 18:40:43 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include +#include + +#include "commonio.h" +#include "pwio.h" + +extern struct passwd *sgetpwent(const char *); +extern int putpwent(const struct passwd *, FILE *); + +struct passwd * +__pw_dup(const struct passwd *pwent) +{ + struct passwd *pw; + + if (!(pw = (struct passwd *) malloc(sizeof *pw))) + return NULL; + *pw = *pwent; + if (!(pw->pw_name = strdup(pwent->pw_name))) + return NULL; + if (!(pw->pw_passwd = strdup(pwent->pw_passwd))) + return NULL; +#ifdef ATT_AGE + if (!(pw->pw_age = strdup(pwent->pw_age))) + return NULL; +#endif +#ifdef ATT_COMMENT + if (!(pw->pw_comment = strdup(pwent->pw_comment))) + return NULL; +#endif + if (!(pw->pw_gecos = strdup(pwent->pw_gecos))) + return NULL; + if (!(pw->pw_dir = strdup(pwent->pw_dir))) + return NULL; + if (!(pw->pw_shell = strdup(pwent->pw_shell))) + return NULL; + return pw; +} + +static void * +passwd_dup(const void *ent) +{ + const struct passwd *pw = ent; + return __pw_dup(pw); +} + +static void +passwd_free(void *ent) +{ + struct passwd *pw = ent; + + free(pw->pw_name); + free(pw->pw_passwd); +#ifdef ATT_AGE + free(pw->pw_age); +#endif +#ifdef ATT_COMMENT + free(pw->pw_comment); +#endif + free(pw->pw_gecos); + free(pw->pw_dir); + free(pw->pw_shell); + free(pw); +} + +static const char * +passwd_getname(const void *ent) +{ + const struct passwd *pw = ent; + return pw->pw_name; +} + +static void * +passwd_parse(const char *line) +{ + return (void *) sgetpwent(line); +} + +static int +passwd_put(const void *ent, FILE *file) +{ + const struct passwd *pw = ent; + return (putpwent(pw, file) == -1) ? -1 : 0; +} + +static struct commonio_ops passwd_ops = { + passwd_dup, + passwd_free, + passwd_getname, + passwd_parse, + passwd_put, + fgets, + fputs +}; + +static struct commonio_db passwd_db = { + PASSWD_FILE, /* filename */ + &passwd_ops, /* ops */ + NULL, /* fp */ + NULL, /* head */ + NULL, /* tail */ + NULL, /* cursor */ + 0, /* changed */ + 0, /* isopen */ + 0, /* locked */ + 0 /* readonly */ +}; + +int +pw_name(const char *filename) +{ + return commonio_setname(&passwd_db, filename); +} + +int +pw_lock(void) +{ + return commonio_lock(&passwd_db); +} + +int +pw_open(int mode) +{ + return commonio_open(&passwd_db, mode); +} + +const struct passwd * +pw_locate(const char *name) +{ + return commonio_locate(&passwd_db, name); +} + +int +pw_update(const struct passwd *pw) +{ + return commonio_update(&passwd_db, (const void *) pw); +} + +int +pw_remove(const char *name) +{ + return commonio_remove(&passwd_db, name); +} + +int +pw_rewind(void) +{ + return commonio_rewind(&passwd_db); +} + +const struct passwd * +pw_next(void) +{ + return commonio_next(&passwd_db); +} + +int +pw_close(void) +{ + return commonio_close(&passwd_db); +} + +int +pw_unlock(void) +{ + return commonio_unlock(&passwd_db); +} + +struct commonio_entry * +__pw_get_head(void) +{ + return passwd_db.head; +} + +void +__pw_del_entry(const struct commonio_entry *ent) +{ + commonio_del_entry(&passwd_db, ent); +} diff --git a/current/lib/pwio.h b/current/lib/pwio.h new file mode 100644 index 00000000..199f67da --- /dev/null +++ b/current/lib/pwio.h @@ -0,0 +1,12 @@ +extern struct passwd *__pw_dup(const struct passwd *); +extern void __pw_set_changed(void); +extern int pw_close(void); +extern const struct passwd *pw_locate(const char *); +extern int pw_lock(void); +extern int pw_name(const char *); +extern const struct passwd *pw_next(void); +extern int pw_open(int); +extern int pw_remove(const char *); +extern int pw_rewind(void); +extern int pw_unlock(void); +extern int pw_update(const struct passwd *); diff --git a/current/lib/pwpack.c b/current/lib/pwpack.c new file mode 100644 index 00000000..67053baf --- /dev/null +++ b/current/lib/pwpack.c @@ -0,0 +1,163 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: pwpack.c,v 1.4 1998/04/16 19:57:42 marekm Exp $") + +#include +#include "defines.h" +#include +#include + + +/* + * pw_pack - convert a (struct pwd) to a packed record + * WARNING: buf must be large enough, no check for overrun! + */ + +int +pw_pack(const struct passwd *passwd, char *buf) +{ + char *cp; + + cp = buf; + strcpy (cp, passwd->pw_name); + cp += strlen (cp) + 1; + + strcpy (cp, passwd->pw_passwd); +#ifdef ATT_AGE + if (passwd->pw_age[0]) { + *cp++ = ','; + strcat (cp, passwd->pw_age); + } +#endif + cp += strlen (cp) + 1; + + memcpy (cp, (const char *) &passwd->pw_uid, sizeof passwd->pw_uid); + cp += sizeof passwd->pw_uid; + + memcpy (cp, (const char *) &passwd->pw_gid, sizeof passwd->pw_gid); + cp += sizeof passwd->pw_gid; +#ifdef BSD_QUOTA + memcpy (cp, (const char *) &passwd->pw_quota, sizeof passwd->pw_quota); + cp += sizeof passwd->pw_quota; +#endif +#ifdef ATT_COMMENT + if (passwd->pw_comment) { + strcpy (cp, passwd->pw_comment); + cp += strlen (cp) + 1; + } else + *cp++ = '\0'; +#endif + strcpy (cp, passwd->pw_gecos); + cp += strlen (cp) + 1; + + strcpy (cp, passwd->pw_dir); + cp += strlen (cp) + 1; + + strcpy (cp, passwd->pw_shell); + cp += strlen (cp) + 1; + + return cp - buf; +} + +/* + * pw_unpack - convert a packed (struct pwd) record to a (struct pwd) + */ + +int +pw_unpack(char *buf, int len, struct passwd *passwd) +{ + char *org = buf; +#ifdef ATT_AGE + char *cp; +#endif + + memzero(passwd, sizeof *passwd); + + passwd->pw_name = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + passwd->pw_passwd = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + +#ifdef ATT_AGE + if (cp = strchr (passwd->pw_passwd, ',')) { + *cp++ = '\0'; + passwd->pw_age = cp; + } else + passwd->pw_age = ""; +#endif + + memcpy ((void *) &passwd->pw_uid, (void *) buf, sizeof passwd->pw_uid); + buf += sizeof passwd->pw_uid; + if (buf - org > len) + return -1; + + memcpy ((void *) &passwd->pw_gid, (void *) buf, sizeof passwd->pw_gid); + buf += sizeof passwd->pw_gid; + if (buf - org > len) + return -1; + +#ifdef BSD_QUOTA + memcpy ((void *) &passwd->pw_quota, (void *) buf, + sizeof passwd->pw_quota); + buf += sizeof passwd->pw_quota; + if (buf - org > len) + return -1; +#endif +#ifdef ATT_COMMENT + passwd->pw_comment = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; +#endif + passwd->pw_gecos = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + passwd->pw_dir = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + passwd->pw_shell = buf; + buf += strlen (buf) + 1; + if (buf - org > len) + return -1; + + return 0; +} diff --git a/current/lib/rad64.c b/current/lib/rad64.c new file mode 100644 index 00000000..249a71e1 --- /dev/null +++ b/current/lib/rad64.c @@ -0,0 +1,126 @@ +/* + * Copyright 1989 - 1992, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: rad64.c,v 1.5 2000/08/26 18:27:17 marekm Exp $") + +/* + * c64i - convert a radix 64 character to an integer + */ + +int +c64i(int c) +{ + if (c == '.') + return (0); + + if (c == '/') + return (1); + + if (c >= '0' && c <= '9') + return (c - '0' + 2); + + if (c >= 'A' && c <= 'Z') + return (c - 'A' + 12); + + if (c >= 'a' && c <= 'z') + return (c - 'a' + 38); + else + return (-1); +} + +/* + * i64c - convert an integer to a radix 64 character + */ + +int +i64c(int i) +{ + if (i <= 0) + return ('.'); + + if (i == 1) + return ('/'); + + if (i >= 2 && i < 12) + return ('0' - 2 + i); + + if (i >= 12 && i < 38) + return ('A' - 12 + i); + + if (i >= 38 && i < 63) + return ('a' - 38 + i); + + return ('z'); +} + +#ifndef HAVE_A64L + +/* + * l64a - convert a long to a string of radix 64 characters + */ + +char * +l64a(long l) +{ + static char buf[8]; + int i = 0; + + if (l < 0L) + return ((char *) 0); + + do { + buf[i++] = i64c ((int) (l % 64)); + buf[i] = '\0'; + } while (l /= 64L, l > 0 && i < 6); + + return (buf); +} + +/* + * a64l - convert a radix 64 string to a long integer + */ + +long +a64l(const char *s) +{ + int i; + long value; + long shift = 0; + + for (i = 0, value = 0L;i < 6 && *s;s++) { + value += (c64i ((int) *s) << shift); + shift += 6; + } + return (value); +} + +#endif /* !HAVE_A64L */ diff --git a/current/lib/rcsid.h b/current/lib/rcsid.h new file mode 100644 index 00000000..3869afc1 --- /dev/null +++ b/current/lib/rcsid.h @@ -0,0 +1,22 @@ +/* + * $Id: rcsid.h,v 1.2 1999/06/07 16:40:44 marekm Exp $ + */ +#define PKG_VER " $Package: " PACKAGE " $ $Version: " VERSION " $ " +#if defined(NO_RCSID) || defined(lint) +#define RCSID(x) /* empty */ +#else +#if __STDC__ +/* + * This function is never called from anywhere, but it calls itself + * recursively only to fool gcc to not generate warnings :-). + */ +static const char *rcsid(const char *); +#define RCSID(x) \ + static const char *rcsid(const char *s) { \ + return rcsid(x); } +#else /* ! __STDC__ */ +#define RCSID(x) \ + static char *rcsid(s) char *s; { \ + return rcsid(x); } +#endif /* ! __STDC__ */ +#endif diff --git a/current/lib/rename.c b/current/lib/rename.c new file mode 100644 index 00000000..d693d794 --- /dev/null +++ b/current/lib/rename.c @@ -0,0 +1,91 @@ +/* + * Copyright 1993 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: rename.c,v 1.3 1997/12/07 23:26:57 marekm Exp $") + +#include "defines.h" +#include +#include + +/* + * rename - rename a file to another name + * + * rename is provided for systems which do not include the rename() + * system call. + */ + +int +rename(const char *begin, const char *end) +{ + struct stat s1, s2; + extern int errno; + int orig_err = errno; + + if (stat (begin, &s1)) + return -1; + + if (stat (end, &s2)) { + errno = orig_err; + } else { + + /* + * See if this is a cross-device link. We do this to + * insure that the link below has a chance of working. + */ + + if (s1.st_dev != s2.st_dev) { + errno = EXDEV; + return -1; + } + + /* + * See if we can unlink the existing destination + * file. If the unlink works the directory is writable, + * so there is no need here to figure that out. + */ + + if (unlink (end)) + return -1; + } + + /* + * Now just link the original name to the final name. If there + * was no file previously, this link will fail if the target + * directory isn't writable. The unlink will fail if the source + * directory isn't writable, but life stinks ... + */ + + if (link (begin, end) || unlink (begin)) + return -1; + + return 0; +} diff --git a/current/lib/rmdir.c b/current/lib/rmdir.c new file mode 100644 index 00000000..d6a57508 --- /dev/null +++ b/current/lib/rmdir.c @@ -0,0 +1,59 @@ +/* + * Copyright 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include +#include + +#include "rcsid.h" +RCSID("$Id: rmdir.c,v 1.4 1998/01/29 23:22:31 marekm Exp $") + +/* + * rmdir - remove a directory + * + * rmdir is provided for systems which do not include the rmdir() + * system call. + */ + +int +rmdir(const char *dir) +{ + int status; + + if (fork()) { + while (wait(&status) != -1) + ; + + return status >> 8; + } + close(2); + open("/dev/null", O_WRONLY); + execl("/bin/rmdir", "rmdir", dir, 0); + _exit(127); + /*NOTREACHED*/ +} diff --git a/current/lib/sgetgrent.c b/current/lib/sgetgrent.c new file mode 100644 index 00000000..daa5fbe2 --- /dev/null +++ b/current/lib/sgetgrent.c @@ -0,0 +1,140 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: sgetgrent.c,v 1.4 1998/04/02 21:51:45 marekm Exp $") + +#include +#include +#include "defines.h" + +#define NFIELDS 4 + +/* + * list - turn a comma-separated string into an array of (char *)'s + * + * list() converts the comma-separated list of member names into + * an array of character pointers. + * + * WARNING: I profiled this once with and without strchr() calls + * and found that using a register variable and an explicit loop + * works best. For large /etc/group files, this is a major win. + * + * FINALLY added dynamic allocation. Still need to fix sgetsgent(). + * --marekm + */ + +static char ** +list(char *s) +{ + static char **members = 0; + static int size = 0; /* max members + 1 */ + int i; + char **rbuf; + + i = 0; + for (;;) { + /* check if there is room for another pointer (to a group + member name, or terminating NULL). */ + if (i >= size) { + size = i + 100; /* at least: i + 1 */ + if (members) { + rbuf = realloc(members, size * sizeof(char *)); + } else { + /* for old (before ANSI C) implementations of + realloc() that don't handle NULL properly */ + rbuf = malloc(size * sizeof(char *)); + } + if (!rbuf) { + if (members) + free(members); + members = 0; + size = 0; + return (char **) 0; + } + members = rbuf; + } + if (!s || s[0] == '\0') + break; + members[i++] = s; + while (*s && *s != ',') + s++; + if (*s) + *s++ = '\0'; + } + members[i] = (char *) 0; + return members; +} + + +struct group * +sgetgrent(const char *buf) +{ + static char *grpbuf = 0; + static size_t size = 0; + static char *grpfields[NFIELDS]; + static struct group grent; + int i; + char *cp; + + if (strlen(buf) + 1 > size) { + /* no need to use realloc() here - just free it and + allocate a larger block */ + if (grpbuf) + free(grpbuf); + size = strlen(buf) + 1000; /* at least: strlen(buf) + 1 */ + grpbuf = malloc(size); + if (!grpbuf) { + size = 0; + return 0; + } + } + strcpy(grpbuf, buf); + + if ((cp = strrchr(grpbuf, '\n'))) + *cp = '\0'; + + for (cp = grpbuf, i = 0; i < NFIELDS && cp; i++) { + grpfields[i] = cp; + if ((cp = strchr(cp, ':'))) + *cp++ = 0; + } + if (i < (NFIELDS-1) || *grpfields[2] == '\0') + return 0; + grent.gr_name = grpfields[0]; + grent.gr_passwd = grpfields[1]; + grent.gr_gid = atoi(grpfields[2]); + grent.gr_mem = list(grpfields[3]); + if (!grent.gr_mem) + return (struct group *) 0; /* out of memory */ + + return &grent; +} diff --git a/current/lib/sgetpwent.c b/current/lib/sgetpwent.c new file mode 100644 index 00000000..993f3c97 --- /dev/null +++ b/current/lib/sgetpwent.c @@ -0,0 +1,136 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: sgetpwent.c,v 1.5 1998/04/02 21:51:46 marekm Exp $") + +#include +#include "defines.h" +#include +#include + +#define NFIELDS 7 + +/* + * sgetpwent - convert a string to a (struct passwd) + * + * sgetpwent() parses a string into the parts required for a password + * structure. Strict checking is made for the UID and GID fields and + * presence of the correct number of colons. Any failing tests result + * in a NULL pointer being returned. + * + * NOTE: This function uses hard-coded string scanning functions for + * performance reasons. I am going to come up with some conditional + * compilation glarp to improve on this in the future. + */ + +struct passwd * +sgetpwent(const char *buf) +{ + static struct passwd pwent; + static char pwdbuf[1024]; + register int i; + register char *cp; + char *ep; + char *fields[NFIELDS]; + + /* + * Copy the string to a static buffer so the pointers into + * the password structure remain valid. + */ + + if (strlen(buf) >= sizeof pwdbuf) + return 0; /* fail if too long */ + strcpy(pwdbuf, buf); + + /* + * Save a pointer to the start of each colon separated + * field. The fields are converted into NUL terminated strings. + */ + + for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) { + fields[i] = cp; + while (*cp && *cp != ':') + ++cp; + + if (*cp) + *cp++ = '\0'; + else + cp = 0; + } + + /* + * There must be exactly NFIELDS colon separated fields or + * the entry is invalid. Also, the UID and GID must be non-blank. + */ + + if (i != NFIELDS || *fields[2] == '\0' || *fields[3] == '\0') + return 0; + + /* + * Each of the fields is converted the appropriate data type + * and the result assigned to the password structure. If the + * UID or GID does not convert to an integer value, a NULL + * pointer is returned. + */ + + pwent.pw_name = fields[0]; + pwent.pw_passwd = fields[1]; + if (fields[2][0] == '\0' || + ((pwent.pw_uid = strtol (fields[2], &ep, 10)) == 0 && *ep)) { + return 0; + } + if (fields[3][0] == '\0' || + ((pwent.pw_gid = strtol (fields[3], &ep, 10)) == 0 && *ep)) { + return 0; + } +#ifdef ATT_AGE + cp = pwent.pw_passwd; + while (*cp && *cp != ',') + ++cp; + + if (*cp) { + *cp++ = '\0'; + pwent.pw_age = cp; + } else { + cp = 0; + pwent.pw_age = ""; + } +#endif + pwent.pw_gecos = fields[4]; +#ifdef ATT_COMMENT + pwent.pw_comment = ""; +#endif + pwent.pw_dir = fields[5]; + pwent.pw_shell = fields[6]; + + return &pwent; +} diff --git a/current/lib/sgetspent.c b/current/lib/sgetspent.c new file mode 100644 index 00000000..1860075f --- /dev/null +++ b/current/lib/sgetspent.c @@ -0,0 +1,198 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifdef SHADOWPWD /*{*/ + +#include "rcsid.h" +RCSID("$Id: sgetspent.c,v 1.5 1998/04/02 21:51:47 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include + +#define FIELDS 9 +#define OFIELDS 5 + +/* + * sgetspent - convert string in shadow file format to (struct spwd *) + */ + +struct spwd * +sgetspent(const char *string) +{ + static char spwbuf[1024]; + static struct spwd spwd; + char *fields[FIELDS]; + char *cp; + char *cpp; + int i; + + /* + * Copy string to local buffer. It has to be tokenized and we + * have to do that to our private copy. + */ + + if (strlen(string) >= sizeof spwbuf) + return 0; /* fail if too long */ + strcpy(spwbuf, string); + + if ((cp = strrchr (spwbuf, '\n'))) + *cp = '\0'; + + /* + * Tokenize the string into colon separated fields. Allow up to + * FIELDS different fields. + */ + + for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) { + fields[i] = cp; + while (*cp && *cp != ':') + cp++; + + if (*cp) + *cp++ = '\0'; + } + + /* + * It is acceptable for the last SVR4 field to be blank. This + * results in the loop being terminated early. In which case, + * we just make the last field be blank and be done with it. + */ + + if (i == (FIELDS-1)) + fields[i++] = cp; + + if ((cp && *cp) || (i != FIELDS && i != OFIELDS)) + return 0; + + /* + * Start populating the structure. The fields are all in + * static storage, as is the structure we pass back. + */ + + spwd.sp_namp = fields[0]; + spwd.sp_pwdp = fields[1]; + + /* + * Get the last changed date. For all of the integer fields, + * we check for proper format. It is an error to have an + * incorrectly formatted number. + */ + + if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) { + return 0; + } else if (fields[2][0] == '\0') + spwd.sp_lstchg = -1; + + /* + * Get the minimum period between password changes. + */ + + if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) { + return 0; + } else if (fields[3][0] == '\0') + spwd.sp_min = -1; + + /* + * Get the maximum number of days a password is valid. + */ + + if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) { + return 0; + } else if (fields[4][0] == '\0') + spwd.sp_max = -1; + + /* + * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow + * formatted file), initialize the other field members to -1. + */ + +#if 0 /* SVR4 */ + if (i == OFIELDS) + return 0; +#else + if (i == OFIELDS) { + spwd.sp_warn = spwd.sp_inact = spwd.sp_expire = + spwd.sp_flag = -1; + + return &spwd; + } +#endif + + /* + * The rest of the fields are mandatory for SVR4, but optional + * for anything else. However, if one is present the others + * must be as well. + */ + + /* + * Get the number of days of password expiry warning. + */ + + if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) { + return 0; + } else if (fields[5][0] == '\0') + spwd.sp_warn = -1; + + /* + * Get the number of days of inactivity before an account is + * disabled. + */ + + if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) { + return 0; + } else if (fields[6][0] == '\0') + spwd.sp_inact = -1; + + /* + * Get the number of days after the epoch before the account is + * set to expire. + */ + + if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) { + return 0; + } else if (fields[7][0] == '\0') + spwd.sp_expire = -1; + + /* + * This field is reserved for future use. But it isn't supposed + * to have anything other than a valid integer in it. + */ + + if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) { + return 0; + } else if (fields[8][0] == '\0') + spwd.sp_flag = -1; + + return (&spwd); +} +#endif /*}*/ diff --git a/current/lib/sgroupio.c b/current/lib/sgroupio.c new file mode 100644 index 00000000..3bf2a087 --- /dev/null +++ b/current/lib/sgroupio.c @@ -0,0 +1,212 @@ + +#include + +#ifdef SHADOWGRP + +#include "rcsid.h" +RCSID("$Id: sgroupio.c,v 1.11 2000/09/02 18:40:43 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" + +#include "commonio.h" +#include "sgroupio.h" + +extern int putsgent(const struct sgrp *, FILE *); +extern struct sgrp *sgetsgent(const char *); + +struct sgrp * +__sgr_dup(const struct sgrp *sgent) +{ + struct sgrp *sg; + int i; + + if (!(sg = (struct sgrp *) malloc(sizeof *sg))) + return NULL; + *sg = *sgent; + if (!(sg->sg_name = strdup(sgent->sg_name))) + return NULL; + if (!(sg->sg_passwd = strdup(sgent->sg_passwd))) + return NULL; + + for (i = 0; sgent->sg_adm[i]; i++) + ; + sg->sg_adm = (char **) malloc((i + 1) * sizeof(char *)); + if (!sg->sg_adm) + return NULL; + for (i = 0; sgent->sg_adm[i]; i++) { + sg->sg_adm[i] = strdup(sgent->sg_adm[i]); + if (!sg->sg_adm[i]) + return NULL; + } + sg->sg_adm[i] = NULL; + + for (i = 0; sgent->sg_mem[i]; i++) + ; + sg->sg_mem = (char **) malloc((i + 1) * sizeof(char *)); + if (!sg->sg_mem) + return NULL; + for (i = 0; sgent->sg_mem[i]; i++) { + sg->sg_mem[i] = strdup(sgent->sg_mem[i]); + if (!sg->sg_mem[i]) + return NULL; + } + sg->sg_mem[i] = NULL; + + return sg; +} + +static void * +gshadow_dup(const void *ent) +{ + const struct sgrp *sg = ent; + return __sgr_dup(sg); +} + +static void +gshadow_free(void *ent) +{ + struct sgrp *sg = ent; + + free(sg->sg_name); + free(sg->sg_passwd); + while(*(sg->sg_adm)) { + free(*(sg->sg_adm)); + sg->sg_adm++; + } + while(*(sg->sg_mem)) { + free(*(sg->sg_mem)); + sg->sg_mem++; + } + free(sg); +} + +static const char * +gshadow_getname(const void *ent) +{ + const struct sgrp *gr = ent; + return gr->sg_name; +} + +static void * +gshadow_parse(const char *line) +{ + return (void *) sgetsgent(line); +} + +static int +gshadow_put(const void *ent, FILE *file) +{ + const struct sgrp *sg = ent; + return (putsgent(sg, file) == -1) ? -1 : 0; +} + +static struct commonio_ops gshadow_ops = { + gshadow_dup, + gshadow_free, + gshadow_getname, + gshadow_parse, + gshadow_put, + fgetsx, + fputsx +}; + +static struct commonio_db gshadow_db = { + SGROUP_FILE, /* filename */ + &gshadow_ops, /* ops */ + NULL, /* fp */ + NULL, /* head */ + NULL, /* tail */ + NULL, /* cursor */ + 0, /* changed */ + 0, /* isopen */ + 0, /* locked */ + 0 /* readonly */ +}; + +int +sgr_name(const char *filename) +{ + return commonio_setname(&gshadow_db, filename); +} + +int +sgr_file_present(void) +{ + return commonio_present(&gshadow_db); +} + +int +sgr_lock(void) +{ + return commonio_lock(&gshadow_db); +} + +int +sgr_open(int mode) +{ + return commonio_open(&gshadow_db, mode); +} + +const struct sgrp * +sgr_locate(const char *name) +{ + return commonio_locate(&gshadow_db, name); +} + +int +sgr_update(const struct sgrp *sg) +{ + return commonio_update(&gshadow_db, (const void *) sg); +} + +int +sgr_remove(const char *name) +{ + return commonio_remove(&gshadow_db, name); +} + +int +sgr_rewind(void) +{ + return commonio_rewind(&gshadow_db); +} + +const struct sgrp * +sgr_next(void) +{ + return commonio_next(&gshadow_db); +} + +int +sgr_close(void) +{ + return commonio_close(&gshadow_db); +} + +int +sgr_unlock(void) +{ + return commonio_unlock(&gshadow_db); +} + +void +__sgr_set_changed(void) +{ + gshadow_db.changed = 1; +} + +struct commonio_entry * +__sgr_get_head(void) +{ + return gshadow_db.head; +} + +void +__sgr_del_entry(const struct commonio_entry *ent) +{ + commonio_del_entry(&gshadow_db, ent); +} +#else +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif diff --git a/current/lib/sgroupio.h b/current/lib/sgroupio.h new file mode 100644 index 00000000..e9c93bf6 --- /dev/null +++ b/current/lib/sgroupio.h @@ -0,0 +1,13 @@ +extern struct sgrp *__sgr_dup(const struct sgrp *); +extern void __sgr_set_changed(void); +extern int sgr_close(void); +extern int sgr_file_present(void); +extern const struct sgrp *sgr_locate(const char *); +extern int sgr_lock(void); +extern int sgr_name(const char *); +extern const struct sgrp *sgr_next(void); +extern int sgr_open(int); +extern int sgr_remove(const char *); +extern int sgr_rewind(void); +extern int sgr_unlock(void); +extern int sgr_update(const struct sgrp *); diff --git a/current/lib/shadow.c b/current/lib/shadow.c new file mode 100644 index 00000000..76179d3a --- /dev/null +++ b/current/lib/shadow.c @@ -0,0 +1,592 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +/* Newer versions of Linux libc already have shadow support. */ +#if defined(SHADOWPWD) && !defined(HAVE_GETSPNAM) /*{*/ + +#include "rcsid.h" +RCSID("$Id: shadow.c,v 1.6 1998/01/29 23:22:32 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include + +#ifdef NDBM +#include +#include +DBM *sp_dbm; +int sp_dbm_mode = -1; +static int dbmopened; +static int dbmerror; +#endif + +#ifdef USE_NIS +static int nis_used; +static int nis_ignore; +static enum { native, start, middle, native2 } nis_state; +static int nis_bound; +static char *nis_domain; +static char *nis_key; +static int nis_keylen; +static char *nis_val; +static int nis_vallen; +#define IS_NISCHAR(c) ((c)=='+') +#endif + +static FILE *shadow; +static char spwbuf[BUFSIZ]; +static struct spwd spwd; + +#define FIELDS 9 +#define OFIELDS 5 + +#ifdef USE_NIS + +/* + * __setspNIS - turn on or off NIS searches + */ + +void +__setspNIS(int flag) +{ + nis_ignore = ! flag; + + if (nis_ignore) + nis_used = 0; +} + +/* + * bind_nis - bind to NIS server + */ + +static int +bind_nis(void) +{ + if (yp_get_default_domain (&nis_domain)) + return -1; + + nis_bound = 1; + return 0; +} +#endif + +/* + * setspent - initialize access to shadow text and DBM files + */ + +void +setspent(void) +{ + if (shadow) + rewind(shadow); + else + shadow = fopen(SHADOW_FILE, "r"); + +#ifdef USE_NIS + nis_state = native; +#endif + + /* + * Attempt to open the DBM files if they have never been opened + * and an error has never been returned. + */ + +#ifdef NDBM + if (! dbmerror && ! dbmopened) { + int mode; + char dbmfiles[BUFSIZ]; + + strcpy (dbmfiles, SHADOW_PAG_FILE); + + if (sp_dbm_mode == -1) + mode = O_RDWR; + else + mode = (sp_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY; + + if (! (sp_dbm = dbm_open (SHADOW_FILE, mode, 0))) + dbmerror = 1; + else + dbmopened = 1; + } +#endif +} + +/* + * endspent - terminate access to shadow text and DBM files + */ + +void +endspent(void) +{ + if (shadow) + (void) fclose (shadow); + + shadow = (FILE *) 0; +#ifdef NDBM + if (dbmopened && sp_dbm) { + dbm_close (sp_dbm); + sp_dbm = 0; + } + dbmopened = 0; + dbmerror = 0; +#endif +} + +/* + * my_sgetspent - convert string in shadow file format to (struct spwd *) + */ + +static struct spwd * +my_sgetspent(const char *string) +{ + char *fields[FIELDS]; + char *cp; + char *cpp; + int i; + + /* + * Copy string to local buffer. It has to be tokenized and we + * have to do that to our private copy. + */ + + if (strlen(string) >= sizeof spwbuf) + return 0; + strcpy(spwbuf, string); + + if ((cp = strrchr (spwbuf, '\n'))) + *cp = '\0'; + + /* + * Tokenize the string into colon separated fields. Allow up to + * FIELDS different fields. + */ + + for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) { + fields[i] = cp; + while (*cp && *cp != ':') + cp++; + + if (*cp) + *cp++ = '\0'; + } + + /* + * It is acceptable for the last SVR4 field to be blank. This + * results in the loop being terminated early. In which case, + * we just make the last field be blank and be done with it. + */ + + if (i == (FIELDS-1)) + fields[i++] = cp; + + if ((cp && *cp) || (i != FIELDS && i != OFIELDS)) + return 0; + + /* + * Start populating the structure. The fields are all in + * static storage, as is the structure we pass back. If we + * ever see a name with '+' as the first character, we try + * to turn on NIS processing. + */ + + spwd.sp_namp = fields[0]; +#ifdef USE_NIS + if (IS_NISCHAR (fields[0][0])) + nis_used = 1; +#endif + spwd.sp_pwdp = fields[1]; + + /* + * Get the last changed date. For all of the integer fields, + * we check for proper format. It is an error to have an + * incorrectly formatted number, unless we are using NIS. + */ + + if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) { +#ifdef USE_NIS + if (! nis_used) + return 0; + else + spwd.sp_lstchg = -1; +#else + return 0; +#endif + } else if (fields[2][0] == '\0') + spwd.sp_lstchg = -1; + + /* + * Get the minimum period between password changes. + */ + + if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) { +#ifdef USE_NIS + if (! nis_used) + return 0; + else + spwd.sp_min = -1; +#else + return 0; +#endif + } else if (fields[3][0] == '\0') + spwd.sp_min = -1; + + /* + * Get the maximum number of days a password is valid. + */ + + if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) { +#ifdef USE_NIS + if (! nis_used) + return 0; + else + spwd.sp_max = -1; +#else + return 0; +#endif + } else if (fields[4][0] == '\0') + spwd.sp_max = -1; + + /* + * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow + * formatted file), initialize the other field members to -1. + */ + +#if 0 /* SVR4 */ + if (i == OFIELDS) + return 0; +#else + if (i == OFIELDS) { + spwd.sp_warn = spwd.sp_inact = spwd.sp_expire = + spwd.sp_flag = -1; + + return &spwd; + } +#endif + + /* + * The rest of the fields are mandatory for SVR4, but optional + * for anything else. However, if one is present the others + * must be as well. + */ + + /* + * Get the number of days of password expiry warning. + */ + + if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) { +#ifdef USE_NIS + if (! nis_used) + return 0; + else + spwd.sp_warn = -1; +#else + return 0; +#endif + } else if (fields[5][0] == '\0') + spwd.sp_warn = -1; + + /* + * Get the number of days of inactivity before an account is + * disabled. + */ + + if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) { +#ifdef USE_NIS + if (! nis_used) + return 0; + else + spwd.sp_inact = -1; +#else + return 0; +#endif + } else if (fields[6][0] == '\0') + spwd.sp_inact = -1; + + /* + * Get the number of days after the epoch before the account is + * set to expire. + */ + + if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) { +#ifdef USE_NIS + if (! nis_used) + return 0; + else + spwd.sp_expire = -1; +#else + return 0; +#endif + } else if (fields[7][0] == '\0') + spwd.sp_expire = -1; + + /* + * This field is reserved for future use. But it isn't supposed + * to have anything other than a valid integer in it. + */ + + if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) { +#ifdef USE_NIS + if (! nis_used) + return 0; + else + spwd.sp_flag = -1; +#else + return 0; +#endif + } else if (fields[8][0] == '\0') + spwd.sp_flag = -1; + + return (&spwd); +} + +/* + * fgetspent - get an entry from a /etc/shadow formatted stream + */ + +struct spwd * +fgetspent(FILE *fp) +{ + char buf[BUFSIZ]; + char *cp; + + if (! fp) + return (0); + +#ifdef USE_NIS + while (fgets (buf, sizeof buf, fp) != (char *) 0) +#else + if (fgets (buf, sizeof buf, fp) != (char *) 0) +#endif + { + if ((cp = strchr (buf, '\n'))) + *cp = '\0'; +#ifdef USE_NIS + if (nis_ignore && IS_NISCHAR (buf[0])) + continue; +#endif + return my_sgetspent(buf); + } + return 0; +} + +/* + * getspent - get a (struct spwd *) from the current shadow file + */ + +struct spwd * +getspent(void) +{ +#ifdef USE_NIS + int nis_1_user = 0; + struct spwd *val; + char buf[BUFSIZ]; +#endif + if (! shadow) + setspent (); + +#ifdef USE_NIS +again: + /* + * See if we are reading from the local file. + */ + + if (nis_state == native || nis_state == native2) { + + /* + * Get the next entry from the shadow file. Return NULL + * right away if there is none. + */ + + if (! (val = fgetspent (shadow))) + return 0; + + /* + * If this entry began with a NIS escape character, we have + * to see if this is just a single user, or if the entire + * map is being asked for. + */ + + if (IS_NISCHAR (val->sp_namp[0])) { + if (val->sp_namp[1]) + nis_1_user = 1; + else + nis_state = start; + } + + /* + * If this isn't a NIS user and this isn't an escape to go + * use a NIS map, it must be a regular local user. + */ + + if (nis_1_user == 0 && nis_state != start) + return val; + + /* + * If this is an escape to use an NIS map, switch over to + * that bunch of code. + */ + + if (nis_state == start) + goto again; + + /* + * NEEDSWORK. Here we substitute pieces-parts of this entry. + */ + + return 0; + } else { + if (nis_bound == 0) { + if (bind_nis ()) { + nis_state = native2; + goto again; + } + } + if (nis_state == start) { + if (yp_first (nis_domain, "shadow.bynam", &nis_key, + &nis_keylen, &nis_val, &nis_vallen)) { + nis_state = native2; + goto again; + } + nis_state = middle; + } else if (nis_state == middle) { + if (yp_next (nis_domain, "shadow.bynam", nis_key, + nis_keylen, &nis_key, &nis_keylen, + &nis_val, &nis_vallen)) { + nis_state = native2; + goto again; + } + } + return my_sgetspent(nis_val); + } +#else + return (fgetspent (shadow)); +#endif +} + +/* + * getspnam - get a shadow entry by name + */ + +struct spwd * +getspnam(const char *name) +{ + struct spwd *sp; +#ifdef NDBM + datum key; + datum content; +#endif +#ifdef USE_NIS + char buf[BUFSIZ]; + static char save_name[16]; + int nis_disabled = 0; +#endif + + setspent (); + +#ifdef NDBM + + /* + * If the DBM file are now open, create a key for this UID and + * try to fetch the entry from the database. A matching record + * will be unpacked into a static structure and returned to + * the user. + */ + + if (dbmopened) { + key.dsize = strlen (name); + key.dptr = (char *) name; + + content = dbm_fetch (sp_dbm, key); + if (content.dptr != 0) { + memcpy (spwbuf, content.dptr, content.dsize); + spw_unpack (spwbuf, content.dsize, &spwd); + endspent(); + return &spwd; + } + } +#endif +#ifdef USE_NIS + /* + * Search the shadow.byname map for this user. + */ + + if (! nis_ignore && ! nis_bound) + bind_nis (); + + if (! nis_ignore && nis_bound) { + char *cp; + + if (yp_match (nis_domain, "shadow.byname", name, + strlen (name), &nis_val, &nis_vallen) == 0) { + + if (cp = strchr (nis_val, '\n')) + *cp = '\0'; + + nis_state = middle; + if ((sp = my_sgetspent(nis_val))) { + strcpy (save_name, sp->sp_namp); + nis_key = save_name; + nis_keylen = strlen (save_name); + } + endspent(); + return sp; + } else + nis_state = native2; + } +#endif +#ifdef USE_NIS + /* + * NEEDSWORK -- this is a mess, and it is the same mess in the + * other three files. I can't just blindly turn off NIS because + * this might be the first pass through the local files. In + * that case, I never discover that NIS is present. + */ + + if (nis_used) { + nis_ignore++; + nis_disabled++; + } +#endif + while ((sp = getspent ()) != (struct spwd *) 0) { + if (strcmp (name, sp->sp_namp) == 0) + break; + } +#ifdef USE_NIS + if (nis_disabled) + nis_ignore--; +#endif + endspent(); + return (sp); +} +#else +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /*}*/ diff --git a/current/lib/shadow_.h b/current/lib/shadow_.h new file mode 100644 index 00000000..ebb43802 --- /dev/null +++ b/current/lib/shadow_.h @@ -0,0 +1,89 @@ +/* + * Copyright 1988 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#ifndef _H_SHADOW +#define _H_SHADOW + +/* + * This information is not derived from AT&T licensed sources. Posted + * to the USENET 11/88, and updated 11/90 with information from SVR4. + * + * $Id: shadow_.h,v 1.2 1997/05/01 23:14:48 marekm Exp $ + */ + +#ifdef ITI_AGING +typedef time_t sptime; +#else +typedef long sptime; +#endif + +/* + * Shadow password security file structure. + */ + +struct spwd { + char *sp_namp; /* login name */ + char *sp_pwdp; /* encrypted password */ + sptime sp_lstchg; /* date of last change */ + sptime sp_min; /* minimum number of days between changes */ + sptime sp_max; /* maximum number of days between changes */ + sptime sp_warn; /* number of days of warning before password + expires */ + sptime sp_inact; /* number of days after password expires + until the account becomes unusable. */ + sptime sp_expire; /* days since 1/1/70 until account expires */ + unsigned long sp_flag; /* reserved for future use */ +}; + +/* + * Shadow password security file functions. + */ + +#include /* for FILE */ + +#if defined(__STDC__) +struct spwd *getspent (void); +struct spwd *getspnam (const char *); +struct spwd *sgetspent (const char *); +struct spwd *fgetspent (FILE *); +void setspent (void); +void endspent (void); +int putspent (const struct spwd *, FILE *); +#else +struct spwd *getspent (); +struct spwd *getspnam (); +struct spwd *sgetspent (); +struct spwd *fgetspent (); +void setspent (); +void endspent (); +int putspent (); +#endif + +#define SHADOW "/etc/shadow" +#endif diff --git a/current/lib/shadowio.c b/current/lib/shadowio.c new file mode 100644 index 00000000..e6707cf2 --- /dev/null +++ b/current/lib/shadowio.c @@ -0,0 +1,171 @@ + +#include + +#ifdef SHADOWPWD + +#include "rcsid.h" +RCSID("$Id: shadowio.c,v 1.12 2000/09/02 18:40:43 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#ifdef HAVE_SHADOW_H +# include +#endif +#include + +#include "commonio.h" +#include "shadowio.h" + +struct spwd * +__spw_dup(const struct spwd *spent) +{ + struct spwd *sp; + + if (!(sp = (struct spwd *) malloc(sizeof *sp))) + return NULL; + *sp = *spent; + if (!(sp->sp_namp = strdup(spent->sp_namp))) + return NULL; + if (!(sp->sp_pwdp = strdup(spent->sp_pwdp))) + return NULL; + return sp; +} + +static void * +shadow_dup(const void *ent) +{ + const struct spwd *sp = ent; + return __spw_dup(sp); +} + +static void +shadow_free(void *ent) +{ + struct spwd *sp = ent; + + free(sp->sp_namp); + free(sp->sp_pwdp); + free(sp); +} + +static const char * +shadow_getname(const void *ent) +{ + const struct spwd *sp = ent; + return sp->sp_namp; +} + +static void * +shadow_parse(const char *line) +{ + return (void *) sgetspent(line); +} + +static int +shadow_put(const void *ent, FILE *file) +{ + const struct spwd *sp = ent; + return (putspent(sp, file) == -1) ? -1 : 0; +} + +static struct commonio_ops shadow_ops = { + shadow_dup, + shadow_free, + shadow_getname, + shadow_parse, + shadow_put, + fgets, + fputs +}; + +static struct commonio_db shadow_db = { + SHADOW_FILE, /* filename */ + &shadow_ops, /* ops */ + NULL, /* fp */ + NULL, /* head */ + NULL, /* tail */ + NULL, /* cursor */ + 0, /* changed */ + 0, /* isopen */ + 0, /* locked */ + 0 /* readonly */ +}; + +int +spw_name(const char *filename) +{ + return commonio_setname(&shadow_db, filename); +} + +int +spw_file_present(void) +{ + return commonio_present(&shadow_db); +} + +int +spw_lock(void) +{ + return commonio_lock(&shadow_db); +} + +int +spw_open(int mode) +{ + return commonio_open(&shadow_db, mode); +} + +const struct spwd * +spw_locate(const char *name) +{ + return commonio_locate(&shadow_db, name); +} + +int +spw_update(const struct spwd *sp) +{ + return commonio_update(&shadow_db, (const void *) sp); +} + +int +spw_remove(const char *name) +{ + return commonio_remove(&shadow_db, name); +} + +int +spw_rewind(void) +{ + return commonio_rewind(&shadow_db); +} + +const struct spwd * +spw_next(void) +{ + return commonio_next(&shadow_db); +} + +int +spw_close(void) +{ + return commonio_close(&shadow_db); +} + +int +spw_unlock(void) +{ + return commonio_unlock(&shadow_db); +} + +struct commonio_entry * +__spw_get_head(void) +{ + return shadow_db.head; +} + +void +__spw_del_entry(const struct commonio_entry *ent) +{ + commonio_del_entry(&shadow_db, ent); +} +#endif diff --git a/current/lib/shadowio.h b/current/lib/shadowio.h new file mode 100644 index 00000000..b3118d5c --- /dev/null +++ b/current/lib/shadowio.h @@ -0,0 +1,13 @@ +extern struct spwd *__spw_dup(const struct spwd *); +extern void __spw_set_changed(void); +extern int spw_close(void); +extern int spw_file_present(void); +extern const struct spwd *spw_locate(const char *); +extern int spw_lock(void); +extern int spw_name(const char *); +extern const struct spwd *spw_next(void); +extern int spw_open(int); +extern int spw_remove(const char *); +extern int spw_rewind(void); +extern int spw_unlock(void); +extern int spw_update(const struct spwd *); diff --git a/current/lib/snprintf.c b/current/lib/snprintf.c new file mode 100644 index 00000000..c62366d9 --- /dev/null +++ b/current/lib/snprintf.c @@ -0,0 +1,320 @@ +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + **************************************************************/ + +/* $XFree86: xc/lib/misc/snprintf.c,v 3.0 1996/08/26 06:19:23 dawes Exp $ */ + +#include +#include "snprintf.h" + +static void dopr(); +static char *end; + +/* varargs declarations: */ + +#if defined(HAVE_STDARG_H) +# include +# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +# define VA_LOCAL_DECL va_list ap; +# define VA_START(f) va_start(ap, f) +# define VA_SHIFT(v,t) ; /* no-op for ANSI */ +# define VA_END va_end(ap) +#else +# if defined(HAVE_VARARGS_H) +# include +# undef HAVE_STDARGS +# define VA_LOCAL_DECL va_list ap; +# define VA_START(f) va_start(ap) /* f is ignored! */ +# define VA_SHIFT(v,t) v = va_arg(ap,t) +# define VA_END va_end(ap) +# else +/*XX ** NO VARARGS ** XX*/ +# endif +#endif + +#ifdef HAVE_STDARGS +int snprintf (char *str, size_t count, const char *fmt, ...); +int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); +#else +int snprintf (); +int vsnprintf (); +#endif + +int +vsnprintf(str, count, fmt, args) + char *str; + size_t count; + const char *fmt; + va_list args; +{ + str[0] = 0; + end = str+count-1; + dopr( str, fmt, args ); + if( count>0 ){ + end[0] = 0; + } + return(strlen(str)); +} + +/* VARARGS3 */ +#ifdef HAVE_STDARGS +int +snprintf (char *str,size_t count,const char *fmt,...) +#else +int +snprintf (va_alist) va_dcl +#endif +{ +#ifndef HAVE_STDARGS + char *str; + size_t count; + char *fmt; +#endif + VA_LOCAL_DECL + + VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t ); + VA_SHIFT (fmt, char *); + (void) vsnprintf ( str, count, fmt, ap); + VA_END; + return( strlen( str ) ); +} + +/* + * dopr(): poor man's version of doprintf + */ + +static void fmtstr( +#if NeedFunctionPrototypes + char *value, int ljust, int len, int zpad +#endif +); + +static void fmtnum( +#if NeedFunctionPrototypes + long value, int base, int dosign, int ljust, int len, int zpad +#endif +); + +static void dostr( +#if NeedFunctionPrototypes + char * +#endif +); + +static char *output; + +static void dopr_outch( +#if NeedFunctionPrototypes + int c +#endif +); + +static void +dopr( buffer, format, args ) + char *buffer; + char *format; + va_list args; +{ + int ch; + long value; + int longflag = 0; + char *strvalue; + int ljust; + int len; + int zpad; + + output = buffer; + while( (ch = *format++) ){ + switch( ch ){ + case '%': + ljust = len = zpad = 0; + nextch: + ch = *format++; + switch( ch ){ + case 0: + dostr( "**end of format**" ); + return; + case '-': ljust = 1; goto nextch; + case '0': /* set zero padding if len not set */ + if(len==0) zpad = '0'; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + len = len*10 + ch - '0'; + goto nextch; + case 'l': longflag = 1; goto nextch; + case 'u': case 'U': + /*fmtnum(value,base,dosign,ljust,len,zpad) */ + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 10,0, ljust, len, zpad ); break; + case 'o': case 'O': + /*fmtnum(value,base,dosign,ljust,len,zpad) */ + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 8,0, ljust, len, zpad ); break; + case 'd': case 'D': + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 10,1, ljust, len, zpad ); break; + case 'x': + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 16,0, ljust, len, zpad ); break; + case 'X': + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value,-16,0, ljust, len, zpad ); break; + case 's': + strvalue = va_arg( args, char *); + fmtstr( strvalue,ljust,len,zpad ); break; + case 'c': + ch = va_arg( args, int ); + dopr_outch( ch ); break; + case '%': dopr_outch( ch ); continue; + default: + dostr( "???????" ); + } + longflag = 0; + break; + default: + dopr_outch( ch ); + break; + } + } + *output = 0; +} + +static void +fmtstr( value, ljust, len, zpad ) + char *value; + int ljust, len, zpad; +{ + int padlen, strlen; /* amount to pad */ + + if( value == 0 ){ + value = ""; + } + for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */ + padlen = len - strlen; + if( padlen < 0 ) padlen = 0; + if( ljust ) padlen = -padlen; + while( padlen > 0 ) { + dopr_outch( ' ' ); + --padlen; + } + dostr( value ); + while( padlen < 0 ) { + dopr_outch( ' ' ); + ++padlen; + } +} + +static void +fmtnum( value, base, dosign, ljust, len, zpad ) + long value; + int base, dosign, ljust, len, zpad; +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int padlen = 0; /* amount to pad */ + int caps = 0; + + /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", + value, base, dosign, ljust, len, zpad )); */ + uvalue = value; + if( dosign ){ + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } + } + if( base < 0 ){ + caps = 1; + base = -base; + } + do{ + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + }while(uvalue); + convert[place] = 0; + padlen = len - place; + if( padlen < 0 ) padlen = 0; + if( ljust ) padlen = -padlen; + /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", + convert,place,signvalue,padlen)); */ + if( zpad && padlen > 0 ){ + if( signvalue ){ + dopr_outch( signvalue ); + --padlen; + signvalue = 0; + } + while( padlen > 0 ){ + dopr_outch( zpad ); + --padlen; + } + } + while( padlen > 0 ) { + dopr_outch( ' ' ); + --padlen; + } + if( signvalue ) dopr_outch( signvalue ); + while( place > 0 ) dopr_outch( convert[--place] ); + while( padlen < 0 ){ + dopr_outch( ' ' ); + ++padlen; + } +} + +static void +dostr( str ) + char *str; +{ + while(*str) dopr_outch(*str++); +} + +static void +dopr_outch( c ) + int c; +{ + if( iscntrl(c) && c != '\n' && c != '\t' ){ + c = '@' + (c & 0x1F); + if( end == 0 || output < end ){ + *output++ = '^'; + } + } + if( end == 0 || output < end ){ + *output++ = c; + } +} diff --git a/current/lib/snprintf.h b/current/lib/snprintf.h new file mode 100644 index 00000000..e900e31e --- /dev/null +++ b/current/lib/snprintf.h @@ -0,0 +1,51 @@ +/* $XFree86: xc/lib/misc/snprintf.h,v 3.1 1996/08/26 14:42:33 dawes Exp $ */ + +#ifndef SNPRINTF_H +#define SNPRINTF_H + +#ifdef HAS_SNPRINTF +#ifdef LIBXT +#define _XtSnprintf snprintf +#define _XtVsnprintf vsnprintf +#endif +#ifdef LIBX11 +#define _XSnprintf snprintf +#define _XVsnprintf vsnprintf +#endif +#else /* !HAS_SNPRINTF */ + +#ifdef LIBXT +#define snprintf _XtSnprintf +#define vsnprintf _XtVsnprintf +#endif +#ifdef LIBX11 +#define snprintf _XSnprintf +#define vsnprintf _XVsnprintf +#endif + +#if 1 /* the system might have no X11 headers. -MM */ +#include +#include +#else /* but we still need this... */ +#include +/* adjust the following defines if necessary (pre-ANSI) */ +#define NeedFunctionPrototypes 1 +#define NeedVarargsPrototypes 1 +#endif + +#if NeedVarargsPrototypes +#define HAVE_STDARG_H +#endif + +#ifdef HAVE_STDARG_H +#include +extern int snprintf (char *str, size_t count, const char *fmt, ...); +extern int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); +#else +extern int snprintf (); +extern int vsnprintf (); +#endif + +#endif /* HAS_SNPRINTF */ + +#endif /* SNPRINTF_H */ diff --git a/current/lib/spdbm.c b/current/lib/spdbm.c new file mode 100644 index 00000000..317ea6b7 --- /dev/null +++ b/current/lib/spdbm.c @@ -0,0 +1,116 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#if defined(SHADOWPWD) && defined(NDBM) /*{*/ + +#include "rcsid.h" +RCSID("$Id: spdbm.c,v 1.3 1997/12/07 23:26:58 marekm Exp $") + +#include +#include +#include "prototypes.h" +#include "defines.h" + +#include +extern DBM *sp_dbm; + +/* + * sp_dbm_update + * + * Updates the DBM password files, if they exist. + */ + +int +sp_dbm_update(struct spwd *sp) +{ + datum key; + datum content; + char data[BUFSIZ]; + int len; + static int once; + + if (! once) { + if (! sp_dbm) + setspent (); + + once++; + } + if (! sp_dbm) + return 0; + + len = spw_pack (sp, data); + + content.dsize = len; + content.dptr = data; + + key.dsize = strlen (sp->sp_namp); + key.dptr = sp->sp_namp; + if (dbm_store (sp_dbm, key, content, DBM_REPLACE)) + return 0; + + return 1; +} + +/* + * sp_dbm_remove + * + * Updates the DBM password files, if they exist. + */ + +int +sp_dbm_remove(char *user) +{ + datum key; + static int once; + + if (! once) { + if (! sp_dbm) + setspent (); + + once++; + } + if (! sp_dbm) + return 0; + + key.dsize = strlen (user); + key.dptr = user; + if (dbm_delete (sp_dbm, key)) + return 0; + + return 1; +} + +int +sp_dbm_present(void) +{ + return (access(SHADOW_PAG_FILE, F_OK) == 0); +} +#endif /*} SHADOWPWD && NDBM */ diff --git a/current/lib/sppack.c b/current/lib/sppack.c new file mode 100644 index 00000000..463f633a --- /dev/null +++ b/current/lib/sppack.c @@ -0,0 +1,113 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include +#ifdef SHADOWPWD /*{*/ + +#include "rcsid.h" +RCSID("$Id: sppack.c,v 1.3 1997/12/07 23:26:58 marekm Exp $") + +#include +#include +#include "defines.h" + +int +spw_pack(const struct spwd *spwd, char *buf) +{ + char *cp; + + cp = buf; + strcpy (cp, spwd->sp_namp); + cp += strlen (cp) + 1; + + strcpy (cp, spwd->sp_pwdp); + cp += strlen (cp) + 1; + + memcpy (cp, &spwd->sp_min, sizeof spwd->sp_min); + cp += sizeof spwd->sp_min; + + memcpy (cp, &spwd->sp_max, sizeof spwd->sp_max); + cp += sizeof spwd->sp_max; + + memcpy (cp, &spwd->sp_lstchg, sizeof spwd->sp_lstchg); + cp += sizeof spwd->sp_lstchg; + + memcpy (cp, &spwd->sp_warn, sizeof spwd->sp_warn); + cp += sizeof spwd->sp_warn; + + memcpy (cp, &spwd->sp_inact, sizeof spwd->sp_inact); + cp += sizeof spwd->sp_inact; + + memcpy (cp, &spwd->sp_expire, sizeof spwd->sp_expire); + cp += sizeof spwd->sp_expire; + + memcpy (cp, &spwd->sp_flag, sizeof spwd->sp_flag); + cp += sizeof spwd->sp_flag; + + return cp - buf; +} + +int +spw_unpack(char *buf, int len, struct spwd *spwd) +{ + char *org = buf; + + spwd->sp_namp = buf; + buf += strlen (buf) + 1; + + spwd->sp_pwdp = buf; + buf += strlen (buf) + 1; + + memcpy (&spwd->sp_min, buf, sizeof spwd->sp_min); + buf += sizeof spwd->sp_min; + + memcpy (&spwd->sp_max, buf, sizeof spwd->sp_max); + buf += sizeof spwd->sp_max; + + memcpy (&spwd->sp_lstchg, buf, sizeof spwd->sp_lstchg); + buf += sizeof spwd->sp_lstchg; + + memcpy (&spwd->sp_warn, buf, sizeof spwd->sp_warn); + buf += sizeof spwd->sp_warn; + + memcpy (&spwd->sp_inact, buf, sizeof spwd->sp_inact); + buf += sizeof spwd->sp_inact; + + memcpy (&spwd->sp_expire, buf, sizeof spwd->sp_expire); + buf += sizeof spwd->sp_expire; + + memcpy (&spwd->sp_flag, buf, sizeof spwd->sp_flag); + buf += sizeof spwd->sp_flag; + + if (buf - org > len) + return -1; + + return 0; +} +#endif /*}*/ diff --git a/current/lib/strcasecmp.c b/current/lib/strcasecmp.c new file mode 100644 index 00000000..414a47aa --- /dev/null +++ b/current/lib/strcasecmp.c @@ -0,0 +1,25 @@ +#include +#include "defines.h" +#include + +#include "rcsid.h" +RCSID("$Id: strcasecmp.c,v 1.1 1999/07/09 18:02:43 marekm Exp $") + +/* + * strcasecmp - compare strings, ignoring case + */ + +char * +strcasecmp(const char *s1, const char *s2) +{ + int ret; + + for (;;) { + ret = tolower(*s1) - tolower(*s2); + if (ret || *s1 == '\0' || *s2 == '\0') + break; + s1++; + s2++; + } + return ret; +} diff --git a/current/lib/strdup.c b/current/lib/strdup.c new file mode 100644 index 00000000..fe522b45 --- /dev/null +++ b/current/lib/strdup.c @@ -0,0 +1,16 @@ +#include +#include "defines.h" +#include "rcsid.h" +RCSID("$Id: strdup.c,v 1.2 1997/12/07 23:26:59 marekm Exp $") + +extern char *malloc(); + +char * +strdup(const char *str) +{ + char *s = malloc(strlen(str) + 1); + + if (s) + strcpy(s, str); + return s; +} diff --git a/current/lib/strerror.c b/current/lib/strerror.c new file mode 100644 index 00000000..184b1a46 --- /dev/null +++ b/current/lib/strerror.c @@ -0,0 +1,23 @@ +#include +#include +#include "defines.h" +#include "rcsid.h" +RCSID("$Id: strerror.c,v 1.3 1998/12/28 20:34:39 marekm Exp $") + +#include + +extern int sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(int err) +{ + static char unknown[80]; + + if (err >= 0 && err < sys_nerr) + return sys_errlist[err]; + + snprintf(unknown, sizeof unknown, _("Unknown error %d"), err); + errno = EINVAL; + return unknown; +} diff --git a/current/lib/strstr.c b/current/lib/strstr.c new file mode 100644 index 00000000..b4fca453 --- /dev/null +++ b/current/lib/strstr.c @@ -0,0 +1,55 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include +#include "defines.h" + +#include "rcsid.h" +RCSID("$Id: strstr.c,v 1.4 1998/01/29 23:22:32 marekm Exp $") + +/* + * strstr - find substring in string + */ + +char * +strstr(const char *string, const char *pattern) +{ + char *cp; + int len; + + len = strlen (pattern); + + for (cp = string;cp = strchr (cp, *pattern);) { + if (strncmp (cp, pattern, len) == 0) + return cp; + + cp++; + } + return 0; +} diff --git a/current/lib/tcfsio.c b/current/lib/tcfsio.c new file mode 100644 index 00000000..2649e0be --- /dev/null +++ b/current/lib/tcfsio.c @@ -0,0 +1,90 @@ + +#include + +#ifdef HAVE_TCFS + +#include "prototypes.h" +#include "defines.h" + +#ifdef TCFS_GDBM_SUPPORT +#undef GDBM_SUPPORT +#define GDBM_SUPPORT +#endif + +#include +#include + +#include "commonio.h" +#include "tcfsio.h" + +static struct commonio_db tcfs_db = { + TCFSPWDFILE, /* filename */ + NULL, /* ops */ + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0, + 0, + 1 +}; + +int +tcfs_file_present(void) +{ + return commonio_present(&tcfs_db); +} + +int +tcfs_lock(void) +{ + return commonio_lock(&tcfs_db); +} + +int +tcfs_open(int mode) +{ + return 1; +/* return tcfs_open(); */ +} + +tcfspwdb * +tcfs_locate(char *name) +{ + return tcfs_getpwnam(name, NULL); +} + +int +tcfs_update(char *user, struct tcfspwd *tcfspword) +{ + char *o, *p; + + o=(char*)calloc(128,sizeof(char)); + p=(char*)calloc(128,sizeof(char)); + strcpy (o, tcfspword->tcfsorig); + strcpy (p, tcfspword->tcfspass); + return tcfs_chgkey(user,o,p); +} + +int +tcfs_remove(char *name) +{ + return tcfs_putpwnam(name, NULL, U_DEL); +} + +int +tcfs_close(void) +{ + return 1; +/* return tcfs_close(&shadow_db); */ +} + +int +tcfs_unlock(void) +{ + return commonio_unlock(&tcfs_db); +} + +#endif diff --git a/current/lib/tcfsio.h b/current/lib/tcfsio.h new file mode 100644 index 00000000..3f53fca5 --- /dev/null +++ b/current/lib/tcfsio.h @@ -0,0 +1,14 @@ +struct tcfspwd { + char tcfspass[200]; /* new password */ + char tcfsorig[200]; /* old password */ +}; + +extern int tcfs_close(void); +extern int tcfs_file_present(void); +extern tcfspwdb *tcfs_locate(char *); +extern int tcfs_lock(void); +extern int tcfs_name(char *); +extern int tcfs_open(int); +extern int tcfs_remove(char *); +extern int tcfs_unlock(void); +extern int tcfs_update(char *, struct tcfspwd *); diff --git a/current/lib/utent.c b/current/lib/utent.c new file mode 100644 index 00000000..0b14d14c --- /dev/null +++ b/current/lib/utent.c @@ -0,0 +1,114 @@ +/* + * Copyright 1993 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifndef HAVE_GETUTENT + +#include "defines.h" +#include +#include +#include + +#ifndef lint +static char rcsid[] = "$Id: utent.c,v 1.4 1998/01/29 23:22:32 marekm Exp $"; +#endif + +static int utmp_fd = -1; +static struct utmp utmp_buf; + +/* + * setutent - open or rewind the utmp file + */ + +void +setutent(void) +{ + if (utmp_fd == -1) + if ((utmp_fd = open (_UTMP_FILE, O_RDWR)) == -1) + utmp_fd = open (_UTMP_FILE, O_RDONLY); + + if (utmp_fd != -1) + lseek (utmp_fd, (off_t) 0L, SEEK_SET); +} + +/* + * endutent - close the utmp file + */ + +void +endutent(void) +{ + if (utmp_fd != -1) + close (utmp_fd); + + utmp_fd = -1; +} + +/* + * getutent - get the next record from the utmp file + */ + +struct utmp * +getutent(void) +{ + if (utmp_fd == -1) + setutent (); + + if (utmp_fd == -1) + return 0; + + if (read (utmp_fd, &utmp_buf, sizeof utmp_buf) != sizeof utmp_buf) + return 0; + + return &utmp_buf; +} + +/* + * getutline - get the utmp entry matching ut_line + */ + +struct utmp * +getutline(const struct utmp *utent) +{ + struct utmp save; + struct utmp *new; + + save = *utent; + while (new = getutent ()) + if (strncmp (new->ut_line, save.ut_line, sizeof new->ut_line)) + continue; + else + return new; + + return (struct utmp *) 0; +} +#else +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif diff --git a/current/libmisc/Makefile.am b/current/libmisc/Makefile.am new file mode 100644 index 00000000..21fe04cd --- /dev/null +++ b/current/libmisc/Makefile.am @@ -0,0 +1,20 @@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +noinst_HEADERS = chkname.h failure.h getdate.h + +noinst_LIBRARIES = libmisc.a + +libdir = $(prefix)/lib +localedir = $(datadir)/locale +INCLUDES = -I$(top_srcdir)/libmisc -I$(top_srcdir)/lib +DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@ + +libmisc_a_SOURCES = addgrps.c age.c basename.c chkname.c chkshell.c \ + chowndir.c chowntty.c console.c copydir.c entry.c env.c failure.c \ + fields.c getdate.y hushed.c isexpired.c limits.c list.c log.c \ + login_access.c login_desrpc.c login_krb.c loginprompt.c mail.c motd.c \ + myname.c obscure.c pam_pass.c pwd2spwd.c pwdcheck.c pwd_init.c rlogin.c \ + salt.c setugid.c setup.c setupenv.c shell.c strtoday.c suauth.c sub.c \ + sulog.c ttytype.c tz.c ulimit.c utmp.c valid.c xmalloc.c + diff --git a/current/libmisc/Makefile.in b/current/libmisc/Makefile.in new file mode 100644 index 00000000..760788b5 --- /dev/null +++ b/current/libmisc/Makefile.in @@ -0,0 +1,435 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +noinst_HEADERS = chkname.h failure.h getdate.h + +noinst_LIBRARIES = libmisc.a + +libdir = $(prefix)/lib +localedir = $(datadir)/locale +INCLUDES = -I$(top_srcdir)/libmisc -I$(top_srcdir)/lib +DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@ + +libmisc_a_SOURCES = addgrps.c age.c basename.c chkname.c chkshell.c chowndir.c chowntty.c console.c copydir.c entry.c env.c failure.c fields.c getdate.y hushed.c isexpired.c limits.c list.c log.c login_access.c login_desrpc.c login_krb.c loginprompt.c mail.c motd.c myname.c obscure.c pam_pass.c pwd2spwd.c pwdcheck.c pwd_init.c rlogin.c salt.c setugid.c setup.c setupenv.c shell.c strtoday.c suauth.c sub.c sulog.c ttytype.c tz.c ulimit.c utmp.c valid.c xmalloc.c + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libmisc_a_LIBADD = +libmisc_a_OBJECTS = addgrps.o age.o basename.o chkname.o chkshell.o \ +chowndir.o chowntty.o console.o copydir.o entry.o env.o failure.o \ +fields.o getdate.o hushed.o isexpired.o limits.o list.o log.o \ +login_access.o login_desrpc.o login_krb.o loginprompt.o mail.o motd.o \ +myname.o obscure.o pam_pass.o pwd2spwd.o pwdcheck.o pwd_init.o rlogin.o \ +salt.o setugid.o setup.o setupenv.o shell.o strtoday.o suauth.o sub.o \ +sulog.o ttytype.o tz.o ulimit.o utmp.o valid.o xmalloc.o +AR = ar +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in getdate.c + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(libmisc_a_SOURCES) +OBJECTS = $(libmisc_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s .y +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps libmisc/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libmisc.a: $(libmisc_a_OBJECTS) $(libmisc_a_DEPENDENCIES) + -rm -f libmisc.a + $(AR) cru libmisc.a $(libmisc_a_OBJECTS) $(libmisc_a_LIBADD) + $(RANLIB) libmisc.a +.y.c: + $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c + if test -f y.tab.h; then \ + if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \ + else :; fi +getdate.h: getdate.c + + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = libmisc + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +addgrps.o: addgrps.c ../config.h ../lib/prototypes.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/rcsid.h +age.o: age.c ../config.h ../lib/prototypes.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/rcsid.h +basename.o: basename.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/prototypes.h +chkname.o: chkname.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h chkname.h +chkshell.o: chkshell.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +chowndir.o: chowndir.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +chowntty.o: chowntty.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +console.o: console.c ../config.h ../lib/defines.h ../lib/gshadow_.h \ + ../lib/getdef.h ../lib/rcsid.h +copydir.o: copydir.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +entry.o: entry.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +env.o: env.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +failure.o: failure.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/faillog.h ../lib/getdef.h failure.h +fields.o: fields.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +getdate.o: getdate.c ../config.h getdate.h ../lib/defines.h \ + ../lib/gshadow_.h +hushed.o: hushed.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/prototypes.h ../lib/getdef.h +isexpired.o: isexpired.c ../config.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/rcsid.h +limits.o: limits.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +list.o: list.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +login_access.o: login_access.c ../config.h ../lib/rcsid.h \ + ../lib/prototypes.h ../lib/defines.h ../lib/gshadow_.h +login_desrpc.o: login_desrpc.c ../config.h +login_krb.o: login_krb.c ../config.h +loginprompt.o: loginprompt.c ../config.h ../lib/rcsid.h \ + ../lib/prototypes.h ../lib/defines.h ../lib/gshadow_.h \ + ../lib/getdef.h +log.o: log.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h +mail.o: mail.c ../config.h ../lib/prototypes.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/getdef.h ../lib/rcsid.h +motd.o: motd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +myname.o: myname.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/prototypes.h +obscure.o: obscure.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +pam_pass.o: pam_pass.c ../config.h +pwd2spwd.o: pwd2spwd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +pwdcheck.o: pwdcheck.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwauth.h +pwd_init.o: pwd_init.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h +rlogin.o: rlogin.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +salt.o: salt.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +setugid.o: setugid.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +setupenv.o: setupenv.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +setup.o: setup.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +shell.o: shell.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +strtoday.o: strtoday.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h getdate.h +suauth.o: suauth.c ../config.h ../lib/prototypes.h ../lib/defines.h \ + ../lib/gshadow_.h +sub.o: sub.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +sulog.o: sulog.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +ttytype.o: ttytype.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +tz.o: tz.c ../config.h ../lib/rcsid.h ../lib/defines.h ../lib/gshadow_.h \ + ../lib/getdef.h +ulimit.o: ulimit.c ../config.h ../lib/rcsid.h +utmp.o: utmp.c ../config.h ../lib/defines.h ../lib/gshadow_.h \ + ../lib/rcsid.h +valid.o: valid.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +xmalloc.o: xmalloc.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + -test -z "getdatehgetdatec" || rm -f getdateh getdatec +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/libmisc/addgrps.c b/current/libmisc/addgrps.c new file mode 100644 index 00000000..589d295f --- /dev/null +++ b/current/libmisc/addgrps.c @@ -0,0 +1,89 @@ +#include + +#ifdef HAVE_SETGROUPS + +#include "prototypes.h" +#include "defines.h" + +#include +#include +#include + +#include "rcsid.h" +RCSID("$Id: addgrps.c,v 1.4 1998/12/28 20:34:41 marekm Exp $") + +#define SEP ",:" + +/* + * Add groups with names from LIST (separated by commas or colons) + * to the supplementary group set. Silently ignore groups which are + * already there. Warning: uses strtok(). + */ + +int +add_groups(const char *list) +{ + GETGROUPS_T *grouplist, *tmp; + int i, ngroups, added; + struct group *grp; + char *token; + char buf[1024]; + + if (strlen(list) >= sizeof(buf)) { + errno = EINVAL; + return -1; + } + strcpy(buf, list); + + i = 16; + for (;;) { + grouplist = malloc(i * sizeof(GETGROUPS_T)); + if (!grouplist) + return -1; + ngroups = getgroups(i, grouplist); + if (i > ngroups) + break; + /* not enough room, so try allocating a larger buffer */ + free(grouplist); + i *= 2; + } + if (ngroups < 0) { + free(grouplist); + return -1; + } + + added = 0; + for (token = strtok(buf, SEP); token; token = strtok(NULL, SEP)) { + + grp = getgrnam(token); + if (!grp) { + fprintf(stderr, _("Warning: unknown group %s\n"), token); + continue; + } + + for (i = 0; i < ngroups && grouplist[i] != grp->gr_gid; i++) + ; + + if (i < ngroups) + continue; + + if (ngroups >= NGROUPS_MAX) { + fprintf(stderr, _("Warning: too many groups\n")); + break; + } + tmp = realloc(grouplist, (ngroups + 1) * sizeof(GETGROUPS_T)); + if (!tmp) { + free(grouplist); + return -1; + } + tmp[ngroups++] = grp->gr_gid; + grouplist = tmp; + added++; + } + + if (added) + return setgroups(ngroups, grouplist); + + return 0; +} +#endif diff --git a/current/libmisc/age.c b/current/libmisc/age.c new file mode 100644 index 00000000..7d3b355f --- /dev/null +++ b/current/libmisc/age.c @@ -0,0 +1,235 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" +#include +#include +#ifdef HAVE_USERSEC_H +#include +#include +#include +#endif + +#ifndef AGING +#if defined(SHADOWPWD) || defined(HAVE_USERSEC_H) +#define AGING 1 +#endif +#else +#if !defined(SHADOWPWD) && !defined(HAVE_USERSEC_H) && !defined(ATT_AGE) +#undef AGING +#endif +#endif + +#if defined(SHADOWPWD) || defined(AGING) /*{*/ + +#include "rcsid.h" +RCSID("$Id: age.c,v 1.6 1998/12/28 20:34:42 marekm Exp $") + +#ifndef PASSWD_PROGRAM +#define PASSWD_PROGRAM "/bin/passwd" +#endif + +/* + * expire - force password change if password expired + * + * expire() calls /bin/passwd to change the user's password + * if it has expired. + */ + +#ifdef SHADOWPWD +int +expire(const struct passwd *pw, const struct spwd *sp) +{ +#else +int +expire(const struct passwd *pw) +{ +#endif + int status; + int child; + int pid; + +#ifdef SHADOWPWD + if (! sp) + sp = pwd_to_spwd (pw); +#endif + + /* + * See if the user's password has expired, and if so + * force them to change their password. + */ + +#ifdef SHADOWPWD + switch (status = isexpired (pw, sp)) +#else + switch (status = isexpired (pw)) +#endif + { + case 0: + return 0; + case 1: + printf(_("Your password has expired.")); + break; + case 2: + printf(_("Your password is inactive.")); + break; + case 3: + printf(_("Your login has expired.")); + break; + } + + /* + * Setting the maximum valid period to less than the minimum + * valid period means that the minimum period will never + * occur while the password is valid, so the user can never + * change that password. + */ + +#ifdef SHADOWPWD + if (status > 1 || sp->sp_max < sp->sp_min) +#else + if (status > 1 || c64i (pw->pw_age[0]) < c64i (pw->pw_age[1])) +#endif + { + puts(_(" Contact the system administrator.\n")); + exit(1); + } + puts(_(" Choose a new password.\n")); + fflush (stdout); + + /* + * Close all the files so that unauthorized access won't + * occur. This needs to be done anyway because those files + * might become stale after "passwd" is executed. + */ + +#ifdef SHADOWPWD + endspent (); +#endif + endpwent (); +#ifdef SHADOWGRP + endsgent (); +#endif + endgrent (); + + /* + * Execute the /bin/passwd command. The exit status will be + * examined to see what the result is. If there are any + * errors the routine will exit. This forces the user to + * change their password before being able to use the account. + */ + + if ((pid = fork ()) == 0) { + int err; + + /* + * Set the UID to be that of the user. This causes + * passwd to work just like it would had they executed + * it from the command line while logged in. + */ + if (setup_uid_gid(pw, 0)) + _exit(126); + + execl(PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *)0); + err = errno; + perror("Can't execute " PASSWD_PROGRAM); + _exit((err == ENOENT) ? 127 : 126); + } else if (pid == -1) { + perror("fork"); + exit(1); + } + while ((child = wait (&status)) != pid && child != -1) + ; + + if (child == pid && status == 0) + return 1; + + exit (1); + /*NOTREACHED*/ +} + +/* + * agecheck - see if warning is needed for password expiration + * + * agecheck sees how many days until the user's password is going + * to expire and warns the user of the pending password expiration. + */ + +#ifdef SHADOWPWD +void +agecheck(const struct passwd *pw, const struct spwd *sp) +{ +#else +void +agecheck(const struct passwd *pw) +{ +#endif + long now = time ((long *) 0) / SCALE; + long remain; + +#ifdef SHADOWPWD + if (! sp) + sp = pwd_to_spwd (pw); + + /* + * The last, max, and warn fields must be supported or the + * warning period cannot be calculated. + */ + + if (sp->sp_lstchg == -1 || sp->sp_max == -1 || sp->sp_warn == -1) + return; +#else + if (pw->pw_age[0] == '\0') + return; +#endif + +#ifdef SHADOWPWD + if ((remain = (sp->sp_lstchg + sp->sp_max) - now) <= sp->sp_warn) +#else + if ((remain = (a64l (pw->pw_age + 2) + c64i (pw->pw_age[0])) * 7 + - now) <= getdef_num ("PASS_WARN_AGE", 7)) +#endif + { + remain /= DAY/SCALE; + if (remain > 1) + printf(_("Your password will expire in %ld days.\n"), remain); + else if (remain == 1) + printf(_("Your password will expire tomorrow.\n")); + else if (remain == 0) + printf(_("Your password will expire today.\n")); + } +} +#endif /*}*/ diff --git a/current/libmisc/basename.c b/current/libmisc/basename.c new file mode 100644 index 00000000..caf3ccdd --- /dev/null +++ b/current/libmisc/basename.c @@ -0,0 +1,22 @@ +/* + * basename.c - not worth copyrighting :-). Some versions of Linux libc + * already have basename(), other versions don't. To avoid confusion, + * we will not use the function from libc and use a different name here. + * --marekm + */ + +#include + +#include "rcsid.h" +RCSID("$Id: basename.c,v 1.2 1997/12/07 23:27:00 marekm Exp $") + +#include "defines.h" +#include "prototypes.h" + +char * +Basename(char *str) +{ + char *cp = strrchr(str, '/'); + + return cp ? cp+1 : str; +} diff --git a/current/libmisc/chkname.c b/current/libmisc/chkname.c new file mode 100644 index 00000000..8e71d69a --- /dev/null +++ b/current/libmisc/chkname.c @@ -0,0 +1,73 @@ +/* + * check_user_name(), check_group_name() - check the new user/group + * name for validity; return value: 1 - OK, 0 - bad name + */ + +#include + +#include "rcsid.h" +RCSID("$Id: chkname.c,v 1.4 1998/04/16 19:57:43 marekm Exp $") + +#include +#include "defines.h" +#include "chkname.h" + +#if HAVE_UTMPX_H +#include +#else +#include +#endif + +static int +good_name(const char *name) +{ + /* + * User/group names must start with a letter, and may not + * contain colons, commas, newlines (used in passwd/group + * files...) or any non-printable characters. + */ + if (!*name || !isalpha(*name)) + return 0; + + while (*name) { + if (*name == ':' || *name == ',' || + *name == '\n' || !isprint(*name)) + return 0; + + name++; + } + + return 1; +} + +int +check_user_name(const char *name) +{ +#if HAVE_UTMPX_H + struct utmpx ut; +#else + struct utmp ut; +#endif + + /* + * User names are limited by whatever utmp can + * handle (usually max 8 characters). + */ + if (strlen(name) > sizeof(ut.ut_user)) + return 0; + + return good_name(name); +} + +int +check_group_name(const char *name) +{ + /* + * Arbitrary limit for group names - max 16 + * characters (same as on HP-UX 10). + */ + if (strlen(name) > 16) + return 0; + + return good_name(name); +} diff --git a/current/libmisc/chkname.h b/current/libmisc/chkname.h new file mode 100644 index 00000000..b9e3ae02 --- /dev/null +++ b/current/libmisc/chkname.h @@ -0,0 +1,15 @@ +/* $Id: chkname.h,v 1.2 2000/08/26 18:27:17 marekm Exp $ */ +#ifndef _CHKNAME_H_ +#define _CHKNAME_H_ + +/* + * check_user_name(), check_group_name() - check the new user/group + * name for validity; return value: 1 - OK, 0 - bad name + */ + +#include "defines.h" + +extern int check_user_name(const char *); +extern int check_group_name(const char *name); + +#endif diff --git a/current/libmisc/chkshell.c b/current/libmisc/chkshell.c new file mode 100644 index 00000000..d2a45d6f --- /dev/null +++ b/current/libmisc/chkshell.c @@ -0,0 +1,98 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: chkshell.c,v 1.1 1997/12/07 23:27:00 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +#ifndef SHELLS_FILE +#define SHELLS_FILE "/etc/shells" +#endif + +/* + * check_shell - see if the user's login shell is listed in /etc/shells + * + * The /etc/shells file is read for valid names of login shells. If the + * /etc/shells file does not exist the user cannot set any shell unless + * they are root. + * + * If getusershell() is available (Linux, *BSD, possibly others), use it + * instead of re-implementing it. + */ + +int +check_shell(const char *sh) +{ + char *cp; + int found = 0; +#ifndef HAVE_GETUSERSHELL + char buf[BUFSIZ]; + FILE *fp; +#endif + +#ifdef HAVE_GETUSERSHELL + setusershell(); + while ((cp = getusershell())) { + if (*cp == '#') + continue; + + if (strcmp(cp, sh) == 0) { + found = 1; + break; + } + } + endusershell(); +#else + if ((fp = fopen (SHELLS_FILE, "r")) == (FILE *) 0) + return 0; + + while (fgets (buf, sizeof(buf), fp)) { + if ((cp = strrchr(buf, '\n'))) + *cp = '\0'; + + if (buf[0] == '#') + continue; + + if (strcmp (buf, sh) == 0) { + found = 1; + break; + } + } + fclose (fp); +#endif + return found; +} + diff --git a/current/libmisc/chowndir.c b/current/libmisc/chowndir.c new file mode 100644 index 00000000..b89c5973 --- /dev/null +++ b/current/libmisc/chowndir.c @@ -0,0 +1,132 @@ +/* + * Copyright 1992, 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: chowndir.c,v 1.6 2000/08/26 18:27:17 marekm Exp $") + +#include +#include +#include "prototypes.h" +#include "defines.h" + +#include +#include + +/* + * chown_tree - change ownership of files in a directory tree + * + * chown_dir() walks a directory tree and changes the ownership + * of all files owned by the provided user ID. + */ + +int +chown_tree(const char *root, uid_t old_uid, uid_t new_uid, gid_t old_gid, gid_t new_gid) +{ + char new_name[1024]; + int rc = 0; + struct DIRECT *ent; + struct stat sb; + DIR *dir; + + /* + * Make certain the directory exists. This routine is called + * directory by the invoker, or recursively. + */ + + if (access(root, F_OK) != 0) + return -1; + + /* + * Open the directory and read each entry. Every entry is tested + * to see if it is a directory, and if so this routine is called + * recursively. If not, it is checked to see if it is owned by + * old user ID. + */ + + if (! (dir = opendir (root))) + return -1; + + while ((ent = readdir (dir))) { + + /* + * Skip the "." and ".." entries + */ + + if (strcmp (ent->d_name, ".") == 0 || + strcmp (ent->d_name, "..") == 0) + continue; + + /* + * Make the filename for both the source and the + * destination files. + */ + + if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name) + break; + + snprintf(new_name, sizeof new_name, "%s/%s", root, ent->d_name); + + /* Don't follow symbolic links! */ + if (LSTAT(new_name, &sb) == -1) + continue; + + if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) { + + /* + * Do the entire subdirectory. + */ + + if ((rc = chown_tree (new_name, old_uid, new_uid, + old_gid, new_gid))) + break; + } +#ifndef HAVE_LCHOWN + /* don't use chown (follows symbolic links!) */ + if (S_ISLNK(sb.st_mode)) + continue; +#endif + if (sb.st_uid == old_uid) + LCHOWN(new_name, new_uid, + sb.st_gid == old_gid ? new_gid:sb.st_gid); + } + closedir (dir); + + /* + * Now do the root of the tree + */ + + if (! stat (root, &sb)) { + if (sb.st_uid == old_uid) + LCHOWN(root, new_uid, + sb.st_gid == old_gid ? new_gid:sb.st_gid); + } + return rc; +} diff --git a/current/libmisc/chowntty.c b/current/libmisc/chowntty.c new file mode 100644 index 00000000..f52b5a4a --- /dev/null +++ b/current/libmisc/chowntty.c @@ -0,0 +1,127 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: chowntty.c,v 1.7 1998/12/28 20:34:43 marekm Exp $") + +#include +#include + +#include +#include + +#include "prototypes.h" +#include "defines.h" +#include +#include "getdef.h" + +/* + * is_my_tty -- determine if "tty" is the same as TTY stdin is using + */ + +static int +is_my_tty(const char *tty) +{ + struct stat by_name, by_fd; + + if (stat (tty, &by_name) || fstat (0, &by_fd)) + return 0; + + if (by_name.st_rdev != by_fd.st_rdev) + return 0; + else + return 1; +} + +/* + * chown_tty() sets the login tty to be owned by the new user ID + * with TTYPERM modes + */ + +void +chown_tty(const char *tty, const struct passwd *info) +{ + char buf[200], full_tty[200]; + char *group; /* TTY group name or number */ + struct group *grent; + gid_t gid; + + /* + * See if login.defs has some value configured for the port group + * ID. Otherwise, use the user's primary group ID. + */ + + if (! (group = getdef_str ("TTYGROUP"))) + gid = info->pw_gid; + else if (group[0] >= '0' && group[0] <= '9') + gid = atoi (group); + else if ((grent = getgrnam (group))) + gid = grent->gr_gid; + else + gid = info->pw_gid; + + /* + * Change the permissions on the TTY to be owned by the user with + * the group as determined above. + */ + + if (*tty != '/') { + snprintf(full_tty, sizeof full_tty, "/dev/%s", tty); + tty = full_tty; + } + + if (! is_my_tty (tty)) { + SYSLOG((LOG_WARN, "unable to determine TTY name, got %s\n", + tty)); + closelog(); + exit (1); + } + + if (chown(tty, info->pw_uid, gid) || + chmod(tty, getdef_num("TTYPERM", 0600))) { + snprintf(buf, sizeof buf, _("Unable to change tty %s"), tty); + SYSLOG((LOG_WARN, "unable to change tty `%s' for user `%s'\n", + tty, info->pw_name)); + closelog(); + perror (buf); + exit(1); + } + +#ifdef __linux__ + /* + * Please don't add code to chown /dev/vcs* to the user logging in - + * it's a potential security hole. I wouldn't like the previous user + * to hold the file descriptor open and watch my screen. We don't + * have the *BSD revoke() system call yet, and vhangup() only works + * for tty devices (which vcs* is not). --marekm + */ +#endif +} diff --git a/current/libmisc/console.c b/current/libmisc/console.c new file mode 100644 index 00000000..75e69074 --- /dev/null +++ b/current/libmisc/console.c @@ -0,0 +1,115 @@ +/* + * Copyright 1991, Julianne Frances Haugh and Chip Rosenthal + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include +#include "defines.h" +#include +#include "getdef.h" + +#include "rcsid.h" +RCSID("$Id: console.c,v 1.5 1998/12/28 20:34:44 marekm Exp $") + +/* + * This is now rather generic function which decides if "tty" is listed + * under "cfgin" in config (directly or indirectly). Fallback to default if + * something is bad. + */ +int +is_listed(const char *cfgin, const char *tty, int def) +{ + FILE *fp; + char buf[200], *cons, *s; + + /* + * If the CONSOLE configuration definition isn't given, + * fallback to default. + */ + + if ((cons = getdef_str(cfgin)) == NULL) + return def; + + /* + * If this isn't a filename, then it is a ":" delimited list of + * console devices upon which root logins are allowed. + */ + + if (*cons != '/') { + cons = strcpy(buf, cons); + while ((s = strtok(cons, ":")) != NULL) { + if (strcmp(s, tty) == 0) + return 1; + + cons = NULL; + } + return 0; + } + + /* + * If we can't open the console list, then call everything a + * console - otherwise root will never be allowed to login. + */ + + if ((fp = fopen(cons, "r")) == NULL) + return def; + + /* + * See if this tty is listed in the console file. + */ + + while (fgets(buf, sizeof(buf), fp) != NULL) { + buf[strlen(buf) - 1] = '\0'; + if (strcmp(buf, tty) == 0) { + (void) fclose(fp); + return 1; + } + } + + /* + * This tty isn't a console. + */ + + (void) fclose(fp); + return 0; +} + +/* + * console - return 1 if the "tty" is a console device, else 0. + * + * Note - we need to take extreme care here to avoid locking out root logins + * if something goes awry. That's why we do things like call everything a + * console if the consoles file can't be opened. Because of this, we must + * warn the user to protect against the remove of the consoles file since + * that would allow an unauthorized root login. + */ + +int +console(const char *tty) +{ + return is_listed("CONSOLE", tty, 1); +} diff --git a/current/libmisc/copydir.c b/current/libmisc/copydir.c new file mode 100644 index 00000000..0f7fed2d --- /dev/null +++ b/current/libmisc/copydir.c @@ -0,0 +1,403 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: copydir.c,v 1.7 2000/08/26 18:27:17 marekm Exp $") + + +#include + +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" + +static const char *src_orig; +static const char *dst_orig; + +struct link_name { + dev_t ln_dev; + ino_t ln_ino; + int ln_count; + char *ln_name; + struct link_name *ln_next; +}; +static struct link_name *links; + +/* + * remove_link - delete a link from the link list + */ + +static void +remove_link(struct link_name *ln) +{ + struct link_name *lp; + + if (links == ln) { + links = ln->ln_next; + free (ln->ln_name); + free (ln); + return; + } + for (lp = links;lp;lp = lp->ln_next) + if (lp->ln_next == ln) + break; + + if (! lp) + return; + + lp->ln_next = lp->ln_next->ln_next; + free (ln->ln_name); + free (ln); +} + +/* + * check_link - see if a file is really a link + */ + +static struct link_name * +check_link(const char *name, const struct stat *sb) +{ + struct link_name *lp; + int src_len; + int dst_len; + int name_len; + int len; + + for (lp = links;lp;lp = lp->ln_next) + if (lp->ln_dev == sb->st_dev && lp->ln_ino == sb->st_ino) + return lp; + + if (sb->st_nlink == 1) + return 0; + + lp = (struct link_name *) xmalloc (sizeof *lp); + src_len = strlen (src_orig); + dst_len = strlen (dst_orig); + name_len = strlen (name); + lp->ln_dev = sb->st_dev; + lp->ln_ino = sb->st_ino; + lp->ln_count = sb->st_nlink; + len = name_len - src_len + dst_len + 1; + lp->ln_name = xmalloc(len); + snprintf(lp->ln_name, len, "%s%s", dst_orig, name + src_len); + lp->ln_next = links; + links = lp; + + return 0; +} + +/* + * copy_tree - copy files in a directory tree + * + * copy_tree() walks a directory tree and copies ordinary files + * as it goes. + */ + +int +copy_tree(const char *src_root, const char *dst_root, uid_t uid, gid_t gid) +{ + char src_name[1024]; + char dst_name[1024]; + char buf[1024]; + int ifd; + int ofd; + int err = 0; + int cnt; + int set_orig = 0; + struct DIRECT *ent; + struct stat sb; + struct link_name *lp; + DIR *dir; + + /* + * Make certain both directories exist. This routine is called + * after the home directory is created, or recursively after the + * target is created. It assumes the target directory exists. + */ + + if (access(src_root, F_OK) != 0 || access(dst_root, F_OK) != 0) + return -1; + + /* + * Open the source directory and read each entry. Every file + * entry in the directory is copied with the UID and GID set + * to the provided values. As an added security feature only + * regular files (and directories ...) are copied, and no file + * is made set-ID. + */ + + if (! (dir = opendir (src_root))) + return -1; + + if (src_orig == 0) { + src_orig = src_root; + dst_orig = dst_root; + set_orig++; + } + while ((ent = readdir (dir))) { + + /* + * Skip the "." and ".." entries + */ + + if (strcmp (ent->d_name, ".") == 0 || + strcmp (ent->d_name, "..") == 0) + continue; + + /* + * Make the filename for both the source and the + * destination files. + */ + + if (strlen (src_root) + strlen (ent->d_name) + 2 > sizeof src_name) { + err++; + break; + } + snprintf(src_name, sizeof src_name, "%s/%s", src_root, ent->d_name); + + if (strlen (dst_root) + strlen (ent->d_name) + 2 > sizeof dst_name) { + err++; + break; + } + snprintf(dst_name, sizeof dst_name, "%s/%s", dst_root, ent->d_name); + + if (LSTAT(src_name, &sb) == -1) + continue; + + if (S_ISDIR(sb.st_mode)) { + + /* + * Create a new target directory, make it owned by + * the user and then recursively copy that directory. + */ + + mkdir (dst_name, sb.st_mode & 0777); + chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid, + gid == (gid_t) -1 ? sb.st_gid:gid); + + if (copy_tree (src_name, dst_name, uid, gid)) { + err++; + break; + } + continue; + } +#ifdef S_IFLNK + /* + * Copy any symbolic links + */ + + if (S_ISLNK(sb.st_mode)) { + char oldlink[1024]; + char dummy[1024]; + int len; + + /* + * Get the name of the file which the link points + * to. If that name begins with the original + * source directory name, that part of the link + * name will be replaced with the original + * destinateion directory name. + */ + + if ((len = readlink(src_name, oldlink, sizeof(oldlink) - 1)) < 0) { + err++; + break; + } + oldlink[len] = '\0'; /* readlink() does not NUL-terminate */ + if (!strncmp(oldlink, src_orig, strlen(src_orig))) { + snprintf(dummy, sizeof dummy, "%s%s", + dst_orig, oldlink + strlen(src_orig)); + strcpy(oldlink, dummy); + } + if (symlink(oldlink, dst_name)) { + err++; + break; + } + continue; + } +#endif + + /* + * See if this is a previously copied link + */ + + if ((lp = check_link (src_name, &sb))) { + if (link (lp->ln_name, dst_name)) { + err++; + break; + } + if (unlink (src_name)) { + err++; + break; + } + if (--lp->ln_count <= 0) + remove_link (lp); + + continue; + } + + /* + * Deal with FIFOs and special files. The user really + * shouldn't have any of these, but it seems like it + * would be nice to copy everything ... + */ + + if (!S_ISREG(sb.st_mode)) { + if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev) || + chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid, + gid == (gid_t) -1 ? sb.st_gid:gid) || + chmod (dst_name, sb.st_mode & 07777)) { + err++; + break; + } + continue; + } + + /* + * Create the new file and copy the contents. The new + * file will be owned by the provided UID and GID values. + */ + + if ((ifd = open (src_name, O_RDONLY)) < 0) { + err++; + break; + } + if ((ofd = open (dst_name, O_WRONLY|O_CREAT, 0)) < 0 || + chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid, + gid == (gid_t) -1 ? sb.st_gid:gid) || + chmod (dst_name, sb.st_mode & 07777)) { + close (ifd); + err++; + break; + } + while ((cnt = read (ifd, buf, sizeof buf)) > 0) { + if (write (ofd, buf, cnt) != cnt) { + cnt = -1; + break; + } + } + close (ifd); + close (ofd); + + if (cnt == -1) { + err++; + break; + } + } + closedir (dir); + + if (set_orig) { + src_orig = 0; + dst_orig = 0; + } + return err ? -1:0; +} + +/* + * remove_tree - remove files in a directory tree + * + * remove_tree() walks a directory tree and deletes all the files + * and directories. + */ + +int +remove_tree(const char *root) +{ + char new_name[1024]; + int err = 0; + struct DIRECT *ent; + struct stat sb; + DIR *dir; + + /* + * Make certain the directory exists. + */ + + if (access(root, F_OK) != 0) + return -1; + + /* + * Open the source directory and read each entry. Every file + * entry in the directory is copied with the UID and GID set + * to the provided values. As an added security feature only + * regular files (and directories ...) are copied, and no file + * is made set-ID. + */ + + dir = opendir (root); + + while ((ent = readdir (dir))) { + + /* + * Skip the "." and ".." entries + */ + + if (strcmp (ent->d_name, ".") == 0 || + strcmp (ent->d_name, "..") == 0) + continue; + + /* + * Make the filename for the current entry. + */ + + if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name) { + err++; + break; + } + snprintf(new_name, sizeof new_name, "%s/%s", root, ent->d_name); + if (LSTAT(new_name, &sb) == -1) + continue; + + if (S_ISDIR(sb.st_mode)) { + + /* + * Recursively delete this directory. + */ + + if (remove_tree (new_name)) { + err++; + break; + } + if (rmdir (new_name)) { + err++; + break; + } + continue; + } + unlink (new_name); + } + closedir (dir); + + return err ? -1:0; +} diff --git a/current/libmisc/entry.c b/current/libmisc/entry.c new file mode 100644 index 00000000..746dfb0a --- /dev/null +++ b/current/libmisc/entry.c @@ -0,0 +1,99 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: entry.c,v 1.4 2000/08/26 18:27:17 marekm Exp $") + +#include +#include +#include "prototypes.h" +#include "defines.h" +#include + +extern struct passwd *fgetpwent (); + +void +pw_entry(const char *name, struct passwd *pwent) +{ + struct passwd *passwd; +#ifdef SHADOWPWD + struct spwd *spwd; +#ifdef ATT_AGE + char *l64a (); + char *cp; +#endif +#endif + + if (! (passwd = getpwnam (name))) { + pwent->pw_name = (char *) 0; + return; + } else { + pwent->pw_name = xstrdup (passwd->pw_name); + pwent->pw_uid = passwd->pw_uid; + pwent->pw_gid = passwd->pw_gid; +#ifdef ATT_COMMENT + pwent->pw_comment = xstrdup (passwd->pw_comment); +#endif + pwent->pw_gecos = xstrdup (passwd->pw_gecos); + pwent->pw_dir = xstrdup (passwd->pw_dir); + pwent->pw_shell = xstrdup (passwd->pw_shell); +#if defined(SHADOWPWD) && !defined(AUTOSHADOW) + setspent (); + if ((spwd = getspnam (name))) { + pwent->pw_passwd = xstrdup (spwd->sp_pwdp); +#ifdef ATT_AGE + pwent->pw_age = (char *) xmalloc (5); + + if (spwd->sp_max > (63*7)) + spwd->sp_max = (63*7); + if (spwd->sp_min > (63*7)) + spwd->sp_min = (63*7); + + pwent->pw_age[0] = i64c (spwd->sp_max / 7); + pwent->pw_age[1] = i64c (spwd->sp_min / 7); + + cp = l64a (spwd->sp_lstchg / 7); + pwent->pw_age[2] = cp[0]; + pwent->pw_age[3] = cp[1]; + + pwent->pw_age[4] = '\0'; +#endif + endspent (); + return; + } + endspent (); +#endif + pwent->pw_passwd = xstrdup (passwd->pw_passwd); +#ifdef ATT_AGE + pwent->pw_age = xstrdup (passwd->pw_age); +#endif + } +} diff --git a/current/libmisc/env.c b/current/libmisc/env.c new file mode 100644 index 00000000..8d7b2a11 --- /dev/null +++ b/current/libmisc/env.c @@ -0,0 +1,250 @@ +/* + * Copyright 1989 - 1992, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: env.c,v 1.9 1999/03/07 19:14:38 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +/* + * NEWENVP_STEP must be a power of two. This is the number + * of (char *) pointers to allocate at a time, to avoid using + * realloc() too often. + */ +#define NEWENVP_STEP 16 + +size_t newenvc = 0; +char **newenvp = NULL; +extern char **environ; + +static const char *forbid[] = { + "_RLD_=", + "BASH_ENV=", /* GNU creeping featurism strikes again... */ + "ENV=", + "HOME=", + "IFS=", + "KRB_CONF=", + "LD_", /* anything with the LD_ prefix */ + "LIBPATH=", + "MAIL=", + "NLSPATH=", + "PATH=", + "SHELL=", + "SHLIB_PATH=", + (char *) 0 +}; + +/* these are allowed, but with no slashes inside + (to work around security problems in GNU gettext) */ +static const char *noslash[] = { + "LANG=", + "LANGUAGE=", + "LC_", /* anything with the LC_ prefix */ + (char *) 0 +}; + +/* + * initenv() must be called once before using addenv(). + */ +void +initenv(void) +{ + newenvp = (char **)xmalloc(NEWENVP_STEP * sizeof(char *)); + *newenvp = NULL; +} + + +void +addenv(const char *string, const char *value) +{ + char *cp, *newstring; + size_t i; + size_t n; + + if (value) { + newstring = xmalloc(strlen(string) + strlen(value) + 2); + sprintf(newstring, "%s=%s", string, value); + } else { + newstring = xstrdup(string); + } + + /* + * Search for a '=' character within the string and if none is found + * just ignore the whole string. + */ + + cp = strchr(newstring, '='); + if (!cp) { + free(newstring); + return; + } + + n = (size_t)(cp - newstring); + + for (i = 0; i < newenvc; i++) { + if (strncmp(newstring, newenvp[i], n) == 0 && + (newenvp[i][n] == '=' || newenvp[i][n] == '\0')) + break; + } + + if (i < newenvc) { + free(newenvp[i]); + newenvp[i] = newstring; + return; + } + + newenvp[newenvc++] = newstring; + + /* + * Check whether newenvc is a multiple of NEWENVP_STEP. + * If so we have to resize the vector. + * the expression (newenvc & (NEWENVP_STEP - 1)) == 0 + * is equal to (newenvc % NEWENVP_STEP) == 0 + * as long as NEWENVP_STEP is a power of 2. + */ + + if ((newenvc & (NEWENVP_STEP - 1)) == 0) { + char **__newenvp; + size_t newsize; + + /* + * If the resize operation succeds we can + * happily go on, else print a message. + */ + + newsize = (newenvc + NEWENVP_STEP) * sizeof(char *); + __newenvp = (char **)realloc(newenvp, newsize); + + if (__newenvp) { + /* + * If this is our current environment, update + * environ so that it doesn't point to some + * free memory area (realloc() could move it). + */ + if (environ == newenvp) + environ = __newenvp; + newenvp = __newenvp; + } else { + fprintf(stderr, _("Environment overflow\n")); + free(newenvp[--newenvc]); + } + } + + /* + * The last entry of newenvp must be NULL + */ + + newenvp[newenvc] = NULL; +} + + +/* + * set_env - copy command line arguments into the environment + */ +void +set_env(int argc, char * const *argv) +{ + int noname = 1; + char variable[1024]; + char *cp; + + for ( ; argc > 0; argc--, argv++) { + if (strlen(*argv) >= sizeof variable) + continue; /* ignore long entries */ + + if (! (cp = strchr (*argv, '='))) { + snprintf(variable, sizeof variable, "L%d", noname++); + addenv(variable, *argv); + } else { + const char **p; + + for (p = forbid; *p; p++) + if (strncmp(*argv, *p, strlen(*p)) == 0) + break; + + if (*p) { + strncpy(variable, *argv, cp - *argv); + variable[cp - *argv] = '\0'; + printf(_("You may not change $%s\n"), variable); + continue; + } + + addenv(*argv, NULL); + } + } +} + +/* + * sanitize_env - remove some nasty environment variables + * If you fall into a total paranoia, you should call this + * function for any root-setuid program or anything the user + * might change the environment with. 99% useless as almost + * all modern Unixes will handle setuid executables properly, + * but... I feel better with that silly precaution. -j. + */ + +void +sanitize_env(void) +{ + char **envp = environ; + const char **bad; + char **cur; + char **move; + + for (cur = envp; *cur; cur++) { + for (bad = forbid; *bad; bad++) { + if (strncmp(*cur, *bad, strlen(*bad)) == 0) { + for (move = cur; *move; move++) + *move = *(move + 1); + cur--; + break; + } + } + } + + for (cur = envp; *cur; cur++) { + for (bad = noslash; *bad; bad++) { + if (strncmp(*cur, *bad, strlen(*bad)) != 0) + continue; + if (!strchr(*cur, '/')) + continue; /* OK */ + for (move = cur; *move; move++) + *move = *(move + 1); + cur--; + break; + } + } +} + diff --git a/current/libmisc/failure.c b/current/libmisc/failure.c new file mode 100644 index 00000000..6f62ef1f --- /dev/null +++ b/current/libmisc/failure.c @@ -0,0 +1,278 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: failure.c,v 1.6 1998/12/28 20:34:46 marekm Exp $") + +#include +#include +#include "defines.h" +#include "faillog.h" +#include "getdef.h" +#include "failure.h" + +#include + +#define YEAR (365L*DAY) + +/* + * failure - make failure entry + * + * failure() creates a new (struct faillog) entry or updates an + * existing one with the current failed login information. + */ + +void +failure(uid_t uid, const char *tty, struct faillog *fl) +{ + int fd; + + /* + * Don't do anything if failure logging isn't set up. + */ + + if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0) + return; + + /* + * The file is indexed by uid value meaning that shared UID's + * share failure log records. That's OK since they really + * share just about everything else ... + */ + + lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET); + if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl) + memzero(fl, sizeof *fl); + + /* + * Update the record. We increment the failure count to log the + * latest failure. The only concern here is overflow, and we'll + * check for that. The line name and time of day are both + * updated as well. + */ + + if (fl->fail_cnt + 1 > 0) + fl->fail_cnt++; + + strncpy(fl->fail_line, tty, sizeof fl->fail_line); + time(&fl->fail_time); + + /* + * Seek back to the correct position in the file and write the + * record out. Ideally we should lock the file in case the same + * account is being logged simultaneously. But the risk doesn't + * seem that great. + */ + + lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET); + write(fd, (char *) fl, sizeof *fl); + close(fd); +} + +static int +too_many_failures(const struct faillog *fl) +{ + time_t now; + + if (fl->fail_max == 0 || fl->fail_cnt < fl->fail_max) + return 0; + + if (fl->fail_locktime == 0) + return 1; /* locked until reset manually */ + + time(&now); + if (fl->fail_time + fl->fail_locktime > now) + return 0; /* enough time since last failure */ + + return 1; +} + +/* + * failcheck - check for failures > allowable + * + * failcheck() is called AFTER the password has been validated. If the + * account has been "attacked" with too many login failures, failcheck() + * returns FALSE to indicate that the login should be denied even though + * the password is valid. + */ + +int +failcheck(uid_t uid, struct faillog *fl, int failed) +{ + int fd; + struct faillog fail; + + /* + * Suppress the check if the log file isn't there. + */ + + if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0) + return 1; + + /* + * Get the record from the file and determine if the user has + * exceeded the failure limit. If "max" is zero, any number + * of failures are permitted. Only when "max" is non-zero and + * "cnt" is greater than or equal to "max" is the account + * considered to be locked. + * + * If read fails, there is no record for this user yet (the + * file is initially zero length and extended by writes), so + * no need to reset the count. + */ + + lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET); + if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl) { + close(fd); + return 1; + } + + if (too_many_failures(fl)) { + close(fd); + return 0; + } + + /* + * The record is updated if this is not a failure. The count will + * be reset to zero, but the rest of the information will be left + * in the record in case someone wants to see where the failed + * login originated. + */ + + if (!failed) { + fail = *fl; + fail.fail_cnt = 0; + + lseek (fd, (off_t) sizeof fail * uid, SEEK_SET); + write (fd, (char *) &fail, sizeof fail); + } + close (fd); + return 1; +} + +/* + * failprint - print line of failure information + * + * failprint takes a (struct faillog) entry and formats it into a + * message which is displayed at login time. + */ + +void +failprint(const struct faillog *fail) +{ + struct tm *tp; +#if HAVE_STRFTIME + char lasttimeb[256]; + char *lasttime = lasttimeb; + const char *fmt; +#else + char *lasttime; +#endif + time_t NOW; + + if (fail->fail_cnt == 0) + return; + + tp = localtime (&(fail->fail_time)); + time(&NOW); + +#if HAVE_STRFTIME + /* + * Only print as much date and time info as it needed to + * know when the failure was. + */ + + if (NOW - fail->fail_time >= YEAR) + fmt = "%Y"; + else if (NOW - fail->fail_time >= DAY) + fmt = "%A %T"; + else + fmt = "%T"; + strftime(lasttimeb, sizeof lasttimeb, fmt, tp); +#else + + /* + * Do the same thing, but don't use strftime since it + * probably doesn't exist on this system + */ + + lasttime = asctime (tp); + lasttime[24] = '\0'; + + if (NOW - fail->fail_time < YEAR) + lasttime[19] = '\0'; + if (NOW - fail->fail_time < DAY) + lasttime = lasttime + 11; + + if (*lasttime == ' ') + lasttime++; +#endif + printf (_("%d %s since last login. Last was %s on %s.\n"), + fail->fail_cnt, fail->fail_cnt > 1 ? _("failures"):_("failure"), + lasttime, fail->fail_line); +} + +/* + * failtmp - update the cummulative failure log + * + * failtmp updates the (struct utmp) formatted failure log which + * maintains a record of all login failures. + */ + +void +failtmp(const struct utmp *failent) +{ + char *ftmp; + int fd; + + /* + * Get the name of the failure file. If no file has been defined + * in login.defs, don't do this. + */ + + if (!(ftmp = getdef_str("FTMP_FILE"))) + return; + + /* + * Open the file for append. It must already exist for this + * feature to be used. + */ + + if ((fd = open(ftmp, O_WRONLY|O_APPEND)) == -1) + return; + + /* + * Output the new failure record and close the log file. + */ + + write(fd, (const char *) failent, sizeof *failent); + close(fd); +} diff --git a/current/libmisc/failure.h b/current/libmisc/failure.h new file mode 100644 index 00000000..1795b50d --- /dev/null +++ b/current/libmisc/failure.h @@ -0,0 +1,44 @@ +/* $Id: failure.h,v 1.2 2000/08/26 18:27:17 marekm Exp $ */ +#ifndef _FAILURE_H_ +#define _FAILURE_H_ + +#include "defines.h" +#include "faillog.h" +#include + +/* + * failure - make failure entry + * + * failure() creates a new (struct faillog) entry or updates an + * existing one with the current failed login information. + */ +extern void failure(uid_t, const char *, struct faillog *); + +/* + * failcheck - check for failures > allowable + * + * failcheck() is called AFTER the password has been validated. If the + * account has been "attacked" with too many login failures, failcheck() + * returns FALSE to indicate that the login should be denied even though + * the password is valid. + */ +extern int failcheck(uid_t, struct faillog *, int); + +/* + * failprint - print line of failure information + * + * failprint takes a (struct faillog) entry and formats it into a + * message which is displayed at login time. + */ +extern void failprint(const struct faillog *); + +/* + * failtmp - update the cummulative failure log + * + * failtmp updates the (struct utmp) formatted failure log which + * maintains a record of all login failures. + */ +extern void failtmp(const struct utmp *); + +#endif + diff --git a/current/libmisc/fields.c b/current/libmisc/fields.c new file mode 100644 index 00000000..a645ec59 --- /dev/null +++ b/current/libmisc/fields.c @@ -0,0 +1,104 @@ +/* + * Copyright 1990, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: fields.c,v 1.5 1997/12/07 23:27:04 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" + +/* + * valid_field - insure that a field contains all legal characters + * + * The supplied field is scanned for non-printing and other illegal + * characters. If any illegal characters are found, valid_field + * returns -1. Zero is returned for success. + */ + +int +valid_field(const char *field, const char *illegal) +{ + const char *cp; + + for (cp = field; *cp && isprint(*cp & 0x7F) && !strchr(illegal, *cp); cp++) + ; + + if (*cp) + return -1; + else + return 0; +} + +/* + * change_field - change a single field if a new value is given. + * + * prompt the user with the name of the field being changed and the + * current value. + */ + +void +change_field(char *buf, size_t maxsize, const char *prompt) +{ + char newf[200]; + char *cp; + + if (maxsize > sizeof(newf)) + maxsize = sizeof(newf); + + printf ("\t%s [%s]: ", prompt, buf); + if (fgets(newf, maxsize, stdin) != newf) + return; + + if (!(cp = strchr(newf, '\n'))) + return; + *cp = '\0'; + + if (newf[0]) { + /* + * Remove leading and trailing whitespace. This also + * makes it possible to change the field to empty, by + * entering a space. --marekm + */ + + while (--cp >= newf && isspace(*cp)) + ; + *++cp = '\0'; + + cp = newf; + while (*cp && isspace(*cp)) + cp++; + + strncpy(buf, cp, maxsize - 1); + buf[maxsize - 1] = '\0'; + } +} diff --git a/current/libmisc/getdate.c b/current/libmisc/getdate.c new file mode 100644 index 00000000..559add3a --- /dev/null +++ b/current/libmisc/getdate.c @@ -0,0 +1,2006 @@ + +/* A Bison parser, made from getdate.y + by GNU Bison version 1.25 + */ + +#define YYBISON 1 /* Identify Bison output. */ + +#define tAGO 258 +#define tDAY 259 +#define tDAY_UNIT 260 +#define tDAYZONE 261 +#define tDST 262 +#define tHOUR_UNIT 263 +#define tID 264 +#define tMERIDIAN 265 +#define tMINUTE_UNIT 266 +#define tMONTH 267 +#define tMONTH_UNIT 268 +#define tSEC_UNIT 269 +#define tSNUMBER 270 +#define tUNUMBER 271 +#define tYEAR_UNIT 272 +#define tZONE 273 + +#line 1 "getdate.y" + +/* +** Originally written by Steven M. Bellovin while +** at the University of North Carolina at Chapel Hill. Later tweaked by +** a couple of people on Usenet. Completely overhauled by Rich $alz +** and Jim Berets in August, 1990; +** +** This grammar has 13 shift/reduce conflicts. +** +** This code is in the public domain and has no copyright. +*/ + +#ifdef HAVE_CONFIG_H +# include +# ifdef FORCE_ALLOCA_H +# include +# endif +#endif + +/* Since the code of getdate.y is not included in the Emacs executable + itself, there is no need to #define static in this file. Even if + the code were included in the Emacs executable, it probably + wouldn't do any harm to #undef it here; this will only cause + problems if we try to write to a static variable, which I don't + think this code needs to do. */ +#ifdef emacs +# undef static +#endif + +#include +#include + +#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) isascii(c) +#endif + +#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) +#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) +#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) + +/* ISDIGIT differs from ISDIGIT_LOCALE, as follows: + - Its arg may be any int or unsigned int; it need not be an unsigned char. + - It's guaranteed to evaluate its argument exactly once. + - It's typically faster. + Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that + only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless + it's important to use the locale's definition of `digit' even when the + host does not conform to Posix. */ +#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) + +#include "getdate.h" + +#if defined (STDC_HEADERS) || defined (USG) +# include +#endif + +/* Some old versions of bison generate parsers that use bcopy. + That loses on systems that don't provide the function, so we have + to redefine it here. */ +#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy) +# define bcopy(from, to, len) memcpy ((to), (from), (len)) +#endif + +extern struct tm *gmtime (); +extern struct tm *localtime (); +extern time_t mktime (); + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in the same program. Note that these are only + the variables produced by yacc. If other parser generators (bison, + byacc, etc) produce additional global names that conflict at link time, + then those parser generators need to be fixed instead of adding those + names to this list. */ + +#define yymaxdepth gd_maxdepth +#define yyparse gd_parse +#define yylex gd_lex +#define yyerror gd_error +#define yylval gd_lval +#define yychar gd_char +#define yydebug gd_debug +#define yypact gd_pact +#define yyr1 gd_r1 +#define yyr2 gd_r2 +#define yydef gd_def +#define yychk gd_chk +#define yypgo gd_pgo +#define yyact gd_act +#define yyexca gd_exca +#define yyerrflag gd_errflag +#define yynerrs gd_nerrs +#define yyps gd_ps +#define yypv gd_pv +#define yys gd_s +#define yy_yys gd_yys +#define yystate gd_state +#define yytmp gd_tmp +#define yyv gd_v +#define yy_yyv gd_yyv +#define yyval gd_val +#define yylloc gd_lloc +#define yyreds gd_reds /* With YYDEBUG defined */ +#define yytoks gd_toks /* With YYDEBUG defined */ +#define yylhs gd_yylhs +#define yylen gd_yylen +#define yydefred gd_yydefred +#define yydgoto gd_yydgoto +#define yysindex gd_yysindex +#define yyrindex gd_yyrindex +#define yygindex gd_yygindex +#define yytable gd_yytable +#define yycheck gd_yycheck + +static int yylex (); +static int yyerror (); + +#define EPOCH 1970 +#define HOUR(x) ((x) * 60) + +#define MAX_BUFF_LEN 128 /* size of buffer to read the date into */ + +/* +** An entry in the lexical lookup table. +*/ +typedef struct _TABLE { + const char *name; + int type; + int value; +} TABLE; + + +/* +** Meridian: am, pm, or 24-hour style. +*/ +typedef enum _MERIDIAN { + MERam, MERpm, MER24 +} MERIDIAN; + + +/* +** Global variables. We could get rid of most of these by using a good +** union as the yacc stack. (This routine was originally written before +** yacc had the %union construct.) Maybe someday; right now we only use +** the %union very rarely. +*/ +static const char *yyInput; +static int yyDayOrdinal; +static int yyDayNumber; +static int yyHaveDate; +static int yyHaveDay; +static int yyHaveRel; +static int yyHaveTime; +static int yyHaveZone; +static int yyTimezone; +static int yyDay; +static int yyHour; +static int yyMinutes; +static int yyMonth; +static int yySeconds; +static int yyYear; +static MERIDIAN yyMeridian; +static int yyRelDay; +static int yyRelHour; +static int yyRelMinutes; +static int yyRelMonth; +static int yyRelSeconds; +static int yyRelYear; + + +#line 175 "getdate.y" +typedef union { + int Number; + enum _MERIDIAN Meridian; +} YYSTYPE; +#include + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define YYFINAL 61 +#define YYFLAG -32768 +#define YYNTBASE 22 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 273 ? yytranslate[x] : 32) + +static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 20, 2, 2, 21, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 19, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18 +}; + +#if YYDEBUG != 0 +static const short yyprhs[] = { 0, + 0, 1, 4, 6, 8, 10, 12, 14, 16, 19, + 24, 29, 36, 43, 45, 47, 50, 52, 55, 58, + 62, 68, 72, 76, 79, 84, 87, 91, 94, 96, + 99, 102, 104, 107, 110, 112, 115, 118, 120, 123, + 126, 128, 131, 134, 136, 139, 142, 144, 146, 147 +}; + +static const short yyrhs[] = { -1, + 22, 23, 0, 24, 0, 25, 0, 27, 0, 26, + 0, 28, 0, 30, 0, 16, 10, 0, 16, 19, + 16, 31, 0, 16, 19, 16, 15, 0, 16, 19, + 16, 19, 16, 31, 0, 16, 19, 16, 19, 16, + 15, 0, 18, 0, 6, 0, 18, 7, 0, 4, + 0, 4, 20, 0, 16, 4, 0, 16, 21, 16, + 0, 16, 21, 16, 21, 16, 0, 16, 15, 15, + 0, 16, 12, 15, 0, 12, 16, 0, 12, 16, + 20, 16, 0, 16, 12, 0, 16, 12, 16, 0, + 29, 3, 0, 29, 0, 16, 17, 0, 15, 17, + 0, 17, 0, 16, 13, 0, 15, 13, 0, 13, + 0, 16, 5, 0, 15, 5, 0, 5, 0, 16, + 8, 0, 15, 8, 0, 8, 0, 16, 11, 0, + 15, 11, 0, 11, 0, 16, 14, 0, 15, 14, + 0, 14, 0, 16, 0, 0, 10, 0 +}; + +#endif + +#if YYDEBUG != 0 +static const short yyrline[] = { 0, + 191, 192, 195, 198, 201, 204, 207, 210, 213, 219, + 225, 234, 240, 252, 255, 258, 264, 268, 272, 278, + 282, 300, 306, 312, 316, 321, 325, 332, 340, 343, + 346, 349, 352, 355, 358, 361, 364, 367, 370, 373, + 376, 379, 382, 385, 388, 391, 394, 399, 432, 436 +}; +#endif + + +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) + +static const char * const yytname[] = { "$","error","$undefined.","tAGO","tDAY", +"tDAY_UNIT","tDAYZONE","tDST","tHOUR_UNIT","tID","tMERIDIAN","tMINUTE_UNIT", +"tMONTH","tMONTH_UNIT","tSEC_UNIT","tSNUMBER","tUNUMBER","tYEAR_UNIT","tZONE", +"':'","','","'/'","spec","item","time","zone","day","date","rel","relunit","number", +"o_merid", NULL +}; +#endif + +static const short yyr1[] = { 0, + 22, 22, 23, 23, 23, 23, 23, 23, 24, 24, + 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, + 27, 27, 27, 27, 27, 27, 27, 28, 28, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 30, 31, 31 +}; + +static const short yyr2[] = { 0, + 0, 2, 1, 1, 1, 1, 1, 1, 2, 4, + 4, 6, 6, 1, 1, 2, 1, 2, 2, 3, + 5, 3, 3, 2, 4, 2, 3, 2, 1, 2, + 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, + 1, 2, 2, 1, 2, 2, 1, 1, 0, 1 +}; + +static const short yydefact[] = { 1, + 0, 17, 38, 15, 41, 44, 0, 35, 47, 0, + 48, 32, 14, 2, 3, 4, 6, 5, 7, 29, + 8, 18, 24, 37, 40, 43, 34, 46, 31, 19, + 36, 39, 9, 42, 26, 33, 45, 0, 30, 0, + 0, 16, 28, 0, 23, 27, 22, 49, 20, 25, + 50, 11, 0, 10, 0, 49, 21, 13, 12, 0, + 0 +}; + +static const short yydefgoto[] = { 1, + 14, 15, 16, 17, 18, 19, 20, 21, 54 +}; + +static const short yypact[] = {-32768, + 0, -19,-32768,-32768,-32768,-32768, -13,-32768,-32768, 30, + 15,-32768, 14,-32768,-32768,-32768,-32768,-32768,-32768, 19, +-32768,-32768, 4,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768, -6,-32768,-32768, 16,-32768, 17, + 23,-32768,-32768, 24,-32768,-32768,-32768, 27, 28,-32768, +-32768,-32768, 29,-32768, 32, -8,-32768,-32768,-32768, 50, +-32768 +}; + +static const short yypgoto[] = {-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -5 +}; + + +#define YYLAST 51 + + +static const short yytable[] = { 60, + 22, 51, 23, 2, 3, 4, 58, 5, 45, 46, + 6, 7, 8, 9, 10, 11, 12, 13, 30, 31, + 42, 43, 32, 44, 33, 34, 35, 36, 37, 38, + 47, 39, 48, 40, 24, 41, 51, 25, 49, 50, + 26, 52, 27, 28, 56, 53, 29, 57, 55, 61, + 59 +}; + +static const short yycheck[] = { 0, + 20, 10, 16, 4, 5, 6, 15, 8, 15, 16, + 11, 12, 13, 14, 15, 16, 17, 18, 4, 5, + 7, 3, 8, 20, 10, 11, 12, 13, 14, 15, + 15, 17, 16, 19, 5, 21, 10, 8, 16, 16, + 11, 15, 13, 14, 16, 19, 17, 16, 21, 0, + 56 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/share/bison.simple" + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab +#define YYRECOVERING() (!!yyerrstatus) +#define YYBACKUP(token, value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval, &yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +int yyparse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (to, from, count) + char *to; + char *from; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (char *to, char *from, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 196 "/usr/share/bison.simple" + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#ifdef __cplusplus +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* not __cplusplus */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not YYPARSE_PARAM */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* not YYPARSE_PARAM */ + +int +yyparse(YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +#define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + int yystacksize = YYINITDEPTH; + +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss - 1; + yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif + + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp)); +#endif +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif + + goto yybackup; + yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + + + switch (yyn) { + +case 3: +#line 195 "getdate.y" +{ + yyHaveTime++; + ; + break;} +case 4: +#line 198 "getdate.y" +{ + yyHaveZone++; + ; + break;} +case 5: +#line 201 "getdate.y" +{ + yyHaveDate++; + ; + break;} +case 6: +#line 204 "getdate.y" +{ + yyHaveDay++; + ; + break;} +case 7: +#line 207 "getdate.y" +{ + yyHaveRel++; + ; + break;} +case 9: +#line 213 "getdate.y" +{ + yyHour = yyvsp[-1].Number; + yyMinutes = 0; + yySeconds = 0; + yyMeridian = yyvsp[0].Meridian; + ; + break;} +case 10: +#line 219 "getdate.y" +{ + yyHour = yyvsp[-3].Number; + yyMinutes = yyvsp[-1].Number; + yySeconds = 0; + yyMeridian = yyvsp[0].Meridian; + ; + break;} +case 11: +#line 225 "getdate.y" +{ + yyHour = yyvsp[-3].Number; + yyMinutes = yyvsp[-1].Number; + yyMeridian = MER24; + yyHaveZone++; + yyTimezone = (yyvsp[0].Number < 0 + ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60 + : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60)); + ; + break;} +case 12: +#line 234 "getdate.y" +{ + yyHour = yyvsp[-5].Number; + yyMinutes = yyvsp[-3].Number; + yySeconds = yyvsp[-1].Number; + yyMeridian = yyvsp[0].Meridian; + ; + break;} +case 13: +#line 240 "getdate.y" +{ + yyHour = yyvsp[-5].Number; + yyMinutes = yyvsp[-3].Number; + yySeconds = yyvsp[-1].Number; + yyMeridian = MER24; + yyHaveZone++; + yyTimezone = (yyvsp[0].Number < 0 + ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60 + : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60)); + ; + break;} +case 14: +#line 252 "getdate.y" +{ + yyTimezone = yyvsp[0].Number; + ; + break;} +case 15: +#line 255 "getdate.y" +{ + yyTimezone = yyvsp[0].Number - 60; + ; + break;} +case 16: +#line 259 "getdate.y" +{ + yyTimezone = yyvsp[-1].Number - 60; + ; + break;} +case 17: +#line 264 "getdate.y" +{ + yyDayOrdinal = 1; + yyDayNumber = yyvsp[0].Number; + ; + break;} +case 18: +#line 268 "getdate.y" +{ + yyDayOrdinal = 1; + yyDayNumber = yyvsp[-1].Number; + ; + break;} +case 19: +#line 272 "getdate.y" +{ + yyDayOrdinal = yyvsp[-1].Number; + yyDayNumber = yyvsp[0].Number; + ; + break;} +case 20: +#line 278 "getdate.y" +{ + yyMonth = yyvsp[-2].Number; + yyDay = yyvsp[0].Number; + ; + break;} +case 21: +#line 282 "getdate.y" +{ + /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY. + The goal in recognizing YYYY/MM/DD is solely to support legacy + machine-generated dates like those in an RCS log listing. If + you want portability, use the ISO 8601 format. */ + if (yyvsp[-4].Number >= 1000) + { + yyYear = yyvsp[-4].Number; + yyMonth = yyvsp[-2].Number; + yyDay = yyvsp[0].Number; + } + else + { + yyMonth = yyvsp[-4].Number; + yyDay = yyvsp[-2].Number; + yyYear = yyvsp[0].Number; + } + ; + break;} +case 22: +#line 300 "getdate.y" +{ + /* ISO 8601 format. yyyy-mm-dd. */ + yyYear = yyvsp[-2].Number; + yyMonth = -yyvsp[-1].Number; + yyDay = -yyvsp[0].Number; + ; + break;} +case 23: +#line 306 "getdate.y" +{ + /* e.g. 17-JUN-1992. */ + yyDay = yyvsp[-2].Number; + yyMonth = yyvsp[-1].Number; + yyYear = -yyvsp[0].Number; + ; + break;} +case 24: +#line 312 "getdate.y" +{ + yyMonth = yyvsp[-1].Number; + yyDay = yyvsp[0].Number; + ; + break;} +case 25: +#line 316 "getdate.y" +{ + yyMonth = yyvsp[-3].Number; + yyDay = yyvsp[-2].Number; + yyYear = yyvsp[0].Number; + ; + break;} +case 26: +#line 321 "getdate.y" +{ + yyMonth = yyvsp[0].Number; + yyDay = yyvsp[-1].Number; + ; + break;} +case 27: +#line 325 "getdate.y" +{ + yyMonth = yyvsp[-1].Number; + yyDay = yyvsp[-2].Number; + yyYear = yyvsp[0].Number; + ; + break;} +case 28: +#line 332 "getdate.y" +{ + yyRelSeconds = -yyRelSeconds; + yyRelMinutes = -yyRelMinutes; + yyRelHour = -yyRelHour; + yyRelDay = -yyRelDay; + yyRelMonth = -yyRelMonth; + yyRelYear = -yyRelYear; + ; + break;} +case 30: +#line 343 "getdate.y" +{ + yyRelYear += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 31: +#line 346 "getdate.y" +{ + yyRelYear += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 32: +#line 349 "getdate.y" +{ + yyRelYear++; + ; + break;} +case 33: +#line 352 "getdate.y" +{ + yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 34: +#line 355 "getdate.y" +{ + yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 35: +#line 358 "getdate.y" +{ + yyRelMonth++; + ; + break;} +case 36: +#line 361 "getdate.y" +{ + yyRelDay += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 37: +#line 364 "getdate.y" +{ + yyRelDay += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 38: +#line 367 "getdate.y" +{ + yyRelDay++; + ; + break;} +case 39: +#line 370 "getdate.y" +{ + yyRelHour += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 40: +#line 373 "getdate.y" +{ + yyRelHour += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 41: +#line 376 "getdate.y" +{ + yyRelHour++; + ; + break;} +case 42: +#line 379 "getdate.y" +{ + yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 43: +#line 382 "getdate.y" +{ + yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 44: +#line 385 "getdate.y" +{ + yyRelMinutes++; + ; + break;} +case 45: +#line 388 "getdate.y" +{ + yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 46: +#line 391 "getdate.y" +{ + yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number; + ; + break;} +case 47: +#line 394 "getdate.y" +{ + yyRelSeconds++; + ; + break;} +case 48: +#line 400 "getdate.y" +{ + if (yyHaveTime && yyHaveDate && !yyHaveRel) + yyYear = yyvsp[0].Number; + else + { + if (yyvsp[0].Number>10000) + { + yyHaveDate++; + yyDay= (yyvsp[0].Number)%100; + yyMonth= (yyvsp[0].Number/100)%100; + yyYear = yyvsp[0].Number/10000; + } + else + { + yyHaveTime++; + if (yyvsp[0].Number < 100) + { + yyHour = yyvsp[0].Number; + yyMinutes = 0; + } + else + { + yyHour = yyvsp[0].Number / 100; + yyMinutes = yyvsp[0].Number % 100; + } + yySeconds = 0; + yyMeridian = MER24; + } + } + ; + break;} +case 49: +#line 433 "getdate.y" +{ + yyval.Meridian = MER24; + ; + break;} +case 50: +#line 437 "getdate.y" +{ + yyval.Meridian = yyvsp[0].Meridian; + ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 498 "/usr/share/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; + +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + free(msg); + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; +} +#line 442 "getdate.y" + + +/* Month and day table. */ +static TABLE const MonthDayTable[] = { + { "january", tMONTH, 1 }, + { "february", tMONTH, 2 }, + { "march", tMONTH, 3 }, + { "april", tMONTH, 4 }, + { "may", tMONTH, 5 }, + { "june", tMONTH, 6 }, + { "july", tMONTH, 7 }, + { "august", tMONTH, 8 }, + { "september", tMONTH, 9 }, + { "sept", tMONTH, 9 }, + { "october", tMONTH, 10 }, + { "november", tMONTH, 11 }, + { "december", tMONTH, 12 }, + { "sunday", tDAY, 0 }, + { "monday", tDAY, 1 }, + { "tuesday", tDAY, 2 }, + { "tues", tDAY, 2 }, + { "wednesday", tDAY, 3 }, + { "wednes", tDAY, 3 }, + { "thursday", tDAY, 4 }, + { "thur", tDAY, 4 }, + { "thurs", tDAY, 4 }, + { "friday", tDAY, 5 }, + { "saturday", tDAY, 6 }, + { NULL } +}; + +/* Time units table. */ +static TABLE const UnitsTable[] = { + { "year", tYEAR_UNIT, 1 }, + { "month", tMONTH_UNIT, 1 }, + { "fortnight", tDAY_UNIT, 14 }, + { "week", tDAY_UNIT, 7 }, + { "day", tDAY_UNIT, 1 }, + { "hour", tHOUR_UNIT, 1 }, + { "minute", tMINUTE_UNIT, 1 }, + { "min", tMINUTE_UNIT, 1 }, + { "second", tSEC_UNIT, 1 }, + { "sec", tSEC_UNIT, 1 }, + { NULL } +}; + +/* Assorted relative-time words. */ +static TABLE const OtherTable[] = { + { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, + { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, + { "today", tMINUTE_UNIT, 0 }, + { "now", tMINUTE_UNIT, 0 }, + { "last", tUNUMBER, -1 }, + { "this", tMINUTE_UNIT, 0 }, + { "next", tUNUMBER, 2 }, + { "first", tUNUMBER, 1 }, +/* { "second", tUNUMBER, 2 }, */ + { "third", tUNUMBER, 3 }, + { "fourth", tUNUMBER, 4 }, + { "fifth", tUNUMBER, 5 }, + { "sixth", tUNUMBER, 6 }, + { "seventh", tUNUMBER, 7 }, + { "eighth", tUNUMBER, 8 }, + { "ninth", tUNUMBER, 9 }, + { "tenth", tUNUMBER, 10 }, + { "eleventh", tUNUMBER, 11 }, + { "twelfth", tUNUMBER, 12 }, + { "ago", tAGO, 1 }, + { NULL } +}; + +/* The timezone table. */ +static TABLE const TimezoneTable[] = { + { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */ + { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ + { "utc", tZONE, HOUR ( 0) }, + { "wet", tZONE, HOUR ( 0) }, /* Western European */ + { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */ + { "wat", tZONE, HOUR ( 1) }, /* West Africa */ + { "at", tZONE, HOUR ( 2) }, /* Azores */ +#if 0 + /* For completeness. BST is also British Summer, and GST is + * also Guam Standard. */ + { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */ + { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */ +#endif +#if 0 + { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */ + { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */ + { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */ +#endif + { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */ + { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */ + { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */ + { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */ + { "cst", tZONE, HOUR ( 6) }, /* Central Standard */ + { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */ + { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */ + { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */ + { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */ + { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */ + { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */ + { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */ + { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */ + { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */ + { "cat", tZONE, HOUR (10) }, /* Central Alaska */ + { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */ + { "nt", tZONE, HOUR (11) }, /* Nome */ + { "idlw", tZONE, HOUR (12) }, /* International Date Line West */ + { "cet", tZONE, -HOUR (1) }, /* Central European */ + { "met", tZONE, -HOUR (1) }, /* Middle European */ + { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */ + { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ + { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ + { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */ + { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */ + { "fwt", tZONE, -HOUR (1) }, /* French Winter */ + { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */ + { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */ + { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */ +#if 0 + { "it", tZONE, -HOUR (3.5) },/* Iran */ +#endif + { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */ + { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */ +#if 0 + { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */ +#endif + { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */ +#if 0 + /* For completeness. NST is also Newfoundland Standard, and SST is + * also Swedish Summer. */ + { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */ + { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */ +#endif /* 0 */ + { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */ + { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */ +#if 0 + { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */ +#endif + { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */ + { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */ +#if 0 + { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */ + { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */ +#endif + { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */ + { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */ + { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */ + { "nzt", tZONE, -HOUR (12) }, /* New Zealand */ + { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */ + { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */ + { "idle", tZONE, -HOUR (12) }, /* International Date Line East */ + { NULL } +}; + +/* Military timezone table. */ +static TABLE const MilitaryTable[] = { + { "a", tZONE, HOUR ( 1) }, + { "b", tZONE, HOUR ( 2) }, + { "c", tZONE, HOUR ( 3) }, + { "d", tZONE, HOUR ( 4) }, + { "e", tZONE, HOUR ( 5) }, + { "f", tZONE, HOUR ( 6) }, + { "g", tZONE, HOUR ( 7) }, + { "h", tZONE, HOUR ( 8) }, + { "i", tZONE, HOUR ( 9) }, + { "k", tZONE, HOUR ( 10) }, + { "l", tZONE, HOUR ( 11) }, + { "m", tZONE, HOUR ( 12) }, + { "n", tZONE, HOUR (- 1) }, + { "o", tZONE, HOUR (- 2) }, + { "p", tZONE, HOUR (- 3) }, + { "q", tZONE, HOUR (- 4) }, + { "r", tZONE, HOUR (- 5) }, + { "s", tZONE, HOUR (- 6) }, + { "t", tZONE, HOUR (- 7) }, + { "u", tZONE, HOUR (- 8) }, + { "v", tZONE, HOUR (- 9) }, + { "w", tZONE, HOUR (-10) }, + { "x", tZONE, HOUR (-11) }, + { "y", tZONE, HOUR (-12) }, + { "z", tZONE, HOUR ( 0) }, + { NULL } +}; + + + + +/* ARGSUSED */ +static int +yyerror (s) + char *s; +{ + return 0; +} + +static int +ToHour (Hours, Meridian) + int Hours; + MERIDIAN Meridian; +{ + switch (Meridian) + { + case MER24: + if (Hours < 0 || Hours > 23) + return -1; + return Hours; + case MERam: + if (Hours < 1 || Hours > 12) + return -1; + if (Hours == 12) + Hours = 0; + return Hours; + case MERpm: + if (Hours < 1 || Hours > 12) + return -1; + if (Hours == 12) + Hours = 0; + return Hours + 12; + default: + abort (); + } + /* NOTREACHED */ +} + +static int +ToYear (Year) + int Year; +{ + if (Year < 0) + Year = -Year; + + /* XPG4 suggests that years 00-68 map to 2000-2068, and + years 69-99 map to 1969-1999. */ + if (Year < 69) + Year += 2000; + else if (Year < 100) + Year += 1900; + + return Year; +} + +static int +LookupWord (buff) + char *buff; +{ + register char *p; + register char *q; + register const TABLE *tp; + int i; + int abbrev; + + /* Make it lowercase. */ + for (p = buff; *p; p++) + if (ISUPPER (*p)) + *p = tolower (*p); + + if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0) + { + yylval.Meridian = MERam; + return tMERIDIAN; + } + if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0) + { + yylval.Meridian = MERpm; + return tMERIDIAN; + } + + /* See if we have an abbreviation for a month. */ + if (strlen (buff) == 3) + abbrev = 1; + else if (strlen (buff) == 4 && buff[3] == '.') + { + abbrev = 1; + buff[3] = '\0'; + } + else + abbrev = 0; + + for (tp = MonthDayTable; tp->name; tp++) + { + if (abbrev) + { + if (strncmp (buff, tp->name, 3) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + } + else if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + } + + for (tp = TimezoneTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + if (strcmp (buff, "dst") == 0) + return tDST; + + for (tp = UnitsTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + /* Strip off any plural and try the units table again. */ + i = strlen (buff) - 1; + if (buff[i] == 's') + { + buff[i] = '\0'; + for (tp = UnitsTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + buff[i] = 's'; /* Put back for "this" in OtherTable. */ + } + + for (tp = OtherTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + /* Military timezones. */ + if (buff[1] == '\0' && ISALPHA (*buff)) + { + for (tp = MilitaryTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + } + + /* Drop out any periods and try the timezone table again. */ + for (i = 0, p = q = buff; *q; q++) + if (*q != '.') + *p++ = *q; + else + i++; + *p = '\0'; + if (i) + for (tp = TimezoneTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + return tID; +} + +static int +yylex () +{ + register char c; + register char *p; + char buff[20]; + int Count; + int sign; + + for (;;) + { + while (ISSPACE (*yyInput)) + yyInput++; + + if (ISDIGIT (c = *yyInput) || c == '-' || c == '+') + { + if (c == '-' || c == '+') + { + sign = c == '-' ? -1 : 1; + if (!ISDIGIT (*++yyInput)) + /* skip the '-' sign */ + continue; + } + else + sign = 0; + for (yylval.Number = 0; ISDIGIT (c = *yyInput++);) + yylval.Number = 10 * yylval.Number + c - '0'; + yyInput--; + if (sign < 0) + yylval.Number = -yylval.Number; + return sign ? tSNUMBER : tUNUMBER; + } + if (ISALPHA (c)) + { + for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';) + if (p < &buff[sizeof buff - 1]) + *p++ = c; + *p = '\0'; + yyInput--; + return LookupWord (buff); + } + if (c != '(') + return *yyInput++; + Count = 0; + do + { + c = *yyInput++; + if (c == '\0') + return c; + if (c == '(') + Count++; + else if (c == ')') + Count--; + } + while (Count > 0); + } +} + +#define TM_YEAR_ORIGIN 1900 + +/* Yield A - B, measured in seconds. */ +static long +difftm (a, b) + struct tm *a, *b; +{ + int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); + int by = b->tm_year + (TM_YEAR_ORIGIN - 1); + long days = ( + /* difference in day of year */ + a->tm_yday - b->tm_yday + /* + intervening leap days */ + + ((ay >> 2) - (by >> 2)) + - (ay / 100 - by / 100) + + ((ay / 100 >> 2) - (by / 100 >> 2)) + /* + difference in years * 365 */ + + (long) (ay - by) * 365 + ); + return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec)); +} + +time_t +get_date (p, now) + const char *p; + const time_t *now; +{ + struct tm tm, tm0, *tmp; + time_t Start; + + yyInput = p; + Start = now ? *now : time ((time_t *) NULL); + tmp = localtime (&Start); + yyYear = tmp->tm_year + TM_YEAR_ORIGIN; + yyMonth = tmp->tm_mon + 1; + yyDay = tmp->tm_mday; + yyHour = tmp->tm_hour; + yyMinutes = tmp->tm_min; + yySeconds = tmp->tm_sec; + yyMeridian = MER24; + yyRelSeconds = 0; + yyRelMinutes = 0; + yyRelHour = 0; + yyRelDay = 0; + yyRelMonth = 0; + yyRelYear = 0; + yyHaveDate = 0; + yyHaveDay = 0; + yyHaveRel = 0; + yyHaveTime = 0; + yyHaveZone = 0; + + if (yyparse () + || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1) + return -1; + + tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear; + tm.tm_mon = yyMonth - 1 + yyRelMonth; + tm.tm_mday = yyDay + yyRelDay; + if (yyHaveTime || (yyHaveRel && !yyHaveDate && !yyHaveDay)) + { + tm.tm_hour = ToHour (yyHour, yyMeridian); + if (tm.tm_hour < 0) + return -1; + tm.tm_min = yyMinutes; + tm.tm_sec = yySeconds; + } + else + { + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + } + tm.tm_hour += yyRelHour; + tm.tm_min += yyRelMinutes; + tm.tm_sec += yyRelSeconds; + tm.tm_isdst = -1; + tm0 = tm; + + Start = mktime (&tm); + + if (Start == (time_t) -1) + { + + /* Guard against falsely reporting errors near the time_t boundaries + when parsing times in other time zones. For example, if the min + time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead + of UTC, then the min localtime value is 1970-01-01 08:00:00; if + we apply mktime to 1970-01-01 00:00:00 we will get an error, so + we apply mktime to 1970-01-02 08:00:00 instead and adjust the time + zone by 24 hours to compensate. This algorithm assumes that + there is no DST transition within a day of the time_t boundaries. */ + if (yyHaveZone) + { + tm = tm0; + if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN) + { + tm.tm_mday++; + yyTimezone -= 24 * 60; + } + else + { + tm.tm_mday--; + yyTimezone += 24 * 60; + } + Start = mktime (&tm); + } + + if (Start == (time_t) -1) + return Start; + } + + if (yyHaveDay && !yyHaveDate) + { + tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7 + + 7 * (yyDayOrdinal - (0 < yyDayOrdinal))); + Start = mktime (&tm); + if (Start == (time_t) -1) + return Start; + } + + if (yyHaveZone) + { + long delta = yyTimezone * 60L + difftm (&tm, gmtime (&Start)); + if ((Start + delta < Start) != (delta < 0)) + return -1; /* time_t overflow */ + Start += delta; + } + + return Start; +} + +#if defined (TEST) + +/* ARGSUSED */ +int +main (ac, av) + int ac; + char *av[]; +{ + char buff[MAX_BUFF_LEN + 1]; + time_t d; + + (void) printf ("Enter date, or blank line to exit.\n\t> "); + (void) fflush (stdout); + + buff[MAX_BUFF_LEN] = 0; + while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0]) + { + d = get_date (buff, (time_t *) NULL); + if (d == -1) + (void) printf ("Bad format - couldn't convert.\n"); + else + (void) printf ("%s", ctime (&d)); + (void) printf ("\t> "); + (void) fflush (stdout); + } + exit (0); + /* NOTREACHED */ +} +#endif /* defined (TEST) */ diff --git a/current/libmisc/getdate.h b/current/libmisc/getdate.h new file mode 100644 index 00000000..691a508f --- /dev/null +++ b/current/libmisc/getdate.h @@ -0,0 +1,8 @@ +#ifndef _GETDATE_H_ +#define _GETDATE_H_ + +#include +#include "defines.h" + +time_t get_date(const char *, const time_t *); +#endif diff --git a/current/libmisc/getdate.y b/current/libmisc/getdate.y new file mode 100644 index 00000000..d33fa063 --- /dev/null +++ b/current/libmisc/getdate.y @@ -0,0 +1,1024 @@ +%{ +/* +** Originally written by Steven M. Bellovin while +** at the University of North Carolina at Chapel Hill. Later tweaked by +** a couple of people on Usenet. Completely overhauled by Rich $alz +** and Jim Berets in August, 1990; +** +** This grammar has 13 shift/reduce conflicts. +** +** This code is in the public domain and has no copyright. +*/ + +#ifdef HAVE_CONFIG_H +# include +# ifdef FORCE_ALLOCA_H +# include +# endif +#endif + +/* Since the code of getdate.y is not included in the Emacs executable + itself, there is no need to #define static in this file. Even if + the code were included in the Emacs executable, it probably + wouldn't do any harm to #undef it here; this will only cause + problems if we try to write to a static variable, which I don't + think this code needs to do. */ +#ifdef emacs +# undef static +#endif + +#include +#include + +#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) isascii(c) +#endif + +#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) +#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) +#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) + +/* ISDIGIT differs from ISDIGIT_LOCALE, as follows: + - Its arg may be any int or unsigned int; it need not be an unsigned char. + - It's guaranteed to evaluate its argument exactly once. + - It's typically faster. + Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that + only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless + it's important to use the locale's definition of `digit' even when the + host does not conform to Posix. */ +#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) + +#include "getdate.h" + +#if defined (STDC_HEADERS) || defined (USG) +# include +#endif + +/* Some old versions of bison generate parsers that use bcopy. + That loses on systems that don't provide the function, so we have + to redefine it here. */ +#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy) +# define bcopy(from, to, len) memcpy ((to), (from), (len)) +#endif + +extern struct tm *gmtime (); +extern struct tm *localtime (); +extern time_t mktime (); + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in the same program. Note that these are only + the variables produced by yacc. If other parser generators (bison, + byacc, etc) produce additional global names that conflict at link time, + then those parser generators need to be fixed instead of adding those + names to this list. */ + +#define yymaxdepth gd_maxdepth +#define yyparse gd_parse +#define yylex gd_lex +#define yyerror gd_error +#define yylval gd_lval +#define yychar gd_char +#define yydebug gd_debug +#define yypact gd_pact +#define yyr1 gd_r1 +#define yyr2 gd_r2 +#define yydef gd_def +#define yychk gd_chk +#define yypgo gd_pgo +#define yyact gd_act +#define yyexca gd_exca +#define yyerrflag gd_errflag +#define yynerrs gd_nerrs +#define yyps gd_ps +#define yypv gd_pv +#define yys gd_s +#define yy_yys gd_yys +#define yystate gd_state +#define yytmp gd_tmp +#define yyv gd_v +#define yy_yyv gd_yyv +#define yyval gd_val +#define yylloc gd_lloc +#define yyreds gd_reds /* With YYDEBUG defined */ +#define yytoks gd_toks /* With YYDEBUG defined */ +#define yylhs gd_yylhs +#define yylen gd_yylen +#define yydefred gd_yydefred +#define yydgoto gd_yydgoto +#define yysindex gd_yysindex +#define yyrindex gd_yyrindex +#define yygindex gd_yygindex +#define yytable gd_yytable +#define yycheck gd_yycheck + +static int yylex (); +static int yyerror (); + +#define EPOCH 1970 +#define HOUR(x) ((x) * 60) + +#define MAX_BUFF_LEN 128 /* size of buffer to read the date into */ + +/* +** An entry in the lexical lookup table. +*/ +typedef struct _TABLE { + const char *name; + int type; + int value; +} TABLE; + + +/* +** Meridian: am, pm, or 24-hour style. +*/ +typedef enum _MERIDIAN { + MERam, MERpm, MER24 +} MERIDIAN; + + +/* +** Global variables. We could get rid of most of these by using a good +** union as the yacc stack. (This routine was originally written before +** yacc had the %union construct.) Maybe someday; right now we only use +** the %union very rarely. +*/ +static const char *yyInput; +static int yyDayOrdinal; +static int yyDayNumber; +static int yyHaveDate; +static int yyHaveDay; +static int yyHaveRel; +static int yyHaveTime; +static int yyHaveZone; +static int yyTimezone; +static int yyDay; +static int yyHour; +static int yyMinutes; +static int yyMonth; +static int yySeconds; +static int yyYear; +static MERIDIAN yyMeridian; +static int yyRelDay; +static int yyRelHour; +static int yyRelMinutes; +static int yyRelMonth; +static int yyRelSeconds; +static int yyRelYear; + +%} + +%union { + int Number; + enum _MERIDIAN Meridian; +} + +%token tAGO tDAY tDAY_UNIT tDAYZONE tDST tHOUR_UNIT tID +%token tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT +%token tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE + +%type tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tMINUTE_UNIT +%type tMONTH tMONTH_UNIT +%type tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE +%type tMERIDIAN o_merid + +%% + +spec : /* NULL */ + | spec item + ; + +item : time { + yyHaveTime++; + } + | zone { + yyHaveZone++; + } + | date { + yyHaveDate++; + } + | day { + yyHaveDay++; + } + | rel { + yyHaveRel++; + } + | number + ; + +time : tUNUMBER tMERIDIAN { + yyHour = $1; + yyMinutes = 0; + yySeconds = 0; + yyMeridian = $2; + } + | tUNUMBER ':' tUNUMBER o_merid { + yyHour = $1; + yyMinutes = $3; + yySeconds = 0; + yyMeridian = $4; + } + | tUNUMBER ':' tUNUMBER tSNUMBER { + yyHour = $1; + yyMinutes = $3; + yyMeridian = MER24; + yyHaveZone++; + yyTimezone = ($4 < 0 + ? -$4 % 100 + (-$4 / 100) * 60 + : - ($4 % 100 + ($4 / 100) * 60)); + } + | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { + yyHour = $1; + yyMinutes = $3; + yySeconds = $5; + yyMeridian = $6; + } + | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER { + yyHour = $1; + yyMinutes = $3; + yySeconds = $5; + yyMeridian = MER24; + yyHaveZone++; + yyTimezone = ($6 < 0 + ? -$6 % 100 + (-$6 / 100) * 60 + : - ($6 % 100 + ($6 / 100) * 60)); + } + ; + +zone : tZONE { + yyTimezone = $1; + } + | tDAYZONE { + yyTimezone = $1 - 60; + } + | + tZONE tDST { + yyTimezone = $1 - 60; + } + ; + +day : tDAY { + yyDayOrdinal = 1; + yyDayNumber = $1; + } + | tDAY ',' { + yyDayOrdinal = 1; + yyDayNumber = $1; + } + | tUNUMBER tDAY { + yyDayOrdinal = $1; + yyDayNumber = $2; + } + ; + +date : tUNUMBER '/' tUNUMBER { + yyMonth = $1; + yyDay = $3; + } + | tUNUMBER '/' tUNUMBER '/' tUNUMBER { + /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY. + The goal in recognizing YYYY/MM/DD is solely to support legacy + machine-generated dates like those in an RCS log listing. If + you want portability, use the ISO 8601 format. */ + if ($1 >= 1000) + { + yyYear = $1; + yyMonth = $3; + yyDay = $5; + } + else + { + yyMonth = $1; + yyDay = $3; + yyYear = $5; + } + } + | tUNUMBER tSNUMBER tSNUMBER { + /* ISO 8601 format. yyyy-mm-dd. */ + yyYear = $1; + yyMonth = -$2; + yyDay = -$3; + } + | tUNUMBER tMONTH tSNUMBER { + /* e.g. 17-JUN-1992. */ + yyDay = $1; + yyMonth = $2; + yyYear = -$3; + } + | tMONTH tUNUMBER { + yyMonth = $1; + yyDay = $2; + } + | tMONTH tUNUMBER ',' tUNUMBER { + yyMonth = $1; + yyDay = $2; + yyYear = $4; + } + | tUNUMBER tMONTH { + yyMonth = $2; + yyDay = $1; + } + | tUNUMBER tMONTH tUNUMBER { + yyMonth = $2; + yyDay = $1; + yyYear = $3; + } + ; + +rel : relunit tAGO { + yyRelSeconds = -yyRelSeconds; + yyRelMinutes = -yyRelMinutes; + yyRelHour = -yyRelHour; + yyRelDay = -yyRelDay; + yyRelMonth = -yyRelMonth; + yyRelYear = -yyRelYear; + } + | relunit + ; + +relunit : tUNUMBER tYEAR_UNIT { + yyRelYear += $1 * $2; + } + | tSNUMBER tYEAR_UNIT { + yyRelYear += $1 * $2; + } + | tYEAR_UNIT { + yyRelYear++; + } + | tUNUMBER tMONTH_UNIT { + yyRelMonth += $1 * $2; + } + | tSNUMBER tMONTH_UNIT { + yyRelMonth += $1 * $2; + } + | tMONTH_UNIT { + yyRelMonth++; + } + | tUNUMBER tDAY_UNIT { + yyRelDay += $1 * $2; + } + | tSNUMBER tDAY_UNIT { + yyRelDay += $1 * $2; + } + | tDAY_UNIT { + yyRelDay++; + } + | tUNUMBER tHOUR_UNIT { + yyRelHour += $1 * $2; + } + | tSNUMBER tHOUR_UNIT { + yyRelHour += $1 * $2; + } + | tHOUR_UNIT { + yyRelHour++; + } + | tUNUMBER tMINUTE_UNIT { + yyRelMinutes += $1 * $2; + } + | tSNUMBER tMINUTE_UNIT { + yyRelMinutes += $1 * $2; + } + | tMINUTE_UNIT { + yyRelMinutes++; + } + | tUNUMBER tSEC_UNIT { + yyRelSeconds += $1 * $2; + } + | tSNUMBER tSEC_UNIT { + yyRelSeconds += $1 * $2; + } + | tSEC_UNIT { + yyRelSeconds++; + } + ; + +number : tUNUMBER + { + if (yyHaveTime && yyHaveDate && !yyHaveRel) + yyYear = $1; + else + { + if ($1>10000) + { + yyHaveDate++; + yyDay= ($1)%100; + yyMonth= ($1/100)%100; + yyYear = $1/10000; + } + else + { + yyHaveTime++; + if ($1 < 100) + { + yyHour = $1; + yyMinutes = 0; + } + else + { + yyHour = $1 / 100; + yyMinutes = $1 % 100; + } + yySeconds = 0; + yyMeridian = MER24; + } + } + } + ; + +o_merid : /* NULL */ + { + $$ = MER24; + } + | tMERIDIAN + { + $$ = $1; + } + ; + +%% + +/* Month and day table. */ +static TABLE const MonthDayTable[] = { + { "january", tMONTH, 1 }, + { "february", tMONTH, 2 }, + { "march", tMONTH, 3 }, + { "april", tMONTH, 4 }, + { "may", tMONTH, 5 }, + { "june", tMONTH, 6 }, + { "july", tMONTH, 7 }, + { "august", tMONTH, 8 }, + { "september", tMONTH, 9 }, + { "sept", tMONTH, 9 }, + { "october", tMONTH, 10 }, + { "november", tMONTH, 11 }, + { "december", tMONTH, 12 }, + { "sunday", tDAY, 0 }, + { "monday", tDAY, 1 }, + { "tuesday", tDAY, 2 }, + { "tues", tDAY, 2 }, + { "wednesday", tDAY, 3 }, + { "wednes", tDAY, 3 }, + { "thursday", tDAY, 4 }, + { "thur", tDAY, 4 }, + { "thurs", tDAY, 4 }, + { "friday", tDAY, 5 }, + { "saturday", tDAY, 6 }, + { NULL } +}; + +/* Time units table. */ +static TABLE const UnitsTable[] = { + { "year", tYEAR_UNIT, 1 }, + { "month", tMONTH_UNIT, 1 }, + { "fortnight", tDAY_UNIT, 14 }, + { "week", tDAY_UNIT, 7 }, + { "day", tDAY_UNIT, 1 }, + { "hour", tHOUR_UNIT, 1 }, + { "minute", tMINUTE_UNIT, 1 }, + { "min", tMINUTE_UNIT, 1 }, + { "second", tSEC_UNIT, 1 }, + { "sec", tSEC_UNIT, 1 }, + { NULL } +}; + +/* Assorted relative-time words. */ +static TABLE const OtherTable[] = { + { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, + { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, + { "today", tMINUTE_UNIT, 0 }, + { "now", tMINUTE_UNIT, 0 }, + { "last", tUNUMBER, -1 }, + { "this", tMINUTE_UNIT, 0 }, + { "next", tUNUMBER, 2 }, + { "first", tUNUMBER, 1 }, +/* { "second", tUNUMBER, 2 }, */ + { "third", tUNUMBER, 3 }, + { "fourth", tUNUMBER, 4 }, + { "fifth", tUNUMBER, 5 }, + { "sixth", tUNUMBER, 6 }, + { "seventh", tUNUMBER, 7 }, + { "eighth", tUNUMBER, 8 }, + { "ninth", tUNUMBER, 9 }, + { "tenth", tUNUMBER, 10 }, + { "eleventh", tUNUMBER, 11 }, + { "twelfth", tUNUMBER, 12 }, + { "ago", tAGO, 1 }, + { NULL } +}; + +/* The timezone table. */ +static TABLE const TimezoneTable[] = { + { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */ + { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ + { "utc", tZONE, HOUR ( 0) }, + { "wet", tZONE, HOUR ( 0) }, /* Western European */ + { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */ + { "wat", tZONE, HOUR ( 1) }, /* West Africa */ + { "at", tZONE, HOUR ( 2) }, /* Azores */ +#if 0 + /* For completeness. BST is also British Summer, and GST is + * also Guam Standard. */ + { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */ + { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */ +#endif +#if 0 + { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */ + { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */ + { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */ +#endif + { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */ + { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */ + { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */ + { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */ + { "cst", tZONE, HOUR ( 6) }, /* Central Standard */ + { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */ + { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */ + { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */ + { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */ + { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */ + { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */ + { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */ + { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */ + { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */ + { "cat", tZONE, HOUR (10) }, /* Central Alaska */ + { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */ + { "nt", tZONE, HOUR (11) }, /* Nome */ + { "idlw", tZONE, HOUR (12) }, /* International Date Line West */ + { "cet", tZONE, -HOUR (1) }, /* Central European */ + { "met", tZONE, -HOUR (1) }, /* Middle European */ + { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */ + { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ + { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ + { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */ + { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */ + { "fwt", tZONE, -HOUR (1) }, /* French Winter */ + { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */ + { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */ + { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */ +#if 0 + { "it", tZONE, -HOUR (3.5) },/* Iran */ +#endif + { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */ + { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */ +#if 0 + { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */ +#endif + { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */ +#if 0 + /* For completeness. NST is also Newfoundland Standard, and SST is + * also Swedish Summer. */ + { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */ + { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */ +#endif /* 0 */ + { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */ + { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */ +#if 0 + { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */ +#endif + { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */ + { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */ +#if 0 + { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */ + { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */ +#endif + { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */ + { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */ + { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */ + { "nzt", tZONE, -HOUR (12) }, /* New Zealand */ + { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */ + { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */ + { "idle", tZONE, -HOUR (12) }, /* International Date Line East */ + { NULL } +}; + +/* Military timezone table. */ +static TABLE const MilitaryTable[] = { + { "a", tZONE, HOUR ( 1) }, + { "b", tZONE, HOUR ( 2) }, + { "c", tZONE, HOUR ( 3) }, + { "d", tZONE, HOUR ( 4) }, + { "e", tZONE, HOUR ( 5) }, + { "f", tZONE, HOUR ( 6) }, + { "g", tZONE, HOUR ( 7) }, + { "h", tZONE, HOUR ( 8) }, + { "i", tZONE, HOUR ( 9) }, + { "k", tZONE, HOUR ( 10) }, + { "l", tZONE, HOUR ( 11) }, + { "m", tZONE, HOUR ( 12) }, + { "n", tZONE, HOUR (- 1) }, + { "o", tZONE, HOUR (- 2) }, + { "p", tZONE, HOUR (- 3) }, + { "q", tZONE, HOUR (- 4) }, + { "r", tZONE, HOUR (- 5) }, + { "s", tZONE, HOUR (- 6) }, + { "t", tZONE, HOUR (- 7) }, + { "u", tZONE, HOUR (- 8) }, + { "v", tZONE, HOUR (- 9) }, + { "w", tZONE, HOUR (-10) }, + { "x", tZONE, HOUR (-11) }, + { "y", tZONE, HOUR (-12) }, + { "z", tZONE, HOUR ( 0) }, + { NULL } +}; + + + + +/* ARGSUSED */ +static int +yyerror (s) + char *s; +{ + return 0; +} + +static int +ToHour (Hours, Meridian) + int Hours; + MERIDIAN Meridian; +{ + switch (Meridian) + { + case MER24: + if (Hours < 0 || Hours > 23) + return -1; + return Hours; + case MERam: + if (Hours < 1 || Hours > 12) + return -1; + if (Hours == 12) + Hours = 0; + return Hours; + case MERpm: + if (Hours < 1 || Hours > 12) + return -1; + if (Hours == 12) + Hours = 0; + return Hours + 12; + default: + abort (); + } + /* NOTREACHED */ +} + +static int +ToYear (Year) + int Year; +{ + if (Year < 0) + Year = -Year; + + /* XPG4 suggests that years 00-68 map to 2000-2068, and + years 69-99 map to 1969-1999. */ + if (Year < 69) + Year += 2000; + else if (Year < 100) + Year += 1900; + + return Year; +} + +static int +LookupWord (buff) + char *buff; +{ + register char *p; + register char *q; + register const TABLE *tp; + int i; + int abbrev; + + /* Make it lowercase. */ + for (p = buff; *p; p++) + if (ISUPPER (*p)) + *p = tolower (*p); + + if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0) + { + yylval.Meridian = MERam; + return tMERIDIAN; + } + if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0) + { + yylval.Meridian = MERpm; + return tMERIDIAN; + } + + /* See if we have an abbreviation for a month. */ + if (strlen (buff) == 3) + abbrev = 1; + else if (strlen (buff) == 4 && buff[3] == '.') + { + abbrev = 1; + buff[3] = '\0'; + } + else + abbrev = 0; + + for (tp = MonthDayTable; tp->name; tp++) + { + if (abbrev) + { + if (strncmp (buff, tp->name, 3) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + } + else if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + } + + for (tp = TimezoneTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + if (strcmp (buff, "dst") == 0) + return tDST; + + for (tp = UnitsTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + /* Strip off any plural and try the units table again. */ + i = strlen (buff) - 1; + if (buff[i] == 's') + { + buff[i] = '\0'; + for (tp = UnitsTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + buff[i] = 's'; /* Put back for "this" in OtherTable. */ + } + + for (tp = OtherTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + /* Military timezones. */ + if (buff[1] == '\0' && ISALPHA (*buff)) + { + for (tp = MilitaryTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + } + + /* Drop out any periods and try the timezone table again. */ + for (i = 0, p = q = buff; *q; q++) + if (*q != '.') + *p++ = *q; + else + i++; + *p = '\0'; + if (i) + for (tp = TimezoneTable; tp->name; tp++) + if (strcmp (buff, tp->name) == 0) + { + yylval.Number = tp->value; + return tp->type; + } + + return tID; +} + +static int +yylex () +{ + register char c; + register char *p; + char buff[20]; + int Count; + int sign; + + for (;;) + { + while (ISSPACE (*yyInput)) + yyInput++; + + if (ISDIGIT (c = *yyInput) || c == '-' || c == '+') + { + if (c == '-' || c == '+') + { + sign = c == '-' ? -1 : 1; + if (!ISDIGIT (*++yyInput)) + /* skip the '-' sign */ + continue; + } + else + sign = 0; + for (yylval.Number = 0; ISDIGIT (c = *yyInput++);) + yylval.Number = 10 * yylval.Number + c - '0'; + yyInput--; + if (sign < 0) + yylval.Number = -yylval.Number; + return sign ? tSNUMBER : tUNUMBER; + } + if (ISALPHA (c)) + { + for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';) + if (p < &buff[sizeof buff - 1]) + *p++ = c; + *p = '\0'; + yyInput--; + return LookupWord (buff); + } + if (c != '(') + return *yyInput++; + Count = 0; + do + { + c = *yyInput++; + if (c == '\0') + return c; + if (c == '(') + Count++; + else if (c == ')') + Count--; + } + while (Count > 0); + } +} + +#define TM_YEAR_ORIGIN 1900 + +/* Yield A - B, measured in seconds. */ +static long +difftm (a, b) + struct tm *a, *b; +{ + int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); + int by = b->tm_year + (TM_YEAR_ORIGIN - 1); + long days = ( + /* difference in day of year */ + a->tm_yday - b->tm_yday + /* + intervening leap days */ + + ((ay >> 2) - (by >> 2)) + - (ay / 100 - by / 100) + + ((ay / 100 >> 2) - (by / 100 >> 2)) + /* + difference in years * 365 */ + + (long) (ay - by) * 365 + ); + return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec)); +} + +time_t +get_date (p, now) + const char *p; + const time_t *now; +{ + struct tm tm, tm0, *tmp; + time_t Start; + + yyInput = p; + Start = now ? *now : time ((time_t *) NULL); + tmp = localtime (&Start); + yyYear = tmp->tm_year + TM_YEAR_ORIGIN; + yyMonth = tmp->tm_mon + 1; + yyDay = tmp->tm_mday; + yyHour = tmp->tm_hour; + yyMinutes = tmp->tm_min; + yySeconds = tmp->tm_sec; + yyMeridian = MER24; + yyRelSeconds = 0; + yyRelMinutes = 0; + yyRelHour = 0; + yyRelDay = 0; + yyRelMonth = 0; + yyRelYear = 0; + yyHaveDate = 0; + yyHaveDay = 0; + yyHaveRel = 0; + yyHaveTime = 0; + yyHaveZone = 0; + + if (yyparse () + || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1) + return -1; + + tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear; + tm.tm_mon = yyMonth - 1 + yyRelMonth; + tm.tm_mday = yyDay + yyRelDay; + if (yyHaveTime || (yyHaveRel && !yyHaveDate && !yyHaveDay)) + { + tm.tm_hour = ToHour (yyHour, yyMeridian); + if (tm.tm_hour < 0) + return -1; + tm.tm_min = yyMinutes; + tm.tm_sec = yySeconds; + } + else + { + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + } + tm.tm_hour += yyRelHour; + tm.tm_min += yyRelMinutes; + tm.tm_sec += yyRelSeconds; + tm.tm_isdst = -1; + tm0 = tm; + + Start = mktime (&tm); + + if (Start == (time_t) -1) + { + + /* Guard against falsely reporting errors near the time_t boundaries + when parsing times in other time zones. For example, if the min + time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead + of UTC, then the min localtime value is 1970-01-01 08:00:00; if + we apply mktime to 1970-01-01 00:00:00 we will get an error, so + we apply mktime to 1970-01-02 08:00:00 instead and adjust the time + zone by 24 hours to compensate. This algorithm assumes that + there is no DST transition within a day of the time_t boundaries. */ + if (yyHaveZone) + { + tm = tm0; + if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN) + { + tm.tm_mday++; + yyTimezone -= 24 * 60; + } + else + { + tm.tm_mday--; + yyTimezone += 24 * 60; + } + Start = mktime (&tm); + } + + if (Start == (time_t) -1) + return Start; + } + + if (yyHaveDay && !yyHaveDate) + { + tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7 + + 7 * (yyDayOrdinal - (0 < yyDayOrdinal))); + Start = mktime (&tm); + if (Start == (time_t) -1) + return Start; + } + + if (yyHaveZone) + { + long delta = yyTimezone * 60L + difftm (&tm, gmtime (&Start)); + if ((Start + delta < Start) != (delta < 0)) + return -1; /* time_t overflow */ + Start += delta; + } + + return Start; +} + +#if defined (TEST) + +/* ARGSUSED */ +int +main (ac, av) + int ac; + char *av[]; +{ + char buff[MAX_BUFF_LEN + 1]; + time_t d; + + (void) printf ("Enter date, or blank line to exit.\n\t> "); + (void) fflush (stdout); + + buff[MAX_BUFF_LEN] = 0; + while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0]) + { + d = get_date (buff, (time_t *) NULL); + if (d == -1) + (void) printf ("Bad format - couldn't convert.\n"); + else + (void) printf ("%s", ctime (&d)); + (void) printf ("\t> "); + (void) fflush (stdout); + } + exit (0); + /* NOTREACHED */ +} +#endif /* defined (TEST) */ diff --git a/current/libmisc/hushed.c b/current/libmisc/hushed.c new file mode 100644 index 00000000..fbc7a19d --- /dev/null +++ b/current/libmisc/hushed.c @@ -0,0 +1,90 @@ +/* + * Copyright 1991, 1993, Julianne Frances Haugh and Chip Rosenthal + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: hushed.c,v 1.4 2000/08/26 18:27:17 marekm Exp $") + +#include +#include +#include "defines.h" +#include "prototypes.h" +#include "getdef.h" +#include + +/* + * hushed - determine if a user receives login messages + * + * Look in the hushed-logins file (or user's home directory) to see + * if the user is to receive the login-time messages. + */ + +int +hushed(const struct passwd *pw) +{ + char *hushfile; + char buf[BUFSIZ]; + int found; + FILE *fp; + + /* + * Get the name of the file to use. If this option is not + * defined, default to a noisy login. + */ + + if ( (hushfile=getdef_str("HUSHLOGIN_FILE")) == NULL ) + return 0; + + /* + * If this is not a fully rooted path then see if the + * file exists in the user's home directory. + */ + + if (hushfile[0] != '/') { + snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir, hushfile); + return (access(buf, F_OK) == 0); + } + + /* + * If this is a fully rooted path then go through the file + * and see if this user is in there. + */ + + if ((fp = fopen(hushfile, "r")) == NULL) + return 0; + + for (found = 0;! found && fgets (buf, sizeof buf, fp);) { + buf[strlen (buf) - 1] = '\0'; + found = ! strcmp (buf, + buf[0] == '/' ? pw->pw_shell:pw->pw_name); + } + (void) fclose(fp); + return found; +} diff --git a/current/libmisc/isexpired.c b/current/libmisc/isexpired.c new file mode 100644 index 00000000..d70b2a79 --- /dev/null +++ b/current/libmisc/isexpired.c @@ -0,0 +1,173 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * Extracted from age.c and made part of libshadow.a - may be useful + * in other shadow-aware programs. --marekm + */ + +#include + +#include +#include "prototypes.h" +#include "defines.h" +#include +#include + +#ifdef HAVE_USERSEC_H +#include +#include +#include +#endif + +#ifndef AGING +#if defined(SHADOWPWD) || defined(HAVE_USERSEC_H) +#define AGING 1 +#endif +#else +#if !defined(SHADOWPWD) && !defined(HAVE_USERSEC_H) && !defined(ATT_AGE) +#undef AGING +#endif +#endif + +#if defined(SHADOWPWD) || defined(AGING) /*{*/ + +#include "rcsid.h" +RCSID("$Id: isexpired.c,v 1.7 1997/12/07 23:27:05 marekm Exp $") + +/* + * isexpired - determine if account is expired yet + * + * isexpired calculates the expiration date based on the + * password expiration criteria. + */ + +/*ARGSUSED*/ + +#ifdef SHADOWPWD +int +isexpired(const struct passwd *pw, const struct spwd *sp) +{ +#else +int +isexpired(const struct passwd *pw) +{ +#endif + long now; +#ifdef HAVE_USERSEC_H + int minage = 0; + int maxage = 10000; + int curage = 0; + struct userpw *pu; +#endif + + now = time ((time_t *) 0) / SCALE; + +#ifdef SHADOWPWD + + if (!sp) + sp = pwd_to_spwd(pw); + + /* + * Quick and easy - there is an expired account field + * along with an inactive account field. Do the expired + * one first since it is worse. + */ + + if (sp->sp_expire > 0 && now >= sp->sp_expire) + return 3; + + /* + * Last changed date 1970-01-01 (not very likely) means that + * the password must be changed on next login (passwd -e). + * + * The check for "x" is a workaround for RedHat NYS libc bug - + * if /etc/shadow doesn't exist, getspnam() still succeeds and + * returns sp_lstchg==0 (must change password) instead of -1! + */ + if (sp->sp_lstchg == 0 && !strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING)) + return 1; + + if (sp->sp_lstchg > 0 && sp->sp_max >= 0 && sp->sp_inact >= 0 && + now >= sp->sp_lstchg + sp->sp_max + sp->sp_inact) + return 2; +#endif +#ifdef HAVE_USERSEC_H /*{*/ + /* + * The aging information lives someplace else. Get it from the + * login.cfg file + */ + + if (getconfattr (SC_SYS_PASSWD, SC_MINAGE, &minage, SEC_INT)) + minage = -1; + + if (getconfattr (SC_SYS_PASSWD, SC_MAXAGE, &maxage, SEC_INT)) + maxage = -1; + + pu = getuserpw (pw->pw_name); + curage = (time (0) - pu->upw_lastupdate) / (7*86400L); + + if (maxage != -1 && curage > maxage) + return 1; +#else /*} !HAVE_USERSEC_H */ + + /* + * The last and max fields must be present for an account + * to have an expired password. A maximum of >10000 days + * is considered to be infinite. + */ + +#ifdef SHADOWPWD + if (sp->sp_lstchg == -1 || + sp->sp_max == -1 || sp->sp_max >= (10000L*DAY/SCALE)) + return 0; +#endif +#ifdef ATT_AGE + if (pw->pw_age[0] == '\0' || pw->pw_age[0] == '/') + return 0; +#endif + + /* + * Calculate today's day and the day on which the password + * is going to expire. If that date has already passed, + * the password has expired. + */ + +#ifdef SHADOWPWD + if (now >= sp->sp_lstchg + sp->sp_max) + return 1; +#endif +#ifdef ATT_AGE + if (a64l (pw->pw_age + 2) + c64i (pw->pw_age[1]) < now / 7) + return 1; +#endif +#endif /*} HAVE_USERSEC_H */ + return 0; +} +#endif /*}*/ diff --git a/current/libmisc/limits.c b/current/libmisc/limits.c new file mode 100644 index 00000000..e17817ea --- /dev/null +++ b/current/libmisc/limits.c @@ -0,0 +1,426 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * Separated from setup.c. --marekm + * Resource limits thanks to Cristian Gafton. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: limits.c,v 1.10 1999/08/27 19:02:51 marekm Exp $") + +#include +#include + +#include + +#include "prototypes.h" +#include "defines.h" +#include +#include "getdef.h" + +#ifdef HAVE_SYS_RESOURCE_H +#include +#define LIMITS +#endif + +#ifdef LIMITS + +#ifndef LIMITS_FILE +#define LIMITS_FILE "/etc/limits" +#endif + +#define LOGIN_ERROR_RLIMIT 1 +#define LOGIN_ERROR_LOGIN 2 + +/* Set a limit on a resource */ +/* + * rlimit - RLIMIT_XXXX + * value - string value to be read + * multiplier - value*multiplier is the actual limit + */ +static int +setrlimit_value(unsigned int rlimit, const char *value, unsigned int multiplier) +{ + struct rlimit rlim; + long limit; + char **endptr = (char **) &value; + const char *value_orig = value; + + limit = strtol(value, endptr, 10); + if (limit == 0 && value_orig == *endptr) /* no chars read */ + return 0; + limit *= multiplier; + rlim.rlim_cur = limit; + rlim.rlim_max = limit; + if (setrlimit(rlimit, &rlim)) + return LOGIN_ERROR_RLIMIT; + return 0; +} + + +static int +set_prio(const char *value) +{ + int prio; + char **endptr = (char **) &value; + + prio = strtol(value, endptr, 10); + if ((prio == 0) && (value == *endptr)) + return 0; + if (setpriority(PRIO_PROCESS, 0, prio)) + return LOGIN_ERROR_RLIMIT; + return 0; +} + + +static int +set_umask(const char *value) +{ + mode_t mask; + char **endptr = (char **) &value; + + mask = strtol(value, endptr, 8) & 0777; + if ((mask == 0) && (value == *endptr)) + return 0; + umask(mask); + return 0; +} + + +/* Counts the number of user logins and check against the limit */ +static int +check_logins(const char *name, const char *maxlogins) +{ + struct utmp *ut; + unsigned int limit, count; + char **endptr = (char **) &maxlogins; + const char *ml_orig = maxlogins; + + limit = strtol(maxlogins, endptr, 10); + if (limit == 0 && ml_orig == *endptr) /* no chars read */ + return 0; + + if (limit == 0) /* maximum 0 logins ? */ { + SYSLOG((LOG_WARN, "No logins allowed for `%s'\n", name)); + return LOGIN_ERROR_LOGIN; + } + + setutent(); + count = 0; + while ((ut = getutent())) { +#ifdef USER_PROCESS + if (ut->ut_type != USER_PROCESS) + continue; +#endif + if (ut->ut_user[0] == '\0') + continue; + if (strncmp(name, ut->ut_user, sizeof(ut->ut_user)) != 0) + continue; + if (++count > limit) + break; + } + endutent(); + /* + * This is called after setutmp(), so the number of logins counted + * includes the user who is currently trying to log in. + */ + if (count > limit) { + SYSLOG((LOG_WARN, "Too many logins (max %d) for %s\n", + limit, name)); + return LOGIN_ERROR_LOGIN; + } + return 0; +} + +/* Function setup_user_limits - checks/set limits for the curent login + * Original idea from Joel Katz's lshell. Ported to shadow-login + * by Cristian Gafton - gafton@sorosis.ro + * + * We are passed a string of the form ('BASH' constants for ulimit) + * [Aa][Cc][Dd][Ff][Mm][Nn][Rr][Ss][Tt][Uu][Ll][Pp] + * (eg. 'C2F256D2048N5' or 'C2 F256 D2048 N5') + * where: + * [Aa]: a = RLIMIT_AS max address space (KB) + * [Cc]: c = RLIMIT_CORE max core file size (KB) + * [Dd]: d = RLIMIT_DATA max data size (KB) + * [Ff]: f = RLIMIT_FSIZE max file size (KB) + * [Mm]: m = RLIMIT_MEMLOCK max locked-in-memory address space (KB) + * [Nn]: n = RLIMIT_NOFILE max number of open files + * [Rr]: r = RLIMIT_RSS max resident set size (KB) + * [Ss]: s = RLIMIT_STACK max stack size (KB) + * [Tt]: t = RLIMIT_CPU max CPU time (MIN) + * [Uu]: u = RLIMIT_NPROC max number of processes + * [Kk]: k = file creation masK (umask) + * [Ll]: l = max number of logins for this user + * [Pp]: p = process priority -20..20 (negative = high, positive = low) + * + * Return value: + * 0 = okay, of course + * LOGIN_ERROR_RLIMIT = error setting some RLIMIT + * LOGIN_ERROR_LOGIN = error - too many logins for this user + * + * buf - the limits string + * name - the username + */ +static int +do_user_limits(const char *buf, const char *name) +{ + const char *pp; + int retval = 0; + + pp = buf; + + while (*pp != '\0') switch(*pp++) { +#ifdef RLIMIT_AS + case 'a': + case 'A': + /* RLIMIT_AS - max address space (KB) */ + retval |= setrlimit_value(RLIMIT_AS, pp, 1024); +#endif +#ifdef RLIMIT_CPU + case 't': + case 'T': + /* RLIMIT_CPU - max CPU time (MIN) */ + retval |= setrlimit_value(RLIMIT_CPU, pp, 60); + break; +#endif +#ifdef RLIMIT_DATA + case 'd': + case 'D': + /* RLIMIT_DATA - max data size (KB) */ + retval |= setrlimit_value(RLIMIT_DATA, pp, 1024); + break; +#endif +#ifdef RLIMIT_FSIZE + case 'f': + case 'F': + /* RLIMIT_FSIZE - Maximum filesize (KB) */ + retval |= setrlimit_value(RLIMIT_FSIZE, pp, 1024); + break; +#endif +#ifdef RLIMIT_NPROC + case 'u': + case 'U': + /* RLIMIT_NPROC - max number of processes */ + retval |= setrlimit_value(RLIMIT_NPROC, pp, 1); + break; +#endif +#ifdef RLIMIT_CORE + case 'c': + case 'C': + /* RLIMIT_CORE - max core file size (KB) */ + retval |= setrlimit_value(RLIMIT_CORE, pp, 1024); + break; +#endif +#ifdef RLIMIT_MEMLOCK + case 'm': + case 'M': + /* RLIMIT_MEMLOCK - max locked-in-memory address space (KB) */ + retval |= setrlimit_value(RLIMIT_MEMLOCK, pp, 1024); + break; +#endif +#ifdef RLIMIT_NOFILE + case 'n': + case 'N': + /* RLIMIT_NOFILE - max number of open files */ + retval |= setrlimit_value(RLIMIT_NOFILE, pp, 1); + break; +#endif +#ifdef RLIMIT_RSS + case 'r': + case 'R': + /* RLIMIT_RSS - max resident set size (KB) */ + retval |= setrlimit_value(RLIMIT_RSS, pp, 1024); + break; +#endif +#ifdef RLIMIT_STACK + case 's': + case 'S': + /* RLIMIT_STACK - max stack size (KB) */ + retval |= setrlimit_value(RLIMIT_STACK, pp, 1024); + break; +#endif + case 'k': + case 'K': + retval |= set_umask(pp); + break; + case 'l': + case 'L': + /* LIMIT the number of concurent logins */ + retval |= check_logins(name, pp); + break; + case 'p': + case 'P': + retval |= set_prio(pp); + break; + } + return retval; +} + +static int +setup_user_limits(const char *uname) +{ + /* TODO: allow and use @group syntax --cristiang */ + FILE *fil; + char buf[1024]; + char name[1024]; + char limits[1024]; + char deflimits[1024]; + char tempbuf[1024]; + + /* init things */ + memzero(buf, sizeof(buf)); + memzero(name, sizeof(name)); + memzero(limits, sizeof(limits)); + memzero(deflimits, sizeof(deflimits)); + memzero(tempbuf, sizeof(tempbuf)); + + /* start the checks */ + fil = fopen(LIMITS_FILE, "r"); + if (fil == NULL) { +#if 0 /* no limits file is ok, not everyone is a BOFH :-). --marekm */ + SYSLOG((LOG_WARN, NO_LIMITS, uname, LIMITS_FILE)); +#endif + return 0; + } + /* The limits file have the following format: + * - '#' (comment) chars only as first chars on a line; + * - username must start on first column + * A better (smarter) checking should be done --cristiang */ + while (fgets(buf, 1024, fil) != NULL) { + if (buf[0]=='#' || buf[0]=='\n') + continue; + memzero(tempbuf, sizeof(tempbuf)); + /* a valid line should have a username, then spaces, + * then limits + * we allow the format: + * username L2 D2048 R4096 + * where spaces={' ',\t}. Also, we reject invalid limits. + * 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 */ + if (sscanf(buf, "%s%[ACDFMNRSTULPacdfmnrstulp0-9 \t-]", + name, tempbuf) == 2) { + if (strcmp(name, uname) == 0) { + strcpy(limits, tempbuf); + break; + } else if (strcmp(name, "*") == 0) { + strcpy(deflimits, tempbuf); + } + } + } + fclose(fil); + if (limits[0] == '\0') { + /* no user specific limits */ + if (deflimits[0] == '\0') /* no default limits */ + return 0; + strcpy(limits, deflimits); /* use the default limits */ + } + return do_user_limits(limits, uname); +} +#endif /* LIMITS */ + + +static void +setup_usergroups(const struct passwd *info) +{ + const struct group *grp; + mode_t oldmask; + +/* + * if not root, and uid == gid, and username is the same as primary + * group name, set umask group bits to be the same as owner bits + * (examples: 022 -> 002, 077 -> 007). + */ + if (info->pw_uid != 0 && info->pw_uid == info->pw_gid) { + grp = getgrgid(info->pw_gid); + if (grp && (strcmp(info->pw_name, grp->gr_name) == 0)) { + oldmask = umask(0777); + umask((oldmask & ~070) | ((oldmask >> 3) & 070)); + } + } +} + +/* + * set the process nice, ulimit, and umask from the password file entry + */ + +void +setup_limits(const struct passwd *info) +{ + char *cp; + int i; + long l; + + if (getdef_bool("USERGROUPS_ENAB")) + setup_usergroups(info); + + /* + * See if the GECOS field contains values for NICE, UMASK or ULIMIT. + * If this feature is enabled in /etc/login.defs, we make those + * values the defaults for this login session. + */ + + if (getdef_bool("QUOTAS_ENAB")) { +#ifdef LIMITS + if (info->pw_uid != 0) + if (setup_user_limits(info->pw_name) & LOGIN_ERROR_LOGIN) { + fprintf(stderr, _("Too many logins.\n")); + sleep(2); + exit(1); + } +#endif + for (cp = info->pw_gecos ; cp != NULL ; cp = strchr (cp, ',')) { + if (*cp == ',') + cp++; + + if (strncmp (cp, "pri=", 4) == 0) { + i = atoi (cp + 4); + if (i >= -20 && i <= 20) + (void) nice (i); + + continue; + } + if (strncmp (cp, "ulimit=", 7) == 0) { + l = strtol (cp + 7, (char **) 0, 10); + set_filesize_limit(l); + continue; + } + if (strncmp (cp, "umask=", 6) == 0) { + i = strtol (cp + 6, (char **) 0, 8) & 0777; + (void) umask (i); + + continue; + } + } + } +} diff --git a/current/libmisc/list.c b/current/libmisc/list.c new file mode 100644 index 00000000..db63c8dc --- /dev/null +++ b/current/libmisc/list.c @@ -0,0 +1,234 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* Removed duplicated code from gpmain.c, useradd.c, userdel.c and + usermod.c. --marekm */ + +#include + +#include "rcsid.h" +RCSID("$Id: list.c,v 1.3 1997/12/07 23:27:05 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" + +/* + * add_list - add a member to a list of group members + * + * the array of member names is searched for the new member + * name, and if not present it is added to a freshly allocated + * list of users. + */ + +char ** +add_list(char **list, const char *member) +{ + int i; + char **tmp; + + /* + * Scan the list for the new name. Return the original list + * pointer if it is present. + */ + + for (i = 0;list[i] != (char *) 0;i++) + if (strcmp (list[i], member) == 0) + return list; + + /* + * Allocate a new list pointer large enough to hold all the + * old entries, and the new entries as well. + */ + + tmp = (char **) xmalloc ((i + 2) * sizeof member); + + /* + * Copy the original list to the new list, then append the + * new member and NULL terminate the result. This new list + * is returned to the invoker. + */ + + for (i = 0;list[i] != (char *) 0;i++) + tmp[i] = list[i]; + + tmp[i++] = xstrdup (member); + tmp[i] = (char *) 0; + + return tmp; +} + +/* + * del_list - delete a member from a list of group members + * + * the array of member names is searched for the old member + * name, and if present it is deleted from a freshly allocated + * list of users. + */ + +char ** +del_list(char **list, const char *member) +{ + int i, j; + char **tmp; + + /* + * Scan the list for the old name. Return the original list + * pointer if it is not present. + */ + + for (i = j = 0;list[i] != (char *) 0;i++) + if (strcmp (list[i], member)) + j++; + + if (j == i) + return list; + + /* + * Allocate a new list pointer large enough to hold all the + * old entries. + */ + + tmp = (char **) xmalloc ((j + 1) * sizeof member); + + /* + * Copy the original list except the deleted members to the + * new list, then NULL terminate the result. This new list + * is returned to the invoker. + */ + + for (i = j = 0;list[i] != (char *) 0;i++) + if (strcmp (list[i], member)) + tmp[j++] = list[i]; + + tmp[j] = (char *) 0; + + return tmp; +} + +char ** +dup_list(char * const *list) +{ + int i; + char **tmp; + + for (i = 0; list[i]; i++) + ; + + tmp = (char **) xmalloc((i + 1) * sizeof(char *)); + + i = 0; + while (*list) + tmp[i++] = xstrdup(*list++); + + tmp[i] = (char *) 0; + return tmp; +} + +int +is_on_list(char * const *list, const char *member) +{ + while (*list) { + if (strcmp(*list, member) == 0) + return 1; + list++; + } + return 0; +} + +/* + * comma_to_list - convert comma-separated list to (char *) array + */ + +char ** +comma_to_list(const char *comma) +{ + char *members; + char **array; + int i; + char *cp, *cp2; + + /* + * Make a copy since we are going to be modifying the list + */ + + members = xstrdup (comma); + + /* + * Count the number of commas in the list + */ + + for (cp = members, i = 0;;i++) + if ((cp2 = strchr (cp, ','))) + cp = cp2 + 1; + else + break; + + /* + * Add 2 - one for the ending NULL, the other for the last item + */ + + i += 2; + + /* + * Allocate the array we're going to store the pointers into. + */ + + array = (char **) xmalloc (sizeof (char *) * i); + + /* + * Empty list is special - 0 members, not 1 empty member. --marekm + */ + + if (!*members) { + *array = (char *) 0; + return array; + } + + /* + * Now go walk that list all over again, this time building the + * array of pointers. + */ + + for (cp = members, i = 0;;i++) { + array[i] = cp; + if ((cp2 = strchr (cp, ','))) { + *cp2++ = '\0'; + cp = cp2; + } else { + array[i + 1] = (char *) 0; + break; + } + } + + /* + * Return the new array of pointers + */ + + return array; +} diff --git a/current/libmisc/log.c b/current/libmisc/log.c new file mode 100644 index 00000000..a0ee0e1b --- /dev/null +++ b/current/libmisc/log.c @@ -0,0 +1,100 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: log.c,v 1.5 1998/04/16 19:57:44 marekm Exp $") + +#include +#include +#include +#include +#include "defines.h" +#if HAVE_LASTLOG_H +#include +#else +#include "lastlog_.h" +#endif + +/* + * dolastlog - create lastlog entry + * + * A "last login" entry is created for the user being logged in. The + * UID is extracted from the global (struct passwd) entry and the + * TTY information is gotten from the (struct utmp). + */ + +void +dolastlog(struct lastlog *ll, const struct passwd *pw, const char *line, const char *host) +{ + int fd; + off_t offset; + struct lastlog newlog; + + /* + * If the file does not exist, don't create it. + */ + + if ((fd = open(LASTLOG_FILE, O_RDWR)) == -1) + return; + + /* + * The file is indexed by UID number. Seek to the record + * for this UID. Negative UID's will create problems, but ... + */ + + offset = (unsigned long) pw->pw_uid * sizeof newlog; + + if (lseek(fd, offset, SEEK_SET) != offset) { + close(fd); + return; + } + + /* + * Read the old entry so we can tell the user when they last + * logged in. Then construct the new entry and write it out + * the way we read the old one in. + */ + + if (read(fd, (char *) &newlog, sizeof newlog) != sizeof newlog) + memzero(&newlog, sizeof newlog); + if (ll) + *ll = newlog; + + time(&newlog.ll_time); + strncpy(newlog.ll_line, line, sizeof newlog.ll_line); +#if HAVE_LL_HOST + strncpy(newlog.ll_host, host, sizeof newlog.ll_host); +#endif + if (lseek(fd, offset, SEEK_SET) == offset) + write(fd, (char *) &newlog, sizeof newlog); + close(fd); +} + diff --git a/current/libmisc/login_access.c b/current/libmisc/login_access.c new file mode 100644 index 00000000..1d06d3e7 --- /dev/null +++ b/current/libmisc/login_access.c @@ -0,0 +1,340 @@ +/* Taken from logdaemon-5.0, only minimal changes. --marekm */ + +/************************************************************************ +* Copyright 1995 by Wietse Venema. All rights reserved. Individual files +* may be covered by other copyrights (as noted in the file itself.) +* +* This material was originally written and compiled by Wietse Venema at +* Eindhoven University of Technology, The Netherlands, in 1990, 1991, +* 1992, 1993, 1994 and 1995. +* +* Redistribution and use in source and binary forms are permitted +* provided that this entire copyright notice is duplicated in all such +* copies. +* +* This software is provided "as is" and without any expressed or implied +* warranties, including, without limitation, the implied warranties of +* merchantibility and fitness for any particular purpose. +************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef LOGIN_ACCESS +#include "rcsid.h" +RCSID("$Id: login_access.c,v 1.6 1998/01/29 23:22:34 marekm Exp $") +#include "prototypes.h" + + /* + * This module implements a simple but effective form of login access + * control based on login names and on host (or domain) names, internet + * addresses (or network numbers), or on terminal line names in case of + * non-networked logins. Diagnostics are reported through syslog(3). + * + * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. + */ + +#include +#include +#include +#include +#include +#include +#ifdef PRIMARY_GROUP_MATCH +#include +#endif +#include +#include +#include +#include +#include +#include +#include /* for inet_ntoa() */ + +extern struct group *getgrnam(); +extern int innetgr(); +#if 0 /* should be defined by */ +extern int errno; +#endif + +#if !defined(MAXHOSTNAMELEN) || (MAXHOSTNAMELEN < 64) +#undef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + + /* Path name of the access control file. */ + +#ifndef TABLE +#define TABLE "/etc/login.access" +#endif + + /* Delimiters for fields and for lists of users, ttys or hosts. */ + +static char fs[] = ":"; /* field separator */ +static char sep[] = ", \t"; /* list-element separator */ + + /* Constants to be used in assignments only, not in comparisons... */ + +#define YES 1 +#define NO 0 + +static int list_match(); +static int user_match(); +static int from_match(); +static int string_match(); + +/* login_access - match username/group and host/tty with access control file */ + +int +login_access(const char *user, const char *from) +{ + FILE *fp; + char line[BUFSIZ]; + char *perm; /* becomes permission field */ + char *users; /* becomes list of login names */ + char *froms; /* becomes list of terminals or hosts */ + int match = NO; + int end; + int lineno = 0; /* for diagnostics */ + + /* + * Process the table one line at a time and stop at the first match. + * Blank lines and lines that begin with a '#' character are ignored. + * Non-comment lines are broken at the ':' character. All fields are + * mandatory. The first field should be a "+" or "-" character. A + * non-existing table means no access control. + */ + + if ((fp = fopen(TABLE, "r"))) { + while (!match && fgets(line, sizeof(line), fp)) { + lineno++; + if (line[end = strlen(line) - 1] != '\n') { + syslog(LOG_ERR, "%s: line %d: missing newline or line too long", + TABLE, lineno); + continue; + } + if (line[0] == '#') + continue; /* comment line */ + while (end > 0 && isspace(line[end - 1])) + end--; + line[end] = 0; /* strip trailing whitespace */ + if (line[0] == 0) /* skip blank lines */ + continue; + if (!(perm = strtok(line, fs)) + || !(users = strtok((char *) 0, fs)) + || !(froms = strtok((char *) 0, fs)) + || strtok((char *) 0, fs)) { + syslog(LOG_ERR, "%s: line %d: bad field count", TABLE, lineno); + continue; + } + if (perm[0] != '+' && perm[0] != '-') { + syslog(LOG_ERR, "%s: line %d: bad first field", TABLE, lineno); + continue; + } + match = (list_match(froms, from, from_match) + && list_match(users, user, user_match)); + } + (void) fclose(fp); + } else if (errno != ENOENT) { + syslog(LOG_ERR, "cannot open %s: %m", TABLE); + } + return (match == 0 || (line[0] == '+')); +} + +/* list_match - match an item against a list of tokens with exceptions */ + +static int +list_match(char *list, const char *item, int (*match_fn)()) +{ + char *tok; + int match = NO; + + /* + * Process tokens one at a time. We have exhausted all possible matches + * when we reach an "EXCEPT" token or the end of the list. If we do find + * a match, look for an "EXCEPT" list and recurse to determine whether + * the match is affected by any exceptions. + */ + + for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) { + if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ + break; + if ((match = (*match_fn) (tok, item))) /* YES */ + break; + } + /* Process exceptions to matches. */ + + if (match != NO) { + while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT")) + /* VOID */ ; + if (tok == 0 || list_match((char *) 0, item, match_fn) == NO) + return (match); + } + return (NO); +} + +/* myhostname - figure out local machine name */ + +static char * +myhostname(void) +{ + static char name[MAXHOSTNAMELEN + 1] = ""; + + if (name[0] == 0) { + gethostname(name, sizeof(name)); + name[MAXHOSTNAMELEN] = 0; + } + return (name); +} + +/* netgroup_match - match group against machine or user */ + +static int +netgroup_match(const char *group, const char *machine, const char *user) +{ +#if 0 /* original code */ +#ifdef NIS + static char *mydomain = 0; + + if (mydomain == 0) + yp_get_default_domain(&mydomain); + return (innetgr(group, machine, user, mydomain)); +#else + syslog(LOG_ERR, "NIS netgroup support not configured"); + return (NO); +#endif +#else /* works better with glibc? */ + static char *mydomain = 0; + + if (mydomain == 0) { + static char domain[MAXHOSTNAMELEN+1]; + + getdomainname(domain, MAXHOSTNAMELEN); + mydomain = domain; + } + + return innetgr(group, machine, user, mydomain); +#endif +} + +/* user_match - match a username against one token */ + +static int +user_match(const char *tok, const char *string) +{ + struct group *group; +#ifdef PRIMARY_GROUP_MATCH + struct passwd *userinf; +#endif + int i; + char *at; + + /* + * If a token has the magic value "ALL" the match always succeeds. + * Otherwise, return YES if the token fully matches the username, or if + * the token is a group that contains the username. + */ + + if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */ + *at = 0; + return (user_match(tok, string) && from_match(at + 1, myhostname())); + } else if (tok[0] == '@') { /* netgroup */ + return (netgroup_match(tok + 1, (char *) 0, string)); + } else if (string_match(tok, string)) { /* ALL or exact match */ + return (YES); + } else if ((group = getgrnam(tok))) { /* try group membership */ + for (i = 0; group->gr_mem[i]; i++) + if (strcasecmp(string, group->gr_mem[i]) == 0) + return (YES); +#ifdef PRIMARY_GROUP_MATCH + /* + * If the sting is an user whose initial GID matches the token, + * accept it. May avoid excessively long lines in /etc/group. + * Radu-Adrian Feurdean + * + * XXX - disabled by default for now. Need to verify that + * getpwnam() doesn't have some nasty side effects. --marekm + */ + if ((userinf = getpwnam(string))) + if (userinf->pw_gid == group->gr_gid) + return (YES); +#endif + } + return (NO); +} + +static char * +resolve_hostname(string) + char *string; +{ +#if 1 + /* + * Resolve hostname to numeric IP address, as suggested + * by Dave Hagewood . --marekm + */ + struct hostent *hp; + + hp = gethostbyname(string); + if (hp) + return inet_ntoa(*((struct in_addr *) *(hp->h_addr_list))); + + syslog(LOG_ERR, "%s - unknown host", string); +#endif + return string; +} + +/* from_match - match a host or tty against a list of tokens */ + +static int +from_match(const char *tok, const char *string) +{ + int tok_len; + int str_len; + + /* + * If a token has the magic value "ALL" the match always succeeds. Return + * YES if the token fully matches the string. If the token is a domain + * name, return YES if it matches the last fields of the string. If the + * token has the magic value "LOCAL", return YES if the string does not + * contain a "." character. If the token is a network number, return YES + * if it matches the head of the string. + */ + + if (tok[0] == '@') { /* netgroup */ + return (netgroup_match(tok + 1, string, (char *) 0)); + } else if (string_match(tok, string)) { /* ALL or exact match */ + return (YES); + } else if (tok[0] == '.') { /* domain: match last fields */ + if ((str_len = strlen(string)) > (tok_len = strlen(tok)) + && strcasecmp(tok, string + str_len - tok_len) == 0) + return (YES); + } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ + if (strchr(string, '.') == 0) + return (YES); + } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */ + && strncmp(tok, resolve_hostname(string), tok_len) == 0) { + return (YES); + } + return (NO); +} + +/* string_match - match a string against one token */ + +static int +string_match(const char *tok, const char *string) +{ + + /* + * If the token has the magic value "ALL" the match always succeeds. + * Otherwise, return YES if the token fully matches the string. + */ + + if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ + return (YES); + } else if (strcasecmp(tok, string) == 0) { /* try exact match */ + return (YES); + } + return (NO); +} +#endif /* LOGIN_ACCESS */ diff --git a/current/libmisc/login_desrpc.c b/current/libmisc/login_desrpc.c new file mode 100644 index 00000000..9767b406 --- /dev/null +++ b/current/libmisc/login_desrpc.c @@ -0,0 +1,77 @@ +/* Taken from logdaemon-5.0, only minimal changes. --marekm */ + +/************************************************************************ +* Copyright 1995 by Wietse Venema. All rights reserved. Individual files +* may be covered by other copyrights (as noted in the file itself.) +* +* This material was originally written and compiled by Wietse Venema at +* Eindhoven University of Technology, The Netherlands, in 1990, 1991, +* 1992, 1993, 1994 and 1995. +* +* Redistribution and use in source and binary forms are permitted +* provided that this entire copyright notice is duplicated in all such +* copies. +* +* This software is provided "as is" and without any expressed or implied +* warranties, including, without limitation, the implied warranties of +* merchantibility and fitness for any particular purpose. +************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef DES_RPC +#include "rcsid.h" +RCSID("$Id: login_desrpc.c,v 1.7 1999/06/07 16:40:44 marekm Exp $") + +#include "defines.h" + + /* + * Decrypt the user's secret secure RPC key and stores it into the + * keyserver. Returns 0 if successful, -1 on failure. + * + * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. + */ + +#include +#include +#include + +#if !(defined __GLIBC__ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0))) +/* these don't seem to be in any header file (libc-5.4.33) */ +/* but will be in glibc 2.1 and */ +extern int getnetname(char *); +extern int getsecretkey(const char *, char *, const char *); +extern int key_setsecret(const char *); +#endif + +int +login_desrpc(const char *passwd) +{ + char netname[MAXNETNAMELEN + 1]; + char secretkey[HEXKEYBYTES + 1]; + + if (getnetname(netname) == 0) + return -1; + + if (getsecretkey(netname, secretkey, passwd) == 0) + return -1; + + if (secretkey[0] == 0) { + fprintf(stderr, + _("Password does not decrypt secret key for %s.\n"), + netname); + return -1; + } + if (key_setsecret(secretkey) < 0) { + fprintf(stderr, + _("Could not set %s's secret key: is the keyserv daemon running?\n"), + netname); + return -1; + } + return 0; +} +#else +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif diff --git a/current/libmisc/login_krb.c b/current/libmisc/login_krb.c new file mode 100644 index 00000000..001a2163 --- /dev/null +++ b/current/libmisc/login_krb.c @@ -0,0 +1,61 @@ +/* Taken from logdaemon-5.0, only minimal changes. --marekm */ + +/************************************************************************ +* Copyright 1995 by Wietse Venema. All rights reserved. Individual files +* may be covered by other copyrights (as noted in the file itself.) +* +* This material was originally written and compiled by Wietse Venema at +* Eindhoven University of Technology, The Netherlands, in 1990, 1991, +* 1992, 1993, 1994 and 1995. +* +* Redistribution and use in source and binary forms are permitted +* provided that this entire copyright notice is duplicated in all such +* copies. +* +* This software is provided "as is" and without any expressed or implied +* warranties, including, without limitation, the implied warranties of +* merchantibility and fitness for any particular purpose. +************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef KERBEROS +#include "rcsid.h" +RCSID("$Id: login_krb.c,v 1.3 1998/01/29 23:22:34 marekm Exp $") + +#include + + /* + * Do an equivalent to kinit here. We need to do the kinit before trying to + * cd to the home directory, because it might be on a remote filesystem that + * uses Kerberos authentication. We also need to do this after we've + * setuid() to the user, or krb_get_pw_in_tkt() won't know where to put the + * ticket. + * + * We don't really care about whether or not it succeeds; if it fails, we'll + * just carry on bravely. + * + * NB: we assume: local realm, same username and password as supplied to login. + * + * Security note: if pp is NULL, login doesn't have the password. This is + * common when it's called by rlogind. Since this is almost always a remote + * connection, we don't want to risk asking for the password by supplying a + * NULL pp to krb_get_pw_in_tkt(), because somebody could be listening. So + * we'll just forget the whole thing. -jdd + */ + +int +login_kerberos(const char *username, const char *password) +{ + char realm[REALM_SZ]; + + (void) krb_get_lrealm(realm, 1); + if (password != 0) + (void) krb_get_pw_in_tkt(username, "", realm, "krbtgt", + realm, DEFAULT_TKT_LIFE, password); +} +#else +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /* KERBEROS */ diff --git a/current/libmisc/loginprompt.c b/current/libmisc/loginprompt.c new file mode 100644 index 00000000..abe81d3a --- /dev/null +++ b/current/libmisc/loginprompt.c @@ -0,0 +1,165 @@ +/* + * Copyright 1989 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: loginprompt.c,v 1.6 2000/08/26 18:27:17 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" +#include "defines.h" +#include "getdef.h" + +static void +login_exit(int sig) +{ + exit(1); +} + +/* + * login_prompt - prompt the user for their login name + * + * login_prompt() displays the standard login prompt. If ISSUE_FILE + * is set in login.defs, this file is displayed before the prompt. + */ + +void +login_prompt(const char *prompt, char *name, int namesize) +{ + char buf[1024]; +#define MAX_ENV 32 + char *envp[MAX_ENV]; + int envc; + char *cp; + int i; + FILE *fp; + RETSIGTYPE (*sigquit)(int); +#ifdef SIGTSTP + RETSIGTYPE (*sigtstp)(int); +#endif + + /* + * There is a small chance that a QUIT character will be part of + * some random noise during a prompt. Deal with this by exiting + * instead of core dumping. If SIGTSTP is defined, do the same + * thing for that signal. + */ + + sigquit = signal(SIGQUIT, login_exit); +#ifdef SIGTSTP + sigtstp = signal(SIGTSTP, login_exit); +#endif + + /* + * See if the user has configured the issue file to + * be displayed and display it before the prompt. + */ + + if (prompt) { + cp = getdef_str("ISSUE_FILE"); + if (cp && (fp = fopen(cp, "r"))) { + while ((i = getc(fp)) != EOF) + putc(i, stdout); + + fclose(fp); + } + gethostname(buf, sizeof buf); + printf(prompt, buf); + fflush(stdout); + } + + /* + * Read the user's response. The trailing newline will be + * removed. + */ + + memzero(buf, sizeof buf); + if (fgets(buf, sizeof buf, stdin) != buf) + exit(1); + + cp = strchr(buf, '\n'); + if (!cp) + exit(1); + *cp = '\0'; /* remove \n [ must be there ] */ + + /* + * Skip leading whitespace. This makes " username" work right. + * Then copy the rest (up to the end or the first "non-graphic" + * character into the username. + */ + + for (cp = buf;*cp == ' ' || *cp == '\t';cp++) + ; + + for (i = 0; i < namesize - 1 && isgraph(*cp); name[i++] = *cp++) + ; + while (isgraph(*cp)) + cp++; + + if (*cp) + cp++; + + name[i] = '\0'; + + /* + * This is a disaster, at best. The user may have entered extra + * environmental variables at the prompt. There are several ways + * to do this, and I just take the easy way out. + */ + + if (*cp != '\0') { /* process new variables */ + char *nvar; + int count = 1; + + for (envc = 0; envc < MAX_ENV; envc++) { + nvar = strtok(envc ? (char *)0 : cp, " \t,"); + if (!nvar) + break; + if (strchr(nvar, '=')) { + envp[envc] = nvar; + } else { + envp[envc] = xmalloc(strlen(nvar) + 32); + sprintf(envp[envc], "L%d=%s", count++, nvar); + } + } + set_env(envc, envp); + } + + /* + * Set the SIGQUIT handler back to its original value + */ + + signal(SIGQUIT, sigquit); +#ifdef SIGTSTP + signal(SIGTSTP, sigtstp); +#endif +} diff --git a/current/libmisc/mail.c b/current/libmisc/mail.c new file mode 100644 index 00000000..7b24e974 --- /dev/null +++ b/current/libmisc/mail.c @@ -0,0 +1,79 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include +#include "prototypes.h" +#include "defines.h" +#include +#include +#include + +#include "getdef.h" + +#include "rcsid.h" +RCSID("$Id: mail.c,v 1.7 1998/12/28 20:34:49 marekm Exp $") + +void +mailcheck(void) +{ + struct stat statbuf; + char *mailbox; + + if (!getdef_bool("MAIL_CHECK_ENAB")) + return; + + /* + * Check incoming mail in Maildir format - J. + */ + if ((mailbox = getenv("MAILDIR"))) { + char *newmail; + + newmail = xmalloc(strlen(mailbox) + 5); + sprintf(newmail, "%s/new", mailbox); + if (stat(newmail, &statbuf) != -1 && statbuf.st_size != 0) { + if (statbuf.st_mtime > statbuf.st_atime) { + free(newmail); + puts(_("You have new mail.")); + return; + } + } + free(newmail); + } + + if (!(mailbox = getenv("MAIL"))) + return; + + if (stat(mailbox, &statbuf) == -1 || statbuf.st_size == 0) + puts(_("No mail.")); + else if (statbuf.st_atime > statbuf.st_mtime) + puts(_("You have mail.")); + else + puts(_("You have new mail.")); +} + diff --git a/current/libmisc/motd.c b/current/libmisc/motd.c new file mode 100644 index 00000000..0ff6973e --- /dev/null +++ b/current/libmisc/motd.c @@ -0,0 +1,69 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: motd.c,v 1.3 1997/12/07 23:27:07 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include "getdef.h" + +/* + * motd -- output the /etc/motd file + * + * motd() determines the name of a login announcement file and outputs + * it to the user's terminal at login time. The MOTD_FILE configuration + * option is a colon-delimited list of filenames. + */ + +void +motd(void) +{ + FILE *fp; + char motdlist[BUFSIZ], *motdfile, *mb; + register int c; + + if ((mb = getdef_str("MOTD_FILE")) == NULL) + return; + + strncpy(motdlist, mb, sizeof(motdlist)); + motdlist[sizeof(motdlist)-1] = '\0'; + + for (mb = motdlist ; (motdfile = strtok(mb,":")) != NULL ; mb = NULL) { + if ((fp = fopen(motdfile, "r")) != NULL) { + while ((c = getc (fp)) != EOF) + putchar (c); + fclose (fp); + } + } + fflush (stdout); +} diff --git a/current/libmisc/myname.c b/current/libmisc/myname.c new file mode 100644 index 00000000..66e80e56 --- /dev/null +++ b/current/libmisc/myname.c @@ -0,0 +1,41 @@ +/* + * myname.c - determine the current username and get the passwd entry + * + * Copyright (C) 1996 Marek Michalkiewicz + * + * This code may be freely used, modified and distributed for any purpose. + * There is no warranty, if it breaks you have to keep both pieces, etc. + * If you improve it, please send me your changes. Thanks! + */ + +#include + +#include "rcsid.h" +RCSID("$Id: myname.c,v 1.2 1997/12/07 23:27:07 marekm Exp $") + +#include "defines.h" +#include +#include "prototypes.h" + +struct passwd * +get_my_pwent(void) +{ + struct passwd *pw; + const char *cp = getlogin(); + uid_t ruid = getuid(); + + /* + * Try getlogin() first - if it fails or returns a non-existent + * username, or a username which doesn't match the real UID, fall + * back to getpwuid(getuid()). This should work reasonably with + * usernames longer than the utmp limit (8 characters), as well as + * shared UIDs - but not both at the same time... + * + * XXX - when running from su, will return the current user (not + * the original user, like getlogin() does). Does this matter? + */ + if (cp && *cp && (pw = getpwnam(cp)) && pw->pw_uid == ruid) + return pw; + + return getpwuid(ruid); +} diff --git a/current/libmisc/obscure.c b/current/libmisc/obscure.c new file mode 100644 index 00000000..845bd264 --- /dev/null +++ b/current/libmisc/obscure.c @@ -0,0 +1,286 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: obscure.c,v 1.9 1999/03/07 19:14:40 marekm Exp $") + +/* + * This version of obscure.c contains modifications to support "cracklib" + * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib + * library source code for this function to operate. + */ + +#include +#include +#include "prototypes.h" +#include "defines.h" + +#include "getdef.h" + +/* + * can't be a palindrome - like `R A D A R' or `M A D A M' + */ + +/*ARGSUSED*/ +static int +palindrome(const char *old, const char *new) +{ + int i, j; + + i = strlen (new); + + for (j = 0;j < i;j++) + if (new[i - j - 1] != new[j]) + return 0; + + return 1; +} + +/* + * more than half of the characters are different ones. + */ + +/*ARGSUSED*/ +static int +similar(const char *old, const char *new) +{ + int i, j; + + /* + * XXX - sometimes this fails when changing from a simple password + * to a really long one (MD5). For now, I just return success if + * the new password is long enough. Please feel free to suggest + * something better... --marekm + */ + if (strlen(new) >= 8) + return 0; + + for (i = j = 0; new[i] && old[i]; i++) + if (strchr(new, old[i])) + j++; + + if (i >= j * 2) + return 0; + + return 1; +} + +/* + * a nice mix of characters. + */ + +/*ARGSUSED*/ +static int +simple(const char *old, const char *new) +{ + int digits = 0; + int uppers = 0; + int lowers = 0; + int others = 0; + int size; + int i; + + for (i = 0;new[i];i++) { + if (isdigit (new[i])) + digits++; + else if (isupper (new[i])) + uppers++; + else if (islower (new[i])) + lowers++; + else + others++; + } + + /* + * The scam is this - a password of only one character type + * must be 8 letters long. Two types, 7, and so on. + */ + + size = 9; + if (digits) size--; + if (uppers) size--; + if (lowers) size--; + if (others) size--; + + if (size <= i) + return 0; + + return 1; +} + +static char * +str_lower(char *string) +{ + char *cp; + + for (cp = string; *cp; cp++) + *cp = tolower(*cp); + return string; +} + +static const char * +password_check(const char *old, const char *new, const struct passwd *pwdp) +{ + const char *msg = NULL; + char *oldmono, *newmono, *wrapped; +#ifdef HAVE_LIBCRACK + char *dictpath; +#ifdef HAVE_LIBCRACK_PW + char *FascistCheckPw(); +#else + char *FascistCheck(); +#endif +#endif + + if (strcmp(new, old) == 0) + return "no change"; + + newmono = str_lower(xstrdup(new)); + oldmono = str_lower(xstrdup(old)); + wrapped = xmalloc(strlen(oldmono) * 2 + 1); + strcpy (wrapped, oldmono); + strcat (wrapped, oldmono); + + if (palindrome(oldmono, newmono)) + msg = "a palindrome"; + + if (!msg && strcmp(oldmono, newmono) == 0) + msg = "case changes only"; + + if (!msg && similar(oldmono, newmono)) + msg = "too similar"; + + if (!msg && simple(old, new)) + msg = "too simple"; + + if (!msg && strstr(wrapped, newmono)) + msg = "rotated"; + +#ifdef HAVE_LIBCRACK + /* + * Invoke Alec Muffett's cracklib routines. + */ + + if (!msg && (dictpath = getdef_str("CRACKLIB_DICTPATH"))) +#ifdef HAVE_LIBCRACK_PW + msg = FascistCheckPw(new, dictpath, pwdp); +#else + msg = FascistCheck(new, dictpath); +#endif +#endif + strzero(newmono); + strzero(oldmono); + strzero(wrapped); + free(newmono); + free(oldmono); + free(wrapped); + + return msg; +} + +/*ARGSUSED*/ +static const char * +obscure_msg(const char *old, const char *new, const struct passwd *pwdp) +{ + int maxlen, oldlen, newlen; + char *new1, *old1; + const char *msg; + + oldlen = strlen(old); + newlen = strlen(new); + +#if 0 /* why not check the password when set for the first time? --marekm */ + if (old[0] == '\0') + return NULL; +#endif + + if ( newlen < getdef_num("PASS_MIN_LEN", 0) ) + return "too short"; + + /* + * Remaining checks are optional. + */ + if (!getdef_bool("OBSCURE_CHECKS_ENAB")) + return NULL; + + msg = password_check(old, new, pwdp); + if (msg) + return msg; + + /* The traditional crypt() truncates passwords to 8 chars. It is + possible to circumvent the above checks by choosing an easy + 8-char password and adding some random characters to it... + Example: "password$%^&*123". So check it again, this time + truncated to the maximum length. Idea from npasswd. --marekm */ + + if (getdef_bool("MD5_CRYPT_ENAB")) + return NULL; /* unlimited password length */ + + maxlen = getdef_num("PASS_MAX_LEN", 8); + if (oldlen <= maxlen && newlen <= maxlen) + return NULL; + + new1 = xstrdup(new); + old1 = xstrdup(old); + if (newlen > maxlen) + new1[maxlen] = '\0'; + if (oldlen > maxlen) + old1[maxlen] = '\0'; + + msg = password_check(old1, new1, pwdp); + + memzero(new1, newlen); + memzero(old1, oldlen); + free(new1); + free(old1); + + return msg; +} + +/* + * Obscure - see if password is obscure enough. + * + * The programmer is encouraged to add as much complexity to this + * routine as desired. Included are some of my favorite ways to + * check passwords. + */ + +int +obscure(const char *old, const char *new, const struct passwd *pwdp) +{ + const char *msg = obscure_msg(old, new, pwdp); + if (msg) { + printf(_("Bad password: %s. "), msg); + return 0; + } + return 1; +} + diff --git a/current/libmisc/pam_pass.c b/current/libmisc/pam_pass.c new file mode 100644 index 00000000..b3e7ac75 --- /dev/null +++ b/current/libmisc/pam_pass.c @@ -0,0 +1,58 @@ +#include + +#ifdef USE_PAM + +#include "rcsid.h" +RCSID("$Id: pam_pass.c,v 1.6 1999/06/07 16:40:44 marekm Exp $") + +/* + * Change the user's password using PAM. Requires libpam and libpam_misc + * (for misc_conv). Note: libpam_misc is probably Linux-PAM specific, + * so you may have to port it if you want to use this code on non-Linux + * systems with PAM (such as Solaris 2.6). --marekm + */ + +#include +#include +#include +#include + +#include "defines.h" + +#include "pam_defs.h" + +static const struct pam_conv conv = { + misc_conv, + NULL +}; + +void +do_pam_passwd(const char *user, int silent, int change_expired) +{ + pam_handle_t *pamh = NULL; + int flags = 0, ret; + + if (silent) + flags |= PAM_SILENT; + if (change_expired) + flags |= PAM_CHANGE_EXPIRED_AUTHTOK; + + ret = pam_start("passwd", user, &conv, &pamh); + if (ret != PAM_SUCCESS) { + fprintf(stderr, _("passwd: pam_start() failed, error %d\n"), + ret); + exit(10); /* XXX */ + } + + ret = pam_chauthtok(pamh, flags); + if (ret != PAM_SUCCESS) { + fprintf(stderr, _("passwd: %s\n"), PAM_STRERROR(pamh, ret)); + pam_end(pamh, ret); + exit(10); /* XXX */ + } + + pam_end(pamh, PAM_SUCCESS); +} +#else /* !USE_PAM */ +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /* !USE_PAM */ diff --git a/current/libmisc/pwd2spwd.c b/current/libmisc/pwd2spwd.c new file mode 100644 index 00000000..e53d96ab --- /dev/null +++ b/current/libmisc/pwd2spwd.c @@ -0,0 +1,103 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifdef SHADOWPWD + +#include "rcsid.h" +RCSID("$Id: pwd2spwd.c,v 1.3 1997/12/07 23:27:07 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include + +extern time_t time (); + +/* + * pwd_to_spwd - create entries for new spwd structure + * + * pwd_to_spwd() creates a new (struct spwd) containing the + * information in the pointed-to (struct passwd). + */ + +struct spwd * +pwd_to_spwd(const struct passwd *pw) +{ + static struct spwd sp; + + /* + * Nice, easy parts first. The name and passwd map directly + * from the old password structure to the new one. + */ + sp.sp_namp = pw->pw_name; + sp.sp_pwdp = pw->pw_passwd; + +#ifdef ATT_AGE + /* + * AT&T-style password aging maps the sp_min, sp_max, and + * sp_lstchg information from the pw_age field, which appears + * after the encrypted password. + */ + if (pw->pw_age[0]) { + sp.sp_max = (c64i(pw->pw_age[0]) * WEEK) / SCALE; + + if (pw->pw_age[1]) + sp.sp_min = (c64i(pw->pw_age[1]) * WEEK) / SCALE; + else + sp.sp_min = (10000L * DAY) / SCALE; + + if (pw->pw_age[1] && pw->pw_age[2]) + sp.sp_lstchg = (a64l(pw->pw_age + 2) * WEEK) / SCALE; + else + sp.sp_lstchg = time((time_t *) 0) / SCALE; + } else +#endif + { + /* + * Defaults used if there is no pw_age information. + */ + sp.sp_min = 0; + sp.sp_max = (10000L * DAY) / SCALE; + sp.sp_lstchg = time((time_t *) 0) / SCALE; + } + + /* + * These fields have no corresponding information in the password + * file. They are set to uninitialized values. + */ + sp.sp_warn = -1; + sp.sp_expire = -1; + sp.sp_inact = -1; + sp.sp_flag = -1; + + return &sp; +} +#endif /* SHADOWPWD */ diff --git a/current/libmisc/pwd_init.c b/current/libmisc/pwd_init.c new file mode 100644 index 00000000..e09f02bd --- /dev/null +++ b/current/libmisc/pwd_init.c @@ -0,0 +1,73 @@ + +#include + +#include "rcsid.h" +RCSID("$Id: pwd_init.c,v 1.1 1997/12/07 23:27:07 marekm Exp $") + +#include "defines.h" +#include +#include +#include + +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +/* + * pwd_init - ignore signals, and set resource limits to safe + * values. Call this before modifying password files, so that + * it is less likely to fail in the middle of operation. + */ +void +pwd_init(void) +{ +#ifdef HAVE_SYS_RESOURCE_H + struct rlimit rlim; + +#ifdef RLIMIT_CORE + rlim.rlim_cur = rlim.rlim_max = 0; + setrlimit(RLIMIT_CORE, &rlim); +#endif + rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; +#ifdef RLIMIT_AS + setrlimit(RLIMIT_AS, &rlim); +#endif +#ifdef RLIMIT_CPU + setrlimit(RLIMIT_CPU, &rlim); +#endif +#ifdef RLIMIT_DATA + setrlimit(RLIMIT_DATA, &rlim); +#endif +#ifdef RLIMIT_FSIZE + setrlimit(RLIMIT_FSIZE, &rlim); +#endif +#ifdef RLIMIT_NOFILE + setrlimit(RLIMIT_NOFILE, &rlim); +#endif +#ifdef RLIMIT_RSS + setrlimit(RLIMIT_RSS, &rlim); +#endif +#ifdef RLIMIT_STACK + setrlimit(RLIMIT_STACK, &rlim); +#endif +#else /* !HAVE_SYS_RESOURCE_H */ + set_filesize_limit(30000); + /* don't know how to set the other limits... */ +#endif /* !HAVE_SYS_RESOURCE_H */ + + signal(SIGALRM, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTERM, SIG_IGN); +#ifdef SIGTSTP + signal(SIGTSTP, SIG_IGN); +#endif +#ifdef SIGTTOU + signal(SIGTTOU, SIG_IGN); +#endif + + umask(077); +} + diff --git a/current/libmisc/pwdcheck.c b/current/libmisc/pwdcheck.c new file mode 100644 index 00000000..1b3cea74 --- /dev/null +++ b/current/libmisc/pwdcheck.c @@ -0,0 +1,69 @@ +#include + +#include "rcsid.h" +RCSID("$Id$") + +#include "prototypes.h" +#include "defines.h" + +#include +#include "pwauth.h" + +#ifdef HAVE_SHADOW_H +#include +#endif + +#ifdef USE_PAM +#include "pam_defs.h" +#endif + +#define WRONGPWD2 "incorrect password for `%s'" + +void +passwd_check(const char *user, const char *passwd, const char *progname) +{ +#ifdef USE_PAM + pam_handle_t *pamh = NULL; + int retcode; + struct pam_conv conv = { misc_conv, NULL }; + + if (pam_start(progname, user, &conv, &pamh)) { +bailout: + SYSLOG((LOG_WARN, WRONGPWD2, user)); + sleep(1); + fprintf(stderr, _("Incorrect password for %s.\n"), user); + exit(1); + } + if (pam_authenticate(pamh, 0)) + goto bailout; + + retcode = pam_acct_mgmt(pamh, 0); + if (retcode == PAM_NEW_AUTHTOK_REQD) { + retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + } else if (retcode) + goto bailout; + + if (pam_setcred(pamh, 0)) + goto bailout; + + /* no need to establish a session; this isn't a session-oriented + * activity... */ + +#else /* !USE_PAM */ + +#ifdef SHADOWPWD + struct spwd *sp; + + if ((sp = getspnam(user))) + passwd = sp->sp_pwdp; + endspent(); +#endif + if (pw_auth(passwd, user, PW_LOGIN, (char *) 0) != 0) { + SYSLOG((LOG_WARN, WRONGPWD2, user)); + sleep(1); + fprintf(stderr, _("Incorrect password for %s.\n"), user); + exit(1); + } +#endif /* !USE_PAM */ +} + diff --git a/current/libmisc/rlogin.c b/current/libmisc/rlogin.c new file mode 100644 index 00000000..d79cc1d9 --- /dev/null +++ b/current/libmisc/rlogin.c @@ -0,0 +1,171 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#ifdef RLOGIN + +#include "rcsid.h" +RCSID("$Id: rlogin.c,v 1.5 1999/08/27 19:02:51 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" + +#include +#include + +extern int ruserok(); + +static struct { + int spd_name; + int spd_baud; +} speed_table [] = { +#ifdef B50 + { B50, 50 }, +#endif +#ifdef B75 + { B75, 75 }, +#endif +#ifdef B110 + { B110, 110 }, +#endif +#ifdef B134 + { B134, 134 }, +#endif +#ifdef B150 + { B150, 150 }, +#endif +#ifdef B200 + { B200, 200 }, +#endif +#ifdef B300 + { B300, 300 }, +#endif +#ifdef B600 + { B600, 600 }, +#endif +#ifdef B1200 + { B1200, 1200 }, +#endif +#ifdef B1800 + { B1800, 1800 }, +#endif +#ifdef B2400 + { B2400, 2400 }, +#endif +#ifdef B4800 + { B4800, 4800 }, +#endif +#ifdef B9600 + { B9600, 9600 }, +#endif +#ifdef B19200 + { B19200, 19200 }, +#endif +#ifdef B38400 + { B38400, 38400 }, +#endif + { -1, -1 } +}; + +static void +get_remote_string(char *buf, int size) +{ + for (;;) { + if (read (0, buf, 1) != 1) + exit (1); + if (*buf == '\0') + return; + if (--size > 0) + ++buf; + } + /*NOTREACHED*/ +} + +int +do_rlogin(const char *remote_host, char *name, int namelen, char *term, int termlen) +{ + struct passwd *pwd; + char remote_name[32]; + char *cp; + int remote_speed = 9600; + int speed_name = B9600; + int i; + TERMIO termio; + + get_remote_string (remote_name, sizeof remote_name); + get_remote_string (name, namelen); + get_remote_string (term, termlen); + + if ((cp = strchr (term, '/'))) { + *cp++ = '\0'; + + if (! (remote_speed = atoi (cp))) + remote_speed = 9600; + } + for (i = 0;speed_table[i].spd_baud != remote_speed && + speed_table[i].spd_name != -1;i++) + ; + + if (speed_table[i].spd_name != -1) + speed_name = speed_table[i].spd_name; + + /* + * Put the terminal in cooked mode with echo turned on. + */ + + GTTY(0, &termio); + termio.c_iflag |= ICRNL|IXON; + termio.c_oflag |= OPOST|ONLCR; + termio.c_lflag |= ICANON|ECHO|ECHOE; +#ifdef CBAUD + termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name; +#else + termio.c_cflag = (termio.c_cflag) | speed_name; +#endif + STTY(0, &termio); + + if (! (pwd = getpwnam (name))) + return 0; + + /* + * ruserok() returns 0 for success on modern systems, and 1 on + * older ones. If you are having trouble with people logging + * in without giving a required password, THIS is the culprit - + * go fix the #define in config.h. + */ + +#ifndef RUSEROK + return 0; +#else + return ruserok (remote_host, pwd->pw_uid == 0, + remote_name, name) == RUSEROK; +#endif +} +#endif /* RLOGIN */ diff --git a/current/libmisc/salt.c b/current/libmisc/salt.c new file mode 100644 index 00000000..b5478e45 --- /dev/null +++ b/current/libmisc/salt.c @@ -0,0 +1,70 @@ +/* + * salt.c - generate a random salt string for crypt() + * + * Written by Marek Michalkiewicz , + * public domain. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: salt.c,v 1.5 1997/12/07 23:27:09 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include + +#if 1 +#include "getdef.h" + +extern char *l64a(); + +/* + * Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB + * in /etc/login.defs is "yes", the salt string will be prefixed by "$1$" + * (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible + * version of crypt() instead of the standard one. + */ +char * +crypt_make_salt(void) +{ + struct timeval tv; + static char result[40]; + + result[0] = '\0'; + if (getdef_bool("MD5_CRYPT_ENAB")) { + strcpy(result, "$1$"); /* magic for the new MD5 crypt() */ + } + + /* + * Generate 8 chars of salt, the old crypt() will use only first 2. + */ + gettimeofday(&tv, (struct timezone *) 0); + strcat(result, l64a(tv.tv_usec)); + strcat(result, l64a(tv.tv_sec + getpid() + clock())); + + if (strlen(result) > 3 + 8) /* magic+salt */ + result[11] = '\0'; + + return result; +} +#else + +/* + * This is the old style random salt generator... + */ +char * +crypt_make_salt(void) +{ + time_t now; + static unsigned long x; + static char result[3]; + + time(&now); + x += now + getpid() + clock(); + result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077); + result[1] = i64c(((x >> 12) ^ x) & 077); + result[2] = '\0'; + return result; +} +#endif diff --git a/current/libmisc/setugid.c b/current/libmisc/setugid.c new file mode 100644 index 00000000..5dae7659 --- /dev/null +++ b/current/libmisc/setugid.c @@ -0,0 +1,134 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * Separated from setup.c. --marekm + */ + +#include + +#include "rcsid.h" +RCSID("$Id: setugid.c,v 1.6 1998/07/23 22:13:16 marekm Exp $") + +#include +#include + +#include "prototypes.h" +#include "defines.h" +#include + +#include "getdef.h" + +/* + * setup_uid_gid() split in two functions for PAM support - + * pam_setcred() needs to be called after initgroups(), but + * before setuid(). + */ + +int +setup_groups(const struct passwd *info) +{ + /* + * Set the real group ID to the primary group ID in the password + * file. + */ + if (setgid (info->pw_gid) == -1) { + perror("setgid"); + SYSLOG((LOG_ERR, "bad group ID `%d' for user `%s': %m\n", + info->pw_gid, info->pw_name)); + closelog(); + return -1; + } +#ifdef HAVE_INITGROUPS + /* + * For systems which support multiple concurrent groups, go get + * the group set from the /etc/group file. + */ + if (initgroups(info->pw_name, info->pw_gid) == -1) { + perror("initgroups"); + SYSLOG((LOG_ERR, "initgroups failed for user `%s': %m\n", + info->pw_name)); + closelog(); + return -1; + } +#endif + return 0; +} + +int +change_uid(const struct passwd *info) +{ + /* + * Set the real UID to the UID value in the password file. + */ +#ifndef BSD + if (setuid(info->pw_uid)) +#else + if (setreuid(info->pw_uid, info->pw_uid)) +#endif + { + perror("setuid"); + SYSLOG((LOG_ERR, "bad user ID `%d' for user `%s': %m\n", + (int) info->pw_uid, info->pw_name)); + closelog(); + return -1; + } + return 0; +} + +/* + * setup_uid_gid() performs the following steps - + * + * set the group ID to the value from the password file entry + * set the supplementary group IDs + * optionally call specified function which may add more groups + * set the user ID to the value from the password file entry + * + * Returns 0 on success, or -1 on failure. + */ + +int +setup_uid_gid(const struct passwd *info, int is_console) +{ + if (setup_groups(info) < 0) + return -1; + +#ifdef HAVE_INITGROUPS + if (is_console) { + char *cp = getdef_str("CONSOLE_GROUPS"); + if (cp && add_groups(cp)) + perror("Warning: add_groups"); + } +#endif /* HAVE_INITGROUPS */ + + if (change_uid(info) < 0) + return -1; + + return 0; +} diff --git a/current/libmisc/setup.c b/current/libmisc/setup.c new file mode 100644 index 00000000..7b8df91b --- /dev/null +++ b/current/libmisc/setup.c @@ -0,0 +1,72 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: setup.c,v 1.3 1997/12/07 23:27:09 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include + +/* + * setup - initialize login environment + * + * setup() performs the following steps - + * + * set the process nice, ulimit, and umask from the password file entry + * set the group ID to the value from the password file entry + * set the supplementary group IDs + * set the user ID to the value from the password file entry + * change to the user's home directory + * set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental + * variables. + */ + +void +setup(struct passwd *info) +{ + /* + * Set resource limits. + */ + setup_limits(info); + + /* + * Set the real group ID, do initgroups, and set the real user ID + * to the value in the password file. + */ + if (setup_uid_gid(info, 0)) + exit(1); + + /* + * Change to the home directory, and set up environment. + */ + setup_env(info); +} diff --git a/current/libmisc/setupenv.c b/current/libmisc/setupenv.c new file mode 100644 index 00000000..1e428ba7 --- /dev/null +++ b/current/libmisc/setupenv.c @@ -0,0 +1,292 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * Separated from setup.c. --marekm + */ + +#include + +#include "rcsid.h" +RCSID("$Id: setupenv.c,v 1.10 2000/08/26 18:27:17 marekm Exp $") + +#include +#include + +#include +#include + +#include "prototypes.h" +#include "defines.h" +#include +#include "getdef.h" + +static void +addenv_path(const char *varname, const char *dirname, const char *filename) +{ + char *buf; + + buf = xmalloc(strlen(dirname) + strlen(filename) + 2); + sprintf(buf, "%s/%s", dirname, filename); + addenv(varname, buf); + free(buf); +} + + +static void +read_env_file(const char *filename) +{ + FILE *fp; + char buf[1024]; + char *cp, *name, *val; + + fp = fopen(filename, "r"); + if (!fp) + return; + while (fgets(buf, sizeof buf, fp) == buf) { + cp = strrchr(buf, '\n'); + if (!cp) + break; + *cp = '\0'; + + cp = buf; + /* ignore whitespace and comments */ + while (*cp && isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') + continue; + /* + * ignore lines which don't follow the name=value format + * (for example, the "export NAME" shell commands) + */ + name = cp; + while (*cp && !isspace(*cp) && *cp != '=') + cp++; + if (*cp != '=') + continue; + /* NUL-terminate the name */ + *cp++ = '\0'; + val = cp; +#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */ +/* + (state, char_type) -> (state, action) + + state: unquoted, single_quoted, double_quoted, escaped, double_quoted_escaped + char_type: normal, white, backslash, single, double + action: remove_curr, remove_curr_skip_next, remove_prev, finish XXX +*/ +no_quote: + if (*cp == '\\') { + /* remove the backslash */ + remove_char(cp); + /* skip over the next character */ + if (*cp) + cp++; + goto no_quote; + } else if (*cp == '\'') { + /* remove the quote */ + remove_char(cp); + /* now within single quotes */ + goto s_quote; + } else if (*cp == '"') { + /* remove the quote */ + remove_char(cp); + /* now within double quotes */ + goto d_quote; + } else if (*cp == '\0') { + /* end of string */ + goto finished; + } else if (isspace(*cp)) { + /* unescaped whitespace - end of string */ + *cp = '\0'; + goto finished; + } else { + cp++; + goto no_quote; + } +s_quote: + if (*cp == '\'') { + /* remove the quote */ + remove_char(cp); + /* unquoted again */ + goto no_quote; + } else if (*cp == '\0') { + /* end of string */ + goto finished; + } else { + /* preserve everything within single quotes */ + cp++; + goto s_quote; + } +d_quote: + if (*cp == '\"') { + /* remove the quote */ + remove_char(cp); + /* unquoted again */ + goto no_quote; + } else if (*cp == '\\') { + cp++; + /* if backslash followed by double quote, remove backslash + else skip over the backslash and following char */ + if (*cp == '"') + remove_char(cp - 1); + else if (*cp) + cp++; + goto d_quote; + } eise if (*cp == '\0') { + /* end of string */ + goto finished; + } else { + /* preserve everything within double quotes */ + goto d_quote; + } +finished: +#endif /* 0 */ + /* + * XXX - should handle quotes, backslash escapes, etc. + * like the shell does. + */ + addenv(name, val); + } + fclose(fp); +} + +/* + * change to the user's home directory + * set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental + * variables. + */ + +void +setup_env(struct passwd *info) +{ + char *cp, *envf; + + /* + * Change the current working directory to be the home directory + * of the user. It is a fatal error for this process to be unable + * to change to that directory. There is no "default" home + * directory. + * + * We no longer do it as root - should work better on NFS-mounted + * home directories. Some systems default to HOME=/, so we make + * this a configurable option. --marekm + */ + + if (chdir(info->pw_dir) == -1) { + static char temp_pw_dir[] = "/"; + if (!getdef_bool("DEFAULT_HOME") || chdir("/") == -1) { + fprintf(stderr, _("Unable to cd to \"%s\"\n"), + info->pw_dir); + SYSLOG((LOG_WARN, + "unable to cd to `%s' for user `%s'\n", + info->pw_dir, info->pw_name)); + closelog(); + exit (1); + } + puts(_("No directory, logging in with HOME=/")); + info->pw_dir = temp_pw_dir; + } + + /* + * Create the HOME environmental variable and export it. + */ + + addenv("HOME", info->pw_dir); + + /* + * Create the SHELL environmental variable and export it. + */ + + if (info->pw_shell == (char *) 0 || ! *info->pw_shell) { + static char temp_pw_shell[] = "/bin/sh"; + info->pw_shell = temp_pw_shell; + } + + addenv("SHELL", info->pw_shell); + + /* + * Create the PATH environmental variable and export it. + */ + + cp = getdef_str((info->pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH"); +#if 0 + addenv(cp ? cp : "PATH=/bin:/usr/bin", NULL); +#else + if (!cp) { + /* not specified, use a minimal default */ + addenv("PATH=/bin:/usr/bin", NULL); + } else if (strchr(cp, '=')) { + /* specified as name=value (PATH=...) */ + addenv(cp, NULL); + } else { + /* only value specified without "PATH=" */ + addenv("PATH", cp); + } +#endif + + /* + * Export the user name. For BSD derived systems, it's "USER", for + * all others it's "LOGNAME". We set both of them. + */ + + addenv("USER", info->pw_name); + addenv("LOGNAME", info->pw_name); + + /* + * MAILDIR environment variable for Qmail + */ + if ((cp=getdef_str("QMAIL_DIR"))) + addenv_path("MAILDIR", info->pw_dir, cp); + + /* + * Create the MAIL environmental variable and export it. login.defs + * knows the prefix. + */ + + if ((cp=getdef_str("MAIL_DIR"))) + addenv_path("MAIL", cp, info->pw_name); + else if ((cp=getdef_str("MAIL_FILE"))) + addenv_path("MAIL", info->pw_dir, cp); + else { +#if defined(MAIL_SPOOL_FILE) + addenv_path("MAIL", info->pw_dir, MAIL_SPOOL_FILE); +#elif defined(MAIL_SPOOL_DIR) + addenv_path("MAIL", MAIL_SPOOL_DIR, info->pw_name); +#endif + } + +#ifndef USE_PAM + /* + * Read environment from optional config file. --marekm + */ + if ((envf = getdef_str("ENVIRON_FILE"))) + read_env_file(envf); +#endif +} diff --git a/current/libmisc/shell.c b/current/libmisc/shell.c new file mode 100644 index 00000000..23058f37 --- /dev/null +++ b/current/libmisc/shell.c @@ -0,0 +1,126 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: shell.c,v 1.7 1998/12/28 20:34:53 marekm Exp $") + +#include +#include +#include "prototypes.h" +#include "defines.h" + + +extern char **newenvp; +extern size_t newenvc; + +/* + * shell - execute the named program + * + * shell begins by trying to figure out what argv[0] is going to + * be for the named process. The user may pass in that argument, + * or it will be the last pathname component of the file with a + * '-' prepended. The first attempt is to just execute the named + * file. If the errno comes back "ENOEXEC", the file is assumed + * at first glance to be a shell script. The first two characters + * must be "#!", in which case "/bin/sh" is executed to process + * the file. If all that fails, give up in disgust ... + */ + +void +shell(const char *file, const char *arg) +{ + char arg0[1024]; + int err; + + if (file == (char *) 0) + exit (1); + + /* + * The argv[0]'th entry is usually the path name, but + * for various reasons the invoker may want to override + * that. So, we determine the 0'th entry only if they + * don't want to tell us what it is themselves. + */ + + if (arg == (char *) 0) { + snprintf(arg0, sizeof arg0, "-%s", Basename((char *) file)); + arg = arg0; + } +#ifdef DEBUG + printf (_("Executing shell %s\n"), file); +#endif + + /* + * First we try the direct approach. The system should be + * able to figure out what we are up to without too much + * grief. + */ + + execle (file, arg, (char *) 0, newenvp); + err = errno; + + /* Linux handles #! in the kernel, and bash doesn't make + sense of "#!" so it wouldn't work anyway... --marekm */ +#ifndef __linux__ + /* + * It is perfectly OK to have a shell script for a login + * shell, and this code attempts to support that. It + * relies on the standard shell being able to make sense + * of the "#!" magic number. + */ + + if (err == ENOEXEC) { + FILE *fp; + + if ((fp = fopen (file, "r"))) { + if (getc (fp) == '#' && getc (fp) == '!') { + fclose (fp); + execle ("/bin/sh", "sh", + file, (char *) 0, newenvp); + err = errno; + } else { + fclose (fp); + } + } + } +#endif + + /* + * Obviously something is really wrong - I can't figure out + * how to execute this stupid shell, so I might as well give + * up in disgust ... + */ + + snprintf(arg0, sizeof arg0, _("Cannot execute %s"), file); + errno = err; + perror(arg0); + exit(1); +} diff --git a/current/libmisc/strtoday.c b/current/libmisc/strtoday.c new file mode 100644 index 00000000..4870f9df --- /dev/null +++ b/current/libmisc/strtoday.c @@ -0,0 +1,207 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#if !defined(__GLIBC__) +#define _XOPEN_SOURCE 500 +#endif + +#include + +#include "rcsid.h" +RCSID("$Id: strtoday.c,v 1.8 1999/03/07 19:14:42 marekm Exp $") + +#include "defines.h" + +#ifndef USE_GETDATE +#define USE_GETDATE 1 +#endif + +#if USE_GETDATE + +#include "getdate.h" + +/* + * strtoday() now uses get_date() (borrowed from GNU shellutils) + * which can handle many date formats, for example: + * 1970-09-17 # ISO 8601. + * 70-9-17 # This century assumed by default. + * 70-09-17 # Leading zeros are ignored. + * 9/17/72 # Common U.S. writing. + * 24 September 1972 + * 24 Sept 72 # September has a special abbreviation. + * 24 Sep 72 # Three-letter abbreviations always allowed. + * Sep 24, 1972 + * 24-sep-72 + * 24sep72 + */ +long +strtoday(const char *str) +{ + time_t t; + + /* + * get_date() interprets an empty string as the current date, + * which is not what we expect, unless you're a BOFH :-). + * (useradd sets sp_expire = current date for new lusers) + */ + if (!str || *str == '\0') + return -1; + + t = get_date(str, (time_t *) 0); + if (t == (time_t) -1) + return -1; + /* convert seconds to days since 1970-01-01 */ + return (t + DAY/2)/DAY; +} + +#else /* !USE_GETDATE */ +/* + * Old code, just in case get_date() doesn't work as expected... + */ + +#include + +#ifdef HAVE_STRPTIME +/* + * for now we allow just one format, but we can define more later + * (we try them all until one succeeds). --marekm + */ +static char *date_formats[] = { + "%Y-%m-%d", + (char *) 0 +}; +#else +/* + * days and juldays are used to compute the number of days in the + * current month, and the cummulative number of days in the preceding + * months. they are declared so that january is 1, not 0. + */ + +static short days[13] = { 0, + 31, 28, 31, 30, 31, 30, /* JAN - JUN */ + 31, 31, 30, 31, 30, 31 }; /* JUL - DEC */ + +static short juldays[13] = { 0, + 0, 31, 59, 90, 120, 151, /* JAN - JUN */ + 181, 212, 243, 273, 304, 334 }; /* JUL - DEC */ +#endif + +/* + * strtoday - compute the number of days since 1970. + * + * the total number of days prior to the current date is + * computed. january 1, 1970 is used as the origin with + * it having a day number of 0. + */ + +long +strtoday(const char *str) +{ +#ifdef HAVE_STRPTIME + struct tm tp; + char * const *fmt; + char *cp; + time_t result; + + memzero(&tp, sizeof tp); + for (fmt = date_formats; *fmt; fmt++) { + cp = strptime((char *) str, *fmt, &tp); + if (!cp || *cp != '\0') + continue; + + result = mktime(&tp); + if (result == (time_t) -1) + continue; + + return result / DAY; /* success */ + } + return -1; +#else + char slop[2]; + int month; + int day; + int year; + long total; + + /* + * start by separating the month, day and year. the order + * is compiled in ... + */ + + if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3) + return -1; + + /* + * the month, day of the month, and year are checked for + * correctness and the year adjusted so it falls between + * 1970 and 2069. + */ + + if (month < 1 || month > 12) + return -1; + + if (day < 1) + return -1; + + if ((month != 2 || (year % 4) != 0) && day > days[month]) + return -1; + else if ((month == 2 && (year % 4) == 0) && day > 29) + return -1; + + if (year < 0) + return -1; + else if (year <= 69) + year += 2000; + else if (year <= 99) + year += 1900; + + /* + * On systems with 32-bit signed time_t, time wraps around in 2038 + * - for now we just limit the year to 2037 (instead of 2069). + * This limit can be removed once no one is using 32-bit systems + * anymore :-). --marekm + */ + if (year < 1970 || year > 2037) + return -1; + + /* + * the total number of days is the total number of days in all + * the whole years, plus the number of leap days, plus the + * number of days in the whole months preceding, plus the number + * of days so far in the month. + */ + + total = (long) ((year - 1970) * 365L) + (((year + 1) - 1970) / 4); + total += (long) juldays[month] + (month > 2 && (year % 4) == 0 ? 1:0); + total += (long) day - 1; + + return total; +#endif /* HAVE_STRPTIME */ +} +#endif /* !USE_GETDATE */ diff --git a/current/libmisc/suauth.c b/current/libmisc/suauth.c new file mode 100644 index 00000000..77cf9292 --- /dev/null +++ b/current/libmisc/suauth.c @@ -0,0 +1,201 @@ +#include + +#ifdef SU_ACCESS + +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +#ifndef SUAUTHFILE +#define SUAUTHFILE "/etc/suauth" +#endif + +#define NOACTION 0 +#define NOPWORD 1 +#define DENY -1 +#define OWNPWORD 2 + +/* Really, I could do with a few const char's here defining all the + * strings output to the user or the syslog. -- chris + */ + +static int applies(const char *, char *); + +int check_su_auth(const char *, const char *); +int isgrp(const char *, const char *); + +static int lines = 0; + +extern struct passwd pwent; + +int +check_su_auth(const char *actual_id, const char *wanted_id) +{ + int posn, endline; + const char field[] = ":"; + FILE *authfile_fd; + char temp[1024]; + char *to_users; + char *from_users; + char *action; + + if (!(authfile_fd = fopen(SUAUTHFILE, "r"))) { + /* + * If the file doesn't exist - default to the standard su + * behaviour (no access control). If open fails for some + * other reason - maybe someone is trying to fool us with + * file descriptors limit etc., so deny access. --marekm + */ + if (errno == ENOENT) + return NOACTION; + SYSLOG((LOG_ERR, "could not open/read config file '%s': %m\n", + SUAUTHFILE)); + return DENY; + } + + while (fgets(temp, sizeof(temp), authfile_fd) != NULL) { + lines++; + + if (temp[endline = strlen(temp) - 1] != '\n') { + SYSLOG((LOG_ERR, + "%s, line %d: line too long or missing newline", + SUAUTHFILE, lines)); + continue; + } + + while (endline > 0 && (temp[endline-1] == ' ' + || temp[endline-1] == '\t' || temp[endline-1] == '\n')) + endline--; + temp[endline] = '\0'; + + posn = 0; + while (temp[posn] == ' ' || temp[posn] == '\t') + posn++; + + if (temp[posn] == '\n' || temp[posn] == '#' || temp[posn] == '\0') { + continue; + } + if (!(to_users = strtok(temp + posn, field)) + || !(from_users = strtok((char *)NULL, field)) + || !(action = strtok((char *)NULL, field)) + || strtok((char *)NULL, field)) { + SYSLOG((LOG_ERR, "%s, line %d. Bad number of fields.\n", + SUAUTHFILE, lines)); + continue; + } + + if (!applies(wanted_id, to_users)) + continue; + if (!applies(actual_id, from_users)) + continue; + if (!strcmp(action, "DENY")) { + SYSLOG((pwent.pw_uid ? LOG_NOTICE : LOG_WARN, + "DENIED su from `%s' to `%s' (%s)\n", + actual_id, wanted_id, SUAUTHFILE)); + fprintf(stderr, _("Access to su to that account DENIED.\n")); + fclose(authfile_fd); + return DENY; + } else if (!strcmp(action, "NOPASS")) { + SYSLOG((pwent.pw_uid ? LOG_INFO : LOG_NOTICE, + "NO password asked for su from `%s' to `%s' (%s)\n", + actual_id, wanted_id, SUAUTHFILE)); + fprintf(stderr, _("Password authentication bypassed.\n")); + fclose(authfile_fd); + return NOPWORD; + } else if (!strcmp(action, "OWNPASS")) { + SYSLOG((pwent.pw_uid ? LOG_INFO : LOG_NOTICE, + "su from `%s' to `%s': asking for user's own password (%s)\n", + actual_id, wanted_id, SUAUTHFILE)); + fprintf(stderr, _("Please enter your OWN password as authentication.\n")); + fclose(authfile_fd); + return OWNPWORD; + } else { + SYSLOG((LOG_ERR, "%s, line %d: unrecognised action!\n", + SUAUTHFILE, lines)); + } + } + fclose(authfile_fd); + return NOACTION; +} + +static int +applies(const char *single, char *list) +{ + const char split[] = ", "; + char *tok; + + int state = 0; + + for (tok = strtok(list, split); tok != NULL; tok = strtok(NULL, split)) { + + if (!strcmp(tok, "ALL")) { + if (state != 0) { + SYSLOG((LOG_ERR, + "%s, line %d: ALL in bad place\n", + SUAUTHFILE, lines)); + return 0; + } + state = 1; + } else if (!strcmp(tok, "EXCEPT")) { + if (state != 1) { + SYSLOG((LOG_ERR, + "%s, line %d: EXCEPT in bas place\n", + SUAUTHFILE, lines)); + return 0; + } + state = 2; + } else if (!strcmp(tok, "GROUP")) { + if ((state != 0) && (state != 2)) { + SYSLOG((LOG_ERR, + "%s, line %d: GROUP in bad place\n", + SUAUTHFILE, lines)); + return 0; + } + state = (state == 0) ? 3 : 4; + } else { + switch (state) { + case 0: /* No control words yet */ + if (!strcmp(tok, single)) + return 1; + break; + case 1: /* An all */ + SYSLOG((LOG_ERR, "%s, line %d: expect another token after ALL\n", + SUAUTHFILE, lines)); + return 0; + case 2: /* All except */ + if (!strcmp(tok, single)) + return 0; + break; + case 3: /* Group */ + if (isgrp(single, tok)) + return 1; + break; + case 4: /* All except group */ + if (isgrp(single, tok)) + return 0; + /* FALL THRU */ + } + } + } + if ((state != 0) && (state != 3)) + return 1; + return 0; +} + +int +isgrp(const char *name, const char *group) +{ + struct group *grp; + + grp = getgrnam(group); + + if (!grp || !grp->gr_mem) + return 0; + + return is_on_list(grp->gr_mem, name); +} +#endif /* SU_ACCESS */ diff --git a/current/libmisc/sub.c b/current/libmisc/sub.c new file mode 100644 index 00000000..88f2df03 --- /dev/null +++ b/current/libmisc/sub.c @@ -0,0 +1,78 @@ +/* + * Copyright 1989 - 1991, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: sub.c,v 1.6 1999/03/07 19:14:43 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" + +#include + +#define BAD_SUBROOT2 "invalid root `%s' for user `%s'\n" +#define NO_SUBROOT2 "no subsystem root `%s' for user `%s'\n" + +/* + * subsystem - change to subsystem root + * + * A subsystem login is indicated by the presense of a "*" as + * the first character of the login shell. The given home + * directory will be used as the root of a new filesystem which + * the user is actually logged into. + */ + +void +subsystem(const struct passwd *pw) +{ + /* + * The new root directory must begin with a "/" character. + */ + + if (pw->pw_dir[0] != '/') { + printf(_("Invalid root directory \"%s\"\n"), pw->pw_dir); + SYSLOG((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name)); + closelog(); + exit (1); + } + + /* + * The directory must be accessible and the current process + * must be able to change into it. + */ + + if (chdir (pw->pw_dir) || chroot (pw->pw_dir)) { + printf(_("Can't change root directory to \"%s\"\n"), pw->pw_dir); + SYSLOG((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name)); + closelog(); + exit (1); + } +} diff --git a/current/libmisc/sulog.c b/current/libmisc/sulog.c new file mode 100644 index 00000000..3de68692 --- /dev/null +++ b/current/libmisc/sulog.c @@ -0,0 +1,74 @@ +/* + * Copyright 1989 - 1992, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: sulog.c,v 1.5 2000/08/26 18:27:17 marekm Exp $") + +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" +#include "getdef.h" + +/* + * sulog - log a SU command execution result + */ + +void +sulog(const char *tty, int success, const char *oldname, const char *name) +{ + char *sulog_file; + time_t now; + struct tm *tm; + FILE *fp; + mode_t oldmask; + + if ((sulog_file = getdef_str("SULOG_FILE")) == (char *) 0) + return; + + oldmask = umask(077); + fp = fopen(sulog_file, "a+"); + umask(oldmask); + if (fp == (FILE *) 0) + return; /* can't open or create logfile */ + + time(&now); + tm = localtime(&now); + + fprintf(fp, "SU %.02d/%.02d %.02d:%.02d %c %.6s %s-%s\n", + tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, + success ? '+':'-', tty, oldname, name); + + fflush(fp); + fclose(fp); +} diff --git a/current/libmisc/ttytype.c b/current/libmisc/ttytype.c new file mode 100644 index 00000000..965dc7f1 --- /dev/null +++ b/current/libmisc/ttytype.c @@ -0,0 +1,89 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: ttytype.c,v 1.5 1997/12/07 23:27:10 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include "getdef.h" + +extern char *getenv(); + +/* + * ttytype - set ttytype from port to terminal type mapping database + */ + +void +ttytype(const char *line) +{ + FILE *fp; + char buf[BUFSIZ]; + char *typefile; + char *cp; + char type[BUFSIZ]; + char port[BUFSIZ]; + + if (getenv ("TERM")) + return; + if ((typefile=getdef_str("TTYTYPE_FILE")) == NULL ) + return; + if (access(typefile, F_OK)) + return; + + if (! (fp = fopen (typefile, "r"))) { + perror (typefile); + return; + } + while (fgets(buf, sizeof buf, fp)) { + if (buf[0] == '#') + continue; + + if ((cp = strchr (buf, '\n'))) + *cp = '\0'; + +#if defined(SUN) || defined(BSD) || defined(SUN4) + if ((sscanf (buf, "%s \"%*[^\"]\" %s", port, type) == 2 || + sscanf (buf, "%s %*s %s", port, type) == 2) && + strcmp (line, port) == 0) + break; +#else /* USG */ + if (sscanf (buf, "%s %s", type, port) == 2 && + strcmp (line, port) == 0) + break; +#endif + } + if (! feof (fp) && ! ferror (fp)) + addenv("TERM", type); + + fclose (fp); +} diff --git a/current/libmisc/tz.c b/current/libmisc/tz.c new file mode 100644 index 00000000..9449f6d8 --- /dev/null +++ b/current/libmisc/tz.c @@ -0,0 +1,67 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh and Chip Rosenthal + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: tz.c,v 1.4 1998/01/29 23:22:36 marekm Exp $") + +#include +#include +#include "defines.h" +#include "getdef.h" + +/* + * tz - return local timezone name + * + * tz() determines the name of the local timezone by reading the + * contents of the file named by ``fname''. + */ + +char * +tz(const char *fname) +{ + FILE *fp = 0; + static char tzbuf[BUFSIZ]; + const char *def_tz; + + if ((fp = fopen(fname,"r")) == NULL || + fgets (tzbuf, sizeof (tzbuf), fp) == NULL) { + if (! (def_tz = getdef_str ("ENV_TZ")) || def_tz[0] == '/') + def_tz = "TZ=CST6CDT"; + + strcpy (tzbuf, def_tz); + } else + tzbuf[strlen(tzbuf) - 1] = '\0'; + + if (fp) + (void) fclose(fp); + + return tzbuf; +} diff --git a/current/libmisc/ulimit.c b/current/libmisc/ulimit.c new file mode 100644 index 00000000..e99dab22 --- /dev/null +++ b/current/libmisc/ulimit.c @@ -0,0 +1,34 @@ +#include + +#include "rcsid.h" +RCSID("$Id: ulimit.c,v 1.2 1997/12/07 23:27:11 marekm Exp $") + +#if HAVE_ULIMIT_H +#include + +#ifndef UL_SETFSIZE +#ifdef UL_SFILLIM +#define UL_SETFSIZE UL_SFILLIM +#else +#define UL_SETFSIZE 2 +#endif +#endif + +#elif HAVE_SYS_RESOURCE_H +#include /* for struct timeval on sunos4 */ +/* XXX - is the above ok or should it be on ultrix? */ +#include +#endif + +void +set_filesize_limit(int blocks) +{ +#if HAVE_ULIMIT_H + ulimit(UL_SETFSIZE, blocks); +#elif defined(RLIMIT_FSIZE) + struct rlimit rlimit_fsize; + + rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks; + setrlimit(RLIMIT_FSIZE, &rlimit_fsize); +#endif +} diff --git a/current/libmisc/utmp.c b/current/libmisc/utmp.c new file mode 100644 index 00000000..bc020a2a --- /dev/null +++ b/current/libmisc/utmp.c @@ -0,0 +1,478 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "defines.h" + +#include + +#if HAVE_UTMPX_H +#include +#endif + +#include +#include + +#include "rcsid.h" +RCSID("$Id: utmp.c,v 1.8 1999/06/07 16:40:44 marekm Exp $") + +#if HAVE_UTMPX_H +extern struct utmpx utxent; +#endif +extern struct utmp utent; + +extern struct utmp *getutent(); +extern struct utmp *getutline(); +extern void setutent(); +extern void endutent(); +extern time_t time(); +extern char *ttyname(); +extern long lseek(); + +#define NO_UTENT \ + "No utmp entry. You must exec \"login\" from the lowest level \"sh\"" +#define NO_TTY \ + "Unable to determine your tty name." + +/* + * checkutmp - see if utmp file is correct for this process + * + * System V is very picky about the contents of the utmp file + * and requires that a slot for the current process exist. + * The utmp file is scanned for an entry with the same process + * ID. If no entry exists the process exits with a message. + * + * The "picky" flag is for network and other logins that may + * use special flags. It allows the pid checks to be overridden. + * This means that getty should never invoke login with any + * command line flags. + */ + +#if defined(__linux__) /* XXX */ + +void +checkutmp(int picky) +{ + char *line; + struct utmp *ut; + pid_t pid = getpid(); + + setutent(); + + /* First, try to find a valid utmp entry for this process. */ + while ((ut = getutent())) + if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] && + (ut->ut_type==LOGIN_PROCESS || ut->ut_type==USER_PROCESS)) + break; + + /* If there is one, just use it, otherwise create a new one. */ + if (ut) { + utent = *ut; + } else { + if (picky) { + puts(NO_UTENT); + exit(1); + } + line = ttyname(0); + if (!line) { + puts(NO_TTY); + exit(1); + } + if (strncmp(line, "/dev/", 5) == 0) + line += 5; + memset((void *) &utent, 0, sizeof utent); + utent.ut_type = LOGIN_PROCESS; + utent.ut_pid = pid; + strncpy(utent.ut_line, line, sizeof utent.ut_line); + /* XXX - assumes /dev/tty?? */ + strncpy(utent.ut_id, utent.ut_line + 3, sizeof utent.ut_id); + strcpy(utent.ut_user, "LOGIN"); + time(&utent.ut_time); + } +} + +#elif defined(LOGIN_PROCESS) + +void +checkutmp(int picky) +{ + char *line; + struct utmp *ut; +#if HAVE_UTMPX_H + struct utmpx *utx; +#endif + pid_t pid = getpid(); + +#if HAVE_UTMPX_H + setutxent(); +#endif + setutent(); + + if (picky) { +#if HAVE_UTMPX_H + while ((utx = getutxent())) + if (utx->ut_pid == pid) + break; + + if (utx) + utxent = *utx; +#endif + while ((ut = getutent())) + if (ut->ut_pid == pid) + break; + + if (ut) + utent = *ut; + +#if HAVE_UTMPX_H + endutxent(); +#endif + endutent(); + + if (!ut) { + puts(NO_UTENT); + exit(1); + } +#ifndef UNIXPC + + /* + * If there is no ut_line value in this record, fill + * it in by getting the TTY name and stuffing it in + * the structure. The UNIX/PC is broken in this regard + * and needs help ... + */ + + if (utent.ut_line[0] == '\0') +#endif /* !UNIXPC */ + { + if (!(line = ttyname(0))) { + puts(NO_TTY); + exit(1); + } + if (strncmp(line, "/dev/", 5) == 0) + line += 5; + strncpy(utent.ut_line, line, sizeof utent.ut_line); +#if HAVE_UTMPX_H + strncpy(utxent.ut_line, line, sizeof utxent.ut_line); +#endif + } + } else { + if (!(line = ttyname(0))) { + puts(NO_TTY); + exit(1); + } + if (strncmp(line, "/dev/", 5) == 0) + line += 5; + + strncpy (utent.ut_line, line, sizeof utent.ut_line); + if ((ut = getutline(&utent))) + strncpy(utent.ut_id, ut->ut_id, sizeof ut->ut_id); + + strcpy(utent.ut_user, "LOGIN"); + utent.ut_pid = getpid(); + utent.ut_type = LOGIN_PROCESS; + time(&utent.ut_time); +#if HAVE_UTMPX_H + strncpy(utxent.ut_line, line, sizeof utxent.ut_line); + if ((utx = getutxline(&utxent))) + strncpy(utxent.ut_id, utx->ut_id, sizeof utxent.ut_id); + + strcpy(utxent.ut_user, "LOGIN"); + utxent.ut_pid = utent.ut_pid; + utxent.ut_type = utent.ut_type; + gettimeofday((struct timeval *) &utxent.ut_tv, NULL); + utent.ut_time = utxent.ut_tv.tv_sec; +#endif + } +} + +#else /* !USG */ + +void +checkutmp(int picky) +{ + char *line; + + /* + * Hand-craft a new utmp entry. + */ + + memzero(&utent, sizeof utent); + if (! (line = ttyname (0))) { + puts (NO_TTY); + exit (1); + } + if (strncmp (line, "/dev/", 5) == 0) + line += 5; + + (void) strncpy (utent.ut_line, line, sizeof utent.ut_line); + (void) time (&utent.ut_time); +} + +#endif /* !USG */ + + +/* + * Some systems already have updwtmp() and possibly updwtmpx(). Others + * don't, so we re-implement these functions if necessary. --marekm + */ + +#ifndef HAVE_UPDWTMP +static void +updwtmp(const char *filename, const struct utmp *ut) +{ + int fd; + + fd = open(filename, O_APPEND | O_WRONLY, 0); + if (fd >= 0) { + write(fd, (const char *) ut, sizeof(*ut)); + close(fd); + } +} +#endif /* ! HAVE_UPDWTMP */ + +#ifdef HAVE_UTMPX_H +#ifndef HAVE_UPDWTMPX +static void +updwtmpx(const char *filename, const struct utmpx *utx) +{ + int fd; + + fd = open(filename, O_APPEND | O_WRONLY, 0); + if (fd >= 0) { + write(fd, (const char *) utx, sizeof(*utx)); + close(fd); + } +} +#endif /* ! HAVE_UPDWTMPX */ +#endif /* ! HAVE_UTMPX_H */ + + +/* + * setutmp - put a USER_PROCESS entry in the utmp file + * + * setutmp changes the type of the current utmp entry to + * USER_PROCESS. the wtmp file will be updated as well. + */ + +#if defined(__linux__) /* XXX */ + +void +setutmp(const char *name, const char *line, const char *host) +{ + utent.ut_type = USER_PROCESS; + strncpy(utent.ut_user, name, sizeof utent.ut_user); + time(&utent.ut_time); + /* other fields already filled in by checkutmp above */ + setutent(); + pututline(&utent); + endutent(); + updwtmp(_WTMP_FILE, &utent); +} + +#elif HAVE_UTMPX_H + +void +setutmp(const char *name, const char *line, const char *host) +{ + struct utmp *utmp, utline; + struct utmpx *utmpx, utxline; + pid_t pid = getpid (); + int found_utmpx = 0, found_utmp = 0; + + /* + * The canonical device name doesn't include "/dev/"; skip it + * if it is already there. + */ + + if (strncmp (line, "/dev/", 5) == 0) + line += 5; + + /* + * Update utmpx. We create an empty entry in case there is + * no matching entry in the utmpx file. + */ + + setutxent (); + setutent (); + + while (utmpx = getutxent ()) { + if (utmpx->ut_pid == pid) { + found_utmpx = 1; + break; + } + } + while (utmp = getutent ()) { + if (utmp->ut_pid == pid) { + found_utmp = 1; + break; + } + } + + /* + * If the entry matching `pid' cannot be found, create a new + * entry with the device name in it. + */ + + if (! found_utmpx) { + memset ((void *) &utxline, 0, sizeof utxline); + strncpy (utxline.ut_line, line, sizeof utxline.ut_line); + utxline.ut_pid = getpid (); + } else { + utxline = *utmpx; + if (strncmp (utxline.ut_line, "/dev/", 5) == 0) { + memmove (utxline.ut_line, utxline.ut_line + 5, + sizeof utxline.ut_line - 5); + utxline.ut_line[sizeof utxline.ut_line - 5] = '\0'; + } + } + if (! found_utmp) { + memset ((void *) &utline, 0, sizeof utline); + strncpy (utline.ut_line, utxline.ut_line, + sizeof utline.ut_line); + utline.ut_pid = utxline.ut_pid; + } else { + utline = *utmp; + if (strncmp (utline.ut_line, "/dev/", 5) == 0) { + memmove (utline.ut_line, utline.ut_line + 5, + sizeof utline.ut_line - 5); + utline.ut_line[sizeof utline.ut_line - 5] = '\0'; + } + } + + /* + * Fill in the fields in the utmpx entry and write it out. Do + * the utmp entry at the same time to make sure things don't + * get messed up. + */ + + strncpy (utxline.ut_user, name, sizeof utxline.ut_user); + strncpy (utline.ut_user, name, sizeof utline.ut_user); + + utline.ut_type = utxline.ut_type = USER_PROCESS; + + gettimeofday(&utxline.ut_tv, NULL); + utline.ut_time = utxline.ut_tv.tv_sec; + + strncpy(utxline.ut_host, host ? host : "", sizeof utxline.ut_host); + + pututxline (&utxline); + pututline (&utline); + + updwtmpx(_WTMP_FILE "x", &utxline); + updwtmp(_WTMP_FILE, &utline); + + utxent = utxline; + utent = utline; +} + +#else /* !SVR4 */ + +void +setutmp(const char *name, const char *line) +{ + struct utmp utmp; + int fd; + int found = 0; + + if ((fd = open(_UTMP_FILE, O_RDWR)) < 0) + return; + +#if !defined(SUN) && !defined(BSD) && !defined(SUN4) /* XXX */ + while (!found && read(fd, (char *)&utmp, sizeof utmp) == sizeof utmp) { + if (! strncmp (line, utmp.ut_line, (int) sizeof utmp.ut_line)) + found++; + } +#endif + + if (! found) { + + /* + * This is a brand-new entry. Clear it out and fill it in + * later. + */ + + memzero(&utmp, sizeof utmp); + strncpy(utmp.ut_line, line, (int) sizeof utmp.ut_line); + } + + /* + * Fill in the parts of the UTMP entry. BSD has just the name, + * while System V has the name, PID and a type. + */ + + strncpy(utmp.ut_user, name, sizeof utent.ut_user); +#ifdef USER_PROCESS + utmp.ut_type = USER_PROCESS; + utmp.ut_pid = getpid (); +#endif + + /* + * Put in the current time (common to everyone) + */ + + (void) time (&utmp.ut_time); + +#ifdef UT_HOST + /* + * Update the host name field for systems with networking support + */ + + (void) strncpy (utmp.ut_host, utent.ut_host, (int) sizeof utmp.ut_host); +#endif + + /* + * Locate the correct position in the UTMP file for this + * entry. + */ + +#ifdef HAVE_TTYSLOT + (void) lseek (fd, (off_t) (sizeof utmp) * ttyslot (), SEEK_SET); +#else + if (found) /* Back up a splot */ + lseek (fd, (off_t) - sizeof utmp, SEEK_CUR); + else /* Otherwise, go to the end of the file */ + lseek (fd, (off_t) 0, SEEK_END); +#endif + + /* + * Scribble out the new entry and close the file. We're done + * with UTMP, next we do WTMP (which is real easy, put it on + * the end of the file. + */ + + (void) write (fd, (char *) &utmp, sizeof utmp); + (void) close (fd); + + updwtmp(_WTMP_FILE, &utmp); + utent = utmp; +} + +#endif /* SVR4 */ diff --git a/current/libmisc/valid.c b/current/libmisc/valid.c new file mode 100644 index 00000000..8559638e --- /dev/null +++ b/current/libmisc/valid.c @@ -0,0 +1,101 @@ +/* + * Copyright 1989 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID("$Id: valid.c,v 1.4 1999/03/07 19:14:44 marekm Exp $") + +#include +#include +#include "prototypes.h" +#include "defines.h" +#include + +/* + * valid - compare encrypted passwords + * + * Valid() compares the DES encrypted password from the password file + * against the password which the user has entered after it has been + * encrypted using the same salt as the original. Entries which do + * not have a password file entry have a NULL pw_name field and this + * is used to indicate that a dummy salt must be used to encrypt the + * password anyway. + */ + +int +valid(const char *password, const struct passwd *ent) +{ + const char *encrypted; + const char *salt; + + /* + * Start with blank or empty password entries. Always encrypt + * a password if no such user exists. Only if the ID exists and + * the password is really empty do you return quickly. This + * routine is meant to waste CPU time. + */ + + if (ent->pw_name && ! ent->pw_passwd[0]) { + if (! password[0]) + return (1); /* user entered nothing */ + else + return (0); /* user entered something! */ + } + + /* + * If there is no entry then we need a salt to use. + */ + + if (ent->pw_name == (char *) 0 || ent->pw_passwd[0] == '\0') { + salt = "xx"; + } else { + salt = ent->pw_passwd; + } + + /* + * Now, perform the encryption using the salt from before on + * the users input. Since we always encrypt the string, it + * should be very difficult to determine if the user exists by + * looking at execution time. + */ + + encrypted = pw_encrypt(password, salt); + + /* + * One last time we must deal with there being no password file + * entry for the user. We use the pw_name == NULL idiom to + * cause non-existent users to not be validated. + */ + + if (ent->pw_name && strcmp(encrypted, ent->pw_passwd) == 0) + return (1); + else + return (0); +} diff --git a/current/libmisc/xmalloc.c b/current/libmisc/xmalloc.c new file mode 100644 index 00000000..e85ae26c --- /dev/null +++ b/current/libmisc/xmalloc.c @@ -0,0 +1,38 @@ +/* Replacements for malloc and strdup with error checking. Too trivial + to be worth copyrighting :-). I did that because a lot of code used + malloc and strdup without checking for NULL pointer, and I like some + message better than a core dump... --marekm + + Yeh, but. Remember that bailing out might leave the system in some + bizarre state. You really want to put in error checking, then add + some back-out failure recovery code. -- jfh */ + +#include + +#include "rcsid.h" +RCSID("$Id: xmalloc.c,v 1.3 1998/12/28 20:34:56 marekm Exp $") + +#include + +#include "defines.h" + +extern char *malloc(); + +char * +xmalloc(size_t size) +{ + char *ptr; + + ptr = malloc(size); + if (!ptr && size) { + fprintf(stderr, _("malloc(%d) failed\n"), (int) size); + exit(13); + } + return ptr; +} + +char * +xstrdup(const char *str) +{ + return strcpy(xmalloc(strlen(str) + 1), str); +} diff --git a/current/ltconfig b/current/ltconfig new file mode 100755 index 00000000..65ec6f65 --- /dev/null +++ b/current/ltconfig @@ -0,0 +1,3017 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A lot of this script is taken from autoconf-2.10. + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} +echo=echo +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec "$SHELL" "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null`} + case X$UNAME in + *-DOS) PATH_SEPARATOR=';' ;; + *) PATH_SEPARATOR=':' ;; + esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +if test "X${echo_test_string+set}" != "Xset"; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" != 'X\t' || + test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running ltconfig again with it. + ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf "%s\n"' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # Cool, printf works + : + elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# The name of this program. +progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` + +# Constants: +PROGRAM=ltconfig +PACKAGE=libtool +VERSION=1.3.3 +TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)" +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5' +rm="rm -f" + +help="Try \`$progname --help' for more information." + +# Global variables: +default_ofile=libtool +can_build_shared=yes +enable_shared=yes +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +enable_static=yes +enable_fast_install=yes +enable_dlopen=unknown +enable_win32_dll=no +ltmain= +silent= +srcdir= +ac_config_guess= +ac_config_sub= +host= +nonopt= +ofile="$default_ofile" +verify_host=yes +with_gcc=no +with_gnu_ld=no +need_locks=yes +ac_ext=c +objext=o +libext=a +exeext= +cache_file= + +old_AR="$AR" +old_CC="$CC" +old_CFLAGS="$CFLAGS" +old_CPPFLAGS="$CPPFLAGS" +old_LDFLAGS="$LDFLAGS" +old_LD="$LD" +old_LN_S="$LN_S" +old_LIBS="$LIBS" +old_NM="$NM" +old_RANLIB="$RANLIB" +old_DLLTOOL="$DLLTOOL" +old_OBJDUMP="$OBJDUMP" +old_AS="$AS" + +# Parse the command line options. +args= +prev= +for option +do + case "$option" in + -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$option" + prev= + continue + fi + + case "$option" in + --help) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + if test -z "$ltmain"; then + ltmain="$option" + elif test -z "$host"; then +# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 +# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then +# echo "$progname: warning \`$option' is not a valid host type" 1>&2 +# fi + host="$option" + else + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac +done + +if test -z "$ltmain"; then + echo "$progname: you must specify a LTMAIN file" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test ! -f "$ltmain"; then + echo "$progname: \`$ltmain' does not exist" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +# Quote any args containing shell metacharacters. +ltconfig_args= +for arg +do + case "$arg" in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ltconfig_args="$ltconfig_args '$arg'" ;; + *) ltconfig_args="$ltconfig_args $arg" ;; + esac +done + +# A relevant subset of AC_INIT. + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 compiler messages saved in config.log +# 6 checking for... messages and results +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>>./config.log + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if test -n "$cache_file" && test -r "$cache_file"; then + echo "loading cache $cache_file within ltconfig" + . $cache_file +fi + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +if test -z "$srcdir"; then + # Assume the source directory is the same one as the path to LTMAIN. + srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` + test "$srcdir" = "$ltmain" && srcdir=. +fi + +trap "$rm conftest*; exit 1" 1 2 15 +if test "$verify_host" = yes; then + # Check for config.guess and config.sub. + ac_aux_dir= + for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/config.guess; then + ac_aux_dir=$ac_dir + break + fi + done + if test -z "$ac_aux_dir"; then + echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 + echo "$help" 1>&2 + exit 1 + fi + ac_config_guess=$ac_aux_dir/config.guess + ac_config_sub=$ac_aux_dir/config.sub + + # Make sure we can run config.sub. + if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : + else + echo "$progname: cannot run $ac_config_sub" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 + + host_alias=$host + case "$host_alias" in + "") + if host_alias=`$SHELL $ac_config_guess`; then : + else + echo "$progname: cannot guess host type; you must specify one" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac + host=`$SHELL $ac_config_sub $host_alias` + echo "$ac_t$host" 1>&6 + + # Make sure the host verified. + test -z "$host" && exit 1 + +elif test -z "$host"; then + echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 + echo "$help" 1>&2 + exit 1 +else + host_alias=$host +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case "$host_os" in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +case "$host_os" in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR cru $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +# Set a sane default for `AR'. +test -z "$AR" && AR=ar + +# Set a sane default for `OBJDUMP'. +test -z "$OBJDUMP" && OBJDUMP=objdump + +# If RANLIB is not set, then run the test. +if test "${RANLIB+set}" != "set"; then + result=no + + echo $ac_n "checking for ranlib... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then + RANLIB="ranlib" + result="ranlib" + break + fi + done + IFS="$save_ifs" + + echo "$ac_t$result" 1>&6 +fi + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" +fi + +# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin. +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$AS" && AS=as + +# Check to see if we are using GCC. +if test "$with_gcc" != yes || test -z "$CC"; then + # If CC is not set, then try to find GCC or a usable CC. + if test -z "$CC"; then + echo $ac_n "checking for gcc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then + CC="gcc" + break + fi + done + IFS="$save_ifs" + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + fi + + # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". + if test -z "$CC"; then + echo $ac_n "checking for cc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + cc_rejected=no + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/cc || test -f $dir/cc$ac_exeext; then + if test "$dir/cc" = "/usr/ucb/cc"; then + cc_rejected=yes + continue + fi + CC="cc" + break + fi + done + IFS="$save_ifs" + if test $cc_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same name, so the bogon will be chosen + # first if we set CC to just the name; use the full file name. + shift + set dummy "$dir/cc" "$@" + shift + CC="$@" + fi + fi + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$CC"; then + echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 + exit 1 + fi + fi + + # Now see if the compiler is really GCC. + with_gcc=no + echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 + echo "$progname:581: checking whether we are using GNU C" >&5 + + $rm conftest.c + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + with_gcc=yes + fi + $rm conftest.c + echo "$ac_t$with_gcc" 1>&6 +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo $ac_n "checking for object suffix... $ac_c" 1>&6 +$rm conftest* +echo 'int i = 1;' > conftest.c +echo "$progname:603: checking for object suffix" >& 5 +if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 +fi +$rm conftest* +echo "$ac_t$objext" 1>&6 + +echo $ac_n "checking for executable suffix... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_exeext="no" + $rm conftest* + echo 'main () { return 0; }' > conftest.c + echo "$progname:629: checking for executable suffix" >& 5 + if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c | *.err | *.$objext ) ;; + *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;; + esac + done + else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* +fi +if test "X$ac_cv_exeext" = Xno; then + exeext="" +else + exeext="$ac_cv_exeext" +fi +echo "$ac_t$ac_cv_exeext" 1>&6 + +echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 +pic_flag= +special_shlib_compile_flags= +wl= +link_static_flag= +no_builtin_flag= + +if test "$with_gcc" = yes; then + wl='-Wl,' + link_static_flag='-static' + + case "$host_os" in + beos* | irix5* | irix6* | osf3* | osf4*) + # PIC is the default for these OSes. + ;; + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # we not sure about C++ programs. + link_static_flag="$link_static_flag ${wl}-lC" + ;; + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + pic_flag='-m68020 -resident32 -malways-restore-a4' + ;; + sysv4*MP*) + if test -d /usr/nec; then + pic_flag=-Kconform_pic + fi + ;; + *) + pic_flag='-fPIC' + ;; + esac +else + # PORTME Check for PIC flags for the system compiler. + case "$host_os" in + aix3* | aix4*) + # All AIX code is PIC. + link_static_flag='-bnso -bI:/lib/syscalls.exp' + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better link_static_flag that works with the bundled CC? + wl='-Wl,' + link_static_flag="${wl}-a ${wl}archive" + pic_flag='+Z' + ;; + + irix5* | irix6*) + wl='-Wl,' + link_static_flag='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + + osf3* | osf4*) + # All OSF/1 code is PIC. + wl='-Wl,' + link_static_flag='-non_shared' + ;; + + sco3.2v5*) + pic_flag='-Kpic' + link_static_flag='-dn' + special_shlib_compile_flags='-belf' + ;; + + solaris*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + sunos4*) + pic_flag='-PIC' + link_static_flag='-Bstatic' + wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + uts4*) + pic_flag='-pic' + link_static_flag='-Bstatic' + ;; + sysv4*MP*) + if test -d /usr/nec ;then + pic_flag='-Kconform_pic' + link_static_flag='-Bstatic' + fi + ;; + *) + can_build_shared=no + ;; + esac +fi + +if test -n "$pic_flag"; then + echo "$ac_t$pic_flag" 1>&6 + + # Check to make sure the pic_flag actually works. + echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $pic_flag -DPIC" + echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5 + if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + case "$host_os" in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then they + # create non-PIC objects. So, if there were any warnings, we assume that + # PIC is not supported. + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + can_build_shared=no + pic_flag= + else + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + fi + ;; + *) + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + ;; + esac + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + can_build_shared=no + pic_flag= + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + echo "$ac_t"none 1>&6 +fi + +# Check to see if options -o and -c are simultaneously supported by compiler +echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6 +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +$rm conftest* +echo "int some_variable = 0;" > conftest.c +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.o" +echo "$progname:829: checking if $compiler supports -c -o file.o" >&5 +if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + echo "$ac_t"no 1>&6 + compiler_c_o=no + else + echo "$ac_t"yes 1>&6 + compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + compiler_c_o=no + echo "$ac_t"no 1>&6 +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5 +if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_o_lo=no + else + echo "$ac_t"yes 1>&6 + compiler_o_lo=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_o_lo=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$ac_t$hard_links" 1>&6 + $rm conftest* + if test "$hard_links" = no; then + echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 + need_locks=warn + fi +else + need_locks=no +fi + +if test "$with_gcc" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c" + echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_rtti_exceptions=no + else + echo "$ac_t"yes 1>&6 + compiler_rtti_exceptions=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_rtti_exceptions=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi + +fi + +# Check for any special shared library compilation flags. +if test -n "$special_shlib_compile_flags"; then + echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : + else + echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 + can_build_shared=no + fi +fi + +echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 +$rm conftest* +echo 'main(){return(0);}' > conftest.c +save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS $link_static_flag" +echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5 +if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + echo "$ac_t$link_static_flag" 1>&6 +else + echo "$ac_t"none 1>&6 + link_static_flag= +fi +LDFLAGS="$save_LDFLAGS" +$rm conftest* + +if test -z "$LN_S"; then + # Check to see if we can use ln -s, or we need hard links. + echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 + $rm conftest.dat + if ln -s X conftest.dat 2>/dev/null; then + $rm conftest.dat + LN_S="ln -s" + else + LN_S=ln + fi + if test "$LN_S" = "ln -s"; then + echo "$ac_t"yes 1>&6 + else + echo "$ac_t"no 1>&6 + fi +fi + +# Make sure LD is an absolute path. +if test -z "$LD"; then + ac_prog=ld + if test "$with_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 + echo "$progname:991: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we are not using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld... $ac_c" 1>&6 + echo "$progname:1015: checking for GNU ld" >&5 + else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 + echo "$progname:1018: checking for non-GNU ld" >&5 + fi + + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" + fi + + if test -n "$LD"; then + echo "$ac_t$LD" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$LD"; then + echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 + exit 1 + fi +fi + +# Check to see if it really is or is not GNU ld. +echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 +# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + with_gnu_ld=yes +else + with_gnu_ld=no +fi +echo "$ac_t$with_gnu_ld" 1>&6 + +# See if the linker supports building shared libraries. +echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. + +case "$host_os" in +cygwin* | mingw*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$with_gcc" != yes; then + with_gnu_ld=no + fi + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case "$host_os" in + aix3* | aix4*) + # On AIX, the GNU linker is very broken + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols' + + archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~ + _lt_hint=1; + for symbol in `cat $export_symbols`; do + echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def; + _lt_hint=`expr 1 + \$_lt_hint`; + done~ + test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts' + + old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' + ;; + + netbsd*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib' + # can we support soname and/or expsyms with a.out? -oliva + fi + ;; + + solaris*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case "$host_os" in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$with_gcc" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4*) + hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib' + hardcode_libdir_separator=':' + if test "$with_gcc" = yes; then + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + shared_flag='-shared' + else + shared_flag='${wl}-bM:SRE' + hardcode_direct=yes + fi + allow_undefined_flag=' ${wl}-berok' + archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}' + archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}' + case "$host_os" in aix4.[01]|aix4.[01].*) + # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on + always_export_symbols=yes ;; + esac + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs' + fix_srcfile_path='`cygpath -w $srcfile`' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case "$host_os" in + hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF + fi + hardcode_libdir_flag_spec='${wl}-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' + ;; + + osf3* | osf4*) + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case "$host_os" in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs' + archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + *) + ld_shlibs=no + ;; + esac +fi +echo "$ac_t$ld_shlibs" 1>&6 +test "$ld_shlibs" = no && can_build_shared=no + +if test -z "$NM"; then + echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 + case "$NM" in + [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path. + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -p" + break + else + NM=${NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$NM" && NM=nm + ;; + esac + echo "$ac_t$NM" 1>&6 +fi + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case "$host_os" in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + symcode='[BCDEGRST]' + ;; +solaris*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + $rm conftest* + cat > conftest.c <&5 + if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then + # Now try to grab the symbols. + nlist=conftest.nm + if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' + + cat <> conftest.c +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$objext conftstm.$objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + pipe_works=yes + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + LIBS="$save_LIBS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + global_symbol_pipe= + fi +done +if test "$pipe_works" = yes; then + echo "${ac_t}ok" 1>&6 +else + echo "${ac_t}failed" 1>&6 +fi + +if test -z "$global_symbol_pipe"; then + global_symbol_to_cdecl= +fi + +# Check hardcoding attributes. +echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$ac_t$hardcode_action" 1>&6 + + +reload_flag= +reload_cmds='$LD$reload_flag -o $output$reload_objs' +echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 +# PORTME Some linkers may need a different reload flag. +reload_flag='-r' +echo "$ac_t$reload_flag" 1>&6 +test -n "$reload_flag" && reload_flag=" $reload_flag" + +# PORTME Fill in your ld.so characteristics +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +file_magic_cmd= +file_magic_test_file= +deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. +echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 +case "$host_os" in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4*) + version_type=linux + # AIX has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + # We preserve .a as extension for shared libraries though AIX4.2 + # and later linker supports .so + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a' + shlibpath_var=LIBPATH + deplibs_check_method=pass_all + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + deplibs_check_method=pass_all + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + +bsdi4*) + version_type=linux + library_names_spec='${libname}.so$major ${libname}.so' + soname_spec='${libname}.so' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw*) + version_type=windows + need_version=no + need_lib_prefix=no + if test "$with_gcc" = yes; then + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a' + else + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + fi + dynamic_linker='Win32 ld.exe' + deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + file_magic_cmd='${OBJDUMP} -f' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case "$version_type" in + freebsd-elf*) + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + deplibs_check_method=unknown + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + finish_cmds='PATH="\$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + case "$host_os" in + freebsd2* | freebsd3.[01]*) + shlibpath_overrides_runpath=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + version_type=irix + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so.$major' + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so' + case "$host_os" in + irix5*) + libsuff= shlibsuff= + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case "$LD" in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib${libsuff}/libc.so*` + deplibs_check_method='pass_all' + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + + if test -f /lib/ld.so.1; then + dynamic_linker='GNU ld.so' + else + # Only the GNU ld.so supports shared libraries on MkLinux. + case "$host_cpu" in + powerpc*) dynamic_linker=no ;; + *) dynamic_linker='Linux ld.so' ;; + esac + fi + ;; + +netbsd*) + version_type=sunos + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + ;; + +openbsd*) + version_type=sunos + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + need_version=no + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method='file_magic COFF format alpha shared library' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + deplibs_check_method='pass_all' + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib" + file_magic_cmd=/usr/bin/file + file_magic_test_file=/lib/libc.so + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case "$host_vendor" in + ncr) + deplibs_check_method='pass_all' + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$ac_t$dynamic_linker" 1>&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 + +# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in +# configure.in, otherwise build static only libraries. +case "$host_os" in +cygwin* | mingw* | os2*) + if test x$can_build_shared = xyes; then + test x$enable_win32_dll = xno && can_build_shared=no + echo "checking if package supports dlls... $can_build_shared" 1>&6 + fi +;; +esac + +if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then + case "$deplibs_check_method" in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac +fi + +echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + test "$enable_shared" = yes && enable_static=no + ;; +esac + +echo "$ac_t$enable_shared" 1>&6 + +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes + +echo "checking whether to build static libraries... $enable_static" 1>&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +echo $ac_n "checking for objdir... $ac_c" 1>&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$ac_t$objdir" 1>&6 + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else +if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then + lt_cv_dlopen=no lt_cv_dlopen_libs= +echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "$progname:2170: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dlopen""... $ac_c" 1>&6 +echo "$progname:2207: checking for dlopen" >&5 +if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +dlopen(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_dlopen=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_dlopen=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 +echo "$progname:2251: checking for dld_link in -ldld" >&5 +ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load""... $ac_c" 1>&6 +echo "$progname:2288: checking for shl_load" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +shl_load(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shl_load=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shl_load=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 +echo "$progname:2333: checking for shl_load in -ldld" >&5 +ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +fi + + +fi + + +fi + +fi + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + fi + + case "$lt_cv_dlopen" in + dlopen) +for ac_hdr in dlfcn.h; do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "$progname:2395: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int fnord = 0; +EOF +ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +done + + if test "x$ac_cv_header_dlfcn_h" = xyes; then + CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + fi + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2433: checking whether a program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self" 1>&6 + + if test "$lt_cv_dlopen_self" = yes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self_static=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self_static=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self_static=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 +fi + ;; + esac + + case "$lt_cv_dlopen_self" in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case "$lt_cv_dlopen_self_static" in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + +# Copy echo and quote the copy, instead of the original, because it is +# used later. +ltecho="$echo" +if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ltecho="$CONFIG_SHELL \$0 --fallback-echo" +fi +LTSHELL="$SHELL" + +LTCONFIG_VERSION="$VERSION" + +# Only quote variables if we're using ltmain.sh. +case "$ltmain" in +*.sh) + # Now quote all the things that may contain metacharacters. + for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \ + AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \ + file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case "$var" in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case "$ltecho" in + *'\$0 --fallback-echo"') + ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + + trap "$rm \"$ofile\"; exit 1" 1 2 15 + echo "creating $ofile" + $rm "$ofile" + cat < "$ofile" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +### BEGIN LIBTOOL CONFIG +EOF + cfgfile="$ofile" + ;; + +*) + # Double-quote the variables that need it (for aesthetics). + for var in old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do + eval "$var=\\\"\$var\\\"" + done + + # Just create a config file. + cfgfile="$ofile.cfg" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + echo "creating $cfgfile" + $rm "$cfgfile" + cat < "$cfgfile" +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +EOF + ;; +esac + +cat <> "$cfgfile" +# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ +# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ +# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\ +# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\ +# $0$ltconfig_args +# +# Compiler and other test output produced by $progname, useful for +# debugging $progname, is in ./config.log if it exists. + +# The version of $progname that generated this script. +LTCONFIG_VERSION=$LTCONFIG_VERSION + +# Shell to use when invoking shell scripts. +SHELL=$LTSHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$ltecho + +# The archiver. +AR=$AR + +# The default C compiler. +CC=$CC + +# The linker used to build libraries. +LD=$LD + +# Whether we need hard or soft links. +LN_S=$LN_S + +# A BSD-compatible nm program. +NM=$NM + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$reload_flag +reload_cmds=$reload_cmds + +# How to pass a linker flag through the compiler. +wl=$wl + +# Object file suffix (normally "o"). +objext="$objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$pic_flag + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$RANLIB +old_archive_cmds=$old_archive_cmds +old_postinstall_cmds=$old_postinstall_cmds +old_postuninstall_cmds=$old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$old_archive_from_new_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$archive_cmds +archive_expsym_cmds=$archive_expsym_cmds +postinstall_cmds=$postinstall_cmds +postuninstall_cmds=$postuninstall_cmds + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$global_symbol_to_cdecl + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$include_expsyms + +EOF + +case "$ltmain" in +*.sh) + echo '### END LIBTOOL CONFIG' >> "$ofile" + echo >> "$ofile" + case "$host_os" in + aix3*) + cat <<\EOF >> "$ofile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # Append the ltmain.sh script. + sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) + + chmod +x "$ofile" + ;; + +*) + # Compile the libtool program. + echo "FIXME: would compile $ltmain" + ;; +esac + +test -n "$cache_file" || exit 0 + +# AC_CACHE_SAVE +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/current/ltmain.sh b/current/ltmain.sh new file mode 100644 index 00000000..ae10cad0 --- /dev/null +++ b/current/ltmain.sh @@ -0,0 +1,3975 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + echo "$modename: not configured to build any kind of library" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case "$arg" in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + execute_dlfiles) + eval "$prev=\"\$$prev \$arg\"" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case "$arg" in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case "$nonopt" in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case "$arg" in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case "$mode" in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + # Accept any command-line options. + case "$arg" in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + esac + + case "$user_target" in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly in scan + # sets, so we specify it separately. + case "$lastarg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case "$user_target" in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case "$libobj" in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case "$libobj" in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $pic_flag -DPIC $srcfile" + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if test -z "$pic_flag" && test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + # Now arrange that obj and lo_libobj become the same file + $show "$LN_S $obj $lo_libobj" + if $run $LN_S $obj $lo_libobj; then + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + command="$base_compile $srcfile" + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link) + modename="$modename: link" + C_compiler="$CC" # save it, to compile generated C sources + CC="$nonopt" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (!dll) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case "$prev" in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case "$arg" in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case "$arg" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi + + prevarg="$arg" + + case "$arg" in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: not more than one -exported-symbols argument allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + dir="$absdir" + ;; + esac + case " $deplibs " in + *" $arg "*) ;; + *) deplibs="$deplibs $arg";; + esac + case " $lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir";; + esac + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + case ":$dllsearchpath:" in + ::) dllsearchpath="$dllsearchdir";; + *":$dllsearchdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dllsearchdir";; + esac + ;; + esac + ;; + + -l*) + if test "$arg" = "-lc"; then + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # These systems don't actually have c library (as such) + continue + ;; + esac + elif test "$arg" = "-lm"; then + case "$host" in + *-*-cygwin* | *-*-beos*) + # These systems don't actually have math library (as such) + continue + ;; + esac + fi + deplibs="$deplibs $arg" + ;; + + -module) + module=yes + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # If we have no pic_flag, then this is the same as -all-static. + if test -z "$pic_flag" && test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + + *.o | *.obj | *.a | *.lib) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A library object. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + fi + libobjs="$libobjs $arg" + ;; + + *.la) + # A libtool-controlled library. + + dlname= + libdir= + library_names= + old_library= + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 + exit 1 + fi + + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + # If there is no directory component, then add one. + case "$arg" in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 + exit 1 + fi + + # Find the relevant object directory and library name. + name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` + + if test "X$installed" = Xyes; then + dir="$libdir" + else + dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$arg"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + fi + + if test -n "$dependency_libs"; then + # Extract -R and -L from dependency_libs + temp_deplibs= + for deplib in $dependency_libs; do + case "$deplib" in + -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + case " $rpath $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + -L*) case "$compile_command $temp_deplibs " in + *" $deplib "*) ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'` + case " $lib_search_path " in + *" $temp_dir "*) ;; + *) lib_search_path="$lib_search_path $temp_dir";; + esac + ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + done + dependency_libs="$temp_deplibs" + fi + + if test -z "$libdir"; then + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$deplibs$dependency_libs" + compile_command="$compile_command $dir/$old_library$dependency_libs" + finalize_command="$finalize_command $dir/$old_library$dependency_libs" + continue + fi + + # This library was specified with -dlopen. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking statically, + # we need to preload. + prev=dlprefiles + else + # We should not create a dependency on this library, but we + # may need any libraries it requires. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + prev= + continue + fi + fi + + # The library was specified with -dlpreopen. + if test "$prev" = dlprefiles; then + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + dlprefiles="$dlprefiles $dir/$old_library" + else + dlprefiles="$dlprefiles $dir/$linklib" + fi + prev= + fi + + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + link_against_libtool_libs="$link_against_libtool_libs $arg" + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # We need an absolute path. + case "$dir" in + [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + ;; + esac + + # This is the magic to use -rpath. + # Skip directories that are in the system default run-time + # search path, unless they have been requested with -R. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + + lib_linked=yes + case "$hardcode_action" in + immediate | unsupported) + if test "$hardcode_direct" = no; then + compile_command="$compile_command $dir/$linklib" + deplibs="$deplibs $dir/$linklib" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + if test -n "$dllsearchpath"; then + dllsearchpath="$dllsearchpath:$dllsearchdir" + else + dllsearchpath="$dllsearchdir" + fi + ;; + esac + elif test "$hardcode_minus_L" = no; then + case "$host" in + *-*-sunos*) + compile_shlibpath="$compile_shlibpath$dir:" + ;; + esac + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = no; then + case ":$compile_shlibpath:" in + *":$dir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$dir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + relink) + if test "$hardcode_direct" = yes; then + compile_command="$compile_command $absdir/$linklib" + deplibs="$deplibs $absdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$compile_command " in + *" -L$absdir "*) ;; + *) compile_command="$compile_command -L$absdir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$absdir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$compile_shlibpath:" in + *":$absdir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$absdir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + *) + lib_linked=no + ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + finalize_command="$finalize_command $libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$finalize_command " in + *" -L$libdir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$finalize_shlibpath:" in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:";; + esac + finalize_command="$finalize_command -l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + fi + else + # Transform directly to old archives if we don't build new libraries. + if test -n "$pic_flag" && test -z "$old_library"; then + $echo "$modename: cannot find static library for \`$arg'" 1>&2 + exit 1 + fi + + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_command="$compile_command $dir/$linklib" + finalize_command="$finalize_command $dir/$linklib" + else + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$dir";; + esac + finalize_command="$finalize_command -l$name" + fi + fi + + # Add in any libraries that this one depends upon. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + esac + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + case "$output" in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *.a | *.lib) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into archives" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + ;; + + *.la) + # Make sure we only generate libraries of the form `libNAME.la'. + case "$outputname" in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + if test -n "$objs"; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 + exit 1 + fi + + # How the heck are we supposed to write a wrapper for a shared library? + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2 + exit 1 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + dependency_libs="$deplibs" + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case "$current" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$revision" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$age" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case "$version_type" in + none) ;; + + irix) + major=`expr $current - $age + 1` + versuffix="$major.$revision" + verstring="sgi$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="sgi$major.$iface:$verstring" + done + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + windows) + # Like Linux, but with '-' rather than '.', since we only + # want one extension on Windows 95. + major=`expr $current - $age` + versuffix="-$major-$age-$revision" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + dependency_libs="$deplibs" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *) + # Add libc to deplibs on all other systems. + deplibs="$deplibs -lc" + ;; + esac + fi + + # Create the output directory, or remove our outputs if we need to. + if test -d $output_objdir; then + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + else + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + if test "$build_libtool_libs" = yes; then + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case "$deplibs_check_method" in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | sed 's/.* -> //'` + case "$potliblink" in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | sed 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) incase we are running --disable-static + for obj in $libobjs; do + oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"` + if test ! -f $oldobj; then + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linkopts="$linkopts $flag" + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + *.lo | *.o | *.obj) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into objects" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case "$output" in + *.lo) + if test -n "$objs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + # Anything else should be a program. + *) + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$compile_rpath " in + *" $libdir "*) ;; + *) compile_rpath="$compile_rpath $libdir" ;; + esac + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + # Create the binary in the object directory, then wrap it. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case "$dlsyms" in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | sed -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{\ +" + + sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ + -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ + < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr_t) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case "$host" in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case "$0" in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|sed 's,.exe$,,'` ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + link_against_libtool_libs='$link_against_libtool_libs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname' + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if (cd \"\$thisdir\" && eval \$relink_command); then : + else + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname$exeext' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + *-*-cygwin* | *-*-mingw | *-*-os2*) + # win32 systems need to use the prog path for dll + # lookup to work + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place incase we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"` + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case "$output" in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + if test -n "$xrpath"; then + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + done + dependency_libs="$temp_xrpath $dependency_libs" + fi + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + fi + $rm $output + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$dlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Directory that this library needs to be installed in: +libdir='$install_libdir'\ +" + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case "$arg" in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case "$file" in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case "$file" in + *.a | *.lib) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$realname $destdir/$realname" + $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case "$destfile" in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.o | *.obj) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + link_against_libtool_libs= + relink_command= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$link_against_libtool_libs"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $link_against_libtool_libs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case "$lib" in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec $SHELL $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case "$file" in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case "$file" in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now actually exec the command. + eval "exec \$cmd$args" + + $echo "$modename: cannot exec \$cmd$args" + exit 1 + else + # Display what would be done. + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool uninstall mode + uninstall) + modename="$modename: uninstall" + rm="$nonopt" + files= + + for arg + do + case "$arg" in + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + rmfiles="$file" + + case "$name" in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $dir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" + + $show "$rm $rmfiles" + $run $rm $rmfiles + + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + # FIXME: should reinstall the best remaining shared library. + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + + *) + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + esac + done + exit 0 + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case "$mode" in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/current/man/Makefile.am b/current/man/Makefile.am new file mode 100644 index 00000000..16a40e7e --- /dev/null +++ b/current/man/Makefile.am @@ -0,0 +1,21 @@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +SUBDIRS = pl + +man_MANS = chage.1 chfn.1 chsh.1 gpasswd.1 \ + login.1 newgrp.1 passwd.1 su.1 \ + shadow.3 \ + dialups.5 faillog.5 limits.5 login.access.5 login.defs.5 \ + passwd.5 porttime.5 shadow.5 suauth.5 \ + chpasswd.8 dpasswd.8 faillog.8 \ + groupadd.8 groupdel.8 groupmod.8 \ + grpck.8 lastlog.8 logoutd.8 mkpasswd.8 newusers.8 \ + pwck.8 pwconv.8 shadowconfig.8 \ + useradd.8 userdel.8 usermod.8 vipw.8 + +EXTRA_DIST = groups.1 id.1 pw_auth.3 pwauth.8 sulogin.8 ${man_MANS} + +# subdirectories for translated manual pages +SUBDIRS = pl + diff --git a/current/man/Makefile.in b/current/man/Makefile.in new file mode 100644 index 00000000..076af868 --- /dev/null +++ b/current/man/Makefile.in @@ -0,0 +1,471 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +# subdirectories for translated manual pages +SUBDIRS = pl + +man_MANS = chage.1 chfn.1 chsh.1 gpasswd.1 login.1 newgrp.1 passwd.1 su.1 shadow.3 dialups.5 faillog.5 limits.5 login.access.5 login.defs.5 passwd.5 porttime.5 shadow.5 suauth.5 chpasswd.8 dpasswd.8 faillog.8 groupadd.8 groupdel.8 groupmod.8 grpck.8 lastlog.8 logoutd.8 mkpasswd.8 newusers.8 pwck.8 pwconv.8 shadowconfig.8 useradd.8 userdel.8 usermod.8 vipw.8 + + +EXTRA_DIST = groups.1 id.1 pw_auth.3 pwauth.8 sulogin.8 ${man_MANS} +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +man1dir = $(mandir)/man1 +man3dir = $(mandir)/man3 +man5dir = $(mandir)/man5 +man8dir = $(mandir)/man8 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps man/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done + +install-man3: + $(mkinstalldirs) $(DESTDIR)$(man3dir) + @list='$(man3_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \ + done + +uninstall-man3: + @list='$(man3_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \ + rm -f $(DESTDIR)$(man3dir)/$$inst; \ + done + +install-man5: + $(mkinstalldirs) $(DESTDIR)$(man5dir) + @list='$(man5_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.5*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \ + done + +uninstall-man5: + @list='$(man5_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.5*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \ + rm -f $(DESTDIR)$(man5dir)/$$inst; \ + done + +install-man8: + $(mkinstalldirs) $(DESTDIR)$(man8dir) + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ + done + +uninstall-man8: + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ + rm -f $(DESTDIR)$(man8dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man1 install-man3 install-man5 \ + install-man8 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 uninstall-man3 uninstall-man5 \ + uninstall-man8 + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = man + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: install-man +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-man +uninstall: uninstall-recursive +all-am: Makefile $(MANS) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man3 \ + $(DESTDIR)$(mandir)/man5 $(DESTDIR)$(mandir)/man8 + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: install-man1 uninstall-man1 install-man3 uninstall-man3 \ +install-man5 uninstall-man5 install-man8 uninstall-man8 install-man \ +uninstall-man install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/man/chage.1 b/current/man/chage.1 new file mode 100644 index 00000000..2c09fc72 --- /dev/null +++ b/current/man/chage.1 @@ -0,0 +1,109 @@ +.\" Copyright 1990 - 1994 Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: chage.1,v 1.6 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH CHAGE 1 +.SH NAME +chage \- change user password expiry information +.SH SYNOPSIS +.TP 6 +\fBchage\fR +[\fB-m \fImindays\fR] [\fB-M \fImaxdays\fR] +[\fB-d \fIlastday\fR] [\fB-I \fIinactive\fR] +.br +[\fB-E \fIexpiredate\fR] [\fB-W \fIwarndays\fR] \fIuser\fR +.TP 6 +\fBchage\fR +\fB-l\fR \fIuser\fR +.SH DESCRIPTION +\fBchage\fR changes the number of days between password changes and the +date of the last password change. +This information is used by the system to determine when a user must +change her password. +The \fBchage\fR command is restricted to the root user, except for the +\fB-l\fR option, which may be used by an unprivileged user to determine +when her password or account is due to expire. +.PP +With the \fB-m\fR option, the value of \fImindays\fR is the minimum number +of days between password changes. +A value of zero for this field indicates that the user may change +her password at any time. +.PP +With the \fB-M\fR option, the value of \fImaxdays\fR is the maximum number +of days during which a password is valid. +When \fImaxdays\fR plus \fIlastday\fR is less than the current day, +the user will be required to change her password before being +able to use her account. +This occurance can be planned for in advance by use of the \fB-W\fR option, +which provides the user with advance warning. +.PP +With the \fB-d\fR option, the value of \fIlastday\fR is the number of days +since January 1st, 1970 when the password was last changed. +The date may also be expressed in the format YYYY-MM-DD (or the format more +commonly used in your area). +.PP +The \fB-E\fR option is used to set a date on which the user's account will +no longer be accessible. +The \fIexpiredate\fR option is the number of days since January 1, 1970 on +which the accounted is locked. +The date may also be expressed in the format YYYY-MM-DD (or the format more +commonly used in your area). +A user whose account is locked must contact the system administrator before +being able to use the system again. +.PP +The \fB-I\fR option is used to set the number of days of inactivity after +a password has expired before the account is locked. +A user whose account is locked must contact the system administrator before +being able to use the system again. +The \fIinactive\fR option is the number of days of inactivity. A value of +0 disables this feature. +.PP +The \fB-W\fR option is used to set the number of days of warning before a +password change is required. +The \fIwarndays\fR option is the number of days prior to the password +expiring that a user will be warned her password is about to expire. +.PP +All of the above values are stored exactly as days when the shadow +password file is used, but are converted to and from weeks when the +standard password file is used. +Because of this conversion, rounding errors may result. +.PP +If none of the options are selected, \fBchage\fR operates in an interactive +fashion, prompting the user with the current values for all of the fields. +Enter the new value to change the field, or leave the line blank to use +the current value. +The current value is displayed between a pair of \fB[ ]\fR marks. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- shadow user account information +.SH SEE ALSO +.BR passwd (5), +.BR shadow (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/chfn.1 b/current/man/chfn.1 new file mode 100644 index 00000000..e0ae8828 --- /dev/null +++ b/current/man/chfn.1 @@ -0,0 +1,66 @@ +.\" Copyright 1990 - 1994 Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: chfn.1,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH CHFN 1 +.SH NAME +chfn \- change user name and information +.SH SYNOPSIS +.TP 5 +\fBchfn\fR +[\fB-f \fIfull_name\fR] [\fB-r \fIroom_no\fR] +.br +[\fB-w \fIwork_ph\fR] [\fB-h \fIhome_ph\fR] [\fB-o \fIother\fR] +[\fIuser\fR] +.SH DESCRIPTION +\fBchfn\fR changes user fullname, office number, office extension, and home +phone number information for a user's account. +This information is typically printed by \fBfinger\fR(1) and similiar +programs. +A normal user may only change the fields for their own account, +the super user may change the fields for any account. +Also, only the super user may use the \fB-o\fR option to change the +undefined portions of the GCOS field. +.PP +The only restrictions placed on the contents of the fields is that no +control characters may be present, nor any of comma, colon, or equal sign. +The \fIother\fR field does not have this restriction, and is used to +store accounting information used by other applications. +.PP +If none of the options are selected, \fBchfn\fR operates in an interactive +fashion, prompting the user with the current values for all of the fields. +Enter the new value to change the field, or leave the line blank to use +the current value. +The current value is displayed between a pair of \fB[ ]\fR marks. +Without options, chfn prompts for the current user account. +.SH FILES +/etc/passwd \- user account information +.SH SEE ALSO +.BR passwd (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/chpasswd.8 b/current/man/chpasswd.8 new file mode 100644 index 00000000..860a1cdc --- /dev/null +++ b/current/man/chpasswd.8 @@ -0,0 +1,62 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: chpasswd.8,v 1.6 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH CHPASSWD 8 +.SH NAME +\fBchpasswd\fR - update password file in batch +.SH SYNOPSIS +\fBchpasswd [-e]\fR +.SH DESCRIPTION +\fBchpasswd\fR reads a file of user name and password pairs +from standard input and uses this information +to update a group of existing users. Without the -e switch, the +passwords are expected to be cleartext. With the -e switch, the +passwords are expected to be in encrypted form. +Each line is of the format +.sp 1 + \fIuser_name\fR:\fIpassword\fR +.sp 1 +The named user must exist. +The supplied password will be encrypted as necessary, and the password age +updated, if present. +.PP +This command is intended to be used in a large system environment where +many accounts are created at a single time. +.SH CAVEATS +.\" The \fBmkpasswd\fR command must be executed afterwards to update the +.\" DBM password files. +The input file must be protected if it contains unencrypted passwords. +.\" This command may be discarded in favor of the newusers(8) command. +.SH SEE ALSO +.\" mkpasswd(8), passwd(1), useradd(1) +.BR passwd (1), +.BR useradd (8), +.BR newusers (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/chsh.1 b/current/man/chsh.1 new file mode 100644 index 00000000..c2c1ee3e --- /dev/null +++ b/current/man/chsh.1 @@ -0,0 +1,66 @@ +.\" Copyright 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: chsh.1,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH CHSH 1 +.SH NAME +chsh \- change login shell +.SH SYNOPSIS +.TP 5 +\fBchsh\fR +[\fB-s \fIlogin_shell\fR] [\fIuser\fR] +.SH DESCRIPTION +\fBchsh\fR changes the user login shell. +This determines the name of the user's initial login command. +A normal user may only change the login shell for their own account, +the super user may change the login shell for any account. +.PP +The only restrictions placed on the login shell is that the +command name must be listed in \fI/etc/shells\fR, unless the +invoker is the super-user, and then any value may be added. +An account with a restricted login shell may not change +their login shell. +For this reason, placing \fB/bin/rsh\fR in \fI/etc/shells\fR +is discouraged since accidentally changing to a restricted +shell would prevent the user from every changing their login +shell back to its original value. +.PP +If the \fB-s\fR option is not selected, \fBchsh\fR operates in an interactive +fashion, prompting the user with the current login shell. +Enter the new value to change the field, or leave the line blank to use +the current value. +The current value is displayed between a pair of \fB[ ]\fR marks. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shells \- list of valid login shells +.SH SEE ALSO +.BR chfn (1), +.BR passwd (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/dialups.5 b/current/man/dialups.5 new file mode 100644 index 00000000..df33d6cd --- /dev/null +++ b/current/man/dialups.5 @@ -0,0 +1,22 @@ +.TH DIALUPS 5 "03 Oct 1999" +.SH NAME +d_passwd \- The dialup shell password file +.br +dialups \- List of dialup lines +.SH DESCRIPTION +The \fBd_passwd\fR file contains the names of login shells which require +dialup passwords. Each line contains the fully qualified path name +for the shell, followed by an optional password. Each field is separated +by a '\fB:\fR'. +.PP +The \fBdialups\fR file contains the names of ports which may be dialup +lines. Each line consists of the last component of the path name. The +leading "\fB/dev/\fR" string is removed. +.SH FILES +/etc/d_passwd \- dialup shell password file +.br +/etc/dialups \- dialup line list +.SH SEE ALSO +.BR login (1), +.SH AUTHOR +Ben Collins diff --git a/current/man/dpasswd.8 b/current/man/dpasswd.8 new file mode 100644 index 00000000..b19b36f8 --- /dev/null +++ b/current/man/dpasswd.8 @@ -0,0 +1,55 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: dpasswd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH DPASSWD 8 +.SH NAME +\fBdpasswd\fR - change dialup password +.SH SYNOPSIS +\fBdpasswd\fR +.RB [ - ( a | d )] +\fIshell\fR +.SH DESCRIPTION +\fBdpasswd\fR adds, deletes, and updates dialup passwords for user +login shells. +The dialup password is prompted for after a user's password has been +authenticated whenever the user logs in over a dialup line. +\fBdpasswd\fR will prompt for the new password twice to insure it +has been entered correctly. +.PP +The \fIshell\fR argument must be the complete pathname of the login +program. +.SH FILES +.br +/etc/d_passwd +.br +/etc/dialups +.SH SEE ALSO +.BR login (1) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/faillog.5 b/current/man/faillog.5 new file mode 100644 index 00000000..8beffdf9 --- /dev/null +++ b/current/man/faillog.5 @@ -0,0 +1,59 @@ +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: faillog.5,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH FAILLOG 5 +.SH NAME +faillog \- Login failure logging file +.SH DESCRIPTION +.I faillog +maintains a count of login failures and the limits for each account. +The file is fixed length record, indexed by numerical UID. +Each record contains the count of login failures since the last +successful login; +the maximum number of failures before the account is disabled; +the line the last login failure occured on; +and the date the last login failure occured. +.PP +The structure of the file is +.DS + + struct faillog { + short fail_cnt; + short fail_max; + char fail_line[12]; + time_t fail_time; + }; + +.DE +.SH FILES +/var/log/faillog \- login failure log +.SH SEE ALSO +.BR faillog (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/faillog.8 b/current/man/faillog.8 new file mode 100644 index 00000000..3ce76a1e --- /dev/null +++ b/current/man/faillog.8 @@ -0,0 +1,100 @@ +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: faillog.8,v 1.7 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH FAILLOG 8 +.SH NAME +faillog \- examine faillog and set login failure limits +.SH SYNOPSIS +.TP 8 +.B faillog +.RB [ -u +.IR login-name ] +.RB [ -a ] +.RB [ -t +.IR days ] +.RB [ -m +.IR max ] +.RB [ -pr ] +.SH DESCRIPTION +\fBfaillog\fR formats the contents of the failure log, +\fI/var/log/faillog\fR, and maintains failure counts and +limits. +The order of the arguments to \fBfaillog\fR is significant. +Each argument is processed immediately in the order given. +.PP +The \fB-p\fR flag causes failure entries to be printed in UID +order. +Entering \fB-u \fIlogin-name\fR flag will +cause the failure record for \fIlogin-name\fR only to be printed. +Entering \fB-t \fIdays\fR will cause only the +failures more recent than \fIdays\fR to be printed. +The \fB-t\fR flag overrides the use of \fB-u\fR. +The \fB-a\fR flag causes all users to be selected. +When used with the \fB-p\fR flag, this option selects all users +who have ever had a login failure. +It is meaningless with the \fB-r\fR flag. +.PP +The \fB-r\fR flag is used to reset the count of login failures. +Write access to \fI/var/log/faillog\fR is required for +this option. +Entering \fB-u \fIlogin-name\fR will cause only the failure count +for \fIlogin-name\fR to be reset. +.PP +The \fB-m\fR flag is used to set the maximum number of login +failures before the account is disabled. +Write access to \fI/var/log/faillog\fR is required for this +option. +Entering \fB-m \fImax\fR will cause all accounts to be disabled +after \fImax\fR failed logins occur. +This may be modified with \fB-u \fIlogin-name\fR to limit this +function to \fIlogin-name\fR only. +Selecting a \fImax\fR value of 0 has the effect of not placing +a limit on the number of failed logins. +The maximum failure count +should always be 0 for \fBroot\fR to prevent +a denial of services attack against the system. +.PP +Options may be combined in virtually any fashion. +Each \fB-p\fR, \fB-r\fR, and \fB-m\fR option will cause +immediate execution using any \fB-u\fR or \fB-t\fR modifier. +.SH CAVEATS +\fBfaillog\fR only prints out users with no successful login since +the last failure. +To print out a user who has had a successful login since their last +failure, you must explicitly request the user with the \fB-u\fR flag, +or print out all users with the \fB-a\fR flag. +.PP +Some systems may replace /var/log with /var/adm or /usr/adm. +.SH FILES +/var/log/faillog \- failure logging file +.SH SEE ALSO +.BR login (1), +.BR faillog (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/gpasswd.1 b/current/man/gpasswd.1 new file mode 100644 index 00000000..2b9c3dfa --- /dev/null +++ b/current/man/gpasswd.1 @@ -0,0 +1,73 @@ +.\" Copyright 1996, Rafal Maszkowski, rzm@pdi.net +.\" All rights reserved. You can redistribute this man page and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of the +.\" License, or (at your option) any later version. +.\" +.\" $Id: gpasswd.1,v 1.2 1996/09/10 02:45:18 marekm Exp $ +.\" +.TH GPASSWD 1 +.SH NAME +gpasswd \- administer the /etc/group file +.br +.SH SYNOPSIS +.B gpasswd \fIgroup\fR +.br +.B gpasswd +.B -a +\fIuser\fR \fIgroup\fR +.br +.B gpasswd +.B -d +\fIuser\fR \fIgroup\fR +.br +.B gpasswd +.B -R +\fIgroup\fR +.br +.B gpasswd +.B -r +\fIgroup\fR +.br +.B gpasswd +.RB [ -A +\fIuser\fR,...] +.RB [ -M +\fIuser\fR,...] +\fIgroup\fR +.br +.SH DESCRIPTION +.B gpasswd +is used to administer the /etc/group file (and /etc/gshadow +file if compiled with SHADOWGRP defined). Every group can +have administrators, members and a password. System +administrator can use \fB-A\fR option to define group +administrator(s) and \fB-M\fR option to define members and +has all rights of group administrators and members. +.PP +Group administrator can add and delete users using \fB-a\fR +and \fB-d\fR options respectively. Administrators can use +\fB-r\fR option to remove group password. When no password +is set only group members can use +.BR newgrp (1) +to join the group. Option \fB-R\fR disables +access to the group through +.BR newgrp (1) +command. +.PP +.B gpasswd +called by a group administrator with group name only prompts +for the group password. If password is set the members can still +.BR newgrp (1) +without a password, non-members must supply the password. + +.SH FILES +/etc/group \- group information +.br +/etc/gshadow \- shadow group information +.SH SEE ALSO +.BR newgrp (1), +.BR groupadd (8), +.BR groupdel (8), +.BR groupmod (8), +.BR grpck (8) diff --git a/current/man/groupadd.8 b/current/man/groupadd.8 new file mode 100644 index 00000000..2d3de403 --- /dev/null +++ b/current/man/groupadd.8 @@ -0,0 +1,64 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: groupadd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GROUPADD 8 +.SH NAME +groupadd \- Create a new group +.SH SYNOPSIS +.B groupadd +[\fB-g\fI gid \fR[\fB-o\fR]] +.I group +.SH DESCRIPTION +The \fBgroupadd\fR command +creates a new group account using the values specified on the +command line and the default values from the system. +The new group will be entered into the system files as needed. +The options which apply to the \fBgroupadd\fR command are +.IP "\fB-g \fIgid\fR" +The numerical value of the group's ID. +This value must be unique, unless the \fB-o\fR option is used. +The value must be non-negative. +The default is to use the smallest ID value greater than 99 and +greater than every other group. +Values between 0 and 99 are typically reserved for system accounts. +.SH FILES +/etc/group \- group account information +.br +/etc/gshadow \- secure group account information +.SH SEE ALSO +.BR chfn (1), +.BR chsh (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR passwd (1), +.BR groupdel (8), +.BR groupmod (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/groupdel.8 b/current/man/groupdel.8 new file mode 100644 index 00000000..19621a6b --- /dev/null +++ b/current/man/groupdel.8 @@ -0,0 +1,60 @@ +.\" Copyright 1991 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: groupdel.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GROUPDEL 8 +.SH NAME +groupdel \- Delete a group +.SH SYNOPSIS +.B groupdel +.I group +.SH DESCRIPTION +The \fBgroupdel\fR command modifies the system account files, deleting +all entries that refer to \fIgroup\fR. +The named group must exist. +.PP +You must manually check all filesystems to insure that no files remain +with the named group as the file group ID. +.SH CAVEATS +You may not remove the primary group of any existing user. +You must remove the user before you remove the group. +.SH FILES +/etc/group \- group information +.br +/etc/gshadow \- secure group information +.SH SEE ALSO +.BR chfn (1), +.BR chsh (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR passwd (1), +.BR groupadd (8), +.BR groupmod (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/groupmod.8 b/current/man/groupmod.8 new file mode 100644 index 00000000..28815dc8 --- /dev/null +++ b/current/man/groupmod.8 @@ -0,0 +1,66 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: groupmod.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GROUPMOD 8 +.SH NAME +groupmod \- Modify a group +.SH SYNOPSIS +.B groupmod +[\fB-g\fI gid \fR[\fB-o\fR]] +[\fB-n\fI group_name \fR] +.I group +.SH DESCRIPTION +The \fBgroupmod\fR command modifies the system account files to reflect +the changes that are specified on the command line. +The options which apply to the \fIgroupmod\fR command are +.IP "\fB-g \fIgid\fR" +The numerical value of the group's ID. +This value must be unique, unless the \fB-o\fR option is used. +The value must be non-negative. +Values between 0 and 99 are typically reserved for system groups. +Any files which the old group ID is the file group ID +must have the file group ID changed manually. +.IP "\fB-n \fIgroup_name\fR" +The name of the group will be changed from \fIgroup\fR to +\fIgroup_name\fR. +.SH FILES +/etc/group \- group information +.br +/etc/gshadow \- secure group information +.SH SEE ALSO +.BR chfn (1), +.BR chsh (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR passwd (1), +.BR groupadd (8), +.BR groupdel (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/groups.1 b/current/man/groups.1 new file mode 100644 index 00000000..bae98989 --- /dev/null +++ b/current/man/groups.1 @@ -0,0 +1,57 @@ +.\" Copyright 1991 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: groups.1,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GROUPS 1 +.SH NAME +groups \- Display current group ID names +.SH SYNOPSIS +.B groups +.RI [ user ] +.SH DESCRIPTION +.B groups +displays the current group ID names +or values. +If the value does not have a corresponding entry in +\fI/etc/group\fR, the value will be displayed as the numerical group value. +The optional \fIuser\fR parameter will display the groups for the named +\fIuser\fR. +.SH NOTE +Systems which do not support concurrent group sets will have the information +from \fI/etc/group\fR reported. +The user must use \fBnewgrp\fR or \fBsg\fR to change their current real and +effective group ID. +.SH FILES +/etc/group \- group information +.SH SEE ALSO +.BR newgrp (1), +.BR getuid (2), +.BR getgid (2), +.BR getgroups (2) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/grpck.8 b/current/man/grpck.8 new file mode 100644 index 00000000..3d2f7948 --- /dev/null +++ b/current/man/grpck.8 @@ -0,0 +1,101 @@ +.\" Copyright 1992 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: grpck.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GRPCK 1 +.SH NAME +grpck \- verify integrity of group files +.SH SYNOPSIS +\fBgrpck\fR [\fB-r\fR] [\fIgroup\fR \fIshadow\fR] +.SH DESCRIPTION +\fBgrpck\fR verifies the integrity of the system authentication information. +All entries in the \fI/etc/group\fR and \fI/etc/gshadow\fR are checked to +see that the entry has the proper format and valid data in each field. +The user is prompted to delete entries that are improperly formatted or +which have other incorrectable errors. +.P +Checks are made to verify that each entry has +.sp +.in +.5i +- the correct number of fields +.br +- a unique group name +.br +- a valid list of members and administrators +.in -.5i +.sp +.P +The checks for correct number of fields and unique group name are fatal. +If the entry has the wrong number of fields, the user will be prompted to +delete the entire line. +If the user does not answer affirmatively, all further checks are bypassed. +An entry with a duplicated group name is prompted for deletion, but the +remaining checks will still be made. +All other errors are warnings and the user is encouraged to run the +\fBgroupmod\fR command to correct the error. +.P +The commands which operate on the \fI/etc/group\fR file are not able to +alter corrupted or duplicated entries. +\fBgrpck\fR should be used in those circumstances to remove the offending +entry. +.SH OPTIONS +By default, \fBgrpck\fR operates on the files \fI/etc/group\fR and +\fI/etc/gshadow\fR. +The user may select alternate files with the \fIgroup\fR and \fIshadow\fR +parameters. +Additionally, the user may execute the command in read-only mode by +specifying the \fB-r\fR flag. +This causes all questions regarding changes to be answered \fBno\fR +without user intervention. +.SH FILES +/etc/group \- group account information +.br +/etc/gshadow \- encrypted passwords and group administrator information +.br +/etc/passwd \- user information +.SH SEE ALSO +.BR groupmod (8), +.BR group (5), +.BR passwd (5), +.BR shadow (5) +.SH DIAGNOSTICS +The \fBgrpck\fR command exits with the following values: +.IP 0 5 +Success +.IP 1 5 +Syntax Error +.IP 2 5 +One or more bad group entries +.IP 3 5 +Cannot open group files +.IP 4 5 +Cannot lock group files +.IP 5 5 +Cannot update group files +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/id.1 b/current/man/id.1 new file mode 100644 index 00000000..19cf6a24 --- /dev/null +++ b/current/man/id.1 @@ -0,0 +1,54 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: id.1,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH ID 1 +.SH NAME +id \- Display current user and group ID names +.SH SYNOPSIS +.B id +.RB [ -a ] +.SH DESCRIPTION +.B id +displays the current real and effective user and group ID names +or values. +If the value does not have a corresponding entry in \fI/etc/passwd\fR +or \fI/etc/group\fR, the value will be displayed without the corresponding +name. +The optional \fB-a\fR flag will display the group set on systems which +support multiple concurrent group membership. +.SH FILES +/etc/passwd \- user account information +.br +/etc/group \- group information +.SH SEE ALSO +.BR getuid (2), +.BR getgid (2), +.BR getgroups (2) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/lastlog.8 b/current/man/lastlog.8 new file mode 100644 index 00000000..85acc13b --- /dev/null +++ b/current/man/lastlog.8 @@ -0,0 +1,63 @@ +.\" Copyright 1992, Phillip Street and Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" @(#)lastlog.8 3.3 08:24:58 29 Sep 1993 (National Guard Release) +.\" $Id: lastlog.8,v 1.6 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH LASTLOG 8 +.SH NAME +lastlog \- examine lastlog file +.SH SYNOPSIS +.B lastlog +.RB [ -u +.IR login-name ] +.RB [ -t +.IR days ] +.SH DESCRIPTION +\fBlastlog\fR formats and prints the contents of the last login log, +\fI/var/log/lastlog\fR. The \fBlogin-name\fR, \fBport\fR, and \fBlast login +time\fR will be printed. +The default (no flags) causes lastlog entries to be printed, sorted +by the numerical UID. +Entering \fB-u \fIlogin-name\fR flag will +cause the lastlog record for \fIlogin-name\fR only to be printed. +Entering \fB-t \fIdays\fR will cause only the +lastlogins more recent than \fIdays\fR to be printed. +The \fB-t\fR flag overrides the use of \fB-u\fR. +.PP +If the user has never logged in the message \fB"**Never logged in**"\fR will +be displayed instead of the port and time. +.SH FILES +/var/log/lastlog \- lastlog logging file +.SH CAVEATS +Large gaps in uid numbers will cause the lastlog program to run longer with +no output to the screen (i.e. if mmdf=800 and last uid=170, program will +appear to hang as it processes uid 171-799). +.SH AUTHORS +Julianne Frances Haugh (jfh@austin.ibm.com) +.br +Phillip Street diff --git a/current/man/limits.5 b/current/man/limits.5 new file mode 100644 index 00000000..4031219c --- /dev/null +++ b/current/man/limits.5 @@ -0,0 +1,76 @@ +.TH LIMITS 5 +.SH NAME +limits \- Resource limits definition +.SH DESCRIPTION +The +.I limits +file (/etc/limits by default or LIMITS_FILE defined config.h) +describes the resource limits you wish to impose. +It should be owned by root and readable by root account only. +.PP +By default no quotas are imposed on 'root'. In fact, there is no way to impose +limits via this procedure to root-equiv accounts (accounts with UID 0). +.PP +Each line describes a limit for a user in the form: +.sp +.I user LIMITS_STRING +.PP +The \fBLIMITS_STRING\fP is a string of a concatenated list of resource limits. +Each limit consists of a letter identifier followed by a numerical limit. +.PP +The valid identifiers are: +.sp +A: max address space (KB) +.br +C: max core file size (KB) +.br +D: max data size (KB) +.br +F: maximum filesize (KB) +.br +M: max locked-in-memory address space (KB) +.br +N: max number of open files +.br +R: max resident set size (KB) +.br +S: max stack size (KB) +.br +T: max CPU time (MIN) +.br +U: max number of processes +.br +K: file creation mask, set by \fBumask\fR(2). +.br +L: max number of logins for this user +.br +P: process priority, set by \fBsetpriority\fR(2). +.PP +For example, \fIL2D2048N5\fP is a valid \fBLIMITS_STRING\fP. For reading convenience, +the following entries are equivalent: +.sp +username L2D2048N5 +.br +username L2 D2048 N5 +.PP +Be aware that after \fIusername\fP the rest of the line is considered a limit +string, thus comments are not allowed. A invalid limits string will be +rejected (not considered) by the login program. +.PP +The default entry is denoted by username "\fB*\fP". If you have multiple \fIdefault\fP +entries in your \fBLIMITS_FILE\fP, then the last one will be used as the default +entry. +.PP +To completely disable limits for a user, a single dash "\fB-\fP" will do. +.PP +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 ;) +.SH FILES +/etc/limits +.SH SEE ALSO +.BR login (1), +.BR setpriority (2), +.BR setrlimit (2) +.SH AUTHOR +Cristian Gafton (gafton@sorosis.ro) diff --git a/current/man/login.1 b/current/man/login.1 new file mode 100644 index 00000000..45a42b5f --- /dev/null +++ b/current/man/login.1 @@ -0,0 +1,155 @@ +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: login.1,v 1.7 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH LOGIN 1 +.SH NAME +login \- Begin session on the system +.SH SYNOPSIS +\fBlogin\fR [\fB-p\fR] [\fIusername\fR] [\fIENV=VAR ...\fR] +.br +\fBlogin\fR [\fB-p\fR] [\fB-h\fR \fIhost\fR] [\fB-f\fR \fIusername\fR] +.br +\fBlogin\fR [\fB-p\fR] \fB-r\fR \fIhost\fR +.SH DESCRIPTION +.B login +is used to establish a new session with the system. +It is normally invoked automatically by responding to the +.I login: +prompt on the user\'s terminal. +.B login +may be special to the shell and may not be invoked as a sub-process. +Typically, +.B login +is treated by the shell as \fBexec login\fR which causes the user +to exit from the current shell. +Attempting to execute \fBlogin\fR from any shell but the login shell +will produce an error message. +.PP +When invoked from the \fIlogin:\fR prompt, the user may enter +environmental variables after the username. +These variables are entered in the form \fBNAME=VALUE\fR. +Not all variables may be set in the fashion, notably \fBPATH\fR, +\fBHOME\fR and \fBSHELL\fR. +Additionally, \fBIFS\fR may be inhibited if the user\'s login +shell is \fB/bin/sh\fR. +.PP +The user is then prompted for a password, where appropriate. +Echoing is disabled to prevent revealing the password. +Only a small number of password failures are permitted before +\fBlogin\fR exits and the communications link is severed. +.PP +If password aging has been enabled for your account, you may be +prompted for a new password before proceeding. +You will be forced to provide your old password and the new +password before continuing. +Please refer to \fBpasswd \fR(1) for more information. +.PP +After a successful login, +you will be informed of any system messages and the presence +of mail. +You may turn off the printing of the system message file, +\fI/etc/motd\fR, by creating a zero-length file \fI.hushlogin\fR +in your login directory. +The mail message will be one of "\fBYou have new mail.\fR", +"\fBYou have mail.\fR", or "\fBNo Mail.\fR" according to +the condition of your mailbox. +.PP +Your user and group ID will be set according to their values in +the \fI/etc/passwd\fR file. +The value for \fB$HOME\fR, \fB$SHELL\fR, \fB$PATH\fR, \fB$LOGNAME\fR, +and \fB$MAIL\fR are set according to the appropriate fields in the +password entry. +Ulimit, umask and nice values may also be set according to +entries in the GECOS field. +.PP +On some installations, the environmental variable \fB$TERM\fR will be +initialize to the terminal type on your tty line, as specified in +\fI/etc/ttytype\fR. +.PP +An initialization script for your command interpreter may also be +executed. +Please see the appropriate manual section for more information on +this function. +.PP +A subsystem login is indicated by the presense of a "*" as the first +character of the login shell. The given home directory will be used as +the root of a new filesystem which the user is actually logged into. +.SH OPTIONS +.TP +.B -p +Preserve environment. +.TP +.B -f +Do not perform authentication, user is preauthenticated. +.TP +.B -h +Name of the remote host for this login. +.TP +.B -r +Perform autologin protocol for rlogin. +.PP +The \fB-r -h\fP and \fB-f\fP options are only used when \fBlogin\fP is invoked by root. +.SH CAVEATS +.PP +This version of \fBlogin\fR has many compilation options, only some of which +may be in use at any particular site. +.PP +The location of files is subject to differences in system configuration. +.SH FILES +/etc/utmp \- list of current login sessions +.br +/etc/wtmp \- list of previous login sessions +.br +/etc/passwd \- user account information +.br +/etc/shadow \- encrypted passwords and age information +.br +/etc/motd \- system message file +.br +/etc/nologin \- prevent non-root users from logging in +.br +/etc/ttytype \- list of terminal types +.br +$HOME/.profile \- initialization script for default shell +.br +$HOME/.hushlogin \- suppress printing of system messages +.br +.SH SEE ALSO +.PP +.BR getty (8), +.BR mail (1), +.BR passwd (1), +.BR sh (1), +.BR su (1), +.BR login.defs (5), +.\" .BR d_passwd (5), +.BR passwd (5), +.BR nologin (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/login.access.5 b/current/man/login.access.5 new file mode 100644 index 00000000..01f06beb --- /dev/null +++ b/current/man/login.access.5 @@ -0,0 +1,52 @@ +.\" this is comment +.TH LOGIN.ACCESS 5 +.\" .Dt SKEY.ACCESS 5 +.\" .Os FreeBSD 1.2 +.SH NAME +login.access \- Login access control table +.SH DESCRIPTION +The +.I login.access +file specifies (user, host) combinations and/or (user, tty) +combinations for which a login will be either accepted or refused. +.PP +When someone logs in, the +.I login.access +is scanned for the first entry that +matches the (user, host) combination, or, in case of non-networked +logins, the first entry that matches the (user, tty) combination. The +permissions field of that table entry determines whether the login will +be accepted or refused. +.PP +Each line of the login access control table has three fields separated by a +":" character: +.sp 1 +.IR permission : users : origins +.sp 1 +The first field should be a "\fB+\fR" (access granted) or "\fB-\fR" +(access denied) character. The second field should be a list of one or +more login names, group names, or +.B ALL +(always matches). The third field should be a list +of one or more tty names (for non-networked logins), host names, domain +names (begin with "\fB.\fR"), host addresses, internet network numbers +(end with "\fB.\fR"), +.B ALL +(always matches) or +.B LOCAL +(matches any string that does not contain a "\fB.\fR" character). +If you run NIS you can use @netgroupname in host or user patterns. +.PP +The +.B EXCEPT +operator makes it possible to write very compact rules. +.PP +The group file is searched only when a name does not match that of the +logged-in user. Only groups are matched in which users are explicitly +listed: the program does not look at a user's primary group id value. +.SH FILES +/etc/login.access +.SH SEE ALSO +.BR login (1) +.SH AUTHOR +Guido van Rooij diff --git a/current/man/login.defs.5 b/current/man/login.defs.5 new file mode 100644 index 00000000..d21a3cc9 --- /dev/null +++ b/current/man/login.defs.5 @@ -0,0 +1,573 @@ +.\" Copyright 1991 - 1993, Julianne Frances Haugh and Chip Rosenthal +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: login.defs.5,v 1.7 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH LOGIN 5 +.SH NAME +/etc/login.defs \- Login configuration +.SH DESCRIPTION +The +.I /etc/login.defs +file defines the site-specific configuration for the shadow login +suite. This file is required. Absence of this file will not prevent +system operation, but will probably result in undesirable operation. +.PP +This file is a readable text file, each line of the file describing +one configuration parameter. The lines consist of a configuration +name and value, seperated by whitespace. Blank lines and comment +lines are ignored. Comments are introduced with a `#' pound sign and +the pound sign must be the first non-white character of the line. +.PP +Parameter values may be of four types: strings, booleans, numbers, +and long numbers. A string is comprised of any printable characters. +A boolean should be either the value ``yes'' or ``no''. An undefined +boolean parameter or one with a value other than these will be given +a ``no'' value. Numbers (both regular and long) may be either decimal +values, octal values (precede the value with ``0'') or hexadecimal +values (precede the value with ``0x''). The maximum value of the +regular and long numeric parameters is machine-dependant. +.PP +The following configuration items are provided: +.\" +.IP "CHFN_AUTH (boolean)" +If +.IR yes , +the +.B chfn +and +.B chsh +programs will ask for password before making any changes, unless +run by the superuser. +.\" +.IP "CHFN_RESTRICT (string)" +This parameter specifies which values in the +.I gecos +field of the +.I passwd +file may be changed by regular users using the +.B chfn +program. It can be any combination of letters +.IR f , +.IR r , +.IR w , +.IR h , +for Full name, Room number, Work phone, and Home phone, respectively. +If not specified, only the superuser can make any changes. +.\" +.IP "CLOSE_SESSIONS (boolean)" +Enable pam_close_session() calling. When using normal (pam_unix.so) +session handling modules, this is not needed. However with modules +(such as kerberos or other persistent session models), +.B login +needs to fork and wait for the shell to exit, so that sessions can be +cleaned up. +.\" +.IP "CONSOLE (string)" +If specified, this definition provides for a restricted set of lines +on which root logins will be allowed. An attempted root login which +does not meet the criteria established here will be rejected. The +value of this field may be one of two forms, either a fully-rooted +pathname such as +.sp +.ft I + CONSOLE /etc/consoles +.ft R +.sp +or a colon-delimited list of terminal lines such as: +.sp +.ft I + CONSOLE console:tty01:tty02:tty03:tty04 +.ft R +.sp +If a pathname is given, each line of the file should specify one +terminal line. If this parameter is not defined or the specified file +does not exist, then root logins will be allowed from any terminal +line. Because the removal of this file, or its truncation, could +result in unauthorized root logins, this file must be protected. +Where security is critical, the colon-separated form should be used +to prevent this potential method of attack. +.\" +.IP "CONSOLE_GROUPS (string)" +XXX needs to be documented. +.\" +.IP "CRACKLIB_DICTPATH (string)" +XXX needs to be documented. +.\" +.IP "DEFAULT_HOME (boolean)" +XXX needs to be documented. +.\" +.IP "DIALUPS_CHECK_ENAB (boolean)" +If +.I yes +and an +.I /etc/dialups +file exists, then secondary passwords are enabled upon the dialup +lines specified in this file. This file should contain a list of +dialups, one per line, for example: +.nf +.sp +.ft I + ttyfm01 + ttyfm02 + \0\0. + \0\0. + \0\0. +.ft R +.sp +.fi +.\" +.IP "ENVIRON_FILE (string)" +File containing a list of environment variables (one per line) to set +when logging in or su'ing. +.\" +.IP "ENV_HZ (string)" +This parameter specifies a value for an HZ environment parameter. +Example usage is: +.sp + \fIENV_HZ HZ=50\fR +.sp +If this parameter is not defined then no HZ value will be established. +.\" +.IP "ENV_PATH (string)" +This parameter must be defined as the search path for regular users. +When a login with UID other than zero occurs, the PATH environment +parameter is initialized to this value. This parameter is required; +if undefined a possibly incorrect default value will be provided. +.\" +.IP "ENV_SUPATH (string)" +This parameter must be defined as the search path for the superuser. +When a login with UID zero occurs, the PATH environment parameter is +initialized to this value. This parameter is required; if undefined +a possibly incorrect default value will be provided. +.\" +.IP "ENV_TZ (string)" +This parameter specifies information for generating a TZ environment +parameter. The value must either be the desired contents of TZ, or +the full pathname of a file which contains this information. Example +usage is: +.sp + \fIENV_TZ\0\0\0\0TZ=CST6CDT\fP +.sp +or +.sp + \fIENV_TZ\0\0\0\0/etc/tzname\fP +.sp +If a nonexistent file is named, then TZ will be initialized to some +default value. If this parameter is not defined then no TZ value will +be established. +.\" +.IP "ERASECHAR (number)" +The terminal +.I erase +character is initialized to this value. This is supported only on +systems with the +.I termio +interface, e.g. System V. If not specified, the erase character will +be initialized to a backspace. See KILLCHAR for related information. +.\" +.IP "FAILLOG_ENAB (boolean)" +If +.I yes +then login failures will be accumulated in +.I /var/log/faillog +in a +.BR faillog (8) +format. +.\" +.IP "FAIL_DELAY (number)" +Delay time in seconds after each failed login attempt. +.\" +.IP "FAKE_SHELL (string)" +Instead of the real user shell, the program specified by this +parameter will be launched, although its visible name (argv[0]) will +be the shell's. The program may do whatever it wants (logging, +additional authentification, banner, ...) before running the actual +shell. +.\" +.IP "FTMP_FILE (string)" +This parameter specifies the full pathname to a file to which login +failures are recorded. When a login failure occurs, a +.I utmp +format record will be appended to this file. Note that this differs +from the +.I /var/log/faillog +failure logging in that this facility logs every failure whereas the +``faillog'' facility accumulates failure information per user. If +this parameter is not specified then logging will be inhibited. See +FAILLOG_ENAB and LOG_UNKFAIL_ENAB for related information. +.\" +.IP "GID_MAX (number)" +.IP "GID_MIN (number)" +Range of group IDs to choose from for the +.B groupadd +program. +.\" +.IP "HUSHLOGIN_FILE (string)" +This parameter is used to establish ``hushlogin'' conditions. There +are two possible ways to establish these conditions. First, if the +value of this parameter is a filename and that file exists in the +user's home directory then ``hushlogin'' conditions will be in effect. +The contents of this file are ignored; its mere presence triggers +``hushlogin'' conditions. Second, if the value of this parameter is +a full pathname and either the user's login name or the user's shell +is found in this file, then ``hushlogin'' conditions will be in effect. +In this case, the file should be in a format similar to: +.nf +.sp +.ft I + demo + /usr/lib/uucp/uucico + \0\0. + \0\0. + \0\0. +.ft R +.sp +.fi +If this parameter is not defined, then ``hushlogin'' conditions will +never occur. When ``hushlogin'' conditions are established, the +message of the day, last successful and unsuccessful login display, +mail status display, and password aging checks are suppressed. Note +that allowing hushlogin files in user home directories allows the user +to disable password aging checks. See MOTD_FILE, FAILLOG_ENAB, +LASTLOG_ENAB, and MAIL_CHECK_ENAB for related information. +.\" +.IP "ISSUE_FILE (string)" +Full pathname of the file to display before each login prompt. +.\" +.IP "KILLCHAR (number)" +The terminal +.I kill +character is initialized to this value. This is supported only on +systems with the +.I termio +interface, e.g. System V. If not specified, the kill character will +be initialized to a \s-2CTRL/U\s0. +See ERASECHAR for related information. +.\" +.IP "LASTLOG_ENAB (boolean)" +If +.IR yes , +and if the +.I /var/log/lastlog +file exists, then a successful user login will be recorded to this +file. Furthermore, if this option is enabled then the times of the +most recent successful and unsuccessful logins will be displayed to +the user upon login. The unsuccessful login display will be suppressed +if FAILLOG_ENAB is not enabled. If ``hushlogin'' conditions are in +effect, then both the successful and unsuccessful login information +will be suppressed. +.\" +.IP "LOGIN_RETRIES (number)" +Number of login attempts allowed before the +.B login +program exits. +.\" +.IP "LOGIN_STRING (string)" +XXX needs to be documented. +.IP "LOGIN_TIMEOUT (number)" +XXX needs to be documented. +.IP "LOG_OK_LOGINS (boolean)" +XXX needs to be documented. +.IP "LOG_UNKFAIL_ENAB (boolean)" +If +.I yes +then unknown usernames will be included when a login failure is +recorded. Note that this is a potential security risk; a common login +failure mode is transposition of the user name and password, thus this +mode will often cause passwords to accumulate in the failure logs. +If this option is disabled then unknown usernames will be suppressed +in login failure messages. +.\" +.IP "MAIL_CHECK_ENAB (boolean)" +If +.IR yes , +the user will be notified of his or her mailbox status upon login. +See MAIL_DIR for related information. +.\" +.IP "MAIL_DIR (string)" +This parameter specifies the full pathname to the directory which +contains the user mailbox files. The user's login name is appended +to this path to form the MAIL environment parameter \- the path to +the user's mailbox. Either this parameter or MAIL_FILE must be defined; +if undefined some possibly incorrect default value will be assumed. +See MAIL_CHECK_ENAB for related information. +.\" +.IP "MAIL_FILE (string)" +This parameter specifies the name of the user's mailbox file. This +name is appended to the name of the user's home directory to form the +MAIL environment parameter \- the path to the user's mailbox. Either +this parameter or MAIL_DIR must be defined; if undefined some possibly +incorrect default value will be assumed. See MAIL_CHECK_ENAB for +related information. +.\" +.IP "MD5_CRYPT_ENAB (boolean)" +If +.IR yes , +the +.B passwd +program will encrypt newly changed passwords using a new MD5-based +.BR crypt (3) +password hashing algorithm, which originally appeared in FreeBSD, and +is also supported by libc-5.4.38 and glibc-2.0 (or higher) on Linux. +This algorithm allows passwords longer than 8 characters (limited by +.BR getpass (3) +to 127 characters), but is incompatible with traditional +.BR crypt (3) +implementations. +.\" +.IP "MOTD_FILE (string)" +This parameter specifies a colon-delimited list of pathnames to ``message +of the day'' files. +If a specified file exists, then its contents are displayed to the user +upon login. +If this parameter is not defined or ``hushlogin'' login conditions are +in effect, this information will be suppressed. +.\" +.IP "NOLOGINS_FILE (string)" +This parameter specifies the full pathname to a file which inhibits +non-root logins. If this file exists and a user other than root +attempts to log in, the contents of the file will be displayed and +the user will be disconnected. If this parameter is not specified +then this feature will be inhibited. +.\" +.IP "NOLOGIN_STR (string)" +XXX needs to be documented. +.\" +.IP "OBSCURE_CHECKS_ENAB (boolean)" +If +.IR yes , +the +.B passwd +program will perform additional checks before accepting a password change. +The checks performed are fairly simple, and their use is recommended. +These obscurity checks are bypassed if +.B passwd +is run by +.IR root . +See PASS_MIN_LEN for related information. +.\" +.IP "PASS_ALWAYS_WARN (boolean)" +XXX needs to be documented. +.\" +.IP "PASS_CHANGE_TRIES (number)" +XXX needs to be documented. +.\" +.IP "PASS_MIN_DAYS (number)" +The minimum number of days allowed between password changes. Any password +changes attempted sooner than this will be rejected. If not specified, a +zero value will be assumed. +.\" +.IP "PASS_MIN_LEN (number)" +The minimum number of characters in an acceptable password. An attempt to +assign a password with fewer characters will be rejected. A zero value +suppresses this check. If not specified, a zero value will be assumed. +.\" +.IP "PASS_MAX_DAYS (number)" +The maximum number of days a password may be used. If the password is +older than this, then the account will be locked. If not specified, +a large value will be assumed. +.\" +.IP "PASS_MAX_LEN (number)" +XXX needs to be documented. +.\" +.IP "PASS_WARN_AGE (number)" +The number of days warning given before a password expires. A zero means +warning is given only upon the day of expiration, a negative value means +no warning is given. If not specified, no warning will be provided. +.\" +.IP "PORTTIME_CHECKS_ENAB (boolean)" +If +.I yes +and an +.I /etc/porttime +file exists, that file will be consulted to ensure the user may login +at this time on the given line. +c.f. +.BR porttime (5) +.\" +.IP "QMAIL_DIR (string)" +For Qmail users, this parameter specifies a directory where a Maildir +hierarchy is stored. +See MAIL_CHECK_ENAB for related information. +.\" +.IP "QUOTAS_ENAB (boolean)" +If +.I yes , +then the user's ``ulimit,'' ``umask,'' and ``niceness'' will be +initialized to the values if specified in the +.I gecos +field of the +.I passwd +file. +c.f. +.BR passwd (5). +.\" +.IP "SU_NAME (string)" +This parameter assigns a command name when ``su -'' is run. For +example, if the parameter is defined as ``su'', then a +.BR ps (1) +listing would show the command running as ``-su''. If this parameter +is undefined, then a +.BR ps (1) +listing would show the name of the actual shell being run, e.g. +something like ``-sh''. +.\" +.IP "SULOG_FILE (string)" +This parameter specifies a full pathname of a file in which +.B su +activity is logged. +If this parameter is not specified, the logging is suppressed. +Because the +.B su +command may be used when attempting to authenticate a password, +either this option, or +.I syslog +should be used to note +.B su +activity. See the SYSLOG_SU_ENAB option for related information. +.\" +.IP "SU_WHEEL_ONLY (boolean)" +XXX needs to be documented. +.\" +.IP "SYSLOG_SG_ENAB (boolean)" +XXX needs to be documented. +.\" +.IP "SYSLOG_SU_ENAB (boolean)" +If +.I yes +and +.B login +was compiled with +.I syslog +support, then all +.B su +activity will be noted through the +.I syslog +facility. +See SULOG_FILE for related information. +.\" +.IP "TTYGROUP (string or number)" +The group ownership of the terminal is initialized to this group +name or number. One well-known security attack involves forcing terminal +control sequences upon another user's terminal line. This problem +can be averted by disabling permissions which allow other users to +access the terminal line, but this unfortunately prevents programs +such as +.B write +from operating. Another solution is to use a version of the +.B write +program which filters out potentially dangerous character sequences, +make this program ``setgid'' to a special group, assign group ownership +of the terminal line to this special group, and assign permissions of +\fI0620\fR to the terminal line. The TTYGROUP definition has been +provided for just this situation. If this item is not defined, then +the group ownership of the terminal is initialized to the user's group +number. See TTYPERMS for related information. +.\" +.IP "TTYPERM (number)" +The login terminal permissions are initialized to this value. Typical +values will be \fI0622\fR to permit others write access to the line +or \fI0600\fR to secure the line from other users. If not specified, +the terminal permissions will be initialized to \fI0622\fR. See +TTYGROUP for related information. +.\" +.IP "TTYTYPE_FILE (string)" +This parameter specifies the full pathname to a file which maps terminal +lines to terminal types. Each line of the file contains a terminal +type and a terminal line, seperated by whitespace, for example: +.nf +.sp +.ft I + vt100\0 tty01 + wyse60 tty02 + \0\0.\0\0\0 \0\0. + \0\0.\0\0\0 \0\0. + \0\0.\0\0\0 \0\0. +.ft R +.sp +.fi +This information is only used to initialize the TERM environment parameter +when it does not already exist. +A line starting with a ``#'' pound sign will be treated as a comment. +If this paramter is not specified, the file does not exist, or the terminal +line is not found in the file, then the TERM environment parameter will not +be set. +.\" +.IP "UID_MAX (number)" +XXX needs to be documented. +.IP "UID_MIN (number)" +XXX needs to be documented. +.\" +.IP "ULIMIT (long number)" +The file size limit is initialized to this value. This is supported +only on systems with a +.IR ulimit , +e.g. System V. If not specified, the file size limit will be initialized +to some large value. +.\" +.IP "UMASK (number)" +The permission mask is initialized to this value. If not specified, +the permission mask will be initialized to zero. +.\" +.IP "USERDEL_CMD (string)" +XXX needs to be documented. +.\" +.SH CROSS REFERENCE +The following cross reference shows which programs in the shadow login +suite use which parameters. +.na +.IP login 12 +CONSOLE DIALUPS_CHECK_ENAB ENV_HZ ENV_SUPATH ENV_TZ ERASECHAR FAILLOG_ENAB +FTMP_FILE HUSHLOGIN_FILE KILLCHAR LASTLOG_ENAB LOG_UNKFAIL_ENAB +MAIL_CHECK_ENAB MAIL_DIR MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB +QUOTAS_ENAB TTYPERM TTYTYPE_FILE ULIMIT UMASK +.IP newusers 12 +PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE UMASK +.IP passwd 12 +OBSCURE_CHECKS_ENAB PASS_MIN_LEN +.IP pwconv 12 +PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE +.IP su 12 +ENV_HZ ENV_SUPATH ENV_TZ HUSHLOGIN_FILE MAIL_CHECK_ENAB MAIL_DIR +MOTD_FILE NOLOGIN_STR QUOTAS_ENAB SULOG_FILE SYSLOG_SU_ENAB +.IP sulogin 12 +ENV_HZ ENV_SUPATH ENV_TZ MAIL_DIR QUOTAS_ENAB TTYPERM +.ad +.SH BUGS +Some of the supported configuration parameters are not documented in this +manual page. +.SH SEE ALSO +.BR login (1), +.BR passwd (5), +.BR faillog (5), +.BR porttime (5), +.BR faillog (8) +.SH AUTHORS +Julianne Frances Haugh (jfh@austin.ibm.com) +.br +Chip Rosenthal (chip@unicom.com) diff --git a/current/man/logoutd.8 b/current/man/logoutd.8 new file mode 100644 index 00000000..b611d4f9 --- /dev/null +++ b/current/man/logoutd.8 @@ -0,0 +1,51 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: logoutd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH LOGOUTD 8 +.SH NAME +logoutd \- Enforce login time restrictions +.SH SYNOPSIS +.B logoutd +.SH DESCRIPTION +.B logoutd +enforces the login time and port restrictions specified in +.IR /etc/porttime . +.B logoutd +should be started from \fI/etc/rc\fR. +The \fI/etc/utmp\fR file is scanned periodically and each user name +is checked to see if the named user is permitted on the named port +at the current time. +Any login session which is violating the restrictions in \fI/etc/porttime\fR +is terminated. +.SH FILES +/etc/porttime \- login and port permissions +.br +/etc/utmp \- current login sessions +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/mkpasswd.8 b/current/man/mkpasswd.8 new file mode 100644 index 00000000..ad4ed796 --- /dev/null +++ b/current/man/mkpasswd.8 @@ -0,0 +1,81 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: mkpasswd.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH MKPASSWD 1 +.SH NAME +mkpasswd \- Update passwd and group database files +.SH SYNOPSIS +\fBmkpasswd\fR [\fB-fvgps\fR] \fIfile\fR +.SH DESCRIPTION +.B mkpasswd +reads the file in the format given by the flags and converts it to the +corresponding database file format. +These database files are used to improve access performance on systems +with large numbers of users. +The output files will be named \fIfile\fR.dir and \fIfile\fR.pag. +.PP +The \fB-f\fR option causes \fBmkpasswd\fR to ignore any existing output +files and overwrite them. +Normally \fBmkpasswd\fR complains about existing output files and quits. +.PP +The \fB-v\fR option causes \fBmkpasswd\fR to output information about +each record as it is converted, with a final message at the very end. +.PP +The \fB-g\fR option treats the input file as though it were in +\fI/etc/group\fR file format. +When combined with the \fB-s\fR option, the \fI/etc/gshadow\fR file +format is used instead. +.PP +The \fB-p\fR option treats the input file as though it were in +\fI/etc/passwd\fR file format. +This is the default. +When combined with the \fB-s\fR option, the \fI/etc/shadow\fR file +format is used instead. +.SH CAVEATS +The use of more than one database file is limited to systems which +include the NDBM database library and therefore may not be available +on every system. +.SH NOTE +Since most commands are capable of updating the database files as +changes are made, this command need only be used when re-creating a +deleted or corrupted database file. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- shadow user information +.br +/etc/group \- group information +.br +/etc/gshadow \- shadow group information +.SH SEE ALSO +.BR passwd (5), +.BR group (5), +.BR shadow (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/newgrp.1 b/current/man/newgrp.1 new file mode 100644 index 00000000..f3308357 --- /dev/null +++ b/current/man/newgrp.1 @@ -0,0 +1,80 @@ +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: newgrp.1,v 1.6 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH NEWGRP 1 +.SH NAME +newgrp \- Change group ID +.br +sg \- Execute command as different group ID +.SH SYNOPSIS +.BR newgrp " [" - ] +[\fIgroup\fR] +.br +.BR sg " [" - ] +[\fIgroup\fR [[\fB-c\fR] \fIcommand\fR]] +.SH DESCRIPTION +.B newgrp +is used to change the current group ID during a login session. +If the optional \fB\-\fR flag is given, the user's environment +will be reinitialized as though the user had logged in, otherwise +the current environment, including current working directory, +remains unchanged. +.PP +.B newgrp +changes the current real group ID to the named group, or to +the default group listed in \fI/etc/passwd\fR if no group name +is given. +The user will be prompted for a password if they do not have a +password and the group does, or if the user is not listed as a +member and the group has a password. +The user will be denied access if the group password is empty +and the user is not listed as a member. +.PP +The +.B sg +command works similiar to \fBnewgrp\fR but does not replace the +user's shell, so upon exit from a \fBsg\fR command, you are +returned to your previous group ID. +.B sg +also accepts a command. +The command will be executed with the Bourne shell and must be +enclosed in quotes. +.SH CAVEATS +This version of \fBnewgrp\fR has many compilation options, +only some of which may be in use at any particular site. +.SH FILES +/etc/passwd \- user account information +.br +/etc/group \- group information +.SH SEE ALSO +.BR login (1), +.BR id (1), +.BR su (1) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/newusers.8 b/current/man/newusers.8 new file mode 100644 index 00000000..447b8d91 --- /dev/null +++ b/current/man/newusers.8 @@ -0,0 +1,68 @@ +.\" Copyright 1991 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: newusers.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH NEWUSERS 8 +.SH NAME +\fBnewusers\fR - update and create new users in batch +.SH SYNOPSIS +\fBnewusers\fR [\fI new_users \fR] +.SH DESCRIPTION +\fBnewusers\fR reads a file of user name and cleartext password pairs +and uses this information to update a group of existing users or to +create new users. +Each line is in the same format as the standard password file (see +\fBpasswd\fR(5)) with the following exceptions. +.IP "\fIpw_passwd\fR" 10 +This field will be encrypted and used as the new value +of the encrpted password. +.IP "\fIpw_age\fR" +This field will be ignored for shadow passwords if the user already +exists. +.IP "\fIpw_gid\fR" +This field may be the name of an existing group, in which case the +named user will be added as a member. If a non-existent numerical +group is given, a new group will be created having this number. +.IP "\fIpw_dir\fR" +This field will be checked for existence as a directory and a new +directory with the same name will be created if it does not already exist. +The ownership of the directory will be set to be that of the user +being created or updated. +.PP +This command is intended to be used in a large system environment where +many accounts are updated at a single time. +.SH CAVEATS +.\" The \fImkpasswd\fR command must be executed afterwards to update the +.\" DBM password files. +The input file must be protected since it contains unencrypted passwords. +.SH SEE ALSO +.\" mkpasswd(8), passwd(1), useradd(1) +.BR passwd (1), +.BR useradd (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/passwd.1 b/current/man/passwd.1 new file mode 100644 index 00000000..8090db76 --- /dev/null +++ b/current/man/passwd.1 @@ -0,0 +1,190 @@ +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: passwd.1,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH PASSWD 1 +.SH NAME +passwd \- change user password +.SH SYNOPSIS +\fBpasswd\fR [\fB-f\fR|\fB-s\fR] [\fIname\fR] +.br +\fBpasswd\fR [\fB-g\fR] [\fB-r\fR|\fBR\fR] \fIgroup\fR +.br +\fBpasswd\fR [\fB-x\fR \fImax\fR] [\fB-n\fR \fImin\fR] +[\fB-w\fR \fIwarn\fR] [\fB-i\fR \fIinact\fR] \fIname\fR +.br +\fBpasswd\fR {\fB-l\fR|\fB-u\fR|\fB-d\fR|\fB-S\fR} \fIname\fR +.SH DESCRIPTION +\fBpasswd\fR changes passwords for user and group accounts. +A normal user may only change the password for their own account, +the super user may change the password for any account. +The administrator of a group may change the password for the group. +\fBpasswd\fR also changes account information, such as the full name +of the user, their login shell, or password expiry dates and intervals. +.SS Password Changes +The user is first prompted for their old password, +if one is present. +This password is then encrypted and compared against the +stored password. +The user has only one chance to enter the correct password. +The super user is permitted to bypass this step so that forgotten +passwords may be changed. +.PP +After the password has been entered, password aging information +is checked to see if the user is permitted to change their password +at this time. +If not, \fBpasswd\fR refuses to change the password and exits. +.PP +The user is then prompted for a replacement password. +This password is tested for complexity. +As a general guideline, +passwords should consist of 6 to 8 characters including +one or more from each of following sets: +.IP "" .5i +Lower case alphabetics +.IP "" .5i +Upper case alphabetics +.IP "" .5i +Digits 0 thru 9 +.IP "" .5i +Punctuation marks +.PP +Care must be taken not to include the system default erase +or kill characters. +\fBpasswd\fR will reject any password which is not suitably +complex. +.PP +If the password is accepted, +\fBpasswd\fR will prompt again and compare the second entry +against the first. +Both entries are require to match in order for the password +to be changed. +.SS Group passwords +When the \fB-g\fR option is used, the password for the named +group is changed. +The user must either be the super user, or a group administrator +for the named group. +The current group password is not prompted for. +The \fB-r\fR option is used with the \fB-g\fR option to remove +the current password from the named group. +This allows group access to all members. +The \fB-R\fR option is used with the \fB-g\fR option to restrict +the named group for all users. +.SS Password expiry information +The password aging information may be changed by the super +user with the \fB-x\fR, \fB-n\fR, \fB-w\fR, and \fB-i\fR options. +The \fB-x\fR option is used to set the maximum number of days +a password remains valid. +After \fImax\fR days, the password is required to be changed. +The \fB-n\fR option is used to set the minimum number of days +before a password may be changed. +The user will not be permitted to change the password until +\fImin\fR days have elapsed. +The \fB-w\fR option is used to set the number of days of warning +the user will receive before their password will expire. +The warning occurs \fIwarn\fR days before the expiration, telling +the user how many days until the password is set to expire. +The \fB-i\fR option is used to disable an account after the +password has been expired for a number of days. +After a user account has had an expired password for \fIinact\fR +days, the user may no longer sign on to the account. +.SS Account maintenance +User accounts may be locked and unlocked with the \fB-l\fR and +\fB-u\fR flags. +The \fB-l\fR option disables an account by changing the password to a +value which matches no possible encrypted value. +The \fB-u\fR option re-enables an account by changing the password +back to its previous value. +.PP +The account status may be given with the \fB-S\fR option. +The status information consists of 6 parts. +The first part indicates if the user account is locked (L), has no +password (NP), or has a usable password (P). +The second part gives the date of the last password change. +The next four parts are the minimum age, maximum age, warning period, +and inactivity period for the password. +.SS Hints for user passwords +The security of a password depends upon the strength of the +encryption algorithm and the size of the key space. +The \fB\s-2UNIX\s+2\fR System encryption method is based on +the NBS DES algorithm and is very secure. +The size of the key space depends upon the randomness of the +password which is selected. +.PP +Compromises in password security normally result from careless +password selection or handling. +For this reason, you should select a password which does not +appear in a dictionary or which must be written down. +The password should also not be a proper name, your license +number, birth date, or street address. +Any of these may be used as guesses to violate system security. +.PP +Your password must easily remembered so that you will not +be forced to write it on a piece of paper. +This can be accomplished by appending two small words together +and separating each with a special character or digit. +For example, Pass%word. +.PP +Other methods of construction involve selecting an easily +remembered phrase from literature and selecting the first +or last letter from each. +An example of this is +.IP "" .5i +Ask not for whom the bell tolls. +.PP +which produces +.IP "" .5i +An4wtbt. +.PP +You may be reasonably sure few crackers will have +included this in their dictionary. +You should, however, select your own methods for constructing +passwords and not rely exclusively on the methods given here. +.SS Notes about group passwords +Group passwords are an inherent security problem since more +than one person is permitted to know the password. +However, groups are a useful tool for permitting co-operation +between different users. +.SH CAVEATS +Not all options may be supported. +Password complexity checking may vary from site to site. +The user is urged to select as complex a password as they +feel comfortable with. +User's may not be able to change their password on a system if NIS +is enabled and they are not logged into the NIS server. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- encrypted user passwords +.SH SEE ALSO +.BR passwd (3), +.\" .BR shadow (3), +.BR group (5), +.BR passwd (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/passwd.5 b/current/man/passwd.5 new file mode 100644 index 00000000..3b21d092 --- /dev/null +++ b/current/man/passwd.5 @@ -0,0 +1,111 @@ +.\" Copyright 1989 - 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: passwd.5,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH PASSWD 5 +.SH NAME +passwd \- The password file +.SH DESCRIPTION +.I passwd +contains various pieces of information for each user account. +Included is +.IP "" .5i +Login name +.IP "" .5i +Optional encrypted password +.IP "" .5i +Numerical user ID +.IP "" .5i +Numerical group ID +.IP "" .5i +User name or comment field +.IP "" .5i +User home directory +.IP "" .5i +User command interpreter +.PP +The password field may not be filled if shadow passwords +have been enabled. +If shadow passwords are being used, the encrypted password will +be found in \fI/etc/shadow\fR. +The encryped password consists of 13 characters from the +64 character alphabet +a thru z, A thru Z, 0 thru 9, \. and /. +Refer to \fBcrypt\fR(3) for details on how this string is +interpreted. +.PP +An optional password age string may follow the encrypted +password, separated by a comma, from the same alphabet +as the password itself. +The first character gives the number of weeks during which the +password is valid. +The second character gives the number of weeks which must pass +before the user is permitted to change the password. +The last two characters give the week since Jan 1970 when the +password was last changed. +When the number of weeks during which the password is valid +have passed, the user will be required to provide a new +password. +.PP +The comment field is used by various system utilities, such as +\fBfinger\fR(1). +Three additional values may be present in the comment field. +They are +.IP "" .5i +pri= \- set initial value of nice +.IP "" .5i +umask= \- set initial value of umask +.IP "" .5i +ulimit= \- set initial value of ulimit +.PP +These fields are separated from each other and from any other +comment field by a comma. +.PP +The home directory field provides the name of the initial +working directory. +\fBLogin\fR uses this information to set the value of +the \fBHOME\fR environmental variable. +.PP +The command interpreter field provides the name of the user's +command language interpreter, or the name of the initial program +to execute. +\fBLogin\fR uses this information to set the value of the +\fBSHELL\fR environmental variable. +If this field is empty, it defaults to the value \fB/bin/sh\fR. +.SH FILES +/etc/passwd \- user account information +.SH SEE ALSO +.BR login (1), +.BR passwd (1), +.BR su (1), +.BR sulogin (8), +.BR shadow (5), +.BR pwconv (8), +.BR pwunconv (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/Makefile.am b/current/man/pl/Makefile.am new file mode 100644 index 00000000..2ef48e2c --- /dev/null +++ b/current/man/pl/Makefile.am @@ -0,0 +1,60 @@ +AUTOMAKE_OPTIONS = 1.0 foreign + +manpldir = $(mandir)/pl +manpl1dir = $(manpldir)/man1 +manpl3dir = $(manpldir)/man3 +manpl5dir = $(manpldir)/man5 +manpl8dir = $(manpldir)/man8 + + +manpl1_DATA = \ + chage.1 \ + chfn.1 \ + chsh.1 \ + groups.1 \ + gpasswd.1 \ + id.1 \ + login.1 \ + newgrp.1 \ + passwd.1 \ + su.1 + +manpl3_DATA = \ + pw_auth.3 \ + shadow.3 + +manpl5_DATA = \ + d_passwd.5 \ + dialups.5 \ + faillog.5 \ + limits.5 \ + login.access.5 \ + login.defs.5 \ + passwd.5 \ + porttime.5 \ + shadow.5 \ + suauth.5 + +manpl8_DATA = \ + chpasswd.8 \ + dpasswd.8 \ + faillog.8 \ + groupadd.8 \ + groupdel.8 \ + groupmod.8 \ + grpck.8 \ + lastlog.8 \ + logoutd.8 \ + mkpasswd.8 \ + newusers.8 \ + pwauth.8 \ + pwck.8 \ + pwconv.8 \ + shadowconfig.8 \ + sulogin.8 + useradd.8 \ + userdel.8 \ + usermod.8 \ + vipw.8 + +EXTRA_DIST = $(manpl1_DATA) $(manpl3_DATA) $(manpl5_DATA) $(manpl8_DATA) diff --git a/current/man/pl/Makefile.in b/current/man/pl/Makefile.in new file mode 100644 index 00000000..277746be --- /dev/null +++ b/current/man/pl/Makefile.in @@ -0,0 +1,316 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +manpldir = $(mandir)/pl +manpl1dir = $(manpldir)/man1 +manpl3dir = $(manpldir)/man3 +manpl5dir = $(manpldir)/man5 +manpl8dir = $(manpldir)/man8 + +manpl1_DATA = chage.1 chfn.1 chsh.1 groups.1 gpasswd.1 id.1 login.1 newgrp.1 passwd.1 su.1 + + +manpl3_DATA = pw_auth.3 shadow.3 + + +manpl5_DATA = d_passwd.5 dialups.5 faillog.5 limits.5 login.access.5 login.defs.5 passwd.5 porttime.5 shadow.5 suauth.5 + + +manpl8_DATA = chpasswd.8 dpasswd.8 faillog.8 groupadd.8 groupdel.8 groupmod.8 grpck.8 lastlog.8 logoutd.8 mkpasswd.8 newusers.8 pwauth.8 pwck.8 pwconv.8 shadowconfig.8 sulogin.8 + + +EXTRA_DIST = $(manpl1_DATA) $(manpl3_DATA) $(manpl5_DATA) $(manpl8_DATA) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +DATA = $(manpl1_DATA) $(manpl3_DATA) $(manpl5_DATA) $(manpl8_DATA) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps man/pl/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-manpl1DATA: $(manpl1_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(manpl1dir) + @list='$(manpl1_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl1dir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl1dir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl1dir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(manpl1dir)/$$p; \ + fi; fi; \ + done + +uninstall-manpl1DATA: + @$(NORMAL_UNINSTALL) + list='$(manpl1_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(manpl1dir)/$$p; \ + done + +install-manpl3DATA: $(manpl3_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(manpl3dir) + @list='$(manpl3_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl3dir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl3dir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl3dir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(manpl3dir)/$$p; \ + fi; fi; \ + done + +uninstall-manpl3DATA: + @$(NORMAL_UNINSTALL) + list='$(manpl3_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(manpl3dir)/$$p; \ + done + +install-manpl5DATA: $(manpl5_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(manpl5dir) + @list='$(manpl5_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl5dir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl5dir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl5dir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(manpl5dir)/$$p; \ + fi; fi; \ + done + +uninstall-manpl5DATA: + @$(NORMAL_UNINSTALL) + list='$(manpl5_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(manpl5dir)/$$p; \ + done + +install-manpl8DATA: $(manpl8_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(manpl8dir) + @list='$(manpl8_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl8dir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(manpl8dir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(manpl8dir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(manpl8dir)/$$p; \ + fi; fi; \ + done + +uninstall-manpl8DATA: + @$(NORMAL_UNINSTALL) + list='$(manpl8_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(manpl8dir)/$$p; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = man/pl + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-manpl1DATA install-manpl3DATA \ + install-manpl5DATA install-manpl8DATA +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-manpl1DATA uninstall-manpl3DATA \ + uninstall-manpl5DATA uninstall-manpl8DATA +uninstall: uninstall-am +all-am: Makefile $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(manpl1dir) $(DESTDIR)$(manpl3dir) \ + $(DESTDIR)$(manpl5dir) $(DESTDIR)$(manpl8dir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: uninstall-manpl1DATA install-manpl1DATA uninstall-manpl3DATA \ +install-manpl3DATA uninstall-manpl5DATA install-manpl5DATA \ +uninstall-manpl8DATA install-manpl8DATA tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + useradd.8 \ + userdel.8 \ + usermod.8 \ + vipw.8 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/man/pl/chage.1 b/current/man/pl/chage.1 new file mode 100644 index 00000000..48f1c879 --- /dev/null +++ b/current/man/pl/chage.1 @@ -0,0 +1,110 @@ +.\" {PTM/WK/1999-09-16} +.\" Copyright 1990 - 1994 Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH CHAGE 1 +.SH NAZWA +chage \- zmieñ informacjê o terminie wa¿no¶ci has³a u¿ytkownika +.SH SK£ADNIA +.TP 6 +.B chage +.RB [ -m +.IR mindni ] +.RB [ -M +.IR maxdni ] +.RB [ -d +.IR ostatni ] +.RB [ -I +.IR nieaktywne ] +.br +.RB [ -E +.IR data_wa¿no¶ci ] +.RB [ -W +.IR dni_ostrzegania ] +.I u¿ytkownik +.TP 6 +.B chage -l \fIu¿ytkownik\fR +.SH OPIS +\fBchage\fR zmienia liczbê dni pomiêdzy zmianami has³a i datê ostatniej +zmiany has³a. Informacjê tê system wykorzystuje do ustalenia, kiedy +u¿ytkownik musi zmieniæ has³o. +Polecenia \fBchage\fR mo¿e u¿yæ tylko u¿ytkownik root, za wyj±tkiem +opcji \fB-l\fR. Mo¿e siê ni± pos³u¿yæ siê u¿ytkownik nieuprzywilejowany +do stwierdzenia, kiedy wygasa jego w³asne has³o lub konto. +.PP +Opcja \fB-m\fR ustawia minimaln± liczbê dni pomiêdzy zmianami has³a +na warto¶æ \fImindni\fR. Warto¶æ zerowa oznacza, ¿e u¿ytkownik mo¿e je zmieniaæ +w dowolnym czasie. +.PP +Opcja \fB-M\fR ustawia maksymaln± liczbê dni, przez jakie has³o jest wa¿ne +na warto¶æ \fImaxdni\fR. +Gdy \fImaxdni\fR plus \fIostatni\fR jest mniejsze ni¿ bie¿±cy dzieñ, +od u¿ytkownika wymagana jest zmiana has³a przed skorzystaniem z konta. +Zdarzenie to mo¿e byæ zaplanowane z wyprzedzeniem przez wykorzystanie +opcji \fB-W\fR, ostrzegaj±cej zawczasu u¿ytkownika o zbli¿aj±cym siê terminie +zmiany. +.PP +Opcja \fB-d\fR ustawia liczbê dni od 1 stycznia 1970 do dnia kiedy ostatnio +zmieniono has³o na \fIostatni\fR. Data mo¿e równie¿ zostaæ podana w postaci +RRRR-MM-DD (lub postaci powszechniej u¿ywanej w twoim regionie). +.PP +Opcja \fB-E\fR s³u¿y do ustawiania daty, od której konto u¿ytkownika +nie bêdzie ju¿ dostêpne. +\fIdata_wa¿no¶ci\fR jest liczb± dni od 1 stycznia 1970, od której konto jest +blokowane. Data mo¿e byæ te¿ wyra¿ona w postaci RRRR-MM-DD (lub innej, +powszechniej u¿ywanej w twoim regionie). +U¿ytkownik, którego konto jest zablokowane musi skontaktowaæ siê +z administratorem systemu zanim bêdzie móg³ z niego ponownie skorzystaæ. +.PP +Opcja \fB-I\fR s³u¿y do ustawiania czasu nieaktywno¶ci po wyga¶niêciu +has³a, po którym konto jest blokowane. Parametr \fInieaktywne\fR podaje +liczbê dni nieaktywno¶ci. Warto¶æ 0 wy³±cza tê funkcjê. +U¿ytkownik, którego konto jest zablokowane musi skontaktowaæ siê +z administratorem systemu zanim bêdzie móg³ z niego ponownie skorzystaæ. +.PP +Opcja \fB-W\fR s³u¿y do ustawiania ostrzegania przed wymagan± zmian± has³a. +Parametr \fIdni_ostrzegania\fR jest liczb± dni przed up³ywem wa¿no¶ci has³a; +od tego dnia u¿ytkownik bêdzie ostrzegany o nadchodz±cym terminie. +.PP +Wszystkie powy¿sze warto¶ci przechowywane s± jako liczba dni, je¿eli u¿ywany +jest dodatkowy, przes³aniany plik hase³ (shadow). Jednak je¿eli u¿ywany jest +standardowy plik hase³, to s± one zamieniane (w obie strony) na liczbê tygodni. +Z powodu powy¿szej konwersji mog± pojawiæ siê b³êdy zaokr±gleñ. +.PP +Je¶li nie podano ¿adnej opcji, to \fBchage\fR dzia³a w trybie interaktywnym, +proponuj±c u¿ytkownikowi warto¶ci bie¿±ce dla ka¿dego z pól. Wprowad¼ now± +warto¶æ by zmieniæ pole, lub pozostaw pust± by u¿yæ warto¶ci bie¿±cej. +Bie¿±ca warto¶æ pola wy¶wietlana jest miêdzy par± znaczników \fB[ ]\fR. +.SH PLIKI +.IR /etc/passwd " - informacje o kontach u¿ytkowników" +.br +.IR /etc/shadow " - chronione informacje o kontach u¿ytkowników" +.SH ZOBACZ TAK¯E +.BR passwd (5), +.BR shadow (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/chfn.1 b/current/man/pl/chfn.1 new file mode 100644 index 00000000..8b254764 --- /dev/null +++ b/current/man/pl/chfn.1 @@ -0,0 +1,77 @@ +.\" {PTM/WK/1999-09-25} +.\" Copyright 1990 - 1994 Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH CHFN 1 +.SH NAZWA +chfn \- zmieñ nazwê u¿ytkownika i informacjê o nim +.SH SK£ADNIA +.TP 5 +.B chfn +.RB [ -f +.IR pe³na_nazwa ] +.RB [ -r +.IR nr_pokoju ] +.br +.RB [ -w +.IR tel_s³u¿b ] +.RB [ -h +.IR tel_dom ] +.RB [ -o +.IR inne ] +.RI [ u¿ytkownik ] +.SH OPIS +\fBchfn\fR zmienia pe³n± nazwê (imiê i nazwisko), telefon s³u¿bowy i domowy +dla danego konta u¿ytkownika. Informacja ta jest zwykle drukowana przez +\fBfinger\fR(1) i podobne mu programy. +Zwyk³y u¿ytkownik mo¿e zmieniaæ wy³±cznie pola opisuj±ce w³asne konto. +Tylko superu¿ytkownik mo¿e zmieniaæ pola dowolnego konta. +Równie¿ tylko on mo¿e pos³u¿yæ siê opcj± \fB-o\fR by zmieniæ niezdefiniowane +czê¶ci pola GECOS. +.PP +Jedynym ograniczeniem nak³adanym na zawarto¶æ pól jest zakaz u¿ywania w nich +znaków kontrolnych oraz przecinka, dwukropka i znaku równo¶ci. +Pola \fIinne\fR (other) nie obowi±zuje to ograniczenie. Pole to s³u¿y do +przechowywania informacji rozliczeniowej u¿ywanej przez inne aplikacje. +.PP +Je¶li nie wybrano ¿adnej z opcji, to \fBchfn\fR dzia³a w trybie interaktywnym, +proponuj±c u¿ytkownikowi warto¶ci bie¿±ce dla ka¿dego z pól. Wprowad¼ now± +warto¶æ by zmieniæ pole, lub pozostaw pust± by u¿yæ warto¶ci bie¿±cej. +Bie¿±ca warto¶æ pola wy¶wietlana jest miêdzy par± znaczników \fB[ ]\fR. +Bez podania opcji \fBchfn\fR pyta o konto u¿ytkownika, które ma podlegaæ +zmianie. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.SH ZOBACZ TAK¯E +.BR passwd (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz +z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/chpasswd.8 b/current/man/pl/chpasswd.8 new file mode 100644 index 00000000..eea01899 --- /dev/null +++ b/current/man/pl/chpasswd.8 @@ -0,0 +1,62 @@ +.\" {PTM/WK/1999-09-16} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH CHPASSWD 8 +.SH NAZWA +chpasswd - wsadowa aktualizacja pliku hase³ +.SH SK£ADNIA +.B chpasswd +.RB [ -e ] +.SH OPIS +\fBchpasswd\fR odczytuje ze standardowego wej¶cia plik zawieraj±cy pary: +nazwa u¿ytkownika i has³o. Odczytan± informacje wykorzystuje do aktualizacji +grupy istniej±cych u¿ytkowników. +Bez prze³±cznika -e, has³a traktowane s± jako podane jawnie. Z prze³±cznikiem +-e has³a powinny byæ dostarczone w postaci zakodowanej (encrypted). +Ka¿dy wiersz ma postaæ +.sp 1 + \fInazwa_U¿ytkownika\fR:\fIhas³o\fR +.sp 1 +Dany u¿ytkownik musi istnieæ. +Je¿eli bêdzie to konieczne, podane has³o zostanie zakodowane a wiek has³a, +je¶li wystêpuje, zaktualizowany. +.PP +Polecenie to przeznaczone jest do u¿ytku w du¿ych systemach, gdzie aktualizuje +siê wiele kont naraz. +.SH PRZESTROGI +.\" Po u¿yciu \fBchpasswd\fR musi zostaæ wykonane polecenie \fImkpasswd\fR, +.\" aktualizuj±ce pliki DBM hase³ (DBM password files). +Plik ¼ród³owy, je¶li zawiera niezakodowane has³a, musi byæ chroniony. +.\" Polecenie to mo¿e byæ zaniechane na rzecz polecenia newusers(8). +.SH ZOBACZ TAK¯E +.\" mkpasswd(8), passwd(1), useradd(1) +.BR passwd (1), +.BR useradd (8), +.BR newusers (8) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/chsh.1 b/current/man/pl/chsh.1 new file mode 100644 index 00000000..7f20e865 --- /dev/null +++ b/current/man/pl/chsh.1 @@ -0,0 +1,70 @@ +.\" {PTM/WK/1999-09-25} +.\" Copyright 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH CHSH 1 +.SH NAZWA +chsh \- zmieñ pow³okê zg³oszeniow± +.SH SK£ADNIA +.TP 5 +.B chsh +.RB [ -s +.IR pow³oka ] +.RI [ u¿ytkownik ] +.SH OPIS +\fBchsh\fR zmienia pow³okê zg³oszeniow± u¿ytkownika. +Okre¶la nazwê pocz±tkowego polecenia zg³oszeniowego u¿ytkownika. +Zwyk³y u¿ytkownik mo¿e zmieniæ wy³±cznie pow³okê zg³oszeniow± w³asnego konta, +superu¿ytkownik mo¿e zmieniæ pow³okê zg³oszeniow± dla dowolnego konta. +.PP +Jedynym ograniczeniem na³o¿onym na pow³okê zg³oszeniow± jest to, ¿e jej nazwa +musi byæ ujêta w \fI/etc/shells\fR, chyba ¿e polecenie \fBchsh\fR wywo³ywane +jest przez superu¿ytkownika, wówczas mo¿e byæ podana nazwa dowolnego polecenia. +U¿ytkownicy kont z ograniczon± pow³ok± logowania nie mog± jej zmieniaæ. +Odradza siê z tego powodu umieszczanie \fB/bin/rsh\fR w pliku \fI/etc/shells\fR, +gdy¿ przypadkowa zmiana na pow³okê ograniczon± uniemo¿liwi u¿ytkownikowi +jak±kolwiek zmianê pow³oki logowania, nawet z powrotem na dotychczasow±. +.PP +je¿eli nie podano opcji \fB-s\fR, to \fBchsh\fR dzia³a w trybie interaktywnym, +proponuj±c u¿ytkownikowi bie¿±c± pow³okê logowania. Wprowad¼ now± warto¶æ +do pola lub pozostaw je puste, by pozostawiæ aktualn± warto¶æ. +Bie¿±ca warto¶æ wy¶wietlana jest pomiêdzy par± znaczników \fB[ ]\fR. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/shells " - lista dozwolonych pow³ok zg³oszeniowych" +.SH ZOBACZ TAK¯E +.BR chfn (1), +.BR passwd (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Istnieje wiele programów i skryptów do zarz±dzania kontami +u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij +siê, ¿e korzystasz z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/d_passwd.5 b/current/man/pl/d_passwd.5 new file mode 100644 index 00000000..0b3989b2 --- /dev/null +++ b/current/man/pl/d_passwd.5 @@ -0,0 +1,30 @@ +.\" +.\" {PTM/WK/1999-09-22} +.\" +.TH D_PASSWD 5 +.SH NAZWA +d_passwd - plik hase³ telefonicznych +.SH OPIS +Z dostêpem do systemu przez liniê telefoniczn± zwi±zane s± dwa pliki +konfiguracyjne: \fI/etc/d_passwd\fR, zawieraj±cy has³a i \fI/etc/dialups\fR, +zawieraj±cy linie. +Ka¿dorazowo, zanim u¿ytkownik ³±cz±cy siê za po¶rednictwem modemu otrzyma +dostêp do systemu, musi podaæ has³o telefoniczne. Has³a te s± niezale¿ne +od hase³ u¿ytkowników i przypisane nie do u¿ytkownika, ani linii terminalowej, +lecz do pow³oki zg³oszeniowej u¿ytkownika. +Do rozpoczêcia sesji wymagane jest zarówno has³o u¿ytkownika jak +i telefoniczne. Zauwa¿ jednak, ¿e has³a telefoniczne nie posiadaj± kontroli +terminu wa¿no¶ci. Nale¿y, po uzgodnieniu, okresowo zmieniaæ je rêcznie. +W pliku \fId_passwd\fR kolejne wiersze definiuj± has³a dla rozmaitych pow³ok: +.br +.sp 1 + pow³oka:zakodowane_has³o: +.br +.sp 1 +Zauwa¿, ¿e po polu has³a wystêpuje dwukropek. Pow³oka powinna byæ +okre¶lona przez bezwzglêdn± nazwê ¶cie¿kow± pliku interpretatora poleceñ. +Do zarz±dzania has³ami telefonicznymi s³u¿y polecenie \fBdpasswd\fR (1). +.SH ZOBACZ TAK¯E +.BR dpasswd (1), +.BR login (1), +.BR dialups (5). diff --git a/current/man/pl/dialups.5 b/current/man/pl/dialups.5 new file mode 100644 index 00000000..3edb8a2c --- /dev/null +++ b/current/man/pl/dialups.5 @@ -0,0 +1,24 @@ +.\" +.\" {PTM/WK/1999-09-22} +.\" +.TH DIALUPS +.SH NAZWA +dialups - plik terminalowych linii telefonicznych +.SH OPIS +Z dostêpem do systemu przez liniê telefoniczn± zwi±zane s± dwa pliki +konfiguracyjne: \fI/etc/d_passwd\fR, zawieraj±cy has³a i \fI/etc/dialups\fR, +zawieraj±cy linie. W ka¿dym wierszu pliku \fIdialups\fR zawarta jest nazwa +pliku specjalnego linii terminalowej, do której pod³±czony jest modem: +.br +.sp 1 + /dev/tty12 + /dev/tty13 +.br +.sp 1 +Warto jest uj±æ w nim \fBwszystkie\fR linie z dostêpem modemowym. +Po³±czenie z linii pominiêtej nie bêdzie dodatkowo weryfikowane - u¿ytkownicy +³±cz±cy siê ni± nie bêd± musieli podawaæ has³a telefonicznego. +.SH ZOBACZ TAK¯E +.BR dpasswd (1), +.BR login (1), +.BR d_passwd (5). diff --git a/current/man/pl/dpasswd.8 b/current/man/pl/dpasswd.8 new file mode 100644 index 00000000..b5cf5624 --- /dev/null +++ b/current/man/pl/dpasswd.8 @@ -0,0 +1,56 @@ +.\" {PTM/WK/1999-09-17} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH DPASSWD 8 +.SH NAZWA +\fBdpasswd\fR - zmieñ has³o telefoniczne +.SH SK£ADNIA +.B dpasswd +.RB [ - ( a | d )] +.I pow³oka +.SH OPIS +\fBdpasswd\fR dodaje, usuwa i aktualizuje has³a telefoniczne (dialup +passwords) dla pow³ok logowania u¿ytkowników. +Ka¿dorazowo, gdy u¿ytkownik loguje siê przez liniê telefoniczn±, +¿±dane jest od niego has³o telefoniczne (po poprawnym uwierzytelnieniu +jego w³asnego has³a). +.PP +\fBdpasswd\fR bêdzie prosiæ o podanie nowego has³a dwukrotnie, by upewniæ +siê, ¿e zosta³o ono poprawnie wprowadzone. +.PP +Argument \fIpow³oka\fR musi byæ pe³n±, ¶cie¿kow± nazw± programu zg³oszenia +(logowania). +.SH PLIKI +.br +.I /etc/d_passwd +.br +.I /etc/dialups +.SH ZOBACZ TAK¯E +.BR login (1) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/faillog.5 b/current/man/pl/faillog.5 new file mode 100644 index 00000000..6fc16cdf --- /dev/null +++ b/current/man/pl/faillog.5 @@ -0,0 +1,59 @@ +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" Translation (c) 1998 "Gwidon S. Naskrent" +.\" $Id: faillog.5,v 1.3 1999/09/20 20:56:42 wojtek2 Exp $ +.\" +.TH faillog 5 +.SH NAZWA +faillog \- plik rejestruj±cy nieudane zalogowania +.SH OPIS +.I faillog +prowadzi licznik nieudanych zalogowañ i limity dla ka¿dego konta. +Plik ten sk³ada siê z rekordów o sta³ej d³ugo¶ci, indeksowanych +liczbowym UID. Ka¿dy rekord zawiera licznik nieudanych zalogowañ +od ostatniego pomy¶lnego logowania, maksymaln± liczbê pomy³ek +przed zablokowaniem konta, konsolê na której nast±pi³o ostatnie +nieudane logowanie, oraz datê tego¿. +.PP +Struktura tego pliku to +.DS + + struct faillog { + short fail_cnt; + short fail_max; + char fail_line[12]; + time_t fail_time; + }; + +.DE +.SH PLIKI +.IR /var/log/faillog " - rejestr nieudanych zalogowañ" +.SH ZOBACZ TAK¯E +.BR faillog (8) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/faillog.8 b/current/man/pl/faillog.8 new file mode 100644 index 00000000..a180cc4b --- /dev/null +++ b/current/man/pl/faillog.8 @@ -0,0 +1,95 @@ +.\" {PTM/WK/1999-09-18} +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH FAILLOG 8 +.SH NAZWA +faillog \- sprawd¼ faillog i ustaw limity b³êdnych logowañ +.SH SK£ADNIA +.TP 8 +.B faillog +.RB [ -u +.IR nazwa ] +.RB [ -a ] +.RB [ -t +.IR dni ] +.RB [ -m +.IR max ] +.RB [ -pr ] +.SH OPIS +\fBfaillog\fR formatuje zawarto¶æ rejestru nieudanych prób rozpoczêcia sesji, +\fI/var/log/faillog\fR, oraz obs³uguje ograniczenia i liczniki b³êdnych prób. +Kolejno¶æ argumentów \fBfaillog\fR jest znacz±ca. Ka¿dy z argumentów jest +natychmiast przetwarzany w zadanej kolejno¶ci. +.PP +Flaga \fB-p\fR powoduje, ¿e zapisy o nieudanych logowaniach wy¶wietlane bêd± +w kolejno¶ci rosn±cych identyfikatorów u¿ytkowników (UID). +Pos³u¿enie siê flag± \fB-u \fInazwa\fR spowoduje, ¿e zostanie wy¶wietlony +wy³±cznie zapis dotycz±cy u¿ytkownika o tej \fInazwie\fR. +U¿ycie \fB-t \fIdni\fR powoduje wy¶wietlanie wy³±cznie nieudanych prób +logowania ¶wie¿szych ni¿ sprzed zadanej liczby \fIdni\fR. +Flaga \fB-t\fR uniewa¿nia u¿ycie \fB-u\fR. +Flaga \fB-a\fR powoduje wybranie wszystkich u¿ytkowników. +W po³±czeniu z flag± \fB-p\fR flag, opcja ta wybiera wszystkich u¿ytkowników, +dla których kiedykolwiek odnotowano niepomy¶ln± próbê logowania. +Opcja ta nie ma znaczenia w po³±czeniu z flag± \fB-r\fR. +.PP +\fB-r\fR s³u¿y do zerowania licznika b³êdnych logowañ. Do poprawnego dzia³ania +tej opcji wymagane jest prawo zapisu do \fI/var/log/faillog\fR. +W po³±czeniu z \fB-u \fInazwa\fR s³u¿y do zerowania licznika b³êdów u¿ytkownika +o podanej \fInazwie\fR. +.PP +Flaga \fB-m\fR ustawia maksymaln± liczbê b³êdów logowania, po której konto +zostanie wy³±czone. Dla tej opcji wymagane jest prawo zapisu do +\fI/var/log/faillog\fR. +Argumenty \fB-m \fImax\fR powoduj±, ¿e wszystkie konta bêd± wy³±czane po +\fImax\fR nieudanych próbach logowania. +U¿ycie dodatkowo \fB-u \fInazwa\fR, ogranicza dzia³anie tej funkcji do +u¿ytkownika o podanej \fInazwie\fR. +Pos³u¿enie siê zerow± warto¶ci± \fImax\fR powoduje, ¿e liczba nieudanych prób +rozpoczêcia sesji jest nieograniczona. +Dla u¿ytkownika \fBroot\fR maksymalna liczba niepowodzeñ powinna byæ zawsze +ustawiona na 0, by zapobiec atakom typu denial of service (odmowa obs³ugi). +.PP +Opcje mog± byæ ³±czone w praktycznie dowolny sposób. Ka¿da z opcji \fB-p\fR, +\fB-r\fR i \fB-m\fR powoduje natychmiastowe wykonanie przy u¿yciu modyfikatora +\fB-u\fR lub \fB-t\fR. +.SH PRZESTROGI +\fBfaillog\fR wy¶wietla wy³±cznie u¿ytkowników, którzy od ostatniej nieudanej +próby nie mieli poprawnych logowañ. +Chc±c wy¶wietliæ u¿ytkownika, który po ostatniej pora¿ce logowa³ siê ju¿ +pomy¶lnie, musisz jawnie za¿±daæ o nim informacji przy pomocy flagi \fB-u\fR. +Mo¿esz tak¿e wy¶wietliæ wszystkich u¿ytkowników pos³uguj±c siê flag± \fB-a\fR. +.PP +W niektórych systemach zamiast /var/log wystêpuje /var/adm lub /usr/adm. +.SH PLIKI +.IR /var/log/faillog " - plik rejestracji b³êdów logowania" +.SH ZOBACZ TAK¯E +.BR login (1), +.BR faillog (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/gpasswd.1 b/current/man/pl/gpasswd.1 new file mode 100644 index 00000000..17f5e4ba --- /dev/null +++ b/current/man/pl/gpasswd.1 @@ -0,0 +1,65 @@ +.\" {PTM/WK/1999-09-16} +.\" Copyright 1996, Rafal Maszkowski, rzm@pdi.net +.\" All rights reserved. You can redistribute this man page and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of the +.\" License, or (at your option) any later version. +.\" +.TH GPASSWD 1 +.SH NAZWA +gpasswd \- administracja plikiem /etc/group +.br +.SH SK£ADNIA +.B gpasswd \fIgrupa\fR +.br +.B gpasswd -a +.I u¿ytkownik grupa +.br +.B gpasswd -d +.I u¿ytkownik grupa +.br +.B gpasswd -R +.I grupa +.br +.B gpasswd -r +.I grupa +.br +.B gpasswd +.RB [ -A +.IR u¿ytkownik ,...] +.RB [ -M +.IR u¿ytkownik ,...] +.I grupa +.SH OPIS +.B gpasswd +s³u¿y do administrowania plikiem \fI/etc/group\fR (oraz \fI/etc/gshadow\fR +je¶li zosta³a wykonana kompilacja ze zdefiniowanym SHADOWGRP). Ka¿da z grup +mo¿e posiadaæ administratorów, cz³onków i has³o. Administrator systemu mo¿e +pos³u¿yæ siê opcj± \fB-A\fR do zdefiniowania administratora(ów) grupy oraz +opcj± \fB-M\fR do zdefiniowania jej cz³onków. Posiada on wszystkie prawa +administratorów i cz³onków grup. +.PP +Administrator grupy mo¿e dodawaæ i usuwaæ u¿ytkowników przy pomocy, +odpowiednio, opcji \fB-a\fR i \fB-d\fR. Administratorzy mog± te¿ u¿ywaæ opcji +\fB-r\fR w celu usuniêcia has³a grupy. Je¿eli grupa nie posiada has³a, +to polecenia +.BR newgrp (1) +do przy³±czenia siê do grupy mog± u¿ywaæ tylko jej cz³onkowie. +Opcja \fB-R\fR wy³±cza dostêp do grupy za pomoc± polecenia +.BR newgrp (1). +.PP +.B gpasswd +wywo³ane przez administratora grupy tylko z nazw± grupy pyta o jej has³o. +Je¿eli has³o jest ustawione, to cz³onkowie grupy mog± nadal wykonywaæ +.BR newgrp (1) +bez has³a, inni musz± natomiast podaæ has³o. +.SH PLIKI +.IR /etc/group " - informacja o grupach" +.br +.IR /etc/gshadow " - chroniona informacja o grupach" +.SH ZOBACZ TAK¯E +.BR newgrp (1), +.BR groupadd (8), +.BR groupdel (8), +.BR groupmod (8), +.BR grpck (8) diff --git a/current/man/pl/groupadd.8 b/current/man/pl/groupadd.8 new file mode 100644 index 00000000..e80b4bd0 --- /dev/null +++ b/current/man/pl/groupadd.8 @@ -0,0 +1,72 @@ +.\" {PTM/WK/0.1/VIII-1999} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: groupadd.8,v 1.1 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GROUPADD 8 +.SH NAZWA +groupadd - twórz now± grupê +.SH SK£ADNIA +.B groupadd +.RB [ -g +.I gid +.RB [ -o ]] +.I grupa +.SH OPIS +Polecenie \fBgroupadd\fR tworzy nowe konto grupy pos³uguj±c siê +warto¶ciami podanymi w wierszu poleceñ i domy¶lnymi warto¶ciami z systemu. +W razie potrzeby zostanie wprowadzona do systemu nowa grupa. +Polecenie \fBgroupadd\fR posiada opcje: +.TP +.BI -g " gid" +Numeryczna warto¶æ identyfikatora grupy. Warto¶æ ta musi byæ niepowtarzalna, +chyba ¿e u¿yto opcji \fB-o\fR. Warto¶æ ID grupy nie mo¿e byæ ujemna. Domy¶lnie +u¿ywana jest najmniejsza warto¶æ identyfikatora wiêksza ni¿ 99 a wiêksza ni¿ +jakiejkolwiek innej grupy. +Warto¶ci miêdzy 0 a 99 s± zwykle zarezerwowane dla kont systemowych. +.SH PLIKI +.IR /etc/group " - informacja o kontach grup" +.br +.IR /etc/gshadow " - bezpieczna informacja o kontach grup" +.SH ZOBACZ TAK¯E +.BR chfn (1), +.BR chsh (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR passwd (1), +.BR groupdel (8), +.BR groupmod (8). +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Istnieje wiele programów i skryptów do zarz±dzania kontami +u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij +siê, ¿e korzystasz z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/groupdel.8 b/current/man/pl/groupdel.8 new file mode 100644 index 00000000..24cd254e --- /dev/null +++ b/current/man/pl/groupdel.8 @@ -0,0 +1,68 @@ +.\" {PTM/WK/0.1/VIII-1999} +.\" Copyright 1991 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: groupdel.8,v 1.1 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GROUPDEL 8 +.SH NAZWA +groupdel - usuñ grupê +.SH SK£ADNIA +.B groupdel +.I grupa +.SH OPIS +Polecenie \fBgroupdel\fR zmienia systemowe pliki kont, usuwaj±c +wszystkie zapisy odnosz±ce siê do \fIgrupy\fR. +Wymieniona grupa musi istnieæ. +.PP +Musisz rêcznie sprawdziæ wszystkie systemy plików, by upewniæ siê, ¿e +nie pozosta³y ¿adne pliki, dla których wymieniona grupa jest grup± w³a¶cicieli. +.SH PRZESTROGI +Nie mo¿esz usun±æ podstawowej grupy ¿adnego z istniej±cych u¿ytkowników. +Musisz usun±æ u¿ytkownika przed usuniêciem takiej grupy. +.SH PLIKI +.IR /etc/group " - informacja o grupach" +.br +.IR /etc/gshadow " - bezpieczna informacja o grupach" +.\" secure group information +.SH ZOBACZ TAK¯E +.BR chfn (1), +.BR chsh (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR passwd (1), +.BR groupadd (8), +.BR groupmod (8). +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Istnieje wiele programów i skryptów do zarz±dzania kontami +u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij +siê, ¿e korzystasz z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/groupmod.8 b/current/man/pl/groupmod.8 new file mode 100644 index 00000000..bead76d1 --- /dev/null +++ b/current/man/pl/groupmod.8 @@ -0,0 +1,77 @@ +.\" {PTM/WK/0.1/VIII-1999} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: groupmod.8,v 1.1 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH GROUPMOD 8 +.SH NAZWA +groupmod - zmieñ dane grupy +.SH SK£ADNIA +.B groupmod +.RB [ -g +.I gid +.RB [ -o ]] +.RB [ -n +.IR nazwa_grupy ] +.I grupa +.SH OPIS +Polecenie \fBgroupmod\fR modyfikuje systemowe pliki kont tak, by +odzwierciedliæ w nich zmiany grup podane w wierszu poleceñ. Obs³uguje ono +nastêpuj±ce opcje: +.TP +.BI -g " gid" +Numeryczna warto¶æ identyfikatora grupy (group ID). +Warto¶æ ta musi byæ niepowtarzalna, chyba ¿e u¿yto opcji \fB-o\fR. +Nie mo¿e byæ ujemna. Warto¶ci pomiêdzy 0 a 99 s± zwykle zarezerwowane +dla grup systemowych. +Pliki, dla których stary identyfikator jest identyfikatorem +grupy pliku, wymagaj± rêcznej zmiany ID grupy. +.TP +.BI -n " nazwa_grupy" +Nazwa grupy zostanie zmieniona z \fIgrupa\fR na \fInazwa_grupy\fR. +.SH PLIKI +.IR /etc/group " - informacja o grupach" +.br +.IR /etc/gshadow " - bezpieczna informacja o grupach" +.SH ZOBACZ TAK¯E +.BR chfn (1), +.BR chsh (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR passwd (1), +.BR groupadd (8), +.BR groupdel (8). +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Istnieje wiele programów i skryptów do zarz±dzania kontami +u¿ytkowników czy grup. Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij +siê, ¿e korzystasz z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/groups.1 b/current/man/pl/groups.1 new file mode 100644 index 00000000..6903d6cd --- /dev/null +++ b/current/man/pl/groups.1 @@ -0,0 +1,61 @@ +.\" {PRM/WK/1999-09-25} +.\" Copyright 1991 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH GROUPS 1 +.SH NAZWA +groups \- wy¶wietl nazwy bie¿±cych grup +.SH SK£ADNIA +.B groups +.RI [ u¿ytkownik ] +.SH OPIS +.B groups +wy¶wietla nazwy lub warto¶ci bie¿±cych identyfikatorów grup. +Je¿eli warto¶æ nie posiada odpowiedniego wpisu w \fI/etc/group\fR, to zostanie +wy¶wietlona jako numeryczny identyfikator grupy. +Opcjonalny parametr \fIu¿ytkownik\fR powoduje wy¶wietlenie grup dla danego +\fIu¿ytkownika\fR. +.SH UWAGA +Systemy nie obs³uguj±ce równoczesnych grup (tj.takie, w których u¿ytkownik mo¿e +w danej byæ cz³onkiem tylko jednej grupy, grupy aktywnej) bêd± wy¶wietlaæ +informacjê z \fI/etc/group\fR. +Do zmiany bie¿±cego rzeczywistego i efektywnego identyfikatora grupy u¿ytkownik +musi u¿yæ polecenia \fBnewgrp\fR lub \fBsg\fR. +.SH PLIKI +.IR /etc/group " - informacja o grupach" +.SH ZOBACZ TAK¯E +.BR newgrp (1), +.BR getuid (2), +.BR getgid (2), +.BR getgroups (2) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz +z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/grpck.8 b/current/man/pl/grpck.8 new file mode 100644 index 00000000..55234e49 --- /dev/null +++ b/current/man/pl/grpck.8 @@ -0,0 +1,103 @@ +.\" {PTM/WK/1999-09-17} +.\" Copyright 1992 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH GRPCK 1 +.SH NAZWA +grpck \- weryfikacja spójno¶ci plików grup +.SH SK£ADNIA +.B grpck +.RB [ -r ] +.RI [ group +.IR shadow ] +.SH OPIS +\fBgrpck\fR weryfikuje integralno¶æ informacji autentykacji systemowej. +Sprawdzane s± wszystkie pozycje w plikach \fI/etc/group\fR +i \fI/etc/gshadow\fR, by upewniæ siê, ¿e ka¿da z nich posiada w³a¶ciwy format +i poprawne dane w ka¿dym z pól. U¿ytkownik monitowany jest o usuniêcie +pozycji, które s± sformatowane niepoprawnie lub posiadaj± inne nie daj±ce +siê skorygowaæ b³êdy. +.P +Kontrolowane jest czy ka¿da pozycja posiada +.sp +.in +.5i +- w³a¶ciw± liczbê pól +.br +- unikaln± nazwê grupy +.br +- poprawn± listê cz³onków i administratorów +.in -.5i +.sp +.P +Kontrola w³a¶ciwej liczby pól i niepowtarzalnej nazwy grupy jest +decyduj±ca. Je¿eli pozycja posiada b³êdn± liczbê pól, to u¿ytkownik jest +proszony o usuniêcie ca³ej pozycji (wiersza). +Je¿eli u¿ytkownik nie potwierdzi decyzji o usuniêciu, to pomijane s± wszelkie +dalsze sprawdzenia. +Pozycja z powtórzon± nazw± grupy powoduje monit o usuniêcie, ale nadal +bêd± wykonywane pozosta³e sprawdzenia. +Wszystkie inne b³êdy daj± ostrze¿enia a u¿ytkownik jest zachêcany +do uruchomienia polecenia \fBgroupmod\fR, by je poprawiæ. +.P +Polecenia dzia³aj±ce na pliku \fI/etc/group\fR nie potrafi± zmieniaæ +uszkodzonych lub powielonych pozycji. W takich okoliczno¶ciach powinien byæ +u¿ywany \fBgrpck\fR, by usun±æ nieprawid³ow± pozycjê. +.SH OPCJE +Domy¶lnie \fBgrpck\fR dzia³a na plikach \fI/etc/group\fR oraz \fI/etc/gshadow\fR. +Przy pomocy parametrów \fIgroup\fR i \fIshadow\fR u¿ytkownik mo¿e wybraæ inne +pliki. +Dodatkowo, u¿ytkownik mo¿e wykonaæ polecenie w trybie tylko-do-odczytu, poprzez +podanie flagi \fB-r\fR. +Powoduje to, ¿e na wszystkie pytania dotycz±ce zmian zostanie, bez ingerencji +u¿ytkownika, u¿yta odpowied¼ \fBnie\fR. +.SH PLIKI +.IR /etc/group " - informacja o kontach grup" +.br +.IR /etc/gshadow " - zakodowana informacja o has³ach i administratorach grup" +.br +.IR /etc/passwd " -informacja o u¿ytkownikach" +.SH ZOBACZ TAK¯E +.BR groupmod (8), +.BR group (5), +.BR passwd (5), +.BR shadow (5) +.SH DIAGNOSTYKA +Polecenie \fBgrpck\fR koñczy pracê z nastêpuj±cymi warto¶ciami kodów: +.IP 0 5 +Powodzenie +.IP 1 5 +B³±d sk³adni +.IP 2 5 +Jedna lub wiêcej z³ych pozycji pliku grup +.IP 3 5 +Niemo¿liwe otwarcie plików grup +.IP 4 5 +Niemo¿liwa blokada plików grup +.IP 5 5 +Niemo¿liwa aktualizacja plików grup +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/id.1 b/current/man/pl/id.1 new file mode 100644 index 00000000..71392b94 --- /dev/null +++ b/current/man/pl/id.1 @@ -0,0 +1,57 @@ +.\" {PTM/WK/1999-09-25} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH ID 1 +.SH NAZWA +id - wy¶wietl nazwy bie¿±cych ID u¿ytkownika i grupy +.SH SK£ADNIA +.B id +.RB [ -a ] +.SH OPIS +.B id +wy¶wietla bie¿±ce nazwy (lub warto¶ci) rzeczywistych i efektywnych +identyfikatorów u¿ytkownika i grupy. +Je¿eli dana warto¶æ nie posiada odpowiedniego wpisu w \fI/etc/passwd\fR +lub \fI/etc/group\fR, to zostanie wy¶wietlona bez odpowiedniej nazwy. +Opcjonalna flaga \fB-a\fR wy¶wietla zestaw grup w systemach, które obs³uguj± +równoczesne cz³onkostwo w wielu grupach. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/group " - informacja o grupach" +.SH ZOBACZ TAK¯E +.BR getuid (2), +.BR getgid (2), +.BR getgroups (2) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz +z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/lastlog.8 b/current/man/pl/lastlog.8 new file mode 100644 index 00000000..63d5e270 --- /dev/null +++ b/current/man/pl/lastlog.8 @@ -0,0 +1,64 @@ +.\" {PTM/WK/1999-09-18} +.\" Copyright 1992, Phillip Street and Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" @(#)lastlog.8 3.3 08:24:58 29 Sep 1993 (National Guard Release) +.\" +.TH LASTLOG 8 +.SH NAZWA +lastlog \- sprawd¼ plik ostatnich logowañ (lastlog) +.SH SK£ADNIA +.B lastlog +.RB [ -u +.IR uid ] +.RB [ -t +.IR dni +.SH OPIS +\fBlastlog\fR formatuje i wy¶wietla zawarto¶æ dziennika ostatnich logowañ, +\fI/var/log/lastlog\fR. Wy¶wietlone zostan± \fBnazwa u¿ytkownika\fR, +\fBport\fR i \fBczas ostatniego logowania\fR. +Domy¶lnie (bez flag) pozycje pliku wy¶wietlane s± w kolejno¶ci identyfikatorów +u¿ytkowników (UID). +Wprowadzenie opcji \fB-u \fInazwa_u¿ytkownika\fR spowoduje wy¶wietlenie +pozycji opisuj±cej ostatnie rozpoczêcie sesji tylko dla tego u¿ytkownika. +U¿ycie \fB-t \fIdni\fR powoduje, ¿e bêd± wy¶wietlone ostatnie logowania +u¿ytkowników nowsze ni¿ sprzed zadanej liczby \fIdni\fR. +Opcja \fB-t\fR przes³ania u¿ycie opcji \fB-u\fR. +.PP +Je¿eli u¿ytkownik nigdy siê nie logowa³ to zamiast portu i czasu logowania +zostanie wy¶wietlony komunikat \fB"**Never logged in**"\fR (nigdy siê nie +logowa³). +.SH PLIKI +.IR /var/log/lastlog " - dziennik ostatnich logowañ" +.SH PRZESTROGI +Du¿e luki w numeracji UID powoduj±, ¿e program bêdzie pracowa³ d³u¿ej, nie +wy¶wietlaj±c wyników (np. je¶li mmdf=800, za¶ ostatni uid=170, to program +bêdzie sprawia³ wra¿enie zawieszonego w trakcie przetwarzania uid 171-799). +.SH AUTORZY +Julianne Frances Haugh (jfh@austin.ibm.com) +.br +Phillip Street diff --git a/current/man/pl/limits.5 b/current/man/pl/limits.5 new file mode 100644 index 00000000..9ffa0f59 --- /dev/null +++ b/current/man/pl/limits.5 @@ -0,0 +1,79 @@ +.\" {PTM/WK/1999-09-18} +.TH LIMITS 5 +.SH NAZWA +limits \- definicja ograniczeñ zasobów +.SH OPIS +Plik +.I limits +(domy¶lnie /etc/limits lub LIMITS_FILE zdefiniowane w config.h) +opisuje ograniczenia zasobów, jakie chcia³by¶ narzuciæ u¿ytkownikom. +W³a¶cicielem tego pliku powinien byæ u¿ytkownik root i wy³±cznie dla niego +plik ten powinien byæ dostêpny do odczytu. +.PP +Domy¶lnie u¿ytkownikowi 'root' nie s± narzucane ¿adne ograniczenia. +W rzeczywisto¶ci, przy u¿yciu tego sposobu nie jest mo¿liwe narzucenie limitów +dla kont równowa¿nych root (kont z UID równym 0). +.PP +Ka¿dy wiersz definiuje ograniczenie dla u¿ytkownika w postaci: +.sp +.I u¿ytkownik £AÑCUCH_OGRANICZEÑ +.PP +\fB£AÑCUCH OGRANICZEÑ\fP sk³ada siê z po³±czonych definicji ograniczeñ zasobów. +Ka¿de ograniczenie opisywane jest liter± z nastêpuj±c± po niej warto¶ci± +numeryczn± limitu. +.PP +Dozwolone s± nastêpuj±ce identyfikatory: +.sp +A: max. przestrzeñ adresowa (KB) +.br +C: max. rozmiar pliku core (KB) +.br +D: max. rozmiar danych (KB) +.br +F: maksymalny rozmiar pliku (KB) +.br +M: max. locked-in-memory address space (KB) +.br +N: max. liczba otwartych plików +.br +R: max. resident set size (KB) +.br +S: max. rozmiar stosu (KB) +.br +T: max. czas procesora (CPU) (MIN) +.br +U: max. liczba procesów +.br +L: max. liczba sesji pracy dla tego u¿ytkownika +.br +P: priorytet procesu, ustawiany przez \fBsetpriority\fR(2). +.PP +Na przyk³ad, \fIL2D2048N5\fP jest poprawnym \fB£AÑCUCHEM OGRANICZEÑ\fP. +Z uwagi na lepsz± czytelno¶ci przyjêto, ¿e poni¿sze zapisy s± równowa¿ne: +.sp +nazwa_u¿ytkownika L2D2048N5 +.br +nazwa_u¿ytkownika L2 D2048 N5 +.PP +Nale¿y podkre¶liæ, ¿e reszta wiersza po \fInazwie_u¿ytkownika\fP traktowana +jest jako ³añcuch ograniczeñ, zatem komentarze nie s± dozwolone. Nieprawid³owy +³añcuch ograniczeñ zostanie odrzucony (nie bêdzie brany pod uwagê) przez +program login. +.PP +Nazwa u¿ytkownika równa "\fB*\fP" oznacza wpis domy¶lny. +Je¿eli w pliku \fBLIMITS_FILE\fP posiadasz wiele takich wpisów, to jako +domy¶lny zostanie u¿yty ostatni z nich. +.PP +Pojedyncza kreska "\fB-\fP" ca³kowicie wy³±cza ograniczenia dla u¿ytkownika. +.PP +Zauwa¿ te¿, proszê, ¿e wszystkie te ograniczenia definiowane s± w odniesieniu +do pojedynczej sesji (per login). Nie s± one globalne ani sta³e. Byæ mo¿e bêd± +kiedy¶ ograniczenia globalne, ale na razie tyle musi wystarczyæ ;) +.SH PLIKI +.I /etc/limits +.SH ZOBACZ TAK¯E +.BR login (1), +.BR setpriority (2), +.BR setrlimit (2) +.SH AUTOR +Cristian Gafton (gafton@sorosis.ro) diff --git a/current/man/pl/login.1 b/current/man/pl/login.1 new file mode 100644 index 00000000..ecedc24c --- /dev/null +++ b/current/man/pl/login.1 @@ -0,0 +1,134 @@ +.\" {PTM/WK/1999-09-25} +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH LOGIN 1 +.SH NAZWA +login \- rozpocznij sesjê pracy w systemie +.SH SK£ADNIA +.B login +.RI [ u¿ytkownik " [" zmienne_¶rodowiska ]] +.\" XXX - udokumentowaæ opcje -f -h -p -r +.SH OPIS +.B login +s³u¿y do utworzenia nowej sesji pracy z systemem. Zwykle wywo³ywane jest +automatycznie w odpowiedzi na zachêtê +.I login: +na terminalu u¿ytkownika. +.B login +mo¿e byæ specyficzne dla pow³oki i mo¿e zostaæ wywo³ane jako podproces. +Najczê¶ciej, +.B login +traktowane jest przez pow³okê jako \fBexec login\fR, co powoduje opuszczenie +przez u¿ytkownika bie¿±cej pow³oki. +Próba wykonania \fBlogin\fR z pow³oki innej ni¿ zg³oszeniowa powoduje komunikat +o b³êdzie. +.PP +Przy wywo³aniu polecenia z zachêty \fIlogin:\fR, u¿ytkownik mo¿e po swojej +nazwie wprowadziæ zmienne ¶rodowiska. Zmienne te wprowadzane s± w postaci: +\fBNAZWA=WARTO¦Æ\fR. Nie wszystkie zmienne mog± jednak byæ ustawione w ten +sposób, szczególnie \fBPATH\fR, \fBHOME\fR i \fBSHELL\fR. +Dodatkowo, zakazane mo¿e byæ \fBIFS\fR (input field separator: separator pól +wej¶ciowych), je¿eli pow³ok± zg³oszeniow± u¿ytkownika \fB/bin/sh\fR. +.PP +U¿ytkownik pytany jest o has³o, je¶li takowe istnieje. +Dla zapobie¿enia ujawnieniu has³a wy¶wietlanie wprowadzanych znaków jest +wy³±czone. Dozwolona jest jedynie niewielka liczba nieudanych prób podania +has³a. Po wyczerpaniu limitu prób \fBlogin\fR koñczy pracê za¶ po³±czenie +komunikacyjne jest zrywane. +.PP +Je¿eli dla twego konta w³±czona jest kontrola wa¿no¶ci has³a, mo¿esz byæ +proszony o podanie nowego has³a przed kontynuacj±. Bêdziesz wówczas musia³ +podaæ stare i nowe has³o. Wiêcej informacji na ten temat znajdziesz +w \fBpasswd \fR(1). +.PP +Po poprawnym rozpoczêciu sesji (zalogowaniu siê), zostanie wy¶wietlona +wiadomo¶æ dnia (je¶li jest) i informacja o stanie skrzynki pocztowej. +Mo¿esz wy³±czyæ wy¶wietlanie zawarto¶ci pliku wiadomo¶ci dnia, +\fI/etc/motd\fR, tworz±c zerowej wielko¶ci plik \fI.hushlogin\fR +w swoim katalogu domowym. +Informacja o stanie skrzynki pocztowej jest jedn± z: +"\fBYou have new mail.\fR" (masz now± pocztê), +"\fBYou have mail.\fR" (masz pocztê), lub "\fBNo Mail.\fR" (brak poczty) - +stosownie do stanu skrzynki. +.PP +Identyfikator u¿ytkownika i grupy (UID i GID) zostan± ustawione wed³ug warto¶ci +w pliku \fI/etc/passwd\fR. +Warto¶ci \fB$HOME\fR, \fB$SHELL\fR, \fB$PATH\fR, \fB$LOGNAME\fR +i \fB$MAIL\fR ustawiane s± stosownie do odpowiednich pól danego wpisu pliku +hase³. +Mog± byæ ustalane równie¿ warto¶ci ulimit, umask oraz nice wed³ug wpisów w polu +GECOS. +.PP +W niektórych systemach zostanie ustawiona zmienna ¶rodowiskowa \fB$TERM\fR, +wskazuj±ca na typ terminala na linii tty, jak podano w \fI/etc/ttytype\fR. +.PP +Mo¿e tak¿e zostaæ wykonany skrypt startowy (inicjacyjny) twojego interpretatora +poleceñ. +Przegl±dnij, proszê, odpowiedni± sekcjê dokumentacji opisuj±c± bardziej +szczegó³owo tê funkcjê. +.SH PRZESTROGI +Niniejsza wersja \fBlogin\fR posiada wiele opcji kompilacji, z których tylko +czê¶æ bêdzie mieæ zastosowanie w danej instalacji. +.PP +Po³o¿enie plików mo¿e byæ ró¿ne w zale¿no¶ci od konfiguracji systemu. +.SH PLIKI +.IR /etc/utmp " - lista bie¿±cych sesji pracy" +.br +.IR /etc/wtmp " - lista poprzednich sesji pracy" +.br +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/shadow " - zakodowane has³a i informacja o ich wa¿no¶ci" +.br +.IR /etc/motd " - plik 'wiadomo¶ci dnia'" +.br +.IR /etc/nologin " - zapobiega logowaniu innych ni¿ root" +.br +.IR /etc/ttytype " - lista typów terminali" +.br +.IR $HOME/.profile " - skrypt startowy domy¶lnej pow³oki" +.br +.IR $HOME/.hushlogin " - zapobiega m.in. wy¶wietlaniu wiadomo¶ci dnia" +.br +.SH ZOBACZ TAK¯E +.BR getty (8), +.BR mail (1), +.BR passwd (1), +.BR sh (1), +.BR su (1), +.BR login.defs (5), +.\" .BR d_passwd (5), +.BR passwd (5), +.BR nologin (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz +z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/login.access.5 b/current/man/pl/login.access.5 new file mode 100644 index 00000000..cfcad56c --- /dev/null +++ b/current/man/pl/login.access.5 @@ -0,0 +1,54 @@ +.\" {PTM/WK/1999-09-17} +.TH LOGIN.ACCESS 5 +.\" .Dt SKEY.ACCESS 5 +.\" .Os FreeBSD 1.2 +.SH NAZWA +login.access \- tabela kontroli dostêpu logowania +.SH OPIS +Plik +.I login.access +okre¶la kombinacje (u¿ytkownik, host) i/lub (u¿ytkownik, tty) +dla których logowanie bêdzie albo przyjête albo odrzucone. +.PP +Gdy kto¶ siê loguje, plik +.I login.access +przeszukiwany jest do znalezienia pierwszej pozycji pasuj±cej do danej +kombinacji (u¿ytkownik, host), lub, w przypadku logowañ nie-sieciowych +kombinacji (u¿ytkownik, tty). Pole zezwolenia w tej tablicy pozycji okre¶la +czy logowanie bêdzie przyjête czy odrzucone. +.PP +Ka¿dy wiersz tabeli kontroli dostêpu logowania posiada trzy, oddzielone +znakiem dwukropka, pola: +.sp 1 +.IR zezwolenie : u¿ytkownicy : pochodzenie +.sp 1 +Pierwsze pole powinno zawieraæ znak "\fB+\fR" (dostêp zapewniony) lub "\fB-\fR" +(zakaz dostêpu). Drugie z pól powinno zawieraæ listê jednego lub wiêcej nazw +u¿ytkowników, grup lub s³owo +.B ALL +(zawsze pasuje do wszystkich). Trzecie pole powinno byæ list± jednej lub wiêcej +nazw tty (dla logowañ nie-sieciowych), nazw hostów, domen (rozpoczynaj±cych siê +od kropki), adresów hostów, internetowych numerów sieci (koñcz±cych siê +kropk±), s³owem +.B ALL +(wszystkie - zawsze pasuje) lub +.B LOCAL +(dopasowuje dowolny ³añcuch nie zawieraj±cy kropki). +Je¿eli uruchomisz NIS mo¿esz u¿yæ @nazwagrupysieciowej we wzorcu hosta +lub u¿ytkownika. +.\" @netgroupname +.PP +Operator +.B EXCEPT +(oprócz) umo¿liwia pisanie z³o¿onych regu³. +.PP +Plik grup przeszukiwany jest wy³±cznie wtedy, gdy nazwa nie pasuje do +loguj±cego siê u¿ytkownika. Dopasowywane s± tylko te grupy, w których +u¿ytkownik jest jawnie wymieniony: program nie sprawdza warto¶ci +identyfikatora grupy g³ównej u¿ytkownika. +.SH PLIKI +.I /etc/login.access +.SH ZOBACZ TAK¯E +.BR login (1) +.SH AUTOR +Guido van Rooij diff --git a/current/man/pl/login.defs.5 b/current/man/pl/login.defs.5 new file mode 100644 index 00000000..79c907de --- /dev/null +++ b/current/man/pl/login.defs.5 @@ -0,0 +1,557 @@ +.\" {PTM/WK/1999-09-18} +.\" Copyright 1991 - 1993, Julianne Frances Haugh and Chip Rosenthal +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH LOGIN 5 +.SH NAZWA +/etc/login.defs \- konfiguracja logowania +.SH OPIS +Plik +.I /etc/login.defs +definiuje specyficzn± dla naszej maszyny konfiguracjê pakietu shadow login. +Plik ten jest wymagany. Jego nieobecno¶æ nie wstrzyma dzia³ania systemu, +ale prawdopodobnie spowoduje nieprzewidywalne dzia³anie. +.PP +Plik ten jest czytelnym plikiem tekstowym. Ka¿dy z jego wierszy opisuje jeden +parametr konfiguracji. Wiersze sk³adaj± siê z nazwy parametru i jego warto¶ci, +oddzielonych bia³ym znakiem. Ignorowane s± puste wiersze i wiersze komentarzy. +Komentarze rozpoczynaj± siê od znaku '#', który musi byæ pierwszym znakiem +wiersza (pomijaj±c bia³e znaki). +.PP +Istniej± cztery typy warto¶ci parametrów: napisy, logiczne (boolean), +liczby i d³ugie liczby (long numbers). Napis jest z³o¿ony +z dowolnych znaków drukowalnych. Parametr logiczny mo¿e mieæ albo warto¶æ +"yes" albo "no". Niezdefiniowanemu parametrowi logicznemu lub parametrowi, +któremu przypisano warto¶æ inn± od powy¿szych przypisane zostanie "no". +Liczby (zarówno zwyk³e jak i d³ugie) mog± byæ warto¶ciami dziesiêtnymi, +ósemkowymi (poprzed¼ warto¶æ cyfr± "0") albo szesnastkowymi (poprzed¼ warto¶æ +sekwencj± "0x"). Maksymalne warto¶ci zwyk³ych i d³ugich parametrów +numerycznych zale¿± od maszyny. +.PP +Obs³ugiwane s± nastêpuj±ce opcje konfiguracyjne: +.\" +.IP "CHFN_AUTH (logiczna)" +Je¿eli ma warto¶æ +.IR yes , +to programy +.B chfn +i +.B chsh +bêd± pytaæ o has³o przed dokonaniem zmian, chyba ¿e uruchamiane s± przez +superu¿ytkownika. +.\" +.IP "CHFN_RESTRICT (napis)" +Ten parametr okre¶la, jakie warto¶ci w polu +.I gecos +pliku +.I passwd +mog± byæ zmieniane przez zwyk³ych u¿ytkowników za pomoc± programu +.B chfn +Mo¿e on byæ dowoln± kombinacj± liter +.IR f , +.IR r , +.IR w , +.IR h , +oznaczaj±cych odpowiednio: Full name (pe³na nazwa), Room number (numer pokoju), +Work phone (telefon s³u¿bowy) i Home phone (telefon domowy). +Je¶li parametr nie jest podany, to zmian mo¿e dokonywaæ wy³±cznie +superu¿ytkownik. +.\" +.IP "CONSOLE (napis)" +Je¶li podana, definicja ta okre¶la ograniczony zestaw linii, na których +dozwolone jest rozpoczynanie sesji u¿ytkownika root. Próby logowania +u¿ytkownika root niespe³niaj±ce ustalonych tu kryteriów zostan± odrzucone. +Warto¶æ tego pola mo¿e wyst±piæ w jednej z dwu postaci: albo pe³nej nazwy +¶cie¿kowej pliku, jak na przyk³ad +.sp +.ft I + CONSOLE /etc/consoles +.ft R +.sp +albo listy linii terminalowych rozdzielonych dwukropkami, jak poni¿ej: +.sp +.ft I + CONSOLE console:tty01:tty02:tty03:tty04 +.ft R +.sp +(Zauwa¿, ¿e wymienione tu nazwy nie zawieraj± ¶cie¿ki /dev/). +Je¿eli podano ¶cie¿kow± nazwê pliku, to ka¿dy jego wiersz powinien okre¶laæ +jedn± liniê terminalow±. Je¶li parametr ten nie jest zdefiniowany albo podany +plik nie istnieje, to u¿ytkownik root bêdzie móg³ siê logowaæ z dowolnej linii +terminalowej. Poniewa¿ usuniêcie lub obciêcie pliku definiuj±cego +dozwolone linie mo¿e spowodowaæ nieautoryzowane logowania roota, plik ten musi +byæ chroniony. Tam, gdzie bezpieczeñstwo jest spraw± kluczow±, powinna byæ +u¿ywana postaæ listy separowanej dwukropkami, co chroni przed potencjaln± +prób± ataku w opisany sposób. +.\" +.IP "CONSOLE_GROUPS (napis)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "CRACKLIB_DICTPATH (napis)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "DEFAULT_HOME (logiczna)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "DIALUPS_CHECK_ENAB (logiczna)" +Je¿eli ma warto¶æ +.I yes +a plik +.I /etc/dialups +istnieje, to na liniach telefonicznych wyszczególnionych w tym pliku s± +w³±czane wtórne has³a (has³a telefoniczne). Plik ten powinien zawieraæ listê +linii telefonicznych (dialups), po jednej w wierszu, na przyk³ad: +.nf +.sp +.ft I + ttyfm01 + ttyfm02 + \0\0. + \0\0. + \0\0. +.ft R +.sp +.fi +.\" +.IP "ENVIRON_FILE (napis)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "ENV_HZ (napis)" +Parametr ten okre¶la warto¶æ parametru ¶rodowiska HZ. Przyk³ad u¿ycia: +.sp + \fIENV_HZ HZ=50\fR +.sp +Je¿eli jest on zdefiniowany, to nie zostanie ustanowiona ¿adna warto¶æ HZ. +.\" +.IP "ENV_PATH (napis)" +Parametr ten musi byæ zdefiniowany jako ¶cie¿ka przeszukiwania dla zwyk³ych +u¿ytkowników. Przy logowaniu z UID innym ni¿ zero, zmienna ¶rodowiskowa PATH +jest inicjowana t± w³a¶nie warto¶ci±. Jest to parametr wymagany; je¿eli nie +zostanie zdefiniowany, to zostanie nadana, byæ mo¿e niepoprawna, warto¶æ +domy¶lna. +.\" +.IP "ENV_SUPATH (napis)" +Parametr ten musi byæ zdefiniowany jako ¶cie¿ka przeszukiwania dla +superu¿ytkownika. Przy rozpoczynaniu sesji z UID równym zero, zmienna +¶rodowiskowa PATH jest inicjowana t± w³a¶nie warto¶ci±. Jest to parametr +wymagany; je¿eli nie zostanie zdefiniowany, to zostanie nadana, byæ mo¿e +niepoprawna, warto¶æ domy¶lna. +.\" +.IP "ENV_TZ (napis)" +Parametr ten zawiera informacjê s³u¿±c± do utworzenia zmiennej ¶rodowiskowej TZ. +Jego warto¶æ musi byæ albo wprost wymagan± zawarto¶ci± TZ, albo +pe³n± nazw± ¶cie¿kow± pliku zawieraj±cego tê informacjê. Przyk³ad u¿ycia: +.sp + \fIENV_TZ\0\0\0\0TZ=CST6CDT\fP +.sp +lub +.sp + \fIENV_TZ\0\0\0\0/etc/tzname\fP +.sp +Je¿eli podano nieistniej±cy plik, to TZ zostanie zainicjowane pewn± warto¶ci± +domy¶ln±. Je¿eli nie zdefiniowano tego parametru to nie bêdzie ustawiona +¿adna warto¶æ TZ. +.\" +.IP "ERASECHAR (liczba)" +T± warto¶ci± jest inicjowany terminalowy znak +.I erase +(kasowania). Jest to obs³ugiwane tylko w systemach z interfejsem +.IR termio, +np. System V. Je¿eli nie podano parametru, to znak kasowania zostanie +zainicjowany na backspace. Informacjê powi±zan± znajdziesz w opisie KILLCHAR. +.\" +.IP "FAILLOG_ENAB (logiczna)" +Je¿eli ustawiona na +.I yes +to nieudane logowania bêd± odnotowywane w pliku +.I /var/log/faillog +w formacie +.BR faillog (8). +.\" +.IP "FAIL_DELAY (liczba)" +Czas opó¼nienia, wyra¿ony w sekundach, po ka¿dej nieudanej próbie logowania. +.\" +.IP "FAKE_SHELL (napis)" +Zamiast rzeczywistej pow³oki u¿ytkownika zostanie uruchomiony program okre¶lony +warto¶ci± tego parametru. Nazwa widoczna (argv[0]) programu bêdzie jednak +nazw± pow³oki. Program przed uruchomieniem faktycznej pow³oki mo¿e wykonywaæ +dowoln± akcjê (logowanie, dodatkowe uwierzytelnianie, banner itp.). +.\" +.IP "FTMP_FILE (napis)" +Okre¶la pe³n± ¶cie¿kow± nazwê pliku, w którym rejestrowane s± nieudane próby +rozpoczynania sesji pracy. W przypadku nieudanej próby logowania do pliku +dopisywana jest pozycja o formacie +.IR utmp . +Zauwa¿, ¿e ró¿ni siê to od rejestracji niepomy¶lnych logowañ do +.IR /var/log/faillog , +gdy¿ opisywana funkcja odnotowuje wszystkie nieudane próby, podczas gdy +"faillog" kumuluje informacjê o pora¿kach danego u¿ytkownika. Je¶li nie +podano tego parametru, to rejestracja bêdzie wy³±czona. Powi±zane informacje +znajdziesz w opisie FAILLOG_ENAB i LOG_UNKFAIL_ENAB. +.\" +.IP "GID_MAX (liczba)" +.IP "GID_MIN (liczba)" +Zakres identyfikatorów grup, w obrêbie którego mo¿e wybieraæ program +.BR groupadd . +.\" +.IP "HUSHLOGIN_FILE (nazwa)" +Parametr u¿ywany do ustalenia okoliczno¶ci cichego logowania ("hushlogin"). +Okoliczno¶ci te mog± byæ ustalone na dwa sposoby. Po pierwsze, je¿eli warto¶ci± +parametru jest nazwa pliku, a plik ten istnieje w katalogu domowym u¿ytkownika, +to wprowadzane s± warunki cichego logowania. Zawarto¶æ pliku jest ignorowana; +sama jego obecno¶æ powoduje ciche logowanie. Po drugie, je¿eli warto¶ci± +parametru jest pe³na nazwa ¶cie¿kowa pliku a w pliku tym znaleziona zostanie +nazwa u¿ytkownika lub nazwa jego pow³oki, to wprowadzone zostan± warunki +cichego logowania. W tym przypadku, plik powinien mieæ format podobny do: +.nf +.sp +.ft I + demo + /usr/lib/uucp/uucico + \0\0. + \0\0. + \0\0. +.ft R +.sp +.fi +Je¿eli nie zdefiniowano tego parametru, to warunki cichego logowania nigdy +nie wyst±pi±. W trakcie cichego logowanie wstrzymane jest wy¶wietlanie +wiadomo¶ci dnia (message of the day), ostatniego udanego i nieudanego +rozpoczêcia sesji pracy, wy¶wietlanie stanu skrzynki pocztowej i sprawdzenie +wieku has³a. Zauwa¿, ¿e zezwolenie na pliki cichego logowania w katalogach +domowych u¿ytkowników pozwala im na wstrzymanie kontroli wa¿no¶ci +has³a. Informacje zwi±zane z tym tematem znajdziesz w opisach MOTD_FILE, +FILELOG_ENAB, LASTLOG_ENAB i MAIL_CHECK_ENAB. +.\" +.IP "ISSUE_FILE (napis)" +Pe³na ¶cie¿kowa nazwa pliku wy¶wietlanego przed ka¿d± zachêt± do logowania. +.\" +.IP "KILLCHAR (liczba)" +T± warto¶ci± inicjowany jest terminalowy znak +.IR kill . +Jest to obs³ugiwane tylko w systemach z interfejsem +.IR termio, +np. System V. Je¿eli nie podano parametru, to znak kasowania zostanie +zainicjowany na \s-2CTRL/U\s0. Informacjê powi±zan± znajdziesz w opisie +ERASECHAR. +.\" +.IP "LASTLOG_ENAB (logiczna)" +Je¶li ma warto¶æ +.IR yes , +i istnieje plik +.IR /var/log/lastlog , +to w tym pliku bêdzie rejestrowane poprawne rozpoczêcie sesji pracy u¿ytkownika +(zalogowanie siê). Ponadto, je¶li opcja ta jest w³±czona, to podczas logowania +siê u¿ytkownika bêdzie wy¶wietlana informacja o liczbie ostatnich udanych +i nieudanych logowañ. Zakoñczone niepowodzeniem logowania nie bêd± wy¶wietlane +je¶li nie w³±czono FAILLOG_ENAB. W warunkach cichego logowanie nie +bêd± wy¶wietlane informacje ani o pomy¶lnych ani o niepomy¶lnych logowaniach. +.\" +.IP "LOGIN_RETRIES (liczba)" +Dozwolona liczba prób logowania przed zakoñczeniem pracy programu +.BR login . +.\" +.IP "LOGIN_STRING (napis)" +XXX powinno zostaæ udokumentowane. +.IP "LOGIN_TIMEOUT (liczba)" +XXX powinno zostaæ udokumentowane. +.IP "LOG_OK_LOGINS (logiczna)" +XXX powinno zostaæ udokumentowane. +.IP "LOG_UNKFAIL_ENAB (logiczna)" +Je¶li posiada warto¶æ +.I yes +to nieznane nazwy u¿ytkowników bêd± równie¿ odnotowywane je¶li w³±czone jest +rejestrowanie nieudanych prób rozpoczêcia sesji. Zauwa¿, ¿e niesie to ze sob± +potencjalne zagro¿enie bezpieczeñstwa: powszechn± przyczyn± nieudanego +logowania jest zamiana nazwy u¿ytkownika i has³a, tryb ten zatem spowoduje, +¿e czêsto w rejestrach nieudanych logowañ bêd± siê odk³adaæ jawne has³a. +Je¿eli opcja ta jest wy³±czona, to nieznane nazwy u¿ytkowników bêd± pomijane +w komunikatach o nieudanych próbach logowania. +.\" +.IP "MAIL_CHECK_ENAB (logiczna)" +Je¿eli ma warto¶æ +.IR yes , +to u¿ytkownik po rozpoczêciu sesji pracy bêdzie powiadamiany o stanie swojej +skrzynki pocztowej. Informacjê zwi±zan± z tym tematem znajdziesz w opisie +MAIL_DIR. +.\" +.IP "MAIL_DIR (napis)" +Okre¶la pe³n± nazwê ¶cie¿kow± do katalogu zawieraj±cego pliki skrzynki +pocztowej u¿ytkownika. Do powy¿szej ¶cie¿ki doklejana jest nazwa u¿ytkownika, +tworz±c w ten sposób zmienn± ¶rodowiskow± MAIL - ¶cie¿kê do skrzynki +u¿ytkownika. Musi byæ zdefiniowany albo niniejszy parametr albo parametr +MAIL_FILE; je¶li nie zostan± zdefiniowane, to zostanie nadana, byæ mo¿e +niepoprawna, warto¶æ domy¶lna. Zobacz tak¿e opis MAIL_CHECK_ENAB. +.\" +.IP "MAIL_FILE (napis)" +Okre¶la nazwê pliku skrzynki pocztowej u¿ytkownika. Nazwa ta doklejana jest +na koniec nazwy katalogu domowego u¿ytkownika tworz±c zmienn± ¶rodowiskow± +MAIL - ¶cie¿kê do skrzynki u¿ytkownika. Musi byæ zdefiniowany albo niniejszy +parametr albo parametr MAIL_DIR; je¶li nie zostan± zdefiniowane, to zostanie +nadana, byæ mo¿e niepoprawna, warto¶æ domy¶lna. Zobacz tak¿e opis +MAIL_CHECK_ENAB. +.\" +.IP "MD5_CRYPT_ENAB (logiczna)" +Je¿eli ma warto¶æ +.IR yes , +to program +.B passwd +bêdzie kodowaæ nowo zmieniane has³a przy pomocy nowego algorytmu +.BR crypt (3), +opartego o MD-5. Algorytm ten pierwotnie pojawi³ siê we FreeBSD i jest te¿ +obs³ugiwany przez libc-5.4.38 oraz glibc-2.0 (lub wy¿sz±) w Linuksie. +Pozwala on na u¿ywanie hase³ d³u¿szych ni¿ 8 znaków (ograniczone przez +.BR getpass (3) +do 127 znaków), ale nie jest zgodny z tradycyjnymi implementacjami polecenia +.BR crypt (3). +.\" +.IP "MOTD_FILE (napis)" +Okre¶la listê rozdzielonych dwukropkami ¶cie¿ek do plików "wiadomo¶ci dnia" +(message of the day, MOTD). Je¶li podany plik istnieje, to jego zawarto¶æ jest +wy¶wietlana u¿ytkownikowi podczas rozpoczynania przez niego sesji pracy. +Je¿eli parametr ten jest niezdefiniowany lub wykonywane jest ciche logowanie, +to informacja ta bêdzie pomijana. +.\" +.IP "NOLOGINS_FILE (napis)" +Okre¶la pe³n± nazwê ¶cie¿kow± pliku zabraniaj±cego logowañ dla u¿ytkowników +innych ni¿ root. Je¿eli plik ten istnieje a u¿ytkownik inny ni¿ root usi³uje +siê zalogowaæ, to wy¶wietlana zostanie zawarto¶æ pliku a u¿ytkownik bêdzie +roz³±czony. Je¿eli nie podano tego parametru, to opisana funkcja bêdzie +wy³±czona. +.\" +.IP "NOLOGIN_STR (napis)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "OBSCURE_CHECKS_ENAB (logiczna)" +Je¿eli ma warto¶æ +.IR yes , +to program +.B passwd +przed akceptacj± zmiany has³a bêdzie wykonywa³ dodatkowe sprawdzenia. +Kontrole te s± do¶æ proste, a ich u¿ycie jest zalecane. +Te sprawdzenia nieoczywisto¶ci s± pomijane, je¿eli +.B passwd +uruchamiane jest przez u¿ytkownika +.IR root . +Zobacz tak¿e opis PASS_MIN_LEN. +.\" +.IP "PASS_ALWAYS_WARN (logiczna)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "PASS_CHANGE_TRIES (liczba)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "PASS_MIN_DAYS (liczba)" +Minimalna liczba dni miêdzy dozwolonymi zmianami has³a. Jakiekolwiek próby +zmiany has³a podejmowane wcze¶niej zostan± odrzucone. Je¿eli nie podano tego +parametru, to przyjêta zostanie warto¶æ zerowa. +.\" +.IP "PASS_MIN_LEN (liczba)" +Minimalna liczba znaków w akceptowalnym ha¶le. Próba przypisania has³a o +mniejszej liczbie znaków zostanie odrzucona. Warto¶æ zero wy³±cza tê +kontrolê. Je¶li nie podano parametru, to przyjêta zostanie warto¶æ zerowa. +.\" +.IP "PASS_MAX_DAYS (liczba)" +Maksymalna liczba dni, przez jak± mo¿e byæ u¿ywane has³o. Je¶li has³o jest +stanie siê starsze, to rachunek zostanie zablokowany. Je¶li nie podano, to +zostanie przyjêta bardzo du¿a warto¶æ. +.\" +.IP "PASS_MAX_LEN (liczba)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "PASS_WARN_AGE (liczba)" +Liczba dni ostrzegania przed wyga¶niêciem has³a. Warto¶æ zerowa oznacza, +¿e ostrze¿enie wyst±pi wy³±cznie w dniu utraty wa¿no¶ci has³a. Warto¶æ +ujemna oznacza brak ostrze¿eñ. Brak parametru oznacza, ¿e ostrze¿enia nie +bêd± wy¶wietlane. +.\" +.IP "PORTTIME_CHECKS_ENAB (logiczna)" +Je¶li ma warto¶æ +.IR yes , +za¶ plik +.I /etc/porttime +istnieje, to bêdzie on przegl±dany, by upewniæ siê czy u¿ytkownik mo¿e siê +w danej chwili zalogowaæ na danej linii. Patrz tak¿e podrêcznik +.BR porttime (5) +.\" +.IP "QMAIL_DIR (napis)" +Dla u¿ytkowników Qmail, parametr ten okre¶la katalog, w którym przechowywana +jest hierarchia Maildir. +Zobacz te¿ MAIL_CHECK_ENAB. +.\" +.IP "QUOTAS_ENAB (logiczna)" +Je¶li ma warto¶æ +.I yes , +wówczas dla danego u¿ytkownika "ulimit," "umask" i "niceness" bêd± +zainicjowane warto¶ciami podanymi (o ile s± podane) w polu +.I gecos +pliku +.IR passwd . +Patrz tak¿e podrêcznik +.BR passwd (5). +.\" +.IP "SU_NAME (napis)" +Przypisuje nazwê polecenia do uruchomionego "su -". Na przyk³ad, je¶li +parametr ten jest zdefiniowany jako "su", to polecenie +.BR ps (1) +poka¿e uruchomione polecenie jako "-su". Je¶li parametr ten jest +niezdefiniowany, to +.BR ps (1) +poka¿e nazwê faktycznie wykonywanej pow³oki, np. co¶ w rodzaju "-sh". +.\" +.IP "SULOG_FILE (napis)" +Pokazuje pe³n± nazwê ¶cie¿kow± pliku, w którym rejestrowane jest wykorzystanie +.BR su . +Je¶li parametr ten nie jest okre¶lony, to rejestrowanie nie jest wykonywane. +Poniewa¿ polecenie +.B su +mo¿e byæ u¿ywane podczas prób uwierzytelnienia has³a, do odnotowywania +u¿ycia +.B su +powinny byæ u¿ywane albo niniejsza opcja +albo +.IR syslog . +Zobacz te¿ opis SYSLOG_SU_ENAB. +.\" +.IP "SU_WHEEL_ONLY (logiczna)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "SYSLOG_SG_ENAB (logiczna)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "SYSLOG_SU_ENAB (logiczna)" +Je¿eli ma warto¶æ +.IR yes , +za¶ program +.B login +zosta³ skompilowany z obs³ug± +.IR syslog , +to wszelkie dzia³ania +.B su +bêd± rejestrowane za pomoc± +.IR syslog . +Zobacz te¿ opis SULOG_FILE. +.\" +.IP "TTYGROUP (napis lub liczba)" +Grupa (w³a¶cicielska) terminala inicjowana jest na nazwê b±d¼ numer tej grupy. +Jeden z dobrze znanych ataków polega na wymuszeniu sekwencji kontrolnych +terminala na linii terminalowej innego u¿ytkownika. Problemu tego mo¿na +unikn±æ wy³±czaj±c prawa zezwalaj±ce innym u¿ytkownikom na dostêp do linii +terminalowej, ale niestety zapobiega to równie¿ dzia³aniu programów takich +jak +.BR write . +Innym rozwi±zaniem jest pos³u¿enie siê tak± wersj± programu +.BR write , +która odfiltrowuje potencjalnie niebezpieczne sekwencje znaków. Nastêpnie +programowi nale¿y przyznaæ rozszerzone prawa dostêpu (SGID) dla specjalnej +grupy, ustawiæ grupê w³a¶cicieli terminala na tê grupê i nadaæ prawa dostêpu +\fI0620\fR do linii. Definicja TTYGROUP powsta³a do obs³ugi tej w³a¶nie +sytuacji. +Je¶li pozycja ta nie jest zdefiniowana, to grupa terminala inicjowana jest +na numer grupy u¿ytkownika. +Zobacz tak¿e TTYPERM. +.\" +.IP "TTYPERM (liczba)" +T± warto¶ci± inicjowane s± prawa terminala logowania. Typowymi warto¶ciami s± +\fI0622\fR zezwalaj±ce innym na pisanie do linii lub \fI0600\fR zabezpieczaj±ce +liniê przed innymi u¿ytkownikami. Je¿eli nie podano tego parametru, to prawa +dostêpu do terminala zostan± zainicjowane warto¶ci± \fI0622\fR. Zobacz te¿ +TTYGROUP. +.\" +.IP "TTYTYPE_FILE (napis)" +Okre¶la pe³n± nazwê ¶cie¿kow± pliku przypisuj±cego typy terminali do linii +terminalowych. Ka¿dy z wierszy tego pliku zawiera rozdzielone bia³ym znakiem +typ i liniê terminala. Na przyk³ad: +.nf +.sp +.ft I + vt100\0 tty01 + wyse60 tty02 + \0\0.\0\0\0 \0\0. + \0\0.\0\0\0 \0\0. + \0\0.\0\0\0 \0\0. +.ft R +.sp +.fi +Informacja ta s³u¿y do inicjowania zmiennej ¶rodowiska TERM. Wiersz +rozpoczynaj±cy siê znakiem # bêdzie traktowany jak komentarz. Je¿eli nie +podano tego parametru lub plik nie istnieje albo nie znaleziono w nim +linii terminala, to zmienna TERM nie zostanie ustawiona. +.\" +.IP "UID_MAX (liczba)" +XXX powinno zostaæ udokumentowane. +.IP "UID_MIN (liczba)" +XXX powinno zostaæ udokumentowane. +.\" +.IP "ULIMIT (d³uga liczba)" +Warto¶ci± t± inicjowany jest limit wielko¶ci pliku. Cecha ta obs³ugiwana +jest wy³±cznie w systemach posiadaj±cych +.IR ulimit , +np. System V. Je¶li nie podano, to limit wielko¶ci pliku zostanie ustalony +na pewn± wielk± warto¶æ. +.\" +.IP "UMASK (liczba)" +T± warto¶ci± inicjowana jest maska praw dostêpu. Nie podana, ustawia mask± +praw na zero. +.\" +.IP "USERDEL_CMD (napis)" +XXX powinno zostaæ udokumentowane. +.\" +.SH POWI¡ZANIA +Poni¿sze zestawienie pokazuje, które z programów wchodz±cych w sk³ad pakietu +shadow wykorzystuj± jakie parametry. +.na +.IP login 12 +CONSOLE DIALUPS_CHECK_ENAB ENV_HZ ENV_SUPATH ENV_TZ ERASECHAR FAILLOG_ENAB +FTMP_FILE HUSHLOGIN_FILE KILLCHAR LASTLOG_ENAB LOG_UNKFAIL_ENAB +MAIL_CHECK_ENAB MAIL_DIR MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB +QUOTAS_ENAB TTYPERM TTYTYPE_FILE ULIMIT UMASK +.IP newusers 12 +PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE UMASK +.IP passwd 12 +OBSCURE_CHECKS_ENAB PASS_MIN_LEN +.IP pwconv 12 +PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE +.IP su 12 +ENV_HZ ENV_SUPATH ENV_TZ HUSHLOGIN_FILE MAIL_CHECK_ENAB MAIL_DIR +MOTD_FILE NOLOGIN_STR QUOTAS_ENAB SULOG_FILE SYSLOG_SU_ENAB +.IP sulogin 12 +ENV_HZ ENV_SUPATH ENV_TZ MAIL_DIR QUOTAS_ENAB TTYPERM +.ad +.SH B£ÊDY +Niektóre z obs³ugiwanych parametrów konfiguracyjnych pozosta³y +nieopisane w niniejszym podrêczniku. +.SH ZOBACZ TAK¯E +.BR login (1), +.BR passwd (5), +.BR faillog (5), +.BR porttime (5), +.BR faillog (8) +.SH AUTORZY +Julianne Frances Haugh (jfh@austin.ibm.com) +.br +Chip Rosenthal (chip@unicom.com) diff --git a/current/man/pl/logoutd.8 b/current/man/pl/logoutd.8 new file mode 100644 index 00000000..d9f8f28a --- /dev/null +++ b/current/man/pl/logoutd.8 @@ -0,0 +1,50 @@ +.\" {PTM/WK/1999-09-17} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH LOGOUTD 8 +.SH NAZWA +logoutd \- wymuszenie ograniczeñ czasu logowania +.SH SK£ADNIA +.B logoutd +.SH OPIS +.B logoutd +wymusza ograniczenia portów i czasów logowania podane w +.IR /etc/porttime . +.B logoutd +powinno byæ uruchamiane z \fI/etc/rc\fR. +Okresowo przegl±dany jest plik \fI/etc/utmp\fR. Sprawdzana jest ka¿da nazwa +u¿ytkownika, by móc stwierdziæ czy posiada on zezwolenie na pracê w bie¿±cym +czasie na danym porcie. +Ka¿da sesja pracy (logowania) naruszaj±ca ograniczenia zawarte +w \fI/etc/porttime\fR jest koñczona. +.SH PLIKI +.IR /etc/porttime " - zezwolenia dla logowania na portach" +.br +.IR /etc/utmp " - bie¿±ce sesje pracy" +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/mkpasswd.8 b/current/man/pl/mkpasswd.8 new file mode 100644 index 00000000..815ea6ac --- /dev/null +++ b/current/man/pl/mkpasswd.8 @@ -0,0 +1,80 @@ +.\" {PTM/WK/1999-09-16} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: mkpasswd.8,v 1.1 1999/09/16 07:11:24 wojtek2 Exp $ +.\" +.TH MKPASSWD 1 +.SH NAZWA +mkpasswd \- aktualizuj pliki baz passwd i group +.SH SK£ADNIA +\fBmkpasswd\fR [\fB-fvgps\fR] \fIplik\fR +.SH OPIS +.B mkpasswd +czyta plik w formacie okre¶lonym przez flagi i konwertuje go postaci +odpowiedniego pliku bazy danych. +Wymienione pliki baz danych u¿ywane s± do poprawienia wydajno¶ci dostêpu +w systemach o du¿ej liczbie u¿ytkowników. +Pliki wynikowe otrzymaj± nazwy \fIplik\fR.dir i \fIplik\fR.pag. +.PP +Opcja \fB-f\fR powoduje, ¿e \fBmkpasswd\fR ignoruje istnienie plików +wynikowych i nadpisuje je. +Normalnie \fBmkpasswd\fR skar¿y siê na istnienie plików wynikowych +i koñczy pracê. +.PP +Opcja \fB-v\fR powoduje wy¶wietlanie informacji o ka¿dym konwertowanym +rekordzie oraz komunikatu koñcowego. +.PP +Opcja \fB-g\fR traktuje plik ¼ród³owy tak, jak gdyby by³ on w formacie +pliku \fI/etc/group\fR. +Przy po³±czeniu z opcj± \fB-s\fR u¿ywany jest format pliku \fI/etc/gshadow\fR. +.PP +Opcja \fB-p\fR traktuje plik ¼ród³owy tak, jak gdyby by³ on w formacie +pliku \fI/etc/passwd\fR. +Jest to opcja domy¶lna. +Przy po³±czeniu z opcj± \fB-s\fR u¿ywany jest format pliku \fI/etc/shadow\fR. +.SH PRZESTROGI +U¿ycie wiêcej ni¿ jednego pliku bazy ogranicza siê do systemów posiadaj±cych +bibliotekê baz danych NDBM. Mo¿e zatem nie byæ dostêpne w ka¿dym systemie. +.SH UWAGA +Poniewa¿ wiêkszo¶æ poleceñ jest w stanie aktualizowaæ pliki bazy danych +podczas dokonywania zmian, \fBmkpasswd\fR potrzebne jest jedynie +do ponownego utworzenia usuniêtego lub zepsutego pliku bazy. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/shadow " - chroniona informacja o u¿ytkownikach" +.br +.IR /etc/group " - informacja o grupach" +.br +.IR /etc/gshadow " - chroniona informacja o grupach" +.SH ZOBACZ TAK¯E +.BR passwd (5), +.BR group (5), +.BR shadow (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/newgrp.1 b/current/man/pl/newgrp.1 new file mode 100644 index 00000000..eaf3b18e --- /dev/null +++ b/current/man/pl/newgrp.1 @@ -0,0 +1,87 @@ +.\" {PTM/WK/1999-09-15} +.\" Copyright 1991, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: newgrp.1,v 1.2 1999/09/25 20:07:46 wojtek2 Exp $ +.\" +.TH NEWGRP 1 +.SH NAZWA +newgrp \- zmieñ identyfikator grupy +.br +sg \- wykonaj polecenie przy innym ID grupy +.SH SK£ADNIA +.BR newgrp " [" - ] +.RI [ grupa ] +.br +.BR sg " [" - ] +.RI [ grupa +.RB [ -c +.IR polecenie ]] +.SH OPIS +.B newgrp +s³u¿y do zmiany bie¿±cego identyfikatora grupy (GID) podczas sesji logowania. +Je¿eli podano opcjonaln± flagê \fB\-\fR, to ¶rodowisko u¿ytkownika zostanie +ponownie zainicjowane, tak jak wówczas, gdy u¿ytkownik siê loguje. Je¿eli nie +u¿yto flagi \fB\-\fR, to bie¿±ce ¶rodowisko, ³±cznie z bie¿±cym katalogiem +roboczym, pozostaje bez zmian. +.PP +.B newgrp +zmienia bie¿±cy faktyczny identyfikator grupy na identyfikator danej grupy +lub, je¶li nie podano nazwy grupy, na identyfikator grupy domy¶lnej, podanej +w \fI/etc/passwd\fR. +Je¿eli grupa posiada has³o, za¶ u¿ytkownik nie ma has³a b±d¼ nie jest jej +cz³onkiem, to zostanie poproszony o podanie has³a. +Je¿eli has³o grupy jest puste za¶ u¿ytkownik nie jest jej cz³onkiem, to +efektem bêdzie odmowa dostêpu. +.PP +Polecenie +.B sg +dzia³a podobnie do \fBnewgrp\fR, lecz nie zastêpuje pow³oki u¿ytkownika, +wiêc po zakoñczeniu \fBsg\fR powracasz do swego poprzedniego identyfikatora +grupy. +.B sg +przyjmuje tak¿e pojedyncze polecenie. Podane polecenie zostanie wykonane +w pow³oce Bourne'a i musi byæ umieszczone w cudzys³owach. +.\" enclosed in quotes. +.SH PRZESTROGI +Niniejsza wersja \fBnewgrp\fR posiada wiele opcji kompilacji, +z których tylko czê¶æ mo¿e byæ u¿yteczna w konkretnej instalacji. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/group " - informacja o grupach" +.SH ZOBACZ TAK¯E +.BR login (1), +.BR id (1), +.BR su (1) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz +z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/newusers.8 b/current/man/pl/newusers.8 new file mode 100644 index 00000000..077da942 --- /dev/null +++ b/current/man/pl/newusers.8 @@ -0,0 +1,69 @@ +.\" {PTM/WK/1999-09-15} +.\" Copyright 1991 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: newusers.8,v 1.3 1999/09/25 20:07:47 wojtek2 Exp $ +.\" +.TH NEWUSERS 8 +.SH NAZWA +newusers - wsadowa aktualizacja i tworzenie nowych u¿ytkowników +.SH SK£ADNIA +.B newusers +.RI [ nowi_u¿ytkownicy ] +.SH OPIS +\fBnewusers\fR odczytuje plik zawieraj±cy pary: nazwa u¿ytkownika i podane +jawnym tekstem has³o. Odczytan± informacjê wykorzystuje do aktualizacji grupy +istniej±cych u¿ytkowników lub utworzenia nowych. +Ka¿dy wiersz pliku posiada taki sam format jak standardowy plik hase³ (patrz +\fBpasswd\fR(5)), z nastêpuj±cymi wyj±tkami: +.IP "\fIpw_passwd\fR" 10 +To pole zostanie zakodowane i u¿yte jako nowa warto¶æ zakodowanego has³a. +.IP "\fIpw_age\fR" +Dla chronionych hase³ (shadow) pole zostanie zignorowane je¶li u¿ytkownik ju¿ +istnieje. +.IP "\fIpw_gid\fR" +Pole to mo¿e zawieraæ nazwê istniej±cej grupy. Dany u¿ytkownik zostanie +wówczas dodany do jej cz³onków. Je¿eli podano numeryczny identyfikator +nieistniej±cej grupy, to zostanie za³o¿ona nowa grupa o tym identyfikatorze. +.IP "\fIpw_dir\fR" +Zostanie wykonane sprawdzenie czy istnieje katalog o tej nazwie. Je¿eli nie, +to bêdzie on utworzony. W³a¶cicielem zostanie ustanowiony tworzony +(lub aktualizowany) u¿ytkownik. Grupa katalogu zostanie ustawiona na grupê +u¿ytkownika. +.PP +Polecenie to przeznaczone jest do u¿ytku w du¿ych systemach, gdzie aktualizuje +siê wiele kont naraz. +.SH PRZESTROGI +.\" Po u¿yciu \fBnewusers\fR musi zostaæ wykonane polecenie \fImkpasswd\fR, +.\" aktualizuj±ce pliki DBM hase³ (DBM password files). +Plik ¼ród³owy, zawieraj±cy niezakodowane has³a, musi byæ chroniony. +.SH ZOBACZ TAK¯E +.\" mkpasswd(8), passwd(1), useradd(1) +.BR passwd (1), +.BR useradd (8) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/passwd.1 b/current/man/pl/passwd.1 new file mode 100644 index 00000000..6e69c963 --- /dev/null +++ b/current/man/pl/passwd.1 @@ -0,0 +1,201 @@ +.\" {PTM/WK/1999-09-20} +.\" Copyright 1989 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH PASSWD 1 +.SH NAZWA +passwd \- zmieñ has³o u¿ytkownika +.SH SK£ADNIA +.B passwd +.RB [ -f | -s ] +.RI [ nazwa ] +.br +.B passwd +.RB [ -g ] +.RB [ -r | R ] +.I grupa +.br +.B passwd +.RB [ -x +.IR max ] +.RB [ -n +.IR min ] +.RB [ -w +.IR ostrze¿ ] +.RB [ -i +.IR nieakt ] +.I nazwa +.br +.B passwd +.RB { -l | -u | -d | -S } +.I nazwa +.SH OPIS +\fBpasswd\fR zmienia has³a kont u¿ytkowników i grup. +Zwyk³y u¿ytkownik mo¿e zmieniæ wy³±cznie has³o w³asnego konta, superu¿ytkownik +mo¿e zmieniaæ has³a dowolnych kont. +Administrator grupy mo¿e zmieniæ has³o tej grupy. +\fBpasswd\fR zmienia tak¿e informacje o koncie, takie jak pe³na nazwa +u¿ytkownika, jego pow³oka zg³oszeniowa (logowania) czy daty i interwa³y dotycz±ce +wa¿no¶ci has³a. +.SS Zmiany has³a +Na pocz±tku u¿ytkownik pytany jest o stare, dotychczasowe has³o, je¶li takie +istnieje. Has³o to jest kodowane i porównywane z przechowywanym has³em. +U¿ytkownik ma tylko jedn± próbê na wprowadzenie poprawnego has³a. +Superu¿ytkownikowi zezwala siê na pominiêcie tego kroku, zatem mog± byæ +zmienione has³a, których zapomniano. +.PP +Po wprowadzeniu has³a, sprawdzana jest informacja o jego wieku, by stwierdziæ +czy u¿ytkownikowi wolno w danym czasie zmieniæ has³o. +Je¿eli nie, to \fBpasswd\fR odmawia zmiany has³a i koñczy pracê. +.PP +Nastêpnie u¿ytkownik proszony jest o nowe, zastêpuj±ce dotychczasowe, has³o +Has³o podlega sprawdzeniu jego zawi³o¶ci. Jako ogóln± wskazówk± mo¿na podaæ, +¿e has³a powinny sk³adaæ siê z 6 do 8 znaków, zawieraj±c po jednym lub wiêcej +znaków z ka¿dej z poni¿szych kategorii: +.IP "" .5i +ma³e litery alfabetu +.IP "" .5i +du¿e litery alfabetu +.IP "" .5i +cyfry od 0 do 9 +.IP "" .5i +znaki interpunkcyjne +.PP +Nale¿y uwa¿aæ, by nie u¿yæ domy¶lnych systemowych znaków akcji erase lub kill. +\fBpasswd\fR odrzuci ka¿de niedostatecznie skomplikowane has³o. +.PP +Je¶li has³o zostanie przyjête, to \fBpasswd\fR prosi o jego powtórzenie +i porównuje drugi wpis z pierwszym. +Oba wpisy musz± byæ takie same by has³o zosta³o zmienione. +.SS Has³a grup +Je¿eli pos³u¿ono siê opcj± \fB-g\fR, to zmieniane jest has³o podanej grupy. +U¿ytkownik powinien byæ albo superu¿ytkownikiem albo administratorem tej grupy. +Nie wystêpuje pytanie o bie¿±ce has³o grupy. +Do usuwania bie¿±cego has³a danej grupy s³u¿y opcja \fB-g\fR w po³±czeniu +z \fB-r\fR. Pozwala to na dostêp do grupy tylko jej cz³onkom. +Opcja \fB-R\fR w po³±czeniu z \fR-g\fR ogranicza dostêp do grupy wszystkim +u¿ytkownikom. +.SS Informacja o wa¿no¶ci konta +Superu¿ytkownik mo¿e zmieniaæ informacjê o wieku konta pos³uguj±c siê opcjami +\fB-x\fR, \fB-n\fR, \fB-w\fR oraz \fB-i\fR. +Opcja \fB-x\fR s³u¿y do ustawiania maksymalnej liczby dni, przez jakie has³o +pozostaje wa¿ne. +Po up³ywie \fImax\fR dni, has³o musi byæ zmienione. +Opcja \fB-n\fR ustawia minimaln± liczbê dni, jakie musz± up³yn±æ zanim has³o +bêdzie mog³o byæ zmienione. +U¿ytkownik nie otrzyma zezwolenia na zmianê has³a przed up³ywem \fImin\fR dni. +Opcja \fB-w\fR s³u¿y do ustawienia liczby dni przed up³ywem terminu wa¿no¶ci +has³a, przez które u¿ytkownik bêdzie otrzymywa³ ostrze¿enie mówi±ce mu, ile dni +pozosta³o do tej daty. Ostrze¿enia zaczn± pojawiaæ siê \fIostrze¿\fR dni przed +up³ywem wa¿no¶ci has³a. +Opcja \fB-i\fR (nieaktywno¶æ) s³u¿y do wy³±czania konta po up³ywie zadanej +liczby dni po wyga¶niêciu has³a. +Po up³ywie \fInieakt\fR dni od przeterminowania has³a u¿ytkownik nie mo¿e ju¿ +korzystaæ z konta. +.SS Utrzymywanie i konserwacja konta +Konta u¿ytkowników mog± byæ blokowane i odblokowywane przy pomocy flag \fB-l\fR +i \fB-u\fR. +Opcja \fB-l\fR wy³±cza konto zmieniaj±c jego has³o na warto¶æ nieodpowiadaj±c± +¿adnemu mo¿liwemu zakodowanemu has³u. +Opcja \fB-u\fR ponownie udostêpnia konto przywracaj±c uprzedni± warto¶æ has³a. +.PP +Stan konta mo¿na uzyskaæ przy pomocy opcji \fB-S\fR. +Informacja o stanie sk³ada siê z 6 czê¶ci. +Pierwsza wskazuje, czy konto u¿ytkownika jest zablokowane (L) (locked), +nie posiada has³a (NP) (no password) lub ma funkcjonalne has³o (P) (password). +Druga czê¶æ podaje datê ostatniej zmiany has³a. +nastêpne cztery to minimalny wiek, maksymalny wiek, okres ostrzegania i okres +nieaktywno¶ci has³a. +.SS Podpowiedzi dotycz±ce hase³ u¿ytkownika +Bezpieczeñstwo has³a zale¿y od si³y algorytmu koduj±cego oraz rozmiaru +klucza. +Metoda kodowania u¿ywana w Systemie \fB\s-2UNIX\s+2\fR oparta jest o algorytm +NBS DES i jest bardzo bezpieczna. +Rozmiar klucza zale¿y od losowo¶ci wybranego has³a. +.PP +Naruszenia bezpieczeñstwa hase³ wynikaj± zwykle z beztroski przy wyborze lub +przechowywaniu has³a. +Z tego powodu powiniene¶ wybraæ has³o nie wystêpuj±ce w s³owniku. Has³o nie +powinno te¿ byæ poprawn± nazw±, imieniem, nazwiskiem, numerem prawa jazdy, +dat± urodzenia czy elementem adresu. +Wszystkie z powy¿szych mog± byæ u¿yte do odgadniêcia has³a i naruszenia +bezpieczeñstwa systemu. +.PP +Has³o musi byæ ³atwe do zapamiêtania, tak by nie byæ zmuszonym do jego +zapisywania na kartce. Mo¿na to osi±gn±æ sklejaj±c ze sob± dwa krótkie s³owa, +ze wstawionym pomiêdzy nie znakiem specjalnym lub cyfr±. +Na przyk³ad, Pass%word, Lew7konia. +.PP +Inna metoda konstrukcji has³a polega na wyborze ³atwego do zapamiêtania zdania +(np. z literatury) i wyborze pierwszej b±d¼ ostatniej litery ka¿dego wyrazu. +Przyk³adem tego jest +.IP "" .5i +Ask not for whom the bell tolls. +.PP +co daje +.IP "" .5i +An4wtbt, +.PP +albo te¿ +.IP "" .5i +A czy znasz Ty, bracie m³ody +.PP +co daje +.IP "" .5i +A3zTbm. +.PP +W zasadzie mo¿esz byæ pewien, ¿e niewielu crackerów bêdzie mieæ takie has³o +w swoim s³owniku. Powiniene¶ jednak wybraæ w³asn± metodê konstrukcji hase³ +a nie polegaæ wy³±cznie na opisanych tutaj. +.SS Uwagi o has³ach grup +Has³a grup s± nieod³±cznym problemem bezpieczeñstwa, gdy¿ do ich znajomo¶ci +uprawniona jest wiêcej ni¿ jedna osoba. +Grupy s± jednak u¿ytecznym narzêdziem pozwalaj±cym na wspó³pracê miêdzy +ró¿nymi u¿ytkownikami. +.SH PRZESTROGI +Mog± nie byæ obs³ugiwane wszystkie opcje. +Sprawdzanie z³o¿ono¶ci has³a mo¿e ró¿niæ siê w ró¿nych instalacjach. Zachêca +siê u¿ytkownika do wyboru tak skomplikowanego has³a, z jakim bêdzie mu +wygodnie. +U¿ytkownicy mog± nie móc zmieniæ has³a w systemie przy w³±czonym NIS, je¶li +nie s± zalogowani do serwera NIS. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/shadow " - zakodowane has³a u¿ytkowników" +.SH ZOBACZ TAK¯E +.BR passwd (3), +.BR shadow (3), +.BR group (5), +.BR passwd (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz +z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/passwd.5 b/current/man/pl/passwd.5 new file mode 100644 index 00000000..e4bcad8e --- /dev/null +++ b/current/man/pl/passwd.5 @@ -0,0 +1,88 @@ +.\" Copyright (c) 1993 Michael Haardt (u31b3hs@pool.informatik.rwth-aachen.de), Fri Apr 2 11:32:09 MET DST 1993 +.\" +.\" This is free documentation; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of +.\" the License, or (at your option) any later version. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with this manual; if not, write to the Free +.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, +.\" USA. +.\" +.\" Modified Sun Jul 25 10:46:28 1993 by Rik Faith (faith@cs.unc.edu) +.\" Modified Sun Aug 21 18:12:27 1994 by Rik Faith (faith@cs.unc.edu) +.\" Modified Sun Jun 18 01:53:57 1995 by Andries Brouwer (aeb@cwi.nl) +.\" +.\" Polish translation nov.1996 piotr.pogorzelski@ippt.gov.pl +.\" +.TH PASSWD 5 "24 Czerwiec 1993" "Linux" "Podrêcznik programisty linuxowego" +.SH NAZWA +passwd \- plik passwd definiuj±cy u¿ytkowników systemu +.SH OPIS +Plik +.B passwd +jest plikiem tekstowym ASCII, który zawiera listê u¿ytkowników systemu +oraz has³a jakich musz± u¿ywaæ aby otrzymaæ dostêp do systemu. +Ka¿dy powinien móc odczytaæ informacje z pliku passwd (poniewa¿ has³a +w tym pliku s± zakodowane jest to poprawne) lecz prawo do modyfikacji +pliku powinien mieæ tylko administrator. +Dodaj±c nowego u¿ytkownika nale¿y pole przeznaczone na has³o pozostawiæ puste +i u¿yæ programu \fBpasswd\fP(1). Gwiazdka lub inny pojedynczy znak w polu +has³a oznacza, ze u¿ytkownik nie mo¿e dostaæ siê do systemu przez \fBlogin\fP(1). +Je¶li g³ówny system plików jest na ram dysku (/dev/ram) nale¿y +plik passwd skopiowaæ na dyskietkê przechowuj±c± g³ówny system plików +przed zamkniêciem systemu. Trzeba równie¿ sprawdziæ prawa dostêpu do. +Je¶li trzeba utworzyæ grupê u¿ytkowników, ich identyfikatory grupy +GID musz± byæ równe oraz musi istnieæ odpowiednia pozycja w pliku +\fI/etc/group\fP, lub grupa nie bêdzie istnia³a. +.PP +Ka¿da pozycja zajmuje jeden wiersz w formacie: +.sp +login_name:has³o:UID:GID:imie_nazwisko:katalog:pow³oka +.RS +.RE +.sp +Krótki opis poszczególnych pól: +.sp +.RS +.TP 1.0in +.I login_name +nazwa u¿ytkownika w systemie (radzê u¿ywaæ ma³ych liter). +.TP +.I has³o +zakodowane has³o u¿ytkownika. +.TP +.I UID +identyfikator u¿ytkownika (liczbowo). +.TP +.I GID +identyfikator grupy (liczbowo). +.TP +.I imiê_nazwisko +Opisowa nazwa u¿ytkownika, zwykle imiê i nazwisko (wykorzystywane +przez programy pocztowe). +.TP +.I katalog +katalog macierzysty ($HOME) u¿ytkownika. +.TP +.I pow³oka +program jaki uruchomiæ po wej¶ciu u¿ytkownika do systemu. +(je¶li pusty u¿yj /bin/sh, je¶li istnieje /etc/shells i +dana pow³oka nie jest tam wymieniona, u¿ytkownik nie bêdzie móg³ +dostaæ siê do systemu wykorzystuj±c protokó³ ftp). +.RE +.SH PLIKI +.I /etc/passwd +.SH "ZOBACZ TAK¯E" +.BR passwd "(1), " login "(1), " group (5) diff --git a/current/man/pl/porttime.5 b/current/man/pl/porttime.5 new file mode 100644 index 00000000..83f0af6a --- /dev/null +++ b/current/man/pl/porttime.5 @@ -0,0 +1,81 @@ +.\" {PTM/WK/1999-09-17} +.\" Copyright 1989 - 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH PORTTIME 5 +.SH NAZWA +porttime \- plik czasów dostêpu do portów +.SH OPIS +.I porttime +zawiera listê urz±dzeñ tty, nazw u¿ytkowników i dozwolonych czasów logowania. +.PP +Ka¿da pozycja sk³ada siê z trzech, rozdzielonych dwukropkiem, pól. +Pierwsze pole zawiera listê oddzielonych przecinkami urz±dzeñ tty lub +gwiazdkê, wskazuj±c±, ¿e pozycja ta pasuje do wszystkich urz±dzeñ tty. +Drugie pole zawiera listê oddzielonych przecinkami nazw u¿ytkowników lub +gwiazdkê, wskazuj±c±, ¿e pozycja dotyczy wszystkich u¿ytkowników. +Trzecie pole jest list± oddzielonych przecinkami dozwolonych czasów dostêpu. +.PP +Ka¿da pozycja czasu dostêpu sk³ada siê z zera lub wiêcej dni tygodnia, +skróconych do \fBSu\fR, \fBMo\fR, \fBTu\fR, \fBWe\fR, \fBTh\fR, \fBFr\fR +i \fBSa\fR, po których nastêpuje para rozdzielonych my¶lnikiem czasów. +Do okre¶lenia dni roboczych (od poniedzia³ku do pi±tku) mo¿e byæ u¿yty +skrót \fBWk\fR. Skrót \fBAl\fR oznacza ka¿dy dzieñ. Je¿eli nie podano dni +tygodnia przyjmowane jest \fBAl\fR. +.SH PRZYK£ADY +Poni¿szy wpis zezwala u¿ytkownikowi \fBjfh\fR na dostêp do ka¿dego portu +w dni robocze od godziny 9-tej do 17-tej. +.br +.sp 1 + *:jfh:Wk0900-1700 +.br +.sp 1 +Poni¿sze pozycje pozwalaj± na dostêp do konsoli (/dev/console) wy³±cznie +u¿ytkownikom \fBroot\fR i \fBoper\fR - w dowolnym czasie. +Przyk³ad ten pokazuje, ¿e plik \fI/etc/porttime\fR stanowi uporz±dkowan± +listê czasów dostêpu. Ka¿dy inny u¿ytkownik bêdzie pasowa³ do drugiej pozycji +listy, nie zezwalaj±cej na dostêp w ¿adnym czasie. +.br +.sp 1 + console:root,oper:Al0000-2400 +.br + console:*: +.br +.sp 1 +Poni¿szy wpis zezwala na dostêp do dowolnego portu u¿ytkownikowi \fBgames\fR +poza godzinami pracy. +.br +.sp 1 + *:games:Wk1700-0900,SaSu0000-2400 +.br +.sp 1 +.SH PLIKI +.IR /etc/porttime " - plik zawieraj±cy czasy dostêpu do portów" +.SH ZOBACZ TAK¯E +.BR login (1) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/pw_auth.3 b/current/man/pl/pw_auth.3 new file mode 100644 index 00000000..ddebc0c1 --- /dev/null +++ b/current/man/pl/pw_auth.3 @@ -0,0 +1,152 @@ +.\" {PTM/WK/1999-09-15} +.\" Copyright 1992 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: pw_auth.3,v 1.1 1999/09/16 07:11:23 wojtek2 Exp $ +.\" +.TH PWAUTH 3 +.SH NAZWA +pwauth \- procedury uwierzytelniania hase³ zdefiniowane przez administratora +.SH SK£ADNIA +.B #include +.PP +.B int pw_auth (char +.I *command, +.B char +.I *user, +.B int +.I reason, +.B char +.IB *input) ; +.SH OPIS +.B pw_auth +wywo³uje funkcje zdefiniowane przez administratora dla danego u¿ytkownika. +.PP +\fIcommand\fR jest nazw± programu uwierzytelniania (autentykacji). +Jest ona otrzymywana z informacji zawartej pliku hase³ u¿ytkowników. +Odpowiedni ³añcuch (z pola has³a) zawiera jedn± lub wiêcej, rozdzielonych +¶rednikami, nazw plików wykonywalnych. +Programy zostan± wykonane w zadanej kolejno¶ci. +Dla ka¿dej z przyczyn (reason) podanych ni¿ej podane s± argumenty wiersza +poleceñ. +.PP +\fIuser\fR jest nazw± sprawdzanego u¿ytkownika, w postaci podanej w pliku +\fI/etc/passwd\fR. +Pozycje opisuj±ce u¿ytkowników indeksowane s± nazw± u¿ytkownika. +Pozwala to na istnienie powtarzaj±cych siê identyfikatorów (UID). Ka¿da +z ró¿nych nazw u¿ytkownika o tym samym identyfikatorze mo¿e +posiadaæ inny program i informacjê autentykuj±c±. +.PP +Ka¿da z dopuszczalnych przyczyn autentykacji obs³ugiwana jest w potencjalnie +ró¿ny sposób. +Do komunikacji z u¿ytkownikiem dostêpne s± standardowe deskryptory plików +0, 1 i 2, chyba ¿e wspomniano inaczej. +Do ustalenia to¿samo¶ci u¿ytkownika wykonuj±cego ¿±danie uwierzytelnienia +mo¿e zostaæ u¿yty rzeczywisty identyfikator. +Przyczyna (\fIreason\fR) jest jedn± z +.IP \fBPW_SU\fR 1i +Wykonaj uwierzytelnienie dla bie¿±cego rzeczywistego identyfikatora u¿ytkownika +próbuj±c prze³±czyæ rzeczywisty ID na podanego u¿ytkownika. +Program uwierzytelniaj±cy zostanie wywo³any z opcj± \fB-s\fR poprzedzaj±c± +nazwê u¿ytkownika. +.IP \fBPW_LOGIN\fR 1i +Wykonaj uwierzytelnienie dla danego u¿ytkownika tworz±c now± sesjê pracy +(loginow±). Program uwierzytelniaj±cy zostanie wywo³any z opcj± \fB-l\fR, +po której wyst±pi nazwa u¿ytkownika. +.IP \fBPW_ADD\fR 1i +Utwórz nowy wpis dla danego u¿ytkownika. +Pozwala to programowi uwierzytelniania na zainicjowanie miejsca dla nowego +u¿ytkownika. +Program zostanie wywo³any z opcj± \fB-a\fR, po której wyst±pi nazwa u¿ytkownika. +.IP \fBPW_CHANGE\fR 1i +Zmieñ istniej±cy wpis dla danego u¿ytkownika. +Pozwala to na programowi uwierzytelniaj±cemu na zmianê informacji autentykuj±cej +dla istniej±cego u¿ytkownika. +Program zostanie wywo³any z opcj± \fB-c\fR poprzedzaj±c± nazwê u¿ytkownika. +.IP \fBPW_DELETE\fR 1i +Usuñ informacjê autentykuj±c± dla danego u¿ytkownika. +Pozwala programowi uwierzytelniania na odzyskanie miejsca po u¿ytkowniku, który +nie bêdzie ju¿ identyfikowany przy u¿yciu tego programu. +Program uwierzytelniania zostanie wywo³any z opcj± \fB-d\fR, +po której wyst±pi nazwa u¿ytkownika. +.IP \fBPW_TELNET\fR 1i +Wykonaj uwierzytelnianie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy +polecenia \fBtelnet\fR. +Program zostanie wywo³any z opcj± \fB-t\fR, po której wyst±pi nazwa u¿ytkownika. +.IP \fBPW_RLOGIN\fR 1i +Wykonaj uwierzytelnienie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy +polecenia \fBrlogin\fR. +Program zostanie wywo³any z opcj± \fB-r\fR, po której wyst±pi nazwa u¿ytkownika. +.IP \fBPW_FTP\fR 1i +Wykonaj uwierzytelnienie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy +polecenia \fBftp\fR. +Program uwierzytelniania zostanie wywo³any z opcj± \fB-f\fR, +po której wyst±pi nazwa u¿ytkownika. +Do komunikacji z u¿ytkownikiem NIE s± dostêpne standardowe deskryptory plików. +Deskryptor standardowego wej¶cia zostanie pod³±czony do procesu macierzystego, +za¶ pozosta³e dwa deskryptory plików dostan± pod³±czone do \fI/dev/null\fR. +Funkcja \fBpw_auth\fR bêdzie potokowaæ pojedynczy wiersz danych do programu +uwierzytelniania pos³uguj±c siê deskryptorem 0. +.IP \fBPW_REXEC\fR 1i +Wykonaj uwierzytelnienie u¿ytkownika pod³±czaj±cego siê do systemu przy pomocy +polecenia \fIrexec\fR. +Program zostanie wywo³any z opcj± \fB-x\fR, po której wyst±pi nazwa u¿ytkownika. +Do komunikacji ze zdalnym u¿ytkownikiem NIE s± dostêpne standardowe +deskryptory plików. +Deskryptor standardowego wej¶cia zostanie pod³±czony do procesu macierzystego, +za¶ pozosta³e dwa deskryptory plików dostan± pod³±czone do \fI/dev/null\fR. +Funkcja \fBpw_auth\fR bêdzie potokowaæ pojedynczy wiersz danych do programu +uwierzytelniania pos³uguj±c siê deskryptorem 0. +.PP +Ostatni argument stanowi dane autentykacji, u¿ywane przez +.B PW_FTP +oraz +.B PW_REXEC +Jest on traktowany jak pojedynczy wiersz tekstu potokowany do programu +uwierzytelniaj±cego. +Dla +.B PW_CHANGE +warto¶æ \fIinput\fR jest warto¶ci± poprzedniej nazwy u¿ytkownika, +je¶li zmieniana jest nazwa. +.SH PRZESTROGI +Funkcja ta nie tworzy faktycznej sesji. +Wskazuje jedynie, czy u¿ytkownik powinien otrzymaæ zezwolenie na jej +utworzenie. +.PP +Obecnie opcje sieciowe nie s± jeszcze przetestowane. +.SH DIAGNOSTYKA +Funkcja \fBpw_auth\fR zwraca 0 je¶li program uwierzytelniania zakoñczy³ +dzia³anie z zerowym kodem powrotu, w przeciwnym wypadku warto¶æ niezerow±. +.SH ZOBACZ TAK¯E +.BR login (1), +.BR passwd (1), +.BR su (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/pwauth.8 b/current/man/pl/pwauth.8 new file mode 100644 index 00000000..e87926c5 --- /dev/null +++ b/current/man/pl/pwauth.8 @@ -0,0 +1,65 @@ +.\" {PTM/WK/1999-09-15} +.\" Copyright 1992, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: pwauth.8,v 1.2 1999/09/25 20:07:47 wojtek2 Exp $ +.\" +.TH PWAUTH 8 +.SH NAZWA +pwauth \- definiowane przez administratora uwierzytelnianie hase³ +.SH OPIS +Administrator systemu mo¿e zdefiniowaæ listê programów, jakie s± u¿ywane +do potwierdzenia to¿samo¶ci u¿ytkownika. +Programy te podawane s± zamiast informacji o zakodowanym ha¶le obecnej +w pliku \fI/etc/passwd\fR albo \fI/etc/shadow\fR. +Narzêdzia administruj±ce kontami u¿ytkowników sprawdzaj± pole zakodowanego +has³a i stwierdzaj± czy u¿ytkownik posiada zdefiniowany przez administratora +program uwierzytelniaj±cy (autentykuj±cy). +Funkcja \fBpw_auth\fR zostanie wywo³ana ka¿dorazowo, gdy jeden z tych +programów administracyjnych stwierdzi, ¿e zmieniany u¿ytkownik posiada +zdefiniowane programy uwierzytelniania. +.PP +Pocz±tkowy wpis tworzony jest przez polecenie \fBuseradd\fR. +Zmiany, takie jak zmiana informacji autentykuj±cej lub usuniêcie konta +u¿ytkownika, spowoduj± wywo³anie funkcji \fBpw_auth\fR. Pozwala to +na utrzymanie aktualno¶ci informacji dla ka¿dego konta. +.PP +Programy uwierzytelniaj±ce nie tworz± sesji pracy (loginowych) ani +sesji sieciowych. Kod zakoñczenia programu uwierzytelniaj±cego jest +wskazaniem czy akcja bêdzie dozwolona. +Proces wo³aj±cy musi posiadaæ odpowiednie uprawnienia do samodzielnego +utworzenia sesji pracy lub sesji sieciowej. +.SH ZOBACZ TAK¯E +.BR login (1), +.BR passwd (1), +.BR su (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR pw_auth (3) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/pwck.8 b/current/man/pl/pwck.8 new file mode 100644 index 00000000..2b71c610 --- /dev/null +++ b/current/man/pl/pwck.8 @@ -0,0 +1,109 @@ +.\" {PTM/WK/1999-09-14} +.\" Copyright 1992, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: pwck.8,v 1.3 1999/09/25 20:07:47 wojtek2 Exp $ +.\" +.TH PWCK 1 +.SH NAZWA +pwck - weryfikacja spójno¶ci plików hase³ +.SH OPIS +\fBpwck\fR [\fB-r\fR] [\fIpasswd\fR \fIshadow\fR] +.SH OPIS +\fBpwck\fR weryfikuje integralno¶æ informacji autentykacji systemowej. +W plikach \fI/etc/passwd\fR i \fI/etc/shadow\fR sprawdzane s± wszystkie +pozycje, by upewniæ siê, ¿e ka¿da z nich posiada w³a¶ciwy format +i poprawne dane w ka¿dym z pól. U¿ytkownik monitowany jest o usuniêcie +pozycji, które s± sformatowane niepoprawnie lub posiadaj± inne nie daj±ce +siê skorygowaæ b³êdy. +.P +Kontrolowane jest czy ka¿da pozycja posiada +.sp +.in +.5i +- w³a¶ciw± liczbê pól +.br +- unikaln± nazwê u¿ytkownika +.br +- poprawny identyfikator u¿ytkownika i grupy +.br +- poprawn± grupê g³ówn± +.br +- poprawny katalog domowy +.br +- poprawn± pow³okê zg³oszeniow± (startow±) +.in -.5i +.sp +.P +Kontrola w³a¶ciwej liczby pól i niepowtarzalnej nazwy u¿ytkownika jest +decyduj±ca. Je¿eli pozycja posiada b³êdn± liczbê pól, to u¿ytkownik jest +proszony o usuniêcie ca³ej pozycji (wiersza). +Je¿eli u¿ytkownik nie potwierdzi decyzji o usuniêciu, to pomijane s± wszelkie +dalsze sprawdzenia. +Pozycja z powtórzon± nazw± u¿ytkownika powoduje monit o usuniêcie, ale nadal +bêd± wykonywane pozosta³e sprawdzenia. +Wszystkie inne b³êdy daj± ostrze¿enia a u¿ytkownik jest zachêcany +do uruchomienia polecenia \fBusermod\fR, by je poprawiæ. +.P +Polecenia dzia³aj±ce na pliku \fI/etc/passwd\fR nie potrafi± zmieniaæ +uszkodzonych lub powielonych pozycji. W takich okoliczno¶ciach powinien byæ +u¿ywany \fBpwck\fR, by usun±æ nieprawid³ow± pozycjê. +.SH OPCJE +Domy¶lnie \fBpwck\fR dzia³a na plikach \fI/etc/passwd\fR oraz \fI/etc/shadow\fR. +Przy pomocy parametrów \fIpasswd\fR i \fIshadow\fR u¿ytkownik mo¿e wybraæ inne +pliki. +Dodatkowo, u¿ytkownik mo¿e wykonaæ polecenie w trybie tylko-do-odczytu, poprzez +podanie flagi \fB-r\fR. +Powoduje to, ¿e na wszystkie pytania dotycz±ce zmian zostanie, bez ingerencji +u¿ytkownika, u¿yta odpowied¼ \fBnie\fR. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/shadow " - zakodowana informacja o has³ach" +.br +.IR /etc/group " - informacja o grupach" +.SH ZOBACZ TAK¯E +.BR usermod (8), +.BR group (5), +.BR passwd (5), +.BR shadow (5) +.SH DIAGNOSTYKA +Polecenie \fBpwck\fR koñczy pracê z nastêpuj±cymi warto¶ciami kodów +zakoñczenia: +.IP 0 5 +Powodzenie +.IP 1 5 +B³±d sk³adni +.IP 2 5 +Jedna lub wiêcej z³ych pozycji pliku hase³ +.IP 3 5 +Niemo¿liwe otwarcie plików hase³ +.IP 4 5 +Niemo¿liwa blokada plików hase³ +.IP 5 5 +Niemo¿liwa aktualizacja plików hase³ +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/pwconv.8 b/current/man/pl/pwconv.8 new file mode 100644 index 00000000..0916ca28 --- /dev/null +++ b/current/man/pl/pwconv.8 @@ -0,0 +1,66 @@ +.\" {PTM/WK/1999-09-14} +.\" $Id: pwconv.8,v 1.1 1999/09/14 18:41:35 wojtek2 Exp $ +.TH PWCONV 8 "26 wrze¶nia 1997" +.SH NAZWA +pwconv, pwunconv, grpconv, grpunconv - konwersja dot. chronionych plików hase³ i grup +.SH SK£ADNIA +.B pwconv +.br +.B pwunconv +.br +.B grpconv +.br +.B grpunconv +.SH OPIS +Wszystkie te cztery programy dzia³aj± na zwyk³ych i dodatkowych (shadow) +plikach hase³ i grup: +.IR /etc/passwd ", " /etc/group ", " /etc/shadow " i " /etc/gshadow . + +.B pwconv +.RI "tworzy " shadow " z " passwd " i opcjonalnie istniej±cego " shadow . +.B pwunconv +.RI "tworzy " passwd " z " passwd " i " shadow " a nastêpnie usuwa " shadow . +.B grpconv +.RI "tworzy " gshadow " z " group " i opcjonalnie istniej±cego " gshadow . +.B grpunconv +.RI "tworzy " group " z " group " i " gshadow " a nastêpnie usuwa " gshadow . + +Ka¿dy z programów zdobywa niezbêdne blokady przed konwersj±. + +.BR pwconv " i " grpconv +s± podobne. Po pierwsze, z pliku dodatkowego usuwane s± pozycje, które +nie istniej± w pliku g³ównym. Nastêpnie, w pliku dodatkowym aktualizowane s± +pozycje nie posiadaj±ce 'x' jako has³a w pliku g³ównym. Dodawane s± pozycje +brakuj±ce w stosunku do pliku g³ównego. Na koniec, has³a w pliku g³ównym +zastêpowane s± przez 'x'. Programy te mog± s³u¿yæ zarówno do pocz±tkowej +konwersji jak i do aktualizacji dodatkowego pliku hase³ je¶li plik g³ówny +zmieniany by³ rêcznie. + +Przy dodawaniu nowych wpisów do +.IR /etc/shadow +.B pwconv +u¿yje warto¶ci +.BR PASS_MIN_DAYS ", " PASS_MAX_DAYS " i " PASS_WARN_AGE +z pliku +.IR /etc/login.defs . + +.RB "Podobnie, " pwunconv " oraz " grpunconv +s± zbli¿one. Has³a w pliku g³ównym aktualizowane s± na podstawie pliku +dodatkowego (shadow). Wpisy istniej±ce w pliku g³ównym, a nie posiadaj±ce +odpowiedników w dodatkowym s± pozostawiane bez zmian. Na koniec usuwany +jest plik dodatkowy. + +Czê¶æ informacji o wa¿no¶ci hase³ jest tracona przez +.BR pwunconv . +Przeprowadza on konwersjê tego, co potrafi. +.SH B£ÊDY +B³êdy w plikach hase³ czy grup (takie jak nieprawid³owe czy powtórzone +pozycje) mog± spowodowaæ zapêtlenie siê omawianych programów lub ró¿nego +rodzaju inne b³êdne zachowanie. Przed konwersj± na lub z dodatkowych plików +hase³ lub grup proszê uruchomiæ \fBpwck\fR i \fBgrpck\fR, by poprawiæ tego +rodzaju b³êdy. +.SH ZOBACZ TAK¯E +.BR login.defs (5), +.BR pwck (8), +.BR grpck (8), +.BR shadowconfig (8) diff --git a/current/man/pl/shadow.3 b/current/man/pl/shadow.3 new file mode 100644 index 00000000..5ad19a23 --- /dev/null +++ b/current/man/pl/shadow.3 @@ -0,0 +1,148 @@ +.\" {PTM/WK/1999-09-16} +.\" Copyright 1989 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: shadow.3,v 1.2 1999/09/25 20:07:47 wojtek2 Exp $ +.\" +.TH SHADOW 3 +.SH NAZWA +shadow \- procedury zakodowanego pliku hase³ +.SH SK£ADNIA +.B #include +.PP +.B struct spwd *getspent(); +.PP +.B struct spwd *getspnam(char +.IB *name ); +.PP +.B void setspent(); +.PP +.B void endspent(); +.PP +.B struct spwd *fgetspent(FILE +.IB *fp ); +.PP +.B struct spwd *sgetspent(char +.IB *cp ); +.PP +.B int putspent(struct spwd +.I *p, +.B FILE +.IB *fp ); +.PP +.B int lckpwdf(); +.PP +.B int ulckpwdf(); +.SH OPIS +.I shadow +operuje na zawarto¶ci dodatkowego pliku hase³ (shadow) \fI/etc/shadow\fR. +Plik \fI#include\fR opisuje strukturê +.sp +struct spwd { +.in +.4i +.br +char *sp_namp; /* nazwa u¿ytkownika (login) */ +.br +char *sp_pwdp; /* zakodowane has³o */ +.br +long sp_lstchg; /* ostatnia zmiana has³a */ +.br +int sp_min; /* dni do dozwolonej zmiany */ +.br +int sp_max; /* dni przed wymagan± zmian± */ +.br +int sp_warn; /* dni ostrze¿enia o wyga¶niêciu */ +.br +int sp_inact; /* dni przed wy³±czeniem konta */ +.br +int sp_expire; /* data wa¿no¶ci konta */ +.br +int sp_flag; /* zarezerwowane do przysz³ego u¿ytku */ +.br +.in -.5i +} +.PP +Znaczenie poszczególnych pól: +.sp +sp_namp \- wska¼nik do zakoñczonej przez nul nazwy u¿ytkownika. +.br +sp_pwdp \- wska¼nik do zakoñczonego nul has³a. +.br +sp_lstchg \- dni od 1 stycznia 1970; data ostatniej zmiany has³a. +.br +sp_min \- dni, przed up³ywem których has³o nie mo¿e byæ zmienione. +.br +sp_max \- dni, po których has³o musi byæ zmienione. +.br +sp_warn \- dni przed dat± up³ywu wa¿no¶ci has³a, od których +u¿ytkownik jest ostrzegany od nadchodz±cym terminie wa¿no¶ci. +.br +sp_inact \- dni po up³yniêciu wa¿no¶ci konta, po których konto jest +uwa¿ane za nieaktywne i wy³±czane. +.br +sp_expire \- dni od 1 stycznia 1970, data gdy konto zostanie +wy³±czone. +.br +sp_flag \- zarezerwowane do przysz³ego u¿ytku. +.SH OPIS +\fBgetspent\fR, \fBgetspname\fR, \fBfgetspent\fR i \fBsgetspent\fR +zwracaj± wska¼nik do \fBstruct spwd\fR. +\fBgetspent\fR zwraca nastêpn± pozycjê w pliku, za¶ \fBfgetspent\fR +nastêpn± pozycjê z podanego strumienia. Zak³ada siê, ¿e strumieñ +ten jest plikiem o poprawnym formacie. +\fBsgetspent\fR zwraca wska¼nik do \fBstruct spwd\fR u¿ywaj±c jako +wej¶cia dostarczonego ³añcucha. +\fBgetspnam\fR wyszukuje od bie¿±cej pozycji w pliku pozycji pasuj±cej +do \fBname\fR. +.PP +\fBsetspent\fR i \fBendspent\fR mog± zostaæ u¿yte do odpowiednio, +rozpoczêcia i zakoñczenia dostêpu do chronionego pliku hase³ (shadow). +.PP +Do zapewnienia wy³±cznego dostêpu do pliku \fI/etc/shadow\fR powinny +byæ u¿ywane procedury \fBlckpwdf\fR i \fBulckpwdf\fR. +\fBlckpwdf\fR przez 15 sekund usi³uje uzyskaæ blokadê przy pomocy +\fBpw_lock\fR. +Kontynuuje próbê uzyskania drugiej blokady przy pomocy \fBspw_lock\fR +przez czas pozosta³y z pocz±tkowych 15 sekund. +Je¿eli po up³ywie 15 sekund którakolwiek z tych prób zawiedzie, +to \fBlckpwdf\fR zwraca -1. +Je¿eli uzyskano obie blokady, to zwracane jest 0. +.SH DIAGNOSTYKA +Je¿eli nie ma dalszych pozycji lub podczas przetwarzania pojawi siê b³±d, +to procedury zwracaj± NULL. +Procedury zwracaj±ce warto¶æ typu \fBint\fR zwracaj± 0 w przypadku powodzenia +a -1 dla pora¿ki. +.SH PRZESTROGI +Procedury te mog± byæ u¿ywane wy³±cznie przez superu¿ytkownika, gdy¿ dostêp +do dodatkowego, chronionego pliku hase³ jest ograniczony. +.SH PLIKI +.IR /etc/shadow " - zakodowane has³a u¿ytkowników" +.SH ZOBACZ TAK¯E +.BR getpwent (3), +.BR shadow (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pl/shadow.5 b/current/man/pl/shadow.5 new file mode 100644 index 00000000..8997bead --- /dev/null +++ b/current/man/pl/shadow.5 @@ -0,0 +1,92 @@ +.\" 1999 PTM Przemek Borys +.\" Copyright 1989 - 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: shadow.5,v 1.3 1999/09/20 20:56:42 wojtek2 Exp $ +.\" +.TH SHADOW 5 +.SH NAZWA +shadow \- zakodowany plik z has³ami +.SH OPIS +.I shadow +zawiera zakodowane dane o has³ach dla kont u¿ytkowników oraz opcjonalne +informacje o wieku (aging) has³a. +Zawarte s± w nim +.IP "" .5i +Nazwa u¿ytkownika (nazwa logowania) +.IP "" .5i +Zakodowane has³o +.IP "" .5i +Dni, licz±c od 1 stycznia 1970, kiedy has³o by³o ostatni raz zmienione +.IP "" .5i +Dni przed których up³yniêciem niemo¿liwa jest zmiany has³a +.IP "" .5i +Dni, po których up³yniêciu konieczna jest zmiana has³a +.IP "" .5i +Ilo¶æ dni, jaka musi dzieliæ has³o od przedawnienia, by u¿ytkownik by³ +ostrzegany +.IP "" .5i +Ilo¶æ dni po przedawnieniu has³a, po których konto jest wy³±czane +.IP "" .5i +Dni od 1 stycznia 1970, okre¶laj±ce datê, kiedy konto jest wy³±czane +.IP "" .5i +Pole zarezerwowane +.PP +Pole has³a musi byæ wype³nione. Zakodowane has³o sk³ada siê z 13-24 znaków z +64 znakowego alfabetu a-z, A-Z, 0-9, \. i /. +Dla szczegó³ów interpretacji tego napisu, odsy³amy do \fIcrypt(3)\fR. +.PP +Data ostatniej zmiany has³a jest podawana jako liczba dni od 1 stycznia +1970. Has³a nie mog± byæ zmieniane przed up³ywem odpowiedniej ilo¶ci dni, a +musz± byæ zmieniane po up³ywie maksymalnej ilo¶ci dni. +Je¶li minimalna liczba dni jest wiêksza od maksymalnej, has³o nie mo¿e byæ +przez u¿ytkownika zmienione. +.PP +Je¶li has³o pozostaje niezmienione po up³ywie jego wa¿no¶ci, to konto jest +uwa¿ane za nieaktywne i zostanie wy³±czone po ustalonej liczbie dni +nieaktywno¶ci. Konto zostanie równie¿ wy³±czone w zadanym dniu wa¿no¶ci +konta bez wzglêdu na informacjê o terminie wa¿no¶ci has³a. +.PP +Informacja w pliku \fIshadow\fR zastêpuje wszelkie has³a lub dane o ich +wieku znajduj±ce siê w \fI/etc/passwd\fR. +.PP +Je¶li ma byæ utrzymywane bezpieczeñstwo hase³, to plik ten nie mo¿e byæ +odczytywalny dla zwyk³ych u¿ytkowników. +.SH Pliki +.IR /etc/passwd " - informacje o kontach u¿ytkowników" +.br +.IR /etc/shadow " - zakodowane has³a u¿ytkowników" +.SH ZOBACZ TAK¯E +chage(1), +login(1), +passwd(1), +su(1), +sulogin(1M), +shadow(3), +passwd(5), +pwconv(8), +pwunconv(8) diff --git a/current/man/pl/shadowconfig.8 b/current/man/pl/shadowconfig.8 new file mode 100644 index 00000000..2d37c1f2 --- /dev/null +++ b/current/man/pl/shadowconfig.8 @@ -0,0 +1,27 @@ +.\" {PTM/WK/1999-09-14} +.\" $Id: shadowconfig.8,v 1.1 1999/09/14 18:41:35 wojtek2 Exp $ +.TH SHADOWCONFIG 8 "19 kwietnia 1997" "Debian GNU/Linux" +.SH NAZWA +shadowconfig - prze³±cza ochronê hase³ i grup przez pliki shadow +.SH SK£ADNIA +.B "shadowconfig" +.IR on " | " off +.SH OPIS +.PP +.B shadowconfig on +w³±cza ochronê hase³ i grup przez dodatkowe, przes³aniane pliki (shadow); +.B shadowconfig off +wy³±cza dodatkowe pliki hase³ i grup. +.B shadowconfig +wy¶wietla komunikat o b³êdzie i koñczy pracê z niezerowym kodem je¶li +znajdzie co¶ nieprawid³owego. W takim wypadku powiniene¶ poprawiæ b³±d +.\" if it finds anything awry. +i uruchomiæ program ponownie. + +W³±czenie ochrony hase³, gdy jest ona ju¿ w³±czona lub jej wy³±czenie, +gdy jest wy³±czona jest nieszkodliwe. + +Przeczytaj +.IR /usr/doc/passwd/README.debian.gz , +gdzie znajdziesz krótkie wprowadzenie do ochrony hase³ z u¿yciem dodatkowych +plików hase³ przes³anianych (shadow passwords) i zwi±zanych tematów. diff --git a/current/man/pl/su.1 b/current/man/pl/su.1 new file mode 100644 index 00000000..d561e67c --- /dev/null +++ b/current/man/pl/su.1 @@ -0,0 +1,87 @@ +.\" {PTM/WK/1999-09-25} +.\" Copyright 1989 - 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.TH SU 1 +.SH NAZWA +su \- zmieñ ID u¿ytkownika lub stañ siê superu¿ytkownikiem +.SH SK£ADNIA +.BR su " [" - ] +.RI [ nazwa_u¿ytkownika " [" argumenty ]] +.SH OPIS +.B su +s³u¿y do stawania siê innym u¿ytkownikiem w trakcie w³asnej sesji pracy. +Wywo³anie bez parametru - nazwy u¿ytkownika, domy¶lnie oznacza dla \fBsu\fR +próbê stania siê superu¿ytkownikiem. +Opcjonalnym argumentem \fB\-\fR mo¿na pos³u¿yæ siê do zasymulowania +rzeczywistego rozpoczynania sesji pracy. Pozwala to na utworzenie ¶rodowiska +u¿ytkownika. podobnego do tego, jakie wystêpuje przy bezpo¶rednim zg³oszeniu +u¿ytkownika w systemie. +.PP +Po nazwie u¿ytkownika mog± wyst±piæ dodatkowe argumenty. Zostan± one +dostarczone pow³oce zg³oszeniowej u¿ytkownika. W szczególno¶ci, argument +\fB-c\fR spowoduje, ¿e nastêpny argument zostanie potraktowany jak polecenie +przez wiêkszo¶æ interpretatorów poleceñ. +.\" Polecenie zostanie wykonane przez pow³okê podan± w +.\" \fB$SHELL\fR, albo je¶li jej nie zdefiniowano, przez podan± w +.\" \fI/etc/passwd\fR. +.\" XXX - powy¿sze nie by³o ca³kiem poprawne. --marekm +Polecenie zostanie wykonane przez pow³okê wymienion± w \fI/etc/passwd\fR dla +docelowego u¿ytkownika. +.PP +U¿ytkownik pytany jest o odpowiednie has³o, je¶li takowe istnieje. +B³êdne has³a powoduj± komunikat o b³êdzie. Wszystkie próby, udane i nieudane, +s± rejestrowane do celów wykrywania nadu¿yæ systemu. +.PP +Do nowej pow³oki przekazywane jest bie¿±ce ¶rodowisko. +Warto¶æ \fB$PATH\fR dla zwyk³ych u¿ytkowników ustawiana jest jest na +\fB/bin:/usr/bin\fR, za¶ dla superu¿ytkownika +na \fB/sbin:/bin:/usr/sbin:/usr/bin\fR. +Mo¿na to zmieniæ przy pomocy definicji \fBENV_PATH\fR i \fBENV_SUPATH\fR +w \fI/etc/login.defs\fR. +.SH PRZESTROGI +.PP +Niniejsza wersja \fBsu\fR posiada wiele opcji kompilacji, z których tylko +czê¶æ bêdzie mieæ zastosowanie w danej instalacji. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/shadow " - zakodowane has³a i informacja o ich wa¿no¶ci" +.br +.IR $HOME/.profile " - plik startowy dla domy¶lnej pow³oki" +.SH ZOBACZ TAK¯E +.BR login (1), +.BR sh (1), +.BR suauth (5), +.BR login.defs (5) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) +.SH OD T£UMACZA +Niniejsza dokumentacja opisuje polecenie wchodz±ce w sk³ad pakietu +shadow-password. +Z uwagi na powtarzaj±ce siê nazwy poleceñ, upewnij siê, ¿e korzystasz +z w³a¶ciwej dokumentacji. diff --git a/current/man/pl/suauth.5 b/current/man/pl/suauth.5 new file mode 100644 index 00000000..c3a54ac7 --- /dev/null +++ b/current/man/pl/suauth.5 @@ -0,0 +1,115 @@ +.\" {PTM/WK/1999-09-14} +.TH SUAUTH 5 "14 lutego 1996" +.UC 5 +.SH NAZWA +suauth - plik szczegó³owej kontroli su +.\" detailed su control file +.SH SK£ADNIA +.B /etc/suauth +.SH OPIS +Plik +.I /etc/suauth +przeszukiwany jest przy ka¿dym wywo³aniu polecenia su. Mo¿e on zmieniaæ +zachowanie siê polecenia su, w oparciu o +.PP +.RS +.nf +1) u¿ytkownika, na którego konto wykonywane jest su +.fi +2) u¿ytkownika wykonuj±cego polecenie su (lub dowoln± z grup, której mo¿e +on byæ cz³onkiem) +.RE +.PP +Plik sformatowany jest jak poni¿ej. Wiersze rozpoczynaj±ce siê od # s± +traktowane jak wiersze komentarza i ignorowane. +.PP +.RS +na-ID:z-ID:AKCJA +.RE +.PP +Gdzie na-ID jest albo s³owem +.B ALL +(wszyscy), albo list± nazw u¿ytkowników rozdzielonych "," albo te¿ s³owami +.B ALL EXCEPT +(wszyscy oprócz), po których nastêpuje lista nazw u¿ytkowników +rozdzielonych przecinkiem. +.PP +z-ID jest formatowane w taki sam sposób jak na-ID, z wyj±tkiem tego, ¿e +rozpoznawane jest dodatkowe s³owo +.BR GROUP. +Zapis +.B ALL EXCEPT GROUP +(wszyscy za wyj±tkiem grupy) jest równie¿ ca³kowicie poprawny. +Po s³owie +.B GROUP +powinna wyst±piæ jedna lub wiêcej rozdzielonych przecinkiem nazw grup. +Niewystarczaj±ce jest podanie g³ównego ID danej grupy - niezbêdny jest +wpis w +.BR /etc/group (5). +.PP +Akcja mo¿e byæ tylko jedn± z obecnie obs³ugiwanych opcji: +.TP 10 +.B DENY +(zakaz) Próba wykonania su jest zatrzymywana jeszcze przed pytaniem o has³o. +.TP 10 +.B NOPASS +(bez has³a) Próba wykonania su jest automatycznie pomy¶lna; brak pytania +o has³o. +.TP 10 +.B OWNPASS +(w³asne has³o) U¿ytkownik wywo³uj±cy su musi wprowadziæ w³asne has³o, by +polecenie zosta³o pomy¶lnie wykonane. Jest on powiadamiany o konieczno¶ci +podania w³asnego has³a. +.PP +Zauwa¿, ¿e istniej± trzy odrêbne pola rozdzielone dwukropkiem. Bia³e znaki +wokó³ dwukropka nie s± dozwolone. Zauwa¿ te¿, ¿e plik analizowany jest +sekwencyjnie, wiersz po wierszu, i stosowana jest pierwsza pasuj±ca regu³a +bez analizy reszty pliku. Umo¿liwia to administratorowi systemu precyzyjn± +kontrolê wed³ug w³asnych upodobañ. +.SH PRZYK£AD +.PP +.nf +# przyk³adowy plik /etc/suauth +# +# para uprzywilejowanych u¿ytkowników +# mo¿e wykonaæ su na konto root +# przy pomocy w³asnych hase³ +# +root:chris,birddog:OWNPASS +# +# Nikt inny nie mo¿e wykonaæ su na konto root, +# chyba ¿e jest cz³onkiem grupy wheel. +# Tak to robi BSD. +# +root:ALL EXCEPT GROUP wheel:DENY +# +# Byæ mo¿e terry i birddog s± kontami, +# których u¿ywa ta sama osoba. +# Mo¿na zrobiæ wzajemny dostêp +# pomiêdzy nimi bez hase³. +# +terry:birddog:NOPASS +birddog:terry:NOPASS +# +.fi +.SH PLIKI +.I /etc/suauth +.SH B£ÊDY +Mo¿e byæ sporo ukrytych. Analizator pliku jest szczególnie wra¿liwy +na b³êdy sk³adniowe. Zak³ada on, ¿e nie bêdzie zbêdnych bia³ych znaków +(za wyj±tkiem pocz±tków i koñców wierszy), a ró¿ne elementy bêd± separowane +konkretnym znakiem ogranicznika. +.SH DIAGNOSTYKA +B³±d analizy pliku zg³aszany jest przy u¿yciu +.BR syslogd (8) +jako zagro¿enie o poziomie ERR (b³±d) w podsystemie AUTH (identyfikacji +u¿ytkownika przy zg³oszeniu). +.\" as level ERR on facility AUTH. +.SH ZOBACZ TAK¯E +.BR su (1) +.SH AUTOR +.nf +Chris Evans (lady0110@sable.ox.ac.uk) +Lady Margaret Hall +Oxford University +England diff --git a/current/man/pl/sulogin.8 b/current/man/pl/sulogin.8 new file mode 100644 index 00000000..e8aca99d --- /dev/null +++ b/current/man/pl/sulogin.8 @@ -0,0 +1,94 @@ +.\" {PTM/WK/1999-09-14} +.\" Copyright 1989 - 1992, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: sulogin.8,v 1.3 1999/09/25 20:07:47 wojtek2 Exp $ +.\" +.TH SULOGIN 8 +.SH NAZWA +sulogin - login w trybie jednou¿ytkownikowym +.SH SK£ADNIA +\fBsulogin\fR [\fIurz±dzenie-tty\fR] +.SH OPIS +.B sulogin +wywo³ywane jest przez \fBinit\fR przed zezwoleniem u¿ytkownikowi +na dostêp do systemu w trybie jednou¿ytkownikowym (single user mode). +Funkcja ta mo¿e byæ dostêpna tylko w niektórych systemach, w których +odpowiednio zmieniono \fBinit\fR lub plik \fB/etc/inittab\fR posiada +pozycjê dla logowania siê w trybie jednou¿ytkownikowym. +.PP +Wy¶wietlany jest symbol zachêty +.IP "" .5i +Type control-d to proceed with normal startup, +.br +(or give root password for system maintenance): +.br +Naci¶nij control-d by kontynuowaæ zwyk³y start, +.br +(lub podaj has³o u¿ytkownika root do konserwacji systemu): +.PP +Wej¶cie i wyj¶cie bêd± obs³ugiwane przy u¿yciu standardowych deskryptorów +plików, chyba ¿e u¿yto opcjonalnego argumentu - nazwy urz±dzenia. +.PP +Je¶li u¿ytkownik wprowadzi poprawne has³o superu¿ytkownika root, +to rozpoczynana jest sesja pracy na koncie root. +Je¿eli natomiast naci¶niêto \fBEOF\fR, to system przechodzi +do wielou¿ytkownikowego trybu pracy. +.PP +Po opuszczeniu przez u¿ytkownika pow³oki przypisanej do +jednou¿ytkownikowego trybu pracy lub po naci¶niêciu \fBEOF\fR, system +wykonuje proces inicjacji wymagany do przej¶cia w tryb wielou¿ytkownikowy. +.SH OSTRZE¯ENIA +.PP +Polecenie to mo¿e byæ u¿ywane wy³±cznie wtedy, gdy \fBinit\fR zosta³ zmieniony +tak, by wywo³ywaæ \fBsulogin\fR zamiast \fB/bin/sh\fR, +albo gdy u¿ytkownik skonfigurowa³ plik \fIinittab\fR tak, by obs³ugiwa³ +logowanie w trybie jednou¿ytkownikowym. +Na przyk³ad, wiersz +.br +.sp 1 +co:s:respawn:/etc/sulogin /dev/console +.br +.sp 1 +powinien wykonaæ polecenie sulogin w trybie jednou¿ytkownikowym. +.PP +Na ile jest to mo¿liwe, tworzone jest pe³ne ¶rodowisko. +Jednak¿e w efekcie mog± nie byæ do³±czone czy zainicjowane ró¿ne +urz±dzenia, za¶ wiele poleceñ u¿ytkownika mo¿e byæ niedostêpnych lub +nie funkcjonowaæ. +.SH PLIKI +.IR /etc/passwd " - informacja o kontach u¿ytkowników" +.br +.IR /etc/shadow " - zakodowane has³a i informacja o ich wa¿no¶ci" +.br +.IR /.profile " - skrypt startowy dla pow³oki trybu jednou¿ytkownikowego" +.SH ZOBACZ TAK¯E +.BR login (1), +.BR init (8), +.BR sh (1) +.SH AUTOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/porttime.5 b/current/man/porttime.5 new file mode 100644 index 00000000..82f0ebfd --- /dev/null +++ b/current/man/porttime.5 @@ -0,0 +1,84 @@ +.\" Copyright 1989 - 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: porttime.5,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH PORTTIME 5 +.SH NAME +porttime \- port access time file +.SH DESCRIPTION +.I porttime +contains a list of tty devices, user names, and permitted login times. +.PP +Each entry consists of three colon separated fields. +The first field is a comma separated list of tty devices, +or an asterisk to indicate that all tty devices are matched by this entry. +The second field is a comma separated list of user names, or an +asterisk to indicated that all user names are matched by this entry. +The third field is a comma separated list of permitted access times. +.PP +Each access time entry consists of zero or more days of the week, +abbreviated \fBSu\fR, \fBMo\fR, \fBTu\fR, \fBWe\fR, \fBTh\fR, +\fBFr\fR, and \fBSa\fR, followed by a pair of times separated by +a hyphen. +The abbreviation \fBWk\fR may be used to represent Monday thru Friday, +and \fBAl\fR may be used to indicate every day. +If no days are given, \fBAl\fR is assumed. +.SH EXAMPLES +The following entry allows access to user \fBjfh\fR on every port +during weekdays from 9am to 5pm. +.br +.sp 1 + *:jfh:Wk0900-1700 +.br +.sp 1 +The following entries allow access only to the users \fBroot\fR and +\fBoper\fR on /dev/console at any time. +This illustrates how the +\fI/etc/porttime\fR file is an ordered list of access times. +Any other user would match the second entry which does not permit +access at any time. +.br +.sp 1 + console:root,oper:Al0000-2400 +.br + console:*: +.br +.sp 1 +The following entry allows access for the user \fBgames\fR on any +port during non-working hours. +.br +.sp 1 + *:games:Wk1700-0900,SaSu0000-2400 +.br +.sp 1 +.SH FILES +/etc/porttime \- file containing port access times +.SH SEE ALSO +.BR login (1) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pw_auth.3 b/current/man/pw_auth.3 new file mode 100644 index 00000000..b3e6d1c0 --- /dev/null +++ b/current/man/pw_auth.3 @@ -0,0 +1,159 @@ +.\" Copyright 1992 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: pw_auth.3,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH PWAUTH 3 +.SH NAME +pwauth \- administrator defined password authentication routines +.SH SYNTAX +.B #include +.PP +.B int pw_auth (char +.I *command, +.B char +.I *user, +.B int +.I reason, +.B char +.IB *input) ; +.SH DESCRIPTION +.B pw_auth +invokes the administrator defined functions for a given user. +.PP +\fIcommand\fR is the name of the authentication program. +It is retrieved from the user's password file information. +The string contains one or more executable file names, delimited by +semi-colons. +Each program will be executed in the order given. +The command line arguments are given for each of the reasons listed +below. +.PP +\fIuser\fR is the name of the user to be authenticated, as given +in the \fI/etc/passwd\fR file. +User entries are indexed by username. +This allows non-unique user IDs to be present and for each different +username associated with that user ID to have a different +authentication program and information. +.PP +Each of the permissible authentication reasons is handled in a +potentially differenent manner. +Unless otherwise mentioned, the standard file descriptors 0, 1, and +2 are available for communicating with the user. +The real user ID may be used to determine the identity of the user +making the authentication request. +\fIreason\fR is one of +.IP \fBPW_SU\fR 1i +Perform authentication for the current real user ID attempting to +switch real user ID to the named user. +The authentication program will be invoked with a \fB-s\fR option, followed +by the username. +.IP \fBPW_LOGIN\fR 1i +Perform authentication for the named user creating a new login session. +The authentication program will be invoked with a \fB-l\fR option, followed +by the username. +.IP \fBPW_ADD\fR 1i +Create a new entry for the named user. +This allows an authentication program to initialize storage for a new +user. +The authentication program will be invoked with a \fB-a\fR option, followed +by the username. +.IP \fBPW_CHANGE\fR 1i +Alter an existing entry for the named user. +This allows an authentication program to alter the authentication +information for an existing user. +The authentication program will be invoked with a \fB-c\fR option, followed +by the username. +.IP \fBPW_DELETE\fR 1i +Delete authentication information for the named user. +This allows an authentication program to reclaim storage for a user which +is no longer authenticated using the authentication program. +The authentication program will be invoked with a \fB-d\fR option, followed +by the username. +.IP \fBPW_TELNET\fR 1i +Authenticate a user who is connecting to the system using the +fBtelnet\fR command. +The authentication program will be invoked with a \fB-t\fR option, followed +by the username. +.IP \fBPW_RLOGIN\fR 1i +Authenticate a user who is connecting to the system using the \fBrlogin\fR +command. +The authentication program will be invoked with a \fB-r\fR option, followed +by the username. +.IP \fBPW_FTP\fR 1i +Authenticate a user who is connecting to the system using the \fBftp\fR +command. +The authentication program will be invoked with a \fR-f\fR option, followed +by the username. +The standard file descriptors are not available for communicating with the +user. +The standard input file descriptor will be connected to the parent process, +while the other two output file descriptors will be connected to +\fI/dev/null\fR. +The \fBpw_auth\fR function will pipe a single line of data to the +authentication program using file descriptor 0. +.IP \fBPW_REXEC\fR 1i +Authenticate a user who is connecting to the system using the \fIrexec\fR +command. +The authentication program will be invoked with a \fB-x\fR option, followed +by the username. +The standard file descriptors are not available for communicating with the +remote user. +The standard input file descriptor will be connected to the parent process, +while the other two output file descriptors will be connected to +\fI/dev/null\fR. +The \fBpw_auth\fR function will pipe a single line of data to the +authentication program using file descriptor 0. +.PP +The last argument is the authentication data which is used by the +.B PW_FTP +and +.B PW_REXEC +reasons. +It is treated as a single line of text which is piped to the authentication +program. +When the reason is +.BR PW_CHANGE, +the value of \fIinput\fR is the value of +previous user name if the user name is being changed. +.SH CAVEATS +This function does not create the actual session. +It only indicates if the user should be allowed to create the session. +.PP +The network options are untested at this time. +.SH DIAGNOSTICS +The \fBpw_auth\fR function returns 0 if the authentication program exited +with a 0 exit code, and a non-zero value otherwise. +.SH SEE ALSO +.BR login (1), +.BR passwd (1), +.BR su (1), +.BR useradd (8), +.BR userdel (8), +usermod(8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pwauth.8 b/current/man/pwauth.8 new file mode 100644 index 00000000..156ec533 --- /dev/null +++ b/current/man/pwauth.8 @@ -0,0 +1,67 @@ +.\" Copyright 1992, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: pwauth.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH PWAUTH 8 +.SH NAME +pwauth \- administrator defined password authentication +.SH DESCRIPTION +The system administrator is able to define a list of programs which +are used to validate a user's identity. +These programs are given in place of the encrypted password +information which is present in either the \fI/etc/passwd\fR or +\fI/etc/shadow\fR files. +The utilities which administer user accounts examine the encrypted +password field and determine if the user has an administrator defined +authentication program. +The \fBpw_auth\fR function will be invoked whenever one of these +administration programs determines that a user which is being altered +has authentication programs defined. +.PP +The initial entry is created with the \fBuseradd\fR command. +Alterations, such as changing authentication information or deleting +the user account, will cause the \fBpw_auth\fR function to be invoked. +This keeps the authentication information up to date for each user +account. +.PP +The authentication programs do not create the actual login or network +sessions. +The exit code from the authentication program is taken as an +indication that the action is to be permitted. +The calling process must have the appropriate priviledges to create +the login or network session itself. +.SH SEE ALSO +.BR login (1), +.BR passwd (1), +.BR su (1), +.BR useradd (8), +.BR userdel (8), +.BR usermod (8), +.BR pw_auth (3) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pwck.8 b/current/man/pwck.8 new file mode 100644 index 00000000..6e500fcb --- /dev/null +++ b/current/man/pwck.8 @@ -0,0 +1,107 @@ +.\" Copyright 1992, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: pwck.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH PWCK 1 +.SH NAME +pwck \- verify integrity of password files +.SH SYNOPSIS +\fBpwck\fR [\fB-r\fR] [\fIpasswd\fR \fIshadow\fR] +.SH DESCRIPTION +\fBpwck\fR verifies the integrity of the system authentication information. +All entries in the \fI/etc/passwd\fR and \fI/etc/shadow\fR are checked to +see that the entry has the proper format and valid data in each field. +The user is prompted to delete entries that are improperly formatted or +which have other incorrectable errors. +.P +Checks are made to verify that each entry has +.sp +.in +.5i +- the correct number of fields +.br +- a unique user name +.br +- a valid user and group identifier +.br +- a valid primary group +.br +- a valid home directory +.br +- a valid login shell +.in -.5i +.sp +.P +The checks for correct number of fields and unique user name are fatal. +If the entry has the wrong number of fields, the user will be prompted to +delete the entire line. +If the user does not answer affirmatively, all further checks are bypassed. +An entry with a duplicated user name is prompted for deletion, but the +remaining checks will still be made. +All other errors are warning and the user is encouraged to run the +\fBusermod\fR command to correct the error. +.P +The commands which operate on the \fI/etc/passwd\fR file are not able to +alter corrupted or duplicated entries. +\fBpwck\fR should be used in those circumstances to remove the offending +entry. +.SH OPTIONS +By default, \fBpwck\fR operates on the files \fI/etc/passwd\fR and +\fI/etc/shadow\fR. +The user may select alternate files with the \fIpasswd\fR and \fIshadow\fR +parameters. +Additionally, the user may execute the command in read-only mode by +specifying the \fB-r\fR flag. +This causes all questions regarding changes to be answered \fBno\fR +without user intervention. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- encrypted password information +.br +/etc/group \- group information +.SH SEE ALSO +.BR usermod (8), +.BR group (5), +.BR passwd (5), +.BR shadow (5) +.SH DIAGNOSTICS +The \fBpwck\fR command exits with the following values: +.IP 0 5 +Success +.IP 1 5 +Syntax Error +.IP 2 5 +One or more bad password entries +.IP 3 5 +Cannot open password files +.IP 4 5 +Cannot lock password files +.IP 5 5 +Cannot update password files +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/pwconv.8 b/current/man/pwconv.8 new file mode 100644 index 00000000..f7bafba5 --- /dev/null +++ b/current/man/pwconv.8 @@ -0,0 +1,63 @@ +.\" $Id: pwconv.8,v 1.8 1998/06/25 22:10:43 marekm Exp $ +.TH PWCONV 8 "26 Sep 1997" +.SH NAME +pwconv, pwunconv, grpconv, grpunconv \- convert to and from shadow passwords and groups. +.SH SYNOPSIS +.B pwconv +.br +.B pwunconv +.br +.B grpconv +.br +.B grpunconv +.SH DESCRIPTION +These four programs all operate on the normal and shadow password and +group files: +.IR /etc/passwd ", " /etc/group ", " /etc/shadow ", and " /etc/gshadow . + +.B pwconv +.RI "creates " shadow " from " passwd " and an optionally existing " shadow . +.B pwunconv +.RI "creates " passwd " from " passwd " and " shadow " and then removes " shadow . +.B grpconv +.RI "creates " gshadow " from " group " and an optionally existing " gshadow . +.B grpunconv +.RI "creates " group " from " group " and " gshadow " and then removes " gshadow . + +Each program acquires the necessary locks before conversion. + +.BR pwconv " and " grpconv +are similiar. First, entries in the shadowed file which don't exist +in the main file are removed. Then, shadowed entries which don't have +`x' as the password in the main file are updated. Any missing +shadowed entries are added. Finally, passwords in the main file are +replaced with `x'. These programs can be used for initial conversion +as well to update the shadowed file if the main file is edited by +hand. + +.B pwconv +will use the values of +.BR PASS_MIN_DAYS ", " PASS_MAX_DAYS ", and " PASS_WARN_AGE +from +.I /etc/login.defs +when adding new entries to +.IR /etc/shadow . + +.RB "Likewise, " pwunconv " and " grpunconv +are similiar. Passwords in the main file are updated from the +shadowed file. Entries which exist in the main file but not in the +shadowed file are left alone. Finally, the shadowed file is removed. + +Some password aging information is lost by +.BR pwunconv . +It will convert what it can. +.SH "BUGS" +Errors in the password or group files (such as invalid or duplicate +entries) may cause these programs to loop forever or fail in other +strange ways. Please run \fBpwck\fR and \fBgrpck\fR to correct any +such errors before converting to or from shadow passwords or groups. +.SH "SEE ALSO" +.BR login.defs (5), +.BR pwck (8), +.BR grpck (8), +.BR shadowconfig (8) diff --git a/current/man/shadow.3 b/current/man/shadow.3 new file mode 100644 index 00000000..0a3b74a9 --- /dev/null +++ b/current/man/shadow.3 @@ -0,0 +1,148 @@ +.\" Copyright 1989 - 1993, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: shadow.3,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH SHADOW 3 +.SH NAME +shadow \- encrypted password file routines +.SH SYNTAX +.B #include +.PP +.B struct spwd *getspent(); +.PP +.B struct spwd *getspnam(char +.IB *name ); +.PP +.B void setspent(); +.PP +.B void endspent(); +.PP +.B struct spwd *fgetspent(FILE +.IB *fp ); +.PP +.B struct spwd *sgetspent(char +.IB *cp ); +.PP +.B int putspent(struct spwd +.I *p, +.B FILE +.IB *fp ); +.PP +.B int lckpwdf(); +.PP +.B int ulckpwdf(); +.SH DESCRIPTION +.I shadow +manipulates the contents of the shadow password file, +\fI/etc/shadow\fR. +The structure in the \fI#include\fR file is +.sp +struct spwd { +.in +.5i +.br + char *sp_namp; /* user login name */ +.br + char *sp_pwdp; /* encrypted password */ +.br + long sp_lstchg; /* last password change */ +.br + int sp_min; /* days until change allowed. */ +.br + int sp_max; /* days before change required */ +.br + int sp_warn; /* days warning for expiration */ +.br + int sp_inact; /* days before account inactive */ +.br + int sp_expire; /* date when account expires */ +.br + int sp_flag; /* reserved for future use */ +.br +.in -.5i +} +.PP +The meanings of each field are +.sp +sp_namp \- pointer to null-terminated user name. +.br +sp_pwdp \- pointer to null-terminated password. +.br +sp_lstchg \- days since Jan 1, 1970 password was last changed. +.br +sp_min \- days before which password may not be changed. +.br +sp_max \- days after which password must be changed. +.br +sp_warn \- days before password is to expire that user is warned +of pending password expiration. +.br +sp_inact \- days after password expires that account is considered +inactive and disabled. +.br +sp_expire \- days since Jan 1, 1970 when account will be disabled. +.br +sp_flag \- reserved for future use. +.SH DESCRIPTION +\fBgetspent\fR, \fBgetspname\fR, \fBfgetspent\fR, and \fBsgetspent\fR +each return a pointer to a \fBstruct spwd\fR. +\fBgetspent\fR returns the +next entry from the file, and \fBfgetspent\fR returns the next +entry from the given stream, which is assumed to be a file of +the proper format. +\fBsgetspent\fR returns a pointer to a \fBstruct spwd\fR using the +provided string as input. +\fBgetspnam\fR searches from the current position in the file for +an entry matching \fBname\fR. +.PP +\fBsetspent\fR and \fBendspent\fR may be used to begin and end, +respectively, access to the shadow password file. +.PP +The \fBlckpwdf\fR and \fBulckpwdf\fR routines should be used to +insure exclusive access to the \fI/etc/shadow\fR file. +\fBlckpwdf\fR attempts to acquire a lock using \fBpw_lock\fR for +up to 15 seconds. +It continues by attempting to acquire a second lock using \fBspw_lock\fR +for the remainder of the initial 15 seconds. +Should either attempt fail after a total of 15 seconds, \fBlckpwdf\fR +returns -1. +When both locks are acquired 0 is returned. +.SH DIAGNOSTICS +Routines return NULL if no more entries are available or if an +error occurs during processing. +Routines which have \fBint\fR as the return value return 0 for +success and -1 for failure. +.SH CAVEATS +These routines may only be used by the super user as access to +the shadow password file is restricted. +.SH FILES +/etc/shadow \- encrypted user passwords +.SH SEE ALSO +.BR getpwent (3), +.BR shadow (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/shadow.5 b/current/man/shadow.5 new file mode 100644 index 00000000..bd3b09a3 --- /dev/null +++ b/current/man/shadow.5 @@ -0,0 +1,99 @@ +.\" Copyright 1989 - 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: shadow.5,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH SHADOW 5 +.SH NAME +shadow \- encrypted password file +.SH DESCRIPTION +.I shadow +contains the encrypted password information for user's accounts +and optional the password aging information. +Included is +.IP "" .5i +Login name +.IP "" .5i +Encrypted password +.IP "" .5i +Days since Jan 1, 1970 that password was last changed +.IP "" .5i +Days before password may be changed +.IP "" .5i +Days after which password must be changed +.IP "" .5i +Days before password is to expire that user is warned +.IP "" .5i +Days after password expires that account is disabled +.IP "" .5i +Days since Jan 1, 1970 that account is disabled +.IP "" .5i +A reserved field +.PP +The password field must be filled. +The encryped password consists of 13 to 24 characters from the +64 character alphabet +a thru z, A thru Z, 0 thru 9, \. and /. +Refer to \fBcrypt\fR(3) for details on how this string is +interpreted. +.PP +The date of the last password change is given as the number +of days since Jan 1, 1970. +The password may not be changed again until the proper number +of days have passed, and must be changed after the maximum +number of days. +If the minimum number of days required is greater than the +maximum number of day allowed, this password may not be +changed by the user. +.PP +An account is considered to be inactive and is disabled if +the password is not changed within the specified number of +days after the password expires. +An account will also be disabled on the specified day +regardless of other password expiration information. +.PP +This information supercedes any password or password age +information present in \fI/etc/passwd\fR. +.PP +This file must not be readable by regular users if password +security is to be maintained. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- encrypted user passwords +.SH SEE ALSO +.BR chage (1), +.BR login (1), +.BR passwd (1), +.BR su (1), +.BR sulogin (8), +.BR shadow (3), +.BR passwd (5), +.BR pwconv (8), +.BR pwunconv (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/shadowconfig.8 b/current/man/shadowconfig.8 new file mode 100644 index 00000000..ac6af945 --- /dev/null +++ b/current/man/shadowconfig.8 @@ -0,0 +1,24 @@ +.\" $Id: shadowconfig.8,v 1.2 1997/12/14 20:07:22 marekm Exp $ +.TH SHADOWCONFIG 8 "19 Apr 1997" "Debian GNU/Linux" +.SH NAME +shadowconfig \- toggle shadow passwords on and off +.SH SYNOPSIS +.B "shadowconfig" +.IR on " | " off +.SH DESCRIPTION +.PP +.B shadowconfig on +will turn shadow passwords on; +.B shadowconfig off +will turn shadow passwords off. +.B shadowconfig +will print an error message and exit with a nonzero code if it finds +anything awry. If that happens, you should correct the error and run +it again. + +Turning shadow passwords on when they are already on, or off when they +are already off, is harmless. + +Read +.I /usr/doc/passwd/README.debian.gz +for a brief introduction to shadow passwords and related features. diff --git a/current/man/su.1 b/current/man/su.1 new file mode 100644 index 00000000..69fe12c4 --- /dev/null +++ b/current/man/su.1 @@ -0,0 +1,87 @@ +.\" Copyright 1989 - 1990, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: su.1,v 1.6 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH SU 1 +.SH NAME +su \- Change user ID or become super-user +.SH SYNOPSIS +.BR su " [" - ] +.RI [ username " [" args ]] +.SH DESCRIPTION +.B su +is used to become another user during a login session. +Invoked without a username, \fBsu\fR defaults to becoming +the super user. +The optional argument \fB\-\fR may be used to provide an +environment similiar to what the user would expect had +the user logged in directly. +.PP +Additional arguments may be provided after the username, +in which case they are supplied to the user\'s login shell. +In particular, an argument of \fB-c\fR will cause the +next argument to be treated as a command by most command +interpreters. +.\" The command will be executed under the shell specified by +.\" \fB$SHELL\fR, or if undefined, by the one specified in +.\" \fI/etc/passwd\fR. +.\" XXX - the above was not quite correct. --marekm +The command will be executed by the shell specified in +\fI/etc/passwd\fR for the target user. +.PP +The user will be prompted for a password, if appropriate. +Invalid passwords will produce an error message. +All attempts, both valid and invalid, are logged to detect +abuses of the system. +.PP +The current environment is passed to the new shell. The value of +\fB$PATH\fR is reset to \fB/bin:/usr/bin\fR for normal users, or +\fB/sbin:/bin:/usr/sbin:/usr/bin\fR for the super user. This may be +changed with the \fBENV_PATH\fR and \fBENV_SUPATH\fR definitions in +\fI/etc/login.defs\fR. +.PP +A subsystem login is indicated by the presense of a "*" as the first +character of the login shell. The given home directory will be used as +the root of a new filesystem which the user is actually logged into. +.SH CAVEATS +.PP +This version of \fBsu\fR has many compilation options, only some of which +may be in use at any particular site. +.SH Files +/etc/passwd \- user account information +.br +/etc/shadow \- encrypted passwords and age information +.br +$HOME/.profile \- initialization script for default shell +.SH SEE ALSO +.BR login (1), +.BR sh (1), +.BR suauth (5), +.BR login.defs (5) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/suauth.5 b/current/man/suauth.5 new file mode 100644 index 00000000..a3aa1581 --- /dev/null +++ b/current/man/suauth.5 @@ -0,0 +1,112 @@ +.TH SUAUTH 5 "Feb 14, 1996" +.UC 5 +.SH NAME +suauth \- Detailed su control file +.SH SYNOPSIS +.B /etc/suauth +.SH DESCRIPTION +The file +.I /etc/suauth +is referenced whenever the su command is called. It can change the +behaviour of the su command, based upon +.PP +.RS +.nf +1) the user su is targetting +.fi +2) the user executing the su command (or any groups he might be +a member of) +.RE +.PP +The file is formatted like this, with lines starting with a # +being treated as comment lines and ignored; +.PP +.RS +to-id:from-id:ACTION +.RE +.PP +Where to-id is either the word +.BR ALL , +a list of usernames +delimited by "," or the words +.B ALL EXCEPT +followed by a list +of usernames delimted by "," +.PP +from-id is formatted the same as to-id except the extra word +.B GROUP +is recognised. +.B ALL EXCEPT GROUP +is perfectly valid too. +Following +.B GROUP +appears one or more group names, delimited by +",". It is not sufficient to have primary group id of the +relevant group, an entry in +.BR /etc/group (5) +is neccessary. +.PP +Action can be one only of the following currently supported +options. +.TP 20 +.B DENY +The attempt to su is stopped before a password is even asked for. +.TP 20 +.B NOPASS +The attempt to su is automatically successful; no password is +asked for. +.TP 20 +.B OWNPASS +For the su command to be successful, the user must enter +his or her own password. They are told this. +.PP +Note there are three separate fields delimted by a colon. No +whitespace must surround this colon. Also note that the file +is examined sequentially line by line, and the first applicable +rule is used without examining the file further. This makes it +possible for a system administrator to exercise as fine control +as he or she wishes. +.SH EXAMPLE +.PP +.nf +# sample /etc/suauth file +# +# A couple of privileged usernames may +# su to root with their own password. +# +root:chris,birddog:OWNPASS +# +# Anyone else may not su to root unless in +# group wheel. This is how BSD does things. +# +root:ALL EXCEPT GROUP wheel:DENY +# +# Perhaps terry and birddog are accounts +# owned by the same person. +# Access can be arranged between them +# with no password. +# +terry:birddog:NOPASS +birddog:terry:NOPASS +# +.fi +.SH FILES +/etc/suauth +.SH BUGS +There could be plenty lurking. The file parser is particularly +unforgiving about syntax errors, expecting no spurious whitespace +(apart from beginning and end of lines), and a specific token +delimiting different things. +.SH DIAGNOSTICS +An error parsing the file is reported using +.BR syslogd (8) +as level ERR on +facility AUTH. +.SH SEE ALSO +.BR su (1) +.SH AUTHOR +.nf +Chris Evans (lady0110@sable.ox.ac.uk) +Lady Margaret Hall +Oxford University +England diff --git a/current/man/sulogin.8 b/current/man/sulogin.8 new file mode 100644 index 00000000..61d61cdb --- /dev/null +++ b/current/man/sulogin.8 @@ -0,0 +1,88 @@ +.\" Copyright 1989 - 1992, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: sulogin.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH SULOGIN 8 +.SH NAME +sulogin \- Single-user login +.SH SYNTAX +\fBsulogin\fR [\fItty-device\fR] +.SH DESCRIPTION +.B sulogin +is invoked by \fBinit\fR prior to allowing the user +access to the system when in single user mode. +This feature may only be available on certain systems where +\fBinit\fR has been modified accordingly, or where the +\fB/etc/inittab\fR has an entry for a single user login. +.PP +The user is prompted +.IP "" .5i +Type control-d to proceed with normal startup, +.br +(or give root password for system maintenance): +.PP +Input and output will be performed with the standard file +descriptors unless the optional device name argument is provided. +.PP +If the user enters the correct root password, a login session +is initiated. +When \fBEOF\fR is pressed instead, the system enters multi-user +mode. +.PP +After the user exits the single-user shell, or presses \fBEOF\fR, +the system begins the initialization process required to enter +multi-user mode. +.SH CAVEATS +.PP +This command can only be used if \fBinit\fR has been modified to call +\fBsulogin\fR instead of \fB/bin/sh\fR, +or if the user has set the \fIinittab\fR to support a single user +login. +For example, the line +.br +.sp 1 +co:s:respawn:/etc/sulogin /dev/console +.br +.sp 1 +should execute the sulogin command in single user mode. +.PP +As complete an environment as possible is created. +However, various devices may be unmounted or uninitialized and many +of the user commands may be unavailable or nonfunctional as a result. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- encrypted passwords and age information +.br +/.profile \- initialization script for single user shell +.SH SEE ALSO +.BR login (1), +.BR init (8), +.BR sh (1) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/useradd.8 b/current/man/useradd.8 new file mode 100644 index 00000000..aa84b755 --- /dev/null +++ b/current/man/useradd.8 @@ -0,0 +1,197 @@ +.\" Copyright 1991 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: useradd.8,v 1.7 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH USERADD 8 +.SH NAME +useradd \- Create a new user or update default new user information +.SH SYNOPSIS +.TP 8 +.B useradd +.\" .RB [ -A +.\" .RI { method | \fBDEFAULT\fR "},... ]" +.RB [ -c +.IR comment ] +.RB [ -d +.IR home_dir ] +.br +.RB [ -e +.IR expire_date ] +.RB [ -f +.IR inactive_time ] +.br +.RB [ -g +.IR initial_group ] +.RB [ -G +.IR group [,...]] +.br +.RB [ -m " [" -k +.IR skeleton_dir ]] +.RB [ -p +.IR passwd ] +.br +.RB [ -s +.IR shell ] +.RB [ -u +.IR uid " [" +.BR -o ]] +.I login +.TP 8 +.B useradd +\fB-D\fR +[\fB-g\fI default_group\fR] +[\fB-b\fI default_home\fR] +.br +[\fB-f\fI default_inactive\fR] +[\fB-e\fI default_expire_date\fR] +.br +[\fB-s\fI default_shell\fR] +.SH DESCRIPTION +.SS Creating New Users +When invoked without the \fB-D\fR option, the \fBuseradd\fR command +creates a new user account using the values specified on the +command line and the default values from the system. +The new user account will be entered into the system files as needed, +the home directory will be created, and initial files copied, depending +on the command line options. +The options which apply to the \fBuseradd\fR command are +.\" .IP "\fB-A {\fImethod\fR|\fBDEFAULT\fR},..." +.\" The value of the user's authentication method. +.\" The authentication method is the name of a program which is responsible +.\" for validating the user's identity. +.\" The string \fBDEFAULT\fR may be used to change the user's authentication +.\" method to the standard system password method. +.\" This is a comma-separated list of program names. +.\" It may include \fBDEFAULT\fR exactly once. +.IP "\fB-c \fIcomment\fR" +The new user's password file comment field. +.IP "\fB-d \fIhome_dir\fR" +The new user will be created using \fIhome_dir\fR as the value for +the user's login directory. +The default is to append the \fIlogin\fR name to \fIdefault_home\fR +and use that as the login directory name. +.IP "\fB-e \fIexpire_date\fR" +The date on which the user account will be disabled. +The date is specified in the format \fIYYYY-MM-DD\fR. +.IP "\fB-f \fIinactive_days\fR" +The number of days after a password expires until the account +is permanently disabled. +A value of 0 disables the account as soon as the password has +expired, and a value of -1 disables the feature. +The default value is -1. +.IP "\fB-g \fIinitial_group\fR" +The group name or number of the user's initial login group. +The group name must exist. A group number must refer to an +already existing group. +The default group number is 1. +.IP "\fB-G \fIgroup,[...]\fR" +A list of supplementary groups which the user is also a member +of. +Each group is separated from the next by a comma, with no +intervening whitespace. +The groups are subject to the same restrictions as the group +given with the \fB-g\fR option. +The default is for the user to belong only to the initial group. +.IP \fB-m\fR +The user's home directory will be created if it does not exist. +The files contained in \fIskeleton_dir\fR will be copied to the +home directory if the \fB-k\fR option is used, otherwise the +files contained in \fI/etc/skel\fR will be used instead. +Any directories contained in \fIskeleton_dir\fR or \fI/etc/skel\fR +will be created in the user's home directory as well. +The \fB-k\fR option is only valid in conjunction with the \fB-m\fR +option. +The default is to not create the directory and to not copy any +files. +.IP "\fB-p \fIpasswd\fR" +The encrypted password, as returned by \fBcrypt\fR(3). +The default is to disable the account. +.IP "\fB-s \fIshell\fR" +The name of the user's login shell. +The default is to leave this field blank, which causes the system +to select the default login shell. +.IP "\fB-u \fIuid\fR" +The numerical value of the user's ID. +This value must be unique, unless the \fI-o\fR option is used. +The value must be non-negative. +The default is to use the smallest ID value greater than 99 and +greater than every other user. +Values between 0 and 99 are typically reserved for system accounts. +.SS Changing the default values +When invoked with the \fB-D\fR option, \fBuseradd\fR will either +display the current default values, or update the default values +from the command line. +The valid options are +.IP "\fB-b \fIdefault_home\fR" +The initial path prefix for a new user's home directory. +The user's name will be affixed to the end of \fIdefault_home\fR +to create the new directory name if the \fB-d\fI option is not +used when creating a new account. +.IP "\fB-e \fIdefault_expire_date\fR" +The date on which the user account is disabled. +.IP "\fB-f \fIdefault_inactive\fR" +The number of days after a password has expired before the +account will be disabled. +.IP "\fB-g \fIdefault_group\fR" +The group name or ID for a new user's initial group. +The named group must exist, and a numerical group ID must have +an existing entry . +.IP "\fB-s \fIdefault_shell\fR" +The name of the new user's login shell. +The named program will be used for all future new user accounts. +.PP +If no options are specified, \fBuseradd\fR displays the current +default values. +.SH NOTES +The system administrator is responsible for placing the default +user files in the \fI/etc/skel\fR directory. +.SH CAVEATS +You may not add a user to an NIS group. +This must be performed on the NIS server. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- secure user account information +.br +/etc/group \- group information +.br +/etc/default/useradd \- default information +.br +/etc/skel \- directory containing default files +.SH SEE ALSO +.BR chfn (1), +.BR chsh (1), +.BR crypt (3), +.BR groupadd (8), +.BR groupdel (8), +.BR groupmod (8), +.BR passwd (1), +.BR userdel (8), +.BR usermod (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/userdel.8 b/current/man/userdel.8 new file mode 100644 index 00000000..9a26713f --- /dev/null +++ b/current/man/userdel.8 @@ -0,0 +1,69 @@ +.\" Copyright 1991 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: userdel.8,v 1.5 2000/08/26 18:27:17 marekm Exp $ +.\" +.TH USERDEL 8 +.SH NAME +userdel \- Delete a user account and related files +.SH SYNOPSIS +.B userdel +[\fB-r\fR] +.I login +.SH DESCRIPTION +The \fBuserdel\fR command modifies the system account files, deleting +all entries that refer to \fIlogin\fR. +The named user must exist. +.IP \fB-r\fR +Files in the user's home directory will be removed along with the +home directory itself and the user's mail spool. +Files located in other file systems will have to be searched for +and deleted manually. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- secure user account information +.br +/etc/group \- group information +.SH CAVEATS +\fBuserdel\fR will not allow you to remove an account if the user +is currently logged in. +You must kill any running processes which belong to an account that +you are deleting. +You may not remove any NIS attributes on an NIS client. +This must be performed on the NIS server. +.SH SEE ALSO +.BR chfn (1), +.BR chsh (1), +.BR groupadd (8), +.BR groupdel (8), +.BR groupmod (8), +.BR passwd (1), +.BR useradd (8), +.BR usermod (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/usermod.8 b/current/man/usermod.8 new file mode 100644 index 00000000..152514fd --- /dev/null +++ b/current/man/usermod.8 @@ -0,0 +1,162 @@ +.\" Copyright 1991 - 1994, Julianne Frances Haugh +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of Julianne F. Haugh nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. +.\" +.\" $Id: usermod.8,v 1.8 2000/09/02 18:40:43 marekm Exp $ +.\" +.TH USERMOD 8 +.SH NAME +usermod \- Modify a user account +.SH SYNOPSIS +.TP 8 +.B usermod +.\" .RB [ -A +.\" .RI { method | \fBDEFAULT\fR "},... ]" +.RB [ -c +.IR comment ] +.RB [ -d +.IR home_dir " [" +.BR -m ]] +.br +.RB [ -e +.IR expire_date ] +.RB [ -f +.IR inactive_time ] +.br +.RB [ -g +.IR initial_group ] +.RB [ -G +.IR group [,...]] +.br +.RB [ -l +.IR login_name ] +.RB [ -p +.IR passwd ] +.br +.RB [ -s +.IR shell ] +.RB [ -u +.IR uid " [" +.BR -o ]] +.RB [ -L | -U ] +.I login +.SH DESCRIPTION +The \fBusermod\fR command modifies the system account files to reflect +the changes that are specified on the command line. +The options which apply to the \fBusermod\fR command are +.\" .IP "\fB-A \fImethod\fR|\fBDEFAULT\fR" +.\" The new value of the user's authentication method. +.\" The authentication method is the name of a program which is responsible +.\" for validating the user's identity. +.\" The string \fBDEFAULT\fR may be used to change the user's authentication +.\" method to the standard system password method. +.IP "\fB-c \fIcomment\fR" +The new value of the user's password file comment field. +It is normally modified using the \fBchfn\fR(1) utility. +.IP "\fB-d \fIhome_dir\fR" +The user's new login directory. +If the \fB-m\fR option is given the contents of the current home directory +will be moved to the new home directory, which is created if it does not +already exist. +.IP "\fB-e \fIexpire_date\fR" +The date on which the user account will be disabled. +The date is specified in the format \fIYYYY-MM-DD\fR. +.IP "\fB-f \fIinactive_days\fR" +The number of days after a password expires until the account +is permanently disabled. +A value of 0 disables the account as soon as the password has +expired, and a value of -1 disables the feature. +The default value is -1. +.IP "\fB-g \fIinitial_group\fR" +The group name or number of the user's new initial login group. +The group name must exist. A group number must refer to an +already existing group. +The default group number is 1. +.IP "\fB-G \fIgroup,[...]\fR" +A list of supplementary groups which the user is also a member +of. +Each group is separated from the next by a comma, with no +intervening whitespace. +The groups are subject to the same restrictions as the group +given with the \fB-g\fR option. +If the user is currently a member of a group which is not listed, +the user will be removed from the group +.IP "\fB-l \fIlogin_name\fR" +The name of the user will be changed from \fIlogin\fR to +\fIlogin_name\fR. +Nothing else is changed. +In particular, the user's home directory name should probably +be changed to reflect the new login name. +.IP "\fB-p \fIpasswd\fR" +The encrypted password, as returned by \fBcrypt\fR(3). +.IP "\fB-s \fIshell\fR" +The name of the user's new login shell. +Setting this field to blank causes the system +to select the default login shell. +.IP "\fB-u \fIuid\fR" +The numerical value of the user's ID. +This value must be unique, unless the \fI-o\fR option is used. +The value must be non-negative. +Values between 0 and 99 are typically reserved for system accounts. +Any files which the user owns and which are located in the directory +tree rooted at the user's home directory will have the file user ID +changed automatically. +Files outside of the user's home directory must be altered manually. +.IP "\fB-L\fR" +Lock a user's password. +This puts a '!' in front of the encrypted password, effectively disabling +the password. You can't use this option with \fI-p\fR or \fI-U\fR. +.IP "\fB-U\fR" +Unlock a user's password. +This removes the '!' in front of the encrypted password. +You can't use this option with \fI-p\fR or \fI-L\fR. +.SH CAVEATS +\fBusermod\fR will not allow you to change the name of a user who is +logged in. +You must make certain that the named user is not executing any processes +when this command is being executed if the user's numerical user ID is +being changed. +You must change the owner of any crontab files manually. +You must change the owner of any at jobs manually. +You must make any changes involving NIS on the NIS server. +.SH FILES +/etc/passwd \- user account information +.br +/etc/shadow \- secure user account information +.br +/etc/group \- group information +.SH SEE ALSO +.BR chfn (1), +.BR chsh (1), +.BR crypt (3), +.BR groupadd (8), +.BR groupdel (8), +.BR groupmod (8), +.BR passwd (1), +.BR useradd (8), +.BR userdel (8) +.SH AUTHOR +Julianne Frances Haugh (jfh@austin.ibm.com) diff --git a/current/man/vipw.8 b/current/man/vipw.8 new file mode 100644 index 00000000..c8d3b3d4 --- /dev/null +++ b/current/man/vipw.8 @@ -0,0 +1,29 @@ +.\" $Id: vipw.8,v 1.2 1997/12/14 20:07:22 marekm Exp $ +.TH VIPW 8 "26 Sep 1997" +.SH NAME +vipw, vigr \- edit the password, group, shadow-password, or shadow-group file. +.SH SYNOPSIS +.BR vipw " [-s]" +.br +.BR vigr " [-s]" +.SH DESCRIPTION +.BR vipw " and " vigr +will edit the files +.IR /etc/passwd " and " /etc/group ", respectively." +With the +.B -s +flag, they will edit the shadow versions of those files, +.IR /etc/shadow " and " /etc/gshadow ", respectively. +The programs will set the appropriate locks to prevent file corruption. + +When looking for an editor, the programs will first try the +environment variable +.BR VISUAL , +then the environment variable +.BR EDITOR , +and finally the default editor, +.BR vi . +.SH "SEE ALSO" +.BR passwd (5), +.BR group (5), +.BR shadow (5) diff --git a/current/missing b/current/missing new file mode 100755 index 00000000..7789652e --- /dev/null +++ b/current/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/current/mkinstalldirs b/current/mkinstalldirs new file mode 100755 index 00000000..4f58503e --- /dev/null +++ b/current/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/current/po/ChangeLog b/current/po/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/current/po/Makefile.in.in b/current/po/Makefile.in.in new file mode 100644 index 00000000..111b40fc --- /dev/null +++ b/current/po/Makefile.in.in @@ -0,0 +1,248 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale +gnulocaledir = $(prefix)/share/locale +gettextsrcdir = $(prefix)/share/gettext/po +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@ + +CC = @CC@ +GENCAT = @GENCAT@ +GMSGFMT = PATH=../src:$$PATH @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = PATH=../src:$$PATH @XGETTEXT@ +MSGMERGE = PATH=../src:$$PATH msgmerge + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. -I$(top_srcdir)/intl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +SOURCES = cat-id-tbl.c +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \ +stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && $(GENCAT) $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: cat-id-tbl.c $(CATALOGS) +all-no: + +$(srcdir)/$(PACKAGE).pot: $(POTFILES) + $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ + --add-comments --keyword=_ --keyword=N_ \ + --files-from=$(srcdir)/POTFILES.in \ + && test ! -f $(PACKAGE).po \ + || ( rm -f $(srcdir)/$(PACKAGE).pot \ + && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot ) + +$(srcdir)/cat-id-tbl.c: stamp-cat-id; @: +$(srcdir)/stamp-cat-id: $(PACKAGE).pot + rm -f cat-id-tbl.tmp + sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \ + | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp + if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \ + rm cat-id-tbl.tmp; \ + else \ + echo cat-id-tbl.c changed; \ + rm -f $(srcdir)/cat-id-tbl.c; \ + mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \ + fi + cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(datadir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(datadir); \ + fi + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + case "$$cat" in \ + *.gmo) destdir=$(gnulocaledir);; \ + *) destdir=$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + dir=$$destdir/$$lang/LC_MESSAGES; \ + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $$dir; \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \ + fi; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + if test "$(PACKAGE)" = "gettext"; then \ + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(gettextsrcdir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ + fi; \ + $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ + $(gettextsrcdir)/Makefile.in.in; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + done + rm -f $(gettextsrcdir)/po-Makefile.in.in + +check: all + +cat-id-tbl.o: ../intl/libgettext.h + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(GMOFILES) + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: update-po $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(PACKAGE).pot + PATH=`pwd`/../src:$$PATH; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + mv $$lang.po $$lang.old.po; \ + echo "$$lang:"; \ + if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ + rm -f $$lang.old.po; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$lang.po; \ + mv $$lang.old.po $$lang.po; \ + fi; \ + done + +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + rm -f $@-t $@ \ + && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ + | sed -e '$$s/\\$$//') > $@-t \ + && chmod a-w $@-t \ + && mv $@-t $@ ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. \ + && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/po/POTFILES.in b/current/po/POTFILES.in new file mode 100644 index 00000000..b04db505 --- /dev/null +++ b/current/po/POTFILES.in @@ -0,0 +1,123 @@ +# List of files which contain translatable strings. + +libmisc/addgrps.c +libmisc/age.c +libmisc/basename.c +libmisc/chkname.c +libmisc/chkshell.c +libmisc/chowndir.c +libmisc/chowntty.c +libmisc/console.c +libmisc/copydir.c +libmisc/entry.c +libmisc/env.c +libmisc/failure.c +libmisc/fields.c +libmisc/hushed.c +libmisc/isexpired.c +libmisc/limits.c +libmisc/list.c +libmisc/log.c +libmisc/login_access.c +libmisc/login_desrpc.c +libmisc/login_krb.c +libmisc/loginprompt.c +libmisc/mail.c +libmisc/motd.c +libmisc/myname.c +libmisc/obscure.c +libmisc/pam_pass.c +libmisc/pwd2spwd.c +libmisc/pwd_init.c +libmisc/rlogin.c +libmisc/salt.c +libmisc/setugid.c +libmisc/setup.c +libmisc/setupenv.c +libmisc/shell.c +libmisc/strtoday.c +libmisc/suauth.c +libmisc/sub.c +libmisc/sulog.c +libmisc/ttytype.c +libmisc/tz.c +libmisc/ulimit.c +libmisc/utmp.c +libmisc/valid.c +libmisc/xmalloc.c +lib/commonio.c +lib/dialchk.c +lib/dialup.c +lib/encrypt.c +lib/fputsx.c +lib/getdef.c +lib/getpass.c +lib/grdbm.c +lib/groupio.c +lib/grpack.c +lib/gsdbm.c +lib/gshadow.c +lib/gspack.c +lib/lockpw.c +lib/md5.c +lib/md5crypt.c +lib/mkdir.c +lib/port.c +lib/putgrent.c +lib/putpwent.c +lib/putspent.c +lib/pwauth.c +lib/pwdbm.c +lib/pwio.c +lib/pwpack.c +lib/rad64.c +lib/rename.c +lib/rmdir.c +lib/sgetgrent.c +lib/sgetpwent.c +lib/sgetspent.c +lib/sgroupio.c +lib/shadow.c +lib/shadowio.c +lib/snprintf.c +lib/spdbm.c +lib/sppack.c +lib/strcasecmp.c +lib/strdup.c +lib/strerror.c +lib/strstr.c +lib/tcfsio.c +lib/utent.c +src/chage.c +src/chfn.c +src/chpasswd.c +src/chsh.c +src/dpasswd.c +src/expiry.c +src/faillog.c +src/gpasswd.c +src/groupadd.c +src/groupdel.c +src/groupmod.c +src/groups.c +src/grpck.c +src/grpconv.c +src/grpunconv.c +src/id.c +src/lastlog.c +src/login.c +src/logoutd.c +src/mkpasswd.c +src/newgrp.c +src/newusers.c +src/passwd.c +src/pwck.c +src/pwconv.c +src/pwunconv.c +src/su.c +src/sulogin.c +src/useradd.c +src/userdel.c +src/usermod.c +src/vipw.c + diff --git a/current/po/cat-id-tbl.c b/current/po/cat-id-tbl.c new file mode 100644 index 00000000..314d8ca0 --- /dev/null +++ b/current/po/cat-id-tbl.c @@ -0,0 +1,504 @@ +/* Automatically generated by po2tbl.sed from shadow.pot. */ + +#if HAVE_CONFIG_H +# include +#endif + +#include "libgettext.h" + +const struct _msg_ent _msg_tbl[] = { + {"", 1}, + {"Warning: unknown group %s\n", 2}, + {"Warning: too many groups\n", 3}, + {"Your password has expired.", 4}, + {"Your password is inactive.", 5}, + {"Your login has expired.", 6}, + {" Contact the system administrator.\n", 7}, + {" Choose a new password.\n", 8}, + {"Your password will expire in %ld days.\n", 9}, + {"Your password will expire tomorrow.\n", 10}, + {"Your password will expire today.\n", 11}, + {"Unable to change tty %s", 12}, + {"Environment overflow\n", 13}, + {"You may not change $%s\n", 14}, + {"%d %s since last login. Last was %s on %s.\n", 15}, + {"failures", 16}, + {"failure", 17}, + {"Too many logins.\n", 18}, + {"Password does not decrypt secret key for %s.\n", 19}, + {"Could not set %s's secret key: is the keyserv daemon running?\n", 20}, + {"You have new mail.", 21}, + {"No mail.", 22}, + {"You have mail.", 23}, + {"Bad password: %s. ", 24}, + {"passwd: pam_start() failed, error %d\n", 25}, + {"passwd: %s\n", 26}, + {"Unable to cd to \"%s\"\n", 27}, + {"No directory, logging in with HOME=/", 28}, + {"Executing shell %s\n", 29}, + {"Cannot execute %s", 30}, + {"Access to su to that account DENIED.\n", 31}, + {"Password authentication bypassed.\n", 32}, + {"Please enter your OWN password as authentication.\n", 33}, + {"Invalid root directory \"%s\"\n", 34}, + {"Can't change root directory to \"%s\"\n", 35}, + {"malloc(%d) failed\n", 36}, + {"Dialup Password: ", 37}, + {"Could not allocate space for config info.\n", 38}, + {"configuration error - unknown item '%s' (notify administrator)\n", 39}, + {"error - lookup '%s' failed\n", 40}, + {"%s not found\n", 41}, + {"Password: ", 42}, + {"%s's Password: ", 43}, + {"(Echo on) ", 44}, + {"Unknown error %d", 45}, + {"\ +Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n\ + [ -I inactive ] [ -E expire ] [ -d last_day ] user\n", 46}, + {"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n", 47}, + {"\ +Enter the new value, or press return for the default\n\ +\n", 48}, + {"Minimum Password Age", 49}, + {"Maximum Password Age", 50}, + {"Last Password Change (YYYY-MM-DD)", 51}, + {"Password Expiration Warning", 52}, + {"Password Inactive", 53}, + {"Account Expiration Date (YYYY-MM-DD)", 54}, + {"Minimum:\t%ld\n", 55}, + {"Maximum:\t%ld\n", 56}, + {"Warning:\t%ld\n", 57}, + {"Inactive:\t%ld\n", 58}, + {"Last Change:\t\t", 59}, + {"Never\n", 60}, + {"Password Expires:\t", 61}, + {"Password Inactive:\t", 62}, + {"Account Expires:\t", 63}, + {"%s: do not include \"l\" with other flags\n", 64}, + {"%s: permission denied\n", 65}, + {"%s: can't lock password file\n", 66}, + {"%s: can't open password file\n", 67}, + {"%s: unknown user: %s\n", 68}, + {"%s: can't lock shadow password file\n", 69}, + {"%s: can't open shadow password file\n", 70}, + {"Changing the aging information for %s\n", 71}, + {"%s: error changing fields\n", 72}, + {"%s: can't update password file\n", 73}, + {"%s: can't update shadow password file\n", 74}, + {"Error updating the DBM password entry.\n", 75}, + {"%s: can't rewrite shadow password file\n", 76}, + {"%s: can't rewrite password file\n", 77}, + {"%s: no aging information present\n", 78}, + {"\ +Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n\ +\t[ -h home_ph ] [ -o other ] [ user ]\n", 79}, + {"\ +Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n", 80}, + {"Enter the new value, or press return for the default\n", 81}, + {"Full Name", 82}, + {"\tFull Name: %s\n", 83}, + {"Room Number", 84}, + {"\tRoom Number: %s\n", 85}, + {"Work Phone", 86}, + {"\tWork Phone: %s\n", 87}, + {"Home Phone", 88}, + {"\tHome Phone: %s\n", 89}, + {"Other", 90}, + {"%s: Permission denied.\n", 91}, + {"%s: Unknown user %s\n", 92}, + {"%s: Cannot determine your user name.\n", 93}, + {"%s: cannot change user `%s' on NIS client.\n", 94}, + {"%s: `%s' is the NIS master for this client.\n", 95}, + {"Changing the user information for %s\n", 96}, + {"%s: invalid name: \"%s\"\n", 97}, + {"%s: invalid room number: \"%s\"\n", 98}, + {"%s: invalid work phone: \"%s\"\n", 99}, + {"%s: invalid home phone: \"%s\"\n", 100}, + {"%s: \"%s\" contains illegal characters\n", 101}, + {"%s: fields too long\n", 102}, + {"Cannot change ID to root.\n", 103}, + {"Cannot lock the password file; try again later.\n", 104}, + {"Cannot open the password file.\n", 105}, + {"%s: %s not found in /etc/passwd\n", 106}, + {"Error updating the password entry.\n", 107}, + {"Cannot commit password file changes.\n", 108}, + {"Cannot unlock the password file.\n", 109}, + {"usage: %s [-e]\n", 110}, + {"%s: can't lock shadow file\n", 111}, + {"%s: can't open shadow file\n", 112}, + {"%s: line %d: line too long\n", 113}, + {"%s: line %d: missing new password\n", 114}, + {"%s: line %d: unknown user %s\n", 115}, + {"%s: line %d: cannot update password entry\n", 116}, + {"%s: error detected, changes ignored\n", 117}, + {"%s: error updating shadow file\n", 118}, + {"%s: error updating password file\n", 119}, + {"Usage: %s [ -s shell ] [ name ]\n", 120}, + {"Login Shell", 121}, + {"You may not change the shell for %s.\n", 122}, + {"Changing the login shell for %s\n", 123}, + {"%s: Invalid entry: %s\n", 124}, + {"%s is an invalid shell.\n", 125}, + {"Usage: %s [ -(a|d) ] shell\n", 126}, + {"Shell password: ", 127}, + {"re-enter Shell password: ", 128}, + {"%s: Passwords do not match, try again.\n", 129}, + {"%s: can't create %s", 130}, + {"%s: can't open %s", 131}, + {"%s: Shell %s not found.\n", 132}, + {"Usage: expiry { -f | -c }\n", 133}, + {"%s: WARNING! Must be set-UID root!\n", 134}, + {"%s: unknown user\n", 135}, + {"usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n", 136}, + {"Unknown User: %s\n", 137}, + {"Username Failures Maximum Latest\n", 138}, + {" %s on %s", 139}, + {" [%lds left]", 140}, + {" [%lds lock]", 141}, + {"usage: %s [-r|-R] group\n", 142}, + {" %s [-a user] group\n", 143}, + {" %s [-d user] group\n", 144}, + {" %s [-A user,...] [-M user,...] group\n", 145}, + {" %s [-M user,...] group\n", 146}, + {"%s: unknown user %s\n", 147}, + {"Permission denied.\n", 148}, + {"%s: shadow group passwords required for -A\n", 149}, + {"Who are you?\n", 150}, + {"unknown group: %s\n", 151}, + {"Adding user %s to group %s\n", 152}, + {"Removing user %s from group %s\n", 153}, + {"%s: unknown member %s\n", 154}, + {"%s: Not a tty\n", 155}, + {"Changing the password for group %s\n", 156}, + {"New Password: ", 157}, + {"Re-enter new password: ", 158}, + {"They don't match; try again", 159}, + {"%s: Try again later\n", 160}, + {"%s: can't get lock\n", 161}, + {"%s: can't get shadow lock\n", 162}, + {"%s: can't open file\n", 163}, + {"%s: can't update entry\n", 164}, + {"%s: can't update shadow entry\n", 165}, + {"%s: can't re-write file\n", 166}, + {"%s: can't re-write shadow file\n", 167}, + {"%s: can't unlock file\n", 168}, + {"%s: can't update DBM files\n", 169}, + {"%s: can't update DBM shadow files\n", 170}, + {"usage: groupadd [-g gid [-o]] group\n", 171}, + {"%s: error adding new group entry\n", 172}, + {"%s: cannot add new dbm group entry\n", 173}, + {"%s: name %s is not unique\n", 174}, + {"%s: gid %ld is not unique\n", 175}, + {"%s: can't get unique gid\n", 176}, + {"%s: %s is a not a valid group name\n", 177}, + {"%s: invalid group %s\n", 178}, + {"%s: -O requires NAME=VALUE\n", 179}, + {"%s: cannot rewrite group file\n", 180}, + {"%s: cannot rewrite shadow group file\n", 181}, + {"%s: unable to lock group file\n", 182}, + {"%s: unable to open group file\n", 183}, + {"%s: unable to lock shadow group file\n", 184}, + {"%s: unable to open shadow group file\n", 185}, + {"%s: group %s exists\n", 186}, + {"usage: groupdel group\n", 187}, + {"%s: error removing group entry\n", 188}, + {"%s: error removing group dbm entry\n", 189}, + {"%s: error removing shadow group entry\n", 190}, + {"%s: error removing shadow group dbm entry\n", 191}, + {"%s: cannot remove user's primary group.\n", 192}, + {"%s: group %s does not exist\n", 193}, + {"%s: group %s is a NIS group\n", 194}, + {"%s: %s is the NIS master\n", 195}, + {"usage: groupmod [-g gid [-o]] [-n name] group\n", 196}, + {"%s: %s not found in /etc/group\n", 197}, + {"%s: cannot add new dbm shadow group entry\n", 198}, + {"%s: %ld is not a unique gid\n", 199}, + {"%s: %s is not a unique name\n", 200}, + {"unknown user %s\n", 201}, + {"Usage: %s [ -r ] [ group [ gshadow ] ]\n", 202}, + {"Usage: %s [ -r ] [ group ]\n", 203}, + {"No", 204}, + {"%s: cannot lock file %s\n", 205}, + {"%s: cannot open file %s\n", 206}, + {"invalid group file entry\n", 207}, + {"delete line `%s'? ", 208}, + {"duplicate group entry\n", 209}, + {"invalid group name `%s'\n", 210}, + {"group %s: bad GID (%d)\n", 211}, + {"group %s: no user %s\n", 212}, + {"delete member `%s'? ", 213}, + {"invalid shadow group file entry\n", 214}, + {"duplicate shadow group entry\n", 215}, + {"no matching group file entry\n", 216}, + {"shadow group %s: no administrative user %s\n", 217}, + {"delete administrative member `%s'? ", 218}, + {"shadow group %s: no user %s\n", 219}, + {"%s: cannot update file %s\n", 220}, + {"%s: the files have been updated; run mkpasswd\n", 221}, + {"%s: no changes\n", 222}, + {"%s: the files have been updated\n", 223}, + {"%s: can't lock group file\n", 224}, + {"%s: can't open group file\n", 225}, + {"%s: can't lock shadow group file\n", 226}, + {"%s: can't open shadow group file\n", 227}, + {"%s: can't remove shadow group %s\n", 228}, + {"%s: can't update shadow entry for %s\n", 229}, + {"%s: can't update entry for group %s\n", 230}, + {"%s: can't update shadow group file\n", 231}, + {"%s: can't update group file\n", 232}, + {"%s: not configured for shadow group support.\n", 233}, + {"%s: can't delete shadow group file\n", 234}, + {"usage: id [ -a ]\n", 235}, + {"usage: id\n", 236}, + {"uid=%d(%s)", 237}, + {"uid=%d", 238}, + {" gid=%d(%s)", 239}, + {" gid=%d", 240}, + {" euid=%d(%s)", 241}, + {" euid=%d", 242}, + {" egid=%d(%s)", 243}, + {" egid=%d", 244}, + {" groups=", 245}, + {"Username Port From Latest\n", 246}, + {"Username Port Latest\n", 247}, + {"**Never logged in**", 248}, + {"usage: %s [-p] [name]\n", 249}, + {" %s [-p] [-h host] [-f name]\n", 250}, + {" %s [-p] -r host\n", 251}, + {"Invalid login time\n", 252}, + {"\ +\n\ +System closed for routine maintenance\n", 253}, + {"\ +\n\ +[Disconnect bypassed -- root login allowed.]\n", 254}, + {"\ +\n\ +Login timed out after %d seconds.\n", 255}, + {" on `%.100s' from `%.200s'", 256}, + {" on `%.100s'", 257}, + {"\ +\n\ +%s login: ", 258}, + {"login: ", 259}, + {"Login incorrect", 260}, + {"Warning: login re-enabled after temporary lockout.\n", 261}, + {"Last login: %s on %s", 262}, + {"Last login: %.19s on %s", 263}, + {" from %.*s", 264}, + {"Starting rad_login\n", 265}, + {"%s: no DBM database on system - no action performed\n", 266}, + {"%s: cannot overwrite file %s\n", 267}, + {"%s: cannot open DBM files for %s\n", 268}, + {"%s: the beginning with ", 269}, + {"%s: error parsing line \"%s\"\n", 270}, + {"adding record for name ", 271}, + {"%s: error adding record for ", 272}, + {"added %d entries, longest was %d\n", 273}, + {"Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n", 274}, + {"Usage: %s [ -vf ] [ -p|g|sp ] file\n", 275}, + {"Usage: %s [ -vf ] [ -p|g ] file\n", 276}, + {"usage: newgrp [ - ] [ group ]\n", 277}, + {"usage: sg group [[-c] command ]\n", 278}, + {"unknown uid: %d\n", 279}, + {"unknown gid: %ld\n", 280}, + {"unknown gid: %d\n", 281}, + {"Sorry.\n", 282}, + {"too many groups\n", 283}, + {"Usage: %s [ input ]\n", 284}, + {"%s: can't lock /etc/passwd.\n", 285}, + {"%s: can't lock files, try again later\n", 286}, + {"%s: can't open files\n", 287}, + {"%s: line %d: invalid line\n", 288}, + {"%s: line %d: can't create GID\n", 289}, + {"%s: line %d: can't create UID\n", 290}, + {"%s: line %d: cannot find user %s\n", 291}, + {"%s: line %d: can't update password\n", 292}, + {"%s: line %d: mkdir failed\n", 293}, + {"%s: line %d: chown failed\n", 294}, + {"%s: line %d: can't update entry\n", 295}, + {"%s: error updating files\n", 296}, + {"usage: %s [ -f | -s ] [ name ]\n", 297}, + {" %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n", 298}, + {" %s { -l | -u | -d | -S | -e } name\n", 299}, + {"User %s has a TCFS key, his old password is required.\n", 300}, + {"You can use -t option to force the change.\n", 301}, + {"Old password: ", 302}, + {"Incorrect password for `%s'\n", 303}, + {"Warning: user %s has a TCFS key.\n", 304}, + {"\ +Enter the new password (minimum of %d, maximum of %d characters)\n\ +Please use a combination of upper and lower case letters and numbers.\n", 305}, + {"New password: ", 306}, + {"Try again.\n", 307}, + {"\ +\n\ +Warning: weak password (enter it again to use it anyway).\n", 308}, + {"They don't match; try again.\n", 309}, + {"The password for %s cannot be changed.\n", 310}, + {"Sorry, the password for %s cannot be changed yet.\n", 311}, + {"%s: out of memory\n", 312}, + {"Cannot lock the TCFS key database; try again later\n", 313}, + {"Cannot open the TCFS key database.\n", 314}, + {"Error updating the TCFS key database.\n", 315}, + {"Cannot commit TCFS changes.\n", 316}, + {"%s: Cannot execute %s", 317}, + {"%s: repository %s not supported\n", 318}, + {"%s: Permission denied\n", 319}, + {"You may not change the password for %s.\n", 320}, + {"Changing password for %s\n", 321}, + {"The password for %s is unchanged.\n", 322}, + {"Password changed.\n", 323}, + {"Usage: %s [ -qr ] [ passwd [ shadow ] ]\n", 324}, + {"Usage: %s [ -qr ] [ passwd ]\n", 325}, + {"invalid password file entry\n", 326}, + {"duplicate password entry\n", 327}, + {"invalid user name `%s'\n", 328}, + {"user %s: bad UID (%d)\n", 329}, + {"user %s: no group %d\n", 330}, + {"user %s: directory %s does not exist\n", 331}, + {"user %s: program %s does not exist\n", 332}, + {"invalid shadow password file entry\n", 333}, + {"duplicate shadow password entry\n", 334}, + {"no matching password file entry\n", 335}, + {"user %s: last password change in the future\n", 336}, + {"%s: can't lock passwd file\n", 337}, + {"%s: can't open passwd file\n", 338}, + {"%s: can't remove shadow entry for %s\n", 339}, + {"%s: can't update passwd entry for %s\n", 340}, + {"%s: can't update shadow file\n", 341}, + {"%s: can't update passwd file\n", 342}, + {"%s: Shadow passwords are not configured.\n", 343}, + {"%s: can't update entry for user %s\n", 344}, + {"%s: can't delete shadow password file\n", 345}, + {"Sorry.", 346}, + {"%s: must be run from a terminal\n", 347}, + {"%s: pam_start: error %d\n", 348}, + {"Unknown id: %s\n", 349}, + {"You are not authorized to su %s\n", 350}, + {"(Enter your own password.)", 351}, + {"%s: permission denied (shell).\n", 352}, + {"\ +%s: %s\n\ +(Ignored)\n", 353}, + {"No shell\n", 354}, + {"No password file\n", 355}, + {"No password entry for 'root'\n", 356}, + {"\ +\n\ +Type control-d to proceed with normal startup,\n\ +(or give root password for system maintenance):", 357}, + {"Entering System Maintenance Mode\n", 358}, + {"%s: rebuild the group database\n", 359}, + {"%s: rebuild the shadow group database\n", 360}, + {"%s: invalid numeric argument `%s'\n", 361}, + {"%s: unknown gid %s\n", 362}, + {"%s: unknown group %s\n", 363}, + {"group=%s,%ld basedir=%s skel=%s\n", 364}, + {"shell=%s ", 365}, + {"inactive=%ld expire=%s", 366}, + {"GROUP=%ld\n", 367}, + {"HOME=%s\n", 368}, + {"INACTIVE=%ld\n", 369}, + {"EXPIRE=%s\n", 370}, + {"SHELL=%s\n", 371}, + {"SKEL=%s\n", 372}, + {"%s: cannot create new defaults file\n", 373}, + {"%s: rename: %s", 374}, + {"%s: group `%s' is a NIS group.\n", 375}, + {"%s: too many groups specified (max %d).\n", 376}, + {"usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n", 377}, + {"\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n", 378}, + {"[-f inactive] [-e expire ] ", 379}, + {"[-A program] ", 380}, + {"[-p passwd] name\n", 381}, + {" %s\t-D [-g group] [-b base] [-s shell]\n", 382}, + {"\t\t[-f inactive] [-e expire ]\n", 383}, + {"%s: error locking group file\n", 384}, + {"%s: error opening group file\n", 385}, + {"%s: error locking shadow group file\n", 386}, + {"%s: error opening shadow group file\n", 387}, + {"%s: uid %d is not unique\n", 388}, + {"%s: can't get unique uid\n", 389}, + {"%s: invalid field `%s'\n", 390}, + {"%s: invalid base directory `%s'\n", 391}, + {"%s: invalid comment `%s'\n", 392}, + {"%s: invalid home directory `%s'\n", 393}, + {"%s: invalid date `%s'\n", 394}, + {"%s: shadow passwords required for -e\n", 395}, + {"%s: shadow passwords required for -f\n", 396}, + {"%s: invalid shell `%s'\n", 397}, + {"%s: invalid user name `%s'\n", 398}, + {"%s: cannot rewrite password file\n", 399}, + {"%s: cannot rewrite shadow password file\n", 400}, + {"%s: unable to lock password file\n", 401}, + {"%s: unable to open password file\n", 402}, + {"%s: cannot lock shadow password file\n", 403}, + {"%s: cannot open shadow password file\n", 404}, + {"%s: error adding authentication method\n", 405}, + {"%s: error adding new password entry\n", 406}, + {"%s: error updating password dbm entry\n", 407}, + {"%s: error adding new shadow password entry\n", 408}, + {"%s: error updating shadow passwd dbm entry\n", 409}, + {"%s: cannot create directory %s\n", 410}, + {"%s: user %s exists\n", 411}, + {"%s: warning: CREATE_HOME not supported, please use -m instead.\n", 412}, + {"usage: %s [-r] name\n", 413}, + {"%s: error updating group entry\n", 414}, + {"%s: cannot update dbm group entry\n", 415}, + {"%s: cannot remove dbm group entry\n", 416}, + {"%s: cannot rewrite TCFS key file\n", 417}, + {"%s: cannot lock TCFS key file\n", 418}, + {"%s: cannot open TCFS key file\n", 419}, + {"%s: cannot open group file\n", 420}, + {"%s: cannot open shadow group file\n", 421}, + {"%s: error deleting authentication\n", 422}, + {"%s: error deleting password entry\n", 423}, + {"%s: error deleting shadow password entry\n", 424}, + {"%s: error deleting TCFS entry\n", 425}, + {"%s: error deleting password dbm entry\n", 426}, + {"%s: error deleting shadow passwd dbm entry\n", 427}, + {"%s: user %s is currently logged in\n", 428}, + {"%s: warning: %s not owned by %s, not removing\n", 429}, + {"%s: warning: can't remove ", 430}, + {"%s: user %s does not exist\n", 431}, + {"%s: user %s is a NIS user\n", 432}, + {"%s: %s not owned by %s, not removing\n", 433}, + {"%s: not removing directory %s (would remove home of user %s)\n", 434}, + {"%s: error removing directory %s\n", 435}, + {"\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n", 436}, + {"[-A {DEFAULT|program},... ] ", 437}, + {"[-p passwd] [-L|-U] name\n", 438}, + {"%s: out of memory in update_group\n", 439}, + {"%s: out of memory in update_gshadow\n", 440}, + {"%s: no flags given\n", 441}, + {"%s: shadow passwords required for -e and -f\n", 442}, + {"%s: uid %ld is not unique\n", 443}, + {"%s: error deleting authentication method\n", 444}, + {"%s: error changing authentication method\n", 445}, + {"%s: error changing password entry\n", 446}, + {"%s: error removing password entry\n", 447}, + {"%s: error adding password dbm entry\n", 448}, + {"%s: error removing passwd dbm entry\n", 449}, + {"%s: error removing shadow password entry\n", 450}, + {"%s: error removing shadow passwd dbm entry\n", 451}, + {"%s: directory %s exists\n", 452}, + {"%s: can't create %s\n", 453}, + {"%s: can't chown %s\n", 454}, + {"%s: cannot rename directory %s to %s\n", 455}, + {"%s: warning: %s not owned by %s\n", 456}, + {"failed to change mailbox owner", 457}, + {"failed to rename mailbox", 458}, + {"\ +\n\ +%s: %s is unchanged\n", 459}, + {"Couldn't lock file", 460}, + {"Couldn't make backup", 461}, + {"%s: can't restore %s: %s (your changes are in %s)\n", 462}, + {"\ +Usage:\n\ +`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n\ +`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n", 463}, +}; + +int _msg_tbl_length = 463; diff --git a/current/po/el.gmo b/current/po/el.gmo new file mode 100644 index 0000000000000000000000000000000000000000..15311f731d090492bd04dae476908b1a7ba04376 GIT binary patch literal 41822 zcmb`P34B~-y}t)HY*6-nJq1crXv&UIC{Vglprud>O0DfQnWV8vCQK4ap{R%`s23GQ zalr+zD_-}7t6r~FdW&o=7BA{e+B-Bunyr&GNo%=n`9I(Heb1S5X3ivqzw`OL^PKm6 zfA798=WIUwEe|L7{q}%F;zYRTor%N^Z%QQEPe>%*h2EQB`EGa;`cK0{;1A)U@OSVq zxWVbO@F4U%;8AcNJPjUsMj|m0UJRGQW$;q?dpHH|fmQGKfcoXe;zy&{mrlf-UE+=pMda3)%clDhh}Vf5pyGEIJQ9A+@q19|{vA|4ZiPp{L(zz*L&;wZ72kP~ zB1qik>>q*3haW)2f4yTCD!u;)C4Vf1Cb=u1(sL_RJ-OZKKL^L7|1ng2{tT5*yP(1! zN8u~oCqwyj0hB-2L;17P=^udd=UY(ztcOZ>A3O!V^=zB36QJa-h3COW=)tc;<>OkY z{OyJcCvi?9aVj_wsy;G>&+$<9S3=p>Lb?A4 zR6c#z={G=%GBE@xlEleGQvO^674G|?>iegl()U9sf7e5$tKZola=x{n0+o(AQ0b_K zlK&`FJbnPF(ut>?`4E&p$6a8dpP=Hi9jbf|yTpcn8C1B{P~m3g93JMdB)&xugsTn&$g z%i%F_H9QJ_272&2Q0afl*}npnj(t%1I{q^2?n-z9`gcRgw?f%JiIp8 zE-djKr+*PDe_w?jJbbzxm(GW356hv-;}cN%@GW>U{5>2Gw?O%Oz*W|KB9!@TDDxFi z>3k5X{2qgf{}b>qxB;r3WS#v^sQi7$4C}5ED%{K9Y48^4!Mh+`VB#xK_Rl!J0u|l? zGi~@sLFM12Q2s81vR~uOKMm#n7w|;55h~vOQ1Lrr7G(h^K)Sxfd*EsC<52nkL#XsV z50y^?P~}iD+s5-;DES-V1b91CJNpWxs1xgqJ1!p!KZgD^NEecL99{&oP~jYV zwav$=a3cBz@Ck@SW%rb8US&7%KfILAjsm^z)tl zN~rMfgsLxJfhxD3!-L?Tpz8HsoOuq)|5u&-3Zlw`k>@rgQvp7uC?YDK()6yumZM0rT0US zAtv!TsPwIeD&H;eAov4~6#dCi?#_lv*K&9utcUXVHmGvC4=Nu222DJn z($xnQ&x(0AoD-qiNhMS~E{C$e87jOLQ2D$Xeh5AQwQnZPW!VKI1sbYz% zuD9*^0jO|)3Kg%7Q11T$J$U2-%L}3E)6G!z>rSZh{svTg`6X1nd;wO%x8Gp%;asSC zUIX6=KMv1_k3hALXQAA`0#%<5xY5d;22~#CLJwXB&w@+f!SDfiID7;uUmk}F_m5EF z^*Qsy7h3<%besj1&Sg;H-49j2z7G|@4N&#I11cY0g@?hTZ?f{0P~lwz=~@%Zq4MQ1 zcsTqocqIHARKKVd%lbZ?X06e5ic90xJF~ zsQmvRl>d)ImCsY~P`Jsl6Dq$(p!`4Z-PZni$Ft!1m|q6fo|@q__-S|ud>$SRH$&y) z2s{>6yvLT)X;Ai8!zpknR6HJp3ipdp`T01M+|y9$$im6+z*}uTUI3LZ*Fd$8Ca8At zE2whW2NnP07hCx%DF0@_W8ke&{XoWdQythNupURXiuSJgc z!>O4622O`No&MrlTMt{H`kRN~>G0Q3<+lYYT?f@!PJ;?34X=dXbNU{5D*Dq`*!_n& zkS;v&L3jgv9?G3pPu{>=;k)3+q0;jQI1#=AFM|ia-D$7s7vqO5fk%rSQO& zRzJhB8P34`QK;~9__e9T}*2{|HWoIVkssH{1N22Nj)#FVO7!=_+3-m?A0E^~9|CWM3g=t!Y`6)^zc;tq zd_Du7hkh}f1RsRw!YAM?*aKC6&S_&00%qV`_;DJf0`yNog?rp;YhDLcUO$0y|5vDVkGs?6-vX#~ ze-hFpxVP`cszXb8rxn@hR30w=6DNKI&XuL z|2mZXI;ed7U#NIi+-<`<7kcRDL76wfO8Btj@1Xqaay`zP|1B&%^7{?|=&bst?)zxE?CrcfqOf^KcP-0iFUU-edE5 z4m=k99Z>o38K``H97^sF@J#qJRJp(N!?r)Z0V+NzcmaF>sy_bC>HDDEjlb85*WfJp3pfM*A5{9Tc)-;|sP^!6sPcFLDx5*6 zcpUR_8}AFD%$LB6;JxtO@YhiJdc-H}czhB3GWsjvmGFO{^7q6~+IsswsB-!koDCm? z@~<0S4!wV|`Mngr1APmufFFXYH=lrqz{lXh@TX3{7ApT^cTXz;H8f9;G5Aeg;QWPJQzL% zRZic49{dYD0`7FI_;e!i7W5}W*`Ed#|C#VexELxO%~0k31$Y(w5mfwkK>3&WjBSTU z!trRYhn4U)cqsf5JP1Ax-wuBT<^S*DmGCdl{OE`5{OS~V80M4Ux$sh`cr?P3;pdyf=XW<{1W^Cl>6g8M_I#*;H~ickS;3m)`!_! zfFFTM&r49{llZ)?mnXv$(9VXchsz!BgNny@q1-(WkA}OT%K6|g*mO^VXQ6*TybyjK zPJ++EBj8SWEv$INhI=#g(6>UB^TSZ(@FZ0F{tV@RCrrZEpzq}}@N9SvI)UeMmypr~BbJ_!+2pd>JY| zzksIP;8ExkU$y0SG&~XQ<**7ahL^zypvvLDoc$hnAo}CJX3KdzoQi%Lyb|64Rlolo zPKHlI<J{>i^wP<@x}WyGNnQ?T7Gi_cl>8szvG8wD@z?>6hQ~Z+=Q~rN`m^^zg<0TyBhU#%36P0;#K$&%pO4v@;n>$pp$uq=k2J|(SHEatP&5So!ECbg<5~3o?(7B}eRR8r z)$mN@e+UnT7dy8e`~zkS;BlzssPWFtES^8ca}Df;_n_2o>vte#*P>?dd=qLF&uV-B z3a>|9!SkJ{mry65{*0m-Cf<+I?-A4&k<)J(JOuSV)Ffy2HMkPHtBeHcLw^|0-#~41 zW*>$#QBByr0xyDdQI|OTEsiI_GcechosI|b{B@pdQ71XGY9m3NK);UXe$+##521ey zegf5n`aMd&?_qv2YB5T`|3-~N9q#lpYt|pXYfzVCelL6tbu;Q0=-&me3dy5QEI}a-vFngKMQpe&#O_xPWFR5e*yJxsGp!t#ry_m z7sfFmO&Ylq(Pv=z_rGYqj`}!CzfGtskr{!PqkiV(f6epPP#;1~!0bxs|31P)1!iA_ zKY~X%H*1~1pWt<URXC~Z%ektlbs1KlOoZURfqcQt7&x=s+K%I(SzavqHnkU9l z*ogVt;ftt`q7Fd+Jy-?LM*SPlhr#e~Gn(Dbpek(Po^NyVN%V*E{1w?qq!w>S)yaF?){;_;pw$zJb}vJYSDGf#-9a zyXEM=k2(_l4bBX0;&D{19^5YtKkuIB!)uWJu#^8B`oB55N$|^u zODO%eqEha8w&SPabj;gOQ+a+f>TZ;N-+{~Ek5J!5>Gw413CwfwA{p@WPz|WhICngn zeUP)zxAJ@|{1zNHZgEwOw<6t`@)lP$E?L5Vi`TLu)zF~FYOgxo*qCZ+m8QXKO08Pj zlx$2bsR+3n%}FE9R(h?e#^#1(YifyeSL@X`C97NOZ%@f>%1hnRT%SpKvYp-5(BRD{ zh^gL$7W7vuVhdKJn|y;C)9FTUep}=6RK|(ilFqCQi&RW#@fy-~^-WW~1kaN4>RY_F zrs@^Rrn*#3MWW(5S$nPZjj0+h-PYZEid<@H&7>R1$=0;joJm)waI>nub%ocI&NL<) zyq4BvrnRkkaz!N`)sb?1OSgK>$(EK?>5TQi#fBL2e$v!L#VyH9Q+-q2RBu%(xw7D( zl0qTQ^+djo_$b`AmXy&qtzMN}JxOU;JhQ%qs5PakTfOD06&TT~s> znki(yXMYn~##POvTqbc0TkKWcL8jc{A?j5%d5uKJJg)Lq z5qbMuZ_6BwDp16E)pSKYGkMCCDGF>}NM~XY6&}MnX8;cb7-ISmRZ->90nA3-y=s?hX=4{Yy7d3(4RaE7DXaFR7LklqDsF z4K;{1;kB+vd9ETPYsks^mex$NHJy>r;t35k)a_Jl>yki|u3m|zHbbkJFy&0bFj>|z zEuk=%O_*}-Ip?%YjA*PdR_7TjYCREbsi!u34at^P+jgdS-gVNfO18+_#GfeGrj%@= zFmF#b)YD+pQ&@{8>T_+nt%(LUp=Dx=x4_kHnxR_ZsS{dGHSL7jN`q`@NY&9UXp#a z3KlGt>GS6U3MiR8kXtldV%dCzZM* zRo&K_A{diVb6o+@4P;i^o>1wTZ!)5_b+rw_FM}4ZCT$|um~5?HG180PEx*=7(4NWE0Q(oLIrN|l62on3Y|@DeO(&`6i8A(h_kUZwZmE5QKrWmGv;oM=g! zZo72_=G6`L;gb6qyknN-!POg$B}IGKS(nea{L71V3fxtK;2Z6;AE8_!~i z76vV~Bs2f2G(DT0fZ5)H9(6*C>&0zeXHquGqa?}-jFtGdCQ~trlit=`qqaTss(B_? zBIO*i3uR24h{=+0Q*}-YSrwNZB|@6;kO46s#h1GCz}2@xV6k45sg+?r;_9WdcNtJF zp<(NosuA_1Oc^*oMop@diLVVBYmzlJW*SwqywOg2yl9k*Wg>x=irUI)hn{5`O&AL` zCnz2{%rIw%i5f=rYO1-${-7j7_L}6?q-v9G4XrKFmM9@pNpG4ld!e^7wYrS8@~_zQ zv3ouFZaR{nt``?nAW=Si<3U{b#v-QZ0zV@e9jO7uBIOG=eS0cX=)sD!!1X_BL`*cB zGxd#03cfUPmeD#dfpUCmG{oIveBx( z6N!{yBp*_Du(ojZ*3AxC1T?hOq`XrbPPMDoH1ny9SKE-RbAqW%h6OB5j|r}qY{R;# zwZ1yps+nVBs&z%$%^V|gY6mvwLd~v3B1r9MLdCs8IoZH7Wl=dHTCeE`Nl`)rm5q|= z2=*&^fn;rcij|q|0*X8dB2p3wGlf(*rrMRaj^=VWkidtiNK8Qll0kH0^QBa*e6+$P zQR9v7U07B*9^-2(J!z_DvKEAF(y*+v>%4Gs)$u96iW{NLao@H~3$sG%yUKgv+m7l* zb27tXxz20Qf=!Fsa1{NuU!=#06|jkj&9=akGHoWXH-%Xy@1sJonI4El(mQ&TBBCY5 zSnT6|MbLQ})XWlJO;4sQS6>!sWr0nZoC@p%&tp?pDpnY^Y`qC2Tx7?xk59PmCK!Oy z4F3KG0lOO>`#S!vhh4zgDq~Z{;<+YGi_myx`s^aha6cZnV9A>_(-&hBcCpN@ltb2T z%=GtkwAUA^z;a+c@CDqSFxyMTHfDxhYHSi7Bko5x>b=>FE(}$r-Wh>ryD3~~fqv{X z;@j<}sJBgRjj2q1HG36xJT?j-yNw{!) zZ{h+>TPC+egZ@ zHQCM3Bu5n5flD@6pG{fP?%YmfxJ@>t%?gr=o;2-*d5_z!t)hi`I@Z9bIhEnWfa3+{ z9~PWA)Ul5!V>?}HW=oJV3nbjg7wFBb%bXQ7`DWn_HZ!GPe5b{%nWh7fz{tB)^KqY{%jD{xYfN zbW6Qk+?l@DWv^eR5wH9<(c*9R+7q3s={5>Zww#n}4r57qNm^)C?S6Ubq?9MiQ&c@O z>oEsXCeLJUMpJJ^lC!AgDfY;0ak{b?Mc`6T?WS?1NsTYgkk*)Na%(V-6Pi=i_4N8R zUZoC(Ce-+a#m1!0*-mZsRF-O5xju zXB56!Frf&AYWJ{InAL3=mfEcit0|#6&RFRlY|L~3NXKV30o5agPD{oVh&xUR{PXt= z>EKdcqH>lw4K=%r+ST_9XUe3+nP<*Vv6)ba*qLW0rdL;|S~x67do6AHZ(WgOKdHK! z)2mi*=B)X1XU(K@LCP4+(($zIvuA1tvGP6qs^-nBnmKb)V!B-l``LtNg)+PVum|=&??8C!xm;bIJT1xgp^r!MDRH2z((iAM9R0~Se~=L?ToQBLy_>1yoR$qR?O_+{i;?C+4}T z8H6^yF6A4#q|S4dIVxfeoroDHDiZVAt@Ne1yC7|I;VQ%YbYgzGFrS`m#ub$f6Jj&J zGKFxqgt*AlFhvi(bGu?PRd}LukY#n)*3LvQF~wYwxSrXN@05sKPhHC-{Fr&6QOR8q zDzZzpOdVG+@=Ly8QnYF4-w&cv24T?1bz>@Q6l_J*(EY4#=9oI@hD^d3jlM= zdRg24f~G=;V8-n0Zw|_{$f&o-1_3Hx{moB^F*i z>$>Yq`&fAGEcc-56oia_3#n17IR~d%`&sXjr9*vn)!aXD+2XBEX+$$yo!^fYY(ojS&`LD-gJS%+~o+3v~pg~PA>g9x`~vEDY%2d^P*sm zU2QJ0*(Mz_HC4gmW(lJY(smBJh~dW0EqxQaUpAp85UFRELw(YsmSkOOYQ?hK>zh|i z^innToQZ|*)VRxMp0W3;IDZR?*qOB4)@33VwxC09>oUb|>zrd30pg-tYL&?~HIulE z=9-#~oU^O-YPp4IE;`z~Yr6WEZd}@wwpy;Wv8l7Pc?CBX$KjXmhc%{*US6j?dupO9 zaAxS|zStY}U;c%>FY>6t#-~v??v~ahSGQRGJPp+${VnbqUWF&`=F(Hy%a>MqR&f1N zwl(Gsm>grP*uSwL$MWX3j0xN{u^Pg4OQj{c0~*Pzs9>?J^~F|##hxo^d>&1%*v{Q( zH1RR}KE(pJ*BZO3<~4OZ*iJeU$B@99mgfDDS<@2lRee)4`!0nDn2WKib;qz)mkO)B zyOlk3npENy>L!Dk`eaYHoYJ8YLvuoR^GqGMoSEeLjm2>RJ4WX5I;Nkx{#YUyNX*tH z!|*T0$!x|vu79;~S<8*d+#|FeyHUyww!Ti|CqpOqQaGw*m0#m7-3M z7Go?M)u%~-VZqFNt90gWX1&-mi((qDQN)fFgd$n9*ma$R-EUcRoGq6jkA_UCJ(SW&V3E~MDiD(-dq{R#f- zTtoemja$g~uv}{zkufCLh0LT^A+(sw!rZT}%Oo3@ct&^E%vrOiFS_ogHO}~M-6N(E zVp;B4=6FVXwe4cXo%~p+jTSo)Z3@N4w;)<6jkH zwjCk4gw^OxWJ2v#Qm*y2+`9~4>t(yu9J;b{Dj4f}xZCqthRZ8FU&d^TM~#Z)+L{}5 z9PjUhn$-wF1ja%6me@pgtIF9HJNHxDkWQ~;eQDC^@55WFwb(XbYWec?9cB+GlPFlb zOB!kfSQ`tv5T7jxzb#MY7J7}xA&FPXhGIp?oRQhJZfD9YZ?Y<%xwp7QSFwI=dhb;Tm#pHSEU)zkZD98nun?ka|gz)6rXajqg+JBq-lo|puNLN@&-GgjU% zpodhB1ScS5hnX8{7FwE?ux)IJ#?Z~${O4fPzS0k7vb!#!-Fwq}Ycg+^XF(@I>>^3m zZatwF)%2j`;$%aX%+yUWCQ5pLzpb&O%3PE9L=Cj?4NUY(gPoB2Mr=GsT?JvbnJFv1 zChy3!dD@^}T$MJj$b{aFm}9fpzP&&|z8lS^%&2W=Wv1j9*+ceK$u;tpVM*^6FpEpx zp$DVmRyh5pv<+qeWR=xY2W3uh;^A}nVNZ*t-!|GjNi5w z(DiTI3%JsnT3C})U?tnzfmDOuY6z;m>zNp;G@{nFvBhL^%7sK_wZWT8W#_iokB-hB6-9V*#sZ)n$^-tIiB2r5{E*WZy} zx~D(imnE^~Jd(Q>ubdzDb*r9i|DOKrj>6kk+5TLAZgA@!IZk=Ko40ogIlvhfq2RL zS1;z3Rh_whuf4Z7yFJH?N$b7N?rdjwkDPhA?x8)M`4Mk8Hz@yyhP!%lUSDpw-OCQ_ z(U9Dk8^LZ*Z*E{X%N(Er4~O<5)|d4Sa6k_GkN|zEl$b z_N}?$4tYP&-rH@`Ld?+aA~oH8`GI`*X2sCH)3q@>*xr-v`$reqlONjK-TM)C{KyG-jeV{A$^{#whduLX4V!8Kn`%qV;YDHdy()(R~xviR2(JGs~ zTyOg>r&;9<4CZs)olaZt`E?ChQT>o(-zQtUwLiaE;kt_t za%MZLaBOYC+v*kaKP(t{?}}Y<*dV{GKY6cb?_f8{rX+jveJaQux}aqvYXlWlmkB28 zLc3#yB-tRd{hND8KN;Ll5R*+RvpcihgSjok*={S%n`ha9Z1-?(i}%~-Haxp_+KYdB zcD=QFGRTz9k^b!Po__U&J=tw}RWRhqdXoy*biASL4pUB3y|r@Cr^4?U?&vi=k2)Kw zw$l5oD~~Qb8_w?9r_R_87P2jb8oZzOqUnHLkJ@gMLHq~1+h56#^pmW7Pj_Fty58;C z{&p9IUv}o`y6O7{2e<6BHAcRd7&~zV(bK)Jvn$llY)Bou2t?)4mml1@ds}XcbFsly zO%-0KOq}iWS*lSGuPnnVV^h}VE0t+CWwOIl*KPVa{IFIVU)Zo|!%ORVi*4gz#{gwV zj+;6>oFioA_;Sv32dKn0+vvozBg1=!yN0tn%qSCn(QWi9#Q-u$vAeT7PwN@(sx+^~O~R>4)y6&R7kXz`Uw3|Fa4TcI6EMX- ziv1|{jf~$qnB8d;pB>zl+d^O1)4jWMA3aFW@X@Hl+TH(8@X2}+q&=J(O(Qz@nGt*c zq)hs4tQqcOqHVnivL?58(6koUP2~3$x}k#1NU;oSjv{|T5j9Z=brP;@1MkA3CZ@Y- zQZ%Hp)i>6qDuSQRa7m0Q94^B#65;#*Mx2bD_2GO7rzWn{B9(3IB#s?8lgTYxO}&b3 zF-6vXMwGO?u-xu`TOfX$2%;Gl8mrXG$c|D1|2!A3JJv$DW+FUVJ>HK}8Ox9TNo+VuV~rtY zGhr-;@q3OcXb1frbPRg+C7cX3WS6tCwPgRDzm9I%O*dUNUZ!&q zvxw1~wy`tSpofXf)>vKi?%6ul6qVI=VeUe5+zO|!gT=KsII^veeV>wEA>6-&Gu)VW zGaZ$ou5uOSb~$$?EvTGeTrL)c5gOG(-I}Yvacwm+_wXC+SSbmG;yWoxM2t*qC5n-Y zOJ}*7AH?5}NSx!MObQ0?f%g90MMGg}I)Y(YL+HTZ?qNb=^Dh`qRob?;7EiC)q0DRR zR6C!hQmAqHwbElxvLvv`Ao+UgR#}I!d0tk!(8KR@%c-Dsm3I>}V~Q`W*X2b~nT7f| zisAM4R0Y?5HSx2aU6)`Bp4rUEKs)P9w?Fb+mi;3wHT$%m)SK;lxxHW8z;ugx|5+Pv zY-6!y%^rDlVpCeyh3T62 zqg#GM9+VdN8}lZn4!n_Msa$Od#Y`H?#w?sUnwFRmzgXJtW9)zaJNbcJ=N5kiDC1=~ z_(Fc>_r_;{+tk<`8EK;(ko)?p^&IBj$u@$TZ@~9CZaNoUGdn&bsa~QdIOMZadxd_I_6r?t=G6K5hhy zbf`t1wD;$`*+AIeFyq8uUy$^P92;%tz|fq|X-__SK$Y>f}$(Q7ZTlm{T-pvj?b$8TS zQR0C0fLShv6I`;3F?P7VH-3loPw-;DGs~Y16>`CkO*m0yz1x`Y-Rt!+ed%uJpsjO@ zJKA_LZ|;P|AF0{$UvKl8d9OJ(iA=UacIC|Np@tTMrpTgxF4Ib}NWx9X{X-{?UFZ$m zeG46E?{F`&s6PmV+?|UUt1hprFE^NHPRQ|=!m}|bxKwWFjI`LM%cZ;2hA8=WK|*m0 zEq;rG7%skl5#y&lnwuIMk*scNba6XjvyPJ5S)%BqHO3QdZQ4s6Iv=)|I%37_DQ%n= z(Idhb$4rggZ4x(@aG#_gX2%q+cZ7B{!)yHDV+dmj2A@TU6Z9K{sT=;$n$7jm#6$B_ zf2J2F?jPzD?aIZ8#ztg}U3zuG922n?9Uo!i>p+vNuJ5|IuT zJl$L_F`Fla(JU?-{P=~7Eg1VN%~u)RK5-~V+Wj+9n`zoTrU)e znb~AeYh58J;eMu(|9iLP2D`kz{>^<|HZA4t&5&98If#g{z1?Yj3T~55^@i+HS{Llp zPjfXT?r^`v*sHW1lZ(3c9=QF%-7(V3M5d^`ZRXh!#t_w!!I<;q(AJMmNleVmbu4YS zV&KNVJU5*Nx4fbvvSF7kS9?<2~n_k4MBfGWR-)q`9}K4BTI7szP`0F^T{fFLVbI+FqqU5% zEAw)`x4VavCzT(Kt+Ic9v#DwBzHyT)H0ju5 zzK`*=9sk_j(NL23QpU!?Jwq>N89eFA^wtyON#SY{mui_sW{3LrcxzvHZv9j1pI*lR zwZ1Tmeuk^YJG^InG0qh$U*cEw?6Xzt*H6N8dq5Q(jTBV)boA*gclHYPc8>~NU(zTv z3wNlbHWBRL6IL)4QLOFOMX8&@B`Y@^BAc9q6J;~L>yi?)2pt5G=0KFo zyxFb0b)!lHNmw#wDHw4W+^1ta3A~H+No1v6)|4FJO!1zKxsev{3z_6^T@^BQUw@nz z;rNAnhfyLD%8Iaya)E}#qbK{}{w*9$9GKD$RfwX~YG?0H(sW|CYmf=!NaUCosrIe* zDy=3G@qQ>03f$i0w(cWUGd3*U`-_GZw9Jm7zTAiwrrhy!5%S}y$)x6id$@{-1X&-N z9~LfY2Db(KxM8l#tfnsL{-CbwO|_$|xdiIvEATJ4YU@fT(@Op|)M=}L9n^fKp4`F^g7QXEBxN&ZTavWcu(O@9;K!U>9z);oqb z<@$|LoT>NpucE4qc#I%%_kXHqJ|E_%E>5kr!olK6XnmR~KJX!jh4A=bG7RV)@H4TnsZFl=1m%+m~ zsq=fCZQfHia$%b9siI;W{ZYkvAWWCR0 z#y~9+T$u+&KJDzp)7-kE@!PgN#dLH2s_5C(?D*GpCVif7#DYCe0@j;(VN$J%iGd+Bgrm2hm z;fR`^vycuvU#HuVAy-9X0s&HEDcYS~MUy(SkrN#}i#8w=Pp^CCFaPa2g-vKo?+~hh zu8$#%O(R?T_w{v6CXABk+Ut~N1>VOy0^}H#jfULL@x8}XvagF|JVWj2%XUu*9)hks z^wpN4GV&{-o6whdURruZE`mZ<^)0;S5T1GIH3w6>%Ucr+TlBr=KBnIGGH-$SyIEL9 z-cLXu%mQs^W``7eI!A}pUv6UTKJ*g2(co4?cD3b93!66yYeJ#>^Jy#ilFnd)kG?R$ zV34F3D7MhOb@wt==+iH>6$aF>q}x4mUw|p`$iAf+^2mJ$rqrY0b1*h)G#S0qR+(%t zpM&xHibc`4cn8dzlJ@0H`x0D+@o>wwzNP-|xiwv-`P5Q>x0{zN?dM@+XkVzbVrktf z$(v`Ft$H6b5}{gl8TBqxahObgV#6%Nqk`nDF!At%Eb=<|YD}&-yK5=uYRo*%i+%Ix zrnZI+ZYjLnXHqgZ{B|F~%yRFNDhF!{FM-L6EMB^_l@GqXeDF%eetQ}HNKEu=GLc-3 z3Kr-2C|{F__!5>Y_QQWS*W{?(rY;r^EiN1pT){3lWL? zu1sWy!@QZ~mKIv#>PoqJl}!7SwB7+TmPUuP-|8~lQsorupV05Az0?N%f{9T@qC_?j zTFXix@+;?Rtv!99^4f_|KJ0&FNcSf-;bDGi=xteZaZN8sn-^{MMi~vky?xA*VQBYY zcmEzU4C`IvzCG%Jqkg##*=|#o*p_aF6*(U@>rH>J7Y8ZEY&XldV7|Q0y>@K|3`&e~ z-0qWW+;Ly1dDaYp*f0o&S72t)XE^4oHNiol8SRl{!0*p)?P)hJMY9)EF))}ludvu% zEwe6hg9(v)!UXKE)TTJSmSY7o4S06Ev@x;6v7L9APuz?q5UOQvSshGuMssGm@?r-Y zJTsMI(oad6n|hk@nA*;3@i`_0MT7o+Slb;#rbXr*`&b`1k1^hxTcPYln@*R!iwUeC zx|w}6z3x7mP*(4hBBRgZ3=Hlu$85aPZS=v1aRQ6Tr*ZrU>&0gOqX729IH3#=UgB0e z7}oo_?9B5`F-IdWpoLkhEc`@)Ou78CB|C$#Co z7a#mB;%q;=8@VldWzl^-$4=3i0h==(CN4PiUy0@v2py^4$*cN-F;ix4GO*Xo+re5F zUg{O3?15ydc~o4nu)c=V5LylUTkm5E7V=c*0%MDhw(0(cTvzz{T}5%xzF*;8Pxd0r z7kk`_l6d(iy8c{I+e*Q!p=L&JtJpBxjW6%kwSj`0(4m;SF_w)H^W}3p63V>qpKyQ2*+`kzQy4r5WW7P)`^++^R)4tjBg5&YrLbTe7dngMzi$@h>t6PLTN? zk&Eu+!g8c^of`73u#B|Fp6-g6sfdcTzp+s0NZ8E}*S%6_H+Wv}69_*sZ7YaUHqUVZ zP3c2lFA8R|Ap!gOB9}4pt5L&%9^4m<%qS;)1FP}E7hIN_c_ow4uwVLWQCP2!ZpfX( zi`R63+5T;8gzNrC;mby0fub88p$ZrEXt-$aGPFIyV5pIc5ssbbs4IJK#l}oScQ|C6 P1QQ72>aI4pgVp~Bva1<4 literal 0 HcmV?d00001 diff --git a/current/po/el.po b/current/po/el.po new file mode 100644 index 00000000..16f129d5 --- /dev/null +++ b/current/po/el.po @@ -0,0 +1,2459 @@ +# Shadow Password Suite +# Greek Translation by Nikos Mavroyanopoulos +# Thanks to Simos Xenitelis (S.Xenitellis@rhbnc.ac.uk) for his +# comments about making this translation better. +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Shadow 980726\n" +"POT-Creation-Date: 2000-09-02 20:40+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Nikos Mavroyanopoulos \n" +"Language-Team: Hellenic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO8859-7\n" +"Content-Transfer-Encoding: 8-bit\n" + +#: libmisc/addgrps.c:60 +#, c-format +msgid "Warning: unknown group %s\n" +msgstr "Ðñïåéäïðïßçóç: Üãíùóôç ïìÜäá %s\n" + +#: libmisc/addgrps.c:71 +msgid "Warning: too many groups\n" +msgstr "Ðñïåéäïðïßçóç: ÐïëëÝò ïìÜäåò\n" + +#: libmisc/age.c:104 +msgid "Your password has expired." +msgstr "Ôï óõíèçìáôéêü óáò Ý÷åé ëÞîåé." + +#: libmisc/age.c:107 +msgid "Your password is inactive." +msgstr "Ôï óõíèçìáôéêü óáò åßíáé áíåíåñãü." + +#: libmisc/age.c:110 +msgid "Your login has expired." +msgstr "Ï êùäéêüò åéóüäïõ óáò Ý÷åé ëÞîåé." + +#: libmisc/age.c:127 +msgid " Contact the system administrator.\n" +msgstr " ÅðéêïéíùíÞóôå ìå ôïí äéá÷åéñéóôÞ ôïõ óõóôÞìáôïò.\n" + +#: libmisc/age.c:130 +msgid " Choose a new password.\n" +msgstr " ÅðéëÝîôå Ýíá íÝï óõíèçìáôéêü.\n" + +#: libmisc/age.c:228 +#, c-format +msgid "Your password will expire in %ld days.\n" +msgstr "Ôï óõíèçìáôéêü óáò èá ëÞîåé óå %ld ìÝñåò.\n" + +#: libmisc/age.c:230 +msgid "Your password will expire tomorrow.\n" +msgstr "Ôï óõíèçìáôéêü óáò èá ëÞîåé áýñéï.\n" + +#: libmisc/age.c:232 +msgid "Your password will expire today.\n" +msgstr "Ôï óõíèçìáôéêü óáò èá ëÞîåé óÞìåñá.\n" + +#: libmisc/chowntty.c:110 +#, c-format +msgid "Unable to change tty %s" +msgstr "Áäõíáìßá áëëáãÞò tty %s" + +#: libmisc/env.c:160 +msgid "Environment overflow\n" +msgstr "Õðåñ÷åßëéóç ðåñéâÜëëïíôïò\n" + +#: libmisc/env.c:200 +#, c-format +msgid "You may not change $%s\n" +msgstr "Äåí ìðïñåßôå íá áëëÜîåôå ôï $%s\n" + +#: libmisc/failure.c:238 +#, c-format +msgid "%d %s since last login. Last was %s on %s.\n" +msgstr "%d %s áðü ôçí ôåëåõôáßá åßóïäï. Ç ôåëåõôáßá Þôáí óôéò %s óôï %s.\n" + +#: libmisc/failure.c:239 +msgid "failures" +msgstr "áðïôõ÷ßåò" + +#: libmisc/failure.c:239 +msgid "failure" +msgstr "áðïôõ÷ßá" + +#: libmisc/limits.c:397 +msgid "Too many logins.\n" +msgstr "ÐïëëÝò åßóïäïé óôï óýóôçìá.\n" + +#: libmisc/login_desrpc.c:63 +#, c-format +msgid "Password does not decrypt secret key for %s.\n" +msgstr "Ôï óõíèçìáôéêü äåí áðïêùäéêïðïéåß ôï ìõóôéêü êëåéäß ãéá ôï(í) %s.\n" + +#: libmisc/login_desrpc.c:69 +#, c-format +msgid "Could not set %s's secret key: is the keyserv daemon running?\n" +msgstr "" +"Äåí åßíáé äõíáôüí íá ôåèåß ôï ìõóôéêü êëåéäß ôïõ %s: Åêôåëåßôáé ï\n" +"äéáêïìéóôÞò êëåéäéþí;\n" + +#: libmisc/mail.c:62 libmisc/mail.c:77 +msgid "You have new mail." +msgstr "¸÷åôå íÝá ãñÜììáôá." + +#: libmisc/mail.c:73 +msgid "No mail." +msgstr "ÊáíÝíá ãñÜììá." + +#: libmisc/mail.c:75 +msgid "You have mail." +msgstr "¸÷åôå ãñÜììáôá." + +#: libmisc/obscure.c:281 src/passwd.c:309 +#, c-format +msgid "Bad password: %s. " +msgstr "Êáêü óõíèçìáôéêü: %s. " + +#: libmisc/pam_pass.c:42 +#, c-format +msgid "passwd: pam_start() failed, error %d\n" +msgstr "óõíèçìáôéêü: pam_start() áðÝôõ÷å, óöÜëìá %d\n" + +#: libmisc/pam_pass.c:49 +#, c-format +msgid "passwd: %s\n" +msgstr "óõíèçìáôéêü: %s\n" + +#: libmisc/setupenv.c:205 +#, c-format +msgid "Unable to cd to \"%s\"\n" +msgstr "Áäõíáìßá áëëáãÞò êáôáëüãïõ óôïí \"%s\"\n" + +#: libmisc/setupenv.c:213 +msgid "No directory, logging in with HOME=/" +msgstr "×ùñßò êáôÜëïãï, åéóáãùãÞ ìå ÌÇÔÑÉÊÏ_ÊÁÔÁËÏÃÏ=/" + +#: libmisc/shell.c:78 +#, c-format +msgid "Executing shell %s\n" +msgstr "ÅêôÝëåóç öëïéïý %s\n" + +#. +#. * Obviously something is really wrong - I can't figure out +#. * how to execute this stupid shell, so I might as well give +#. * up in disgust ... +#. +#: libmisc/shell.c:122 +#, c-format +msgid "Cannot execute %s" +msgstr "Áäõíáìßá åêôÝëåóçò %s" + +#: libmisc/suauth.c:99 +msgid "Access to su to that account DENIED.\n" +msgstr "Ðñüóâáóç óôç su óå áõôüí ôïí ëïãáñéáóìü ÁÑÍÇÈÇÊÅ.\n" + +#: libmisc/suauth.c:106 +msgid "Password authentication bypassed.\n" +msgstr "ÐáñÜêáìøç åîáêñßâùóçò ìå óõíèçìáôéêü.\n" + +#: libmisc/suauth.c:113 +msgid "Please enter your OWN password as authentication.\n" +msgstr "Ðáñáêáëþ åéóÜãåôå ôï ÄÉÊÏ óáò óõíèçìáôéêü ãéá åîáêñßâùóç.\n" + +#: libmisc/sub.c:61 +#, c-format +msgid "Invalid root directory \"%s\"\n" +msgstr "Ìç Ýãêõñïò ðñùôáñ÷éêüò êáôÜëïãïò \"%s\"\n" + +#: libmisc/sub.c:73 +#, c-format +msgid "Can't change root directory to \"%s\"\n" +msgstr "Áäõíáìßá áëëáãÞò ôïõ ðñùôáñ÷éêïý êáôáëüãïõ óå \"%s\"\n" + +#: libmisc/xmalloc.c:28 +#, c-format +msgid "malloc(%d) failed\n" +msgstr "Ç êëÞóç malloc(%d) áðÝôõ÷å\n" + +#: lib/dialchk.c:71 +msgid "Dialup Password: " +msgstr "Óõíèçìáôéêü ôçëåöùíéêÞò óýíäåóçò: " + +#: lib/getdef.c:253 +msgid "Could not allocate space for config info.\n" +msgstr "Áäõíáìßá äÝóìåõóçò ÷þñïõ ãéá ðëçñïöïñßåò äéáìüñöùóçò.\n" + +#. +#. * Item was never found. +#. +#: lib/getdef.c:307 +#, c-format +msgid "configuration error - unknown item '%s' (notify administrator)\n" +msgstr "" +"óöÜëìá äéáìüñöùóçò - Üãíùóôï áíôéêåßìåíï '%s' (åéäïðïéåßóôå ôïí " +"äéá÷åéñéóôÞ)\n" + +#: lib/getdef.c:394 +#, c-format +msgid "error - lookup '%s' failed\n" +msgstr "óöÜëìá - ç áíáæÞôçóç '%s' áðÝôõ÷å\n" + +#: lib/getdef.c:402 +#, c-format +msgid "%s not found\n" +msgstr "%s äåí âñÝèçêå\n" + +#. +#. * get the password from her, and set the salt for +#. * the decryption from the group file. +#. +#: lib/pwauth.c:54 src/newgrp.c:305 +msgid "Password: " +msgstr "Óõíèçìáôéêü: " + +#: lib/pwauth.c:56 +#, c-format +msgid "%s's Password: " +msgstr "Ôïõ %s ôï Óõíèçìáôéêü: " + +#: lib/pwauth.c:270 +msgid "(Echo on) " +msgstr "" + +#: lib/strerror.c:20 +#, c-format +msgid "Unknown error %d" +msgstr "Áãíùóôï óöÜëìá %d" + +#: src/chage.c:156 +#, c-format +msgid "" +"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n" +" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n" +msgstr "" +"×ñÞóç: %s [ -l ] [ -m åëá÷_ìÝñåò ] [ -M ìåã_ìÝñåò ] [ -W ðñïåéä. ]\n" +"\t[ -I áíåíåñãü ] [ -E ëÞîç ] [ -d ôåëåõôáßá_ìÝñá ] ÷ñÞóôçò\n" + +#: src/chage.c:158 +#, c-format +msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n" +msgstr "" +"×ñÞóç: %s [ -l ] [ -m åëÜ÷_ìÝñåò ] [ -M ìåã_ìÝñåò ]\n" +"[ -d ôåëåõôáßá_ìÝñá ] ÷ñÞóôçò\n" + +#: src/chage.c:193 +msgid "" +"Enter the new value, or press return for the default\n" +"\n" +msgstr "" +"ÅéóÜãåôå ôçí íÝá ôéìÞ, Þ ðéÝóôå `return' ãéá ôçí ðñïêáèïñéóìÝíç\n" +"\n" + +#: src/chage.c:196 +msgid "Minimum Password Age" +msgstr "Ìéêñüôåñç äéÜñêåéá óõíèçìáôéêïý" + +#: src/chage.c:201 +msgid "Maximum Password Age" +msgstr "ÌÝãéóôç äéÜñêåéá óõíèçìáôéêïý" + +#: src/chage.c:207 +msgid "Last Password Change (YYYY-MM-DD)" +msgstr "Ôåëåõôáßá áëëáãÞ óõíèçìáôéêïý (××××-ÌÌ-ÇÇ)" + +#: src/chage.c:216 +msgid "Password Expiration Warning" +msgstr "Ðñïåéäïðïßçóç ëÞîçò óõíèçìáôéêïý" + +#: src/chage.c:221 +msgid "Password Inactive" +msgstr "Áíåíåñãü óõíèçìáôéêü" + +#: src/chage.c:227 +msgid "Account Expiration Date (YYYY-MM-DD)" +msgstr "Çìåñïìçíßá ËÞîçò Ëïãáñéáóìïý (××××-ÌÌ-ÇÇ)" + +#. +#. * Start with the easy numbers - the number of days before the +#. * password can be changed, the number of days after which the +#. * password must be chaged, the number of days before the +#. * password expires that the user is told, and the number of +#. * days after the password expires that the account becomes +#. * unusable. +#. +#: src/chage.c:281 +#, c-format +msgid "Minimum:\t%ld\n" +msgstr "ÅëÜ÷éóôï:\t%ld\n" + +#: src/chage.c:282 +#, c-format +msgid "Maximum:\t%ld\n" +msgstr "ÌÝãéóôï:\t%ld\n" + +#: src/chage.c:284 +#, c-format +msgid "Warning:\t%ld\n" +msgstr "Ðñïåéäïðïßçóç:\t%ld\n" + +#: src/chage.c:285 +#, c-format +msgid "Inactive:\t%ld\n" +msgstr "Áíåíåñãüò:\t%ld\n" + +#. +#. * The "last change" date is either "Never" or the date the +#. * password was last modified. The date is the number of +#. * days since 1/1/1970. +#. +#: src/chage.c:294 +msgid "Last Change:\t\t" +msgstr "Ôåëåõôáßá áëëáãÞ:\t\t" + +#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340 +msgid "Never\n" +msgstr "ÐïôÝ\n" + +#. +#. * The password expiration date is determined from the last +#. * change date plus the number of days the password is valid +#. * for. +#. +#: src/chage.c:308 +msgid "Password Expires:\t" +msgstr "Ôï óõíèçìáôéêü ëÞãåé:\t" + +#. +#. * The account becomes inactive if the password is expired +#. * for more than "inactdays". The expiration date is calculated +#. * and the number of inactive days is added. The resulting date +#. * is when the active will be disabled. +#. +#: src/chage.c:324 +#, fuzzy +msgid "Password Inactive:\t" +msgstr "Áíåíåñãü óõíèçìáôéêü" + +#. +#. * The account will expire on the given date regardless of the +#. * password expiring or not. +#. +#: src/chage.c:338 +#, fuzzy +msgid "Account Expires:\t" +msgstr "Ôï óõíèçìáôéêü ëÞãåé:\t" + +#: src/chage.c:486 +#, c-format +msgid "%s: do not include \"l\" with other flags\n" +msgstr "%s: Íá ìçí óõìðåñéëáìâÜíåôå ôï \"l\" ìå ôéò Üëëåò åíäåßîåéò\n" + +#: src/chage.c:498 src/chage.c:610 src/login.c:529 +#, c-format +msgid "%s: permission denied\n" +msgstr "%s: Üäåéá áðïññßöèçêå\n" + +#: src/chage.c:510 src/chpasswd.c:120 +#, c-format +msgid "%s: can't lock password file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/chage.c:516 src/chpasswd.c:124 +#, c-format +msgid "%s: can't open password file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/chage.c:523 +#, c-format +msgid "%s: unknown user: %s\n" +msgstr "%s: Üãíùóôïò ÷ñÞóôçò: %s\n" + +#: src/chage.c:542 +#, c-format +msgid "%s: can't lock shadow password file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/chage.c:549 +#, c-format +msgid "%s: can't open shadow password file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/chage.c:631 +#, c-format +msgid "Changing the aging information for %s\n" +msgstr "ÁëëáãÞ ðëçñïöïñéþí ÷ñüíïõ ãéá ôïí %s\n" + +#: src/chage.c:633 +#, c-format +msgid "%s: error changing fields\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí áëëáãÞ ðåäßùí\n" + +#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183 +#, c-format +msgid "%s: can't update password file\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/chage.c:690 src/pwunconv.c:178 +#, c-format +msgid "%s: can't update shadow password file\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409 +#: src/passwd.c:825 src/passwd.c:926 +msgid "Error updating the DBM password entry.\n" +msgstr "" +"ÓöÜëìá êáôÜ ôçí áíáíÝùóç ôçò êáôá÷þñçóçò óôï dbm áñ÷åßï óõíèçìáôéêþí.\n" + +#: src/chage.c:771 +#, c-format +msgid "%s: can't rewrite shadow password file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/chage.c:785 +#, c-format +msgid "%s: can't rewrite password file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/chage.c:836 +#, c-format +msgid "%s: no aging information present\n" +msgstr "%s: Äåí õðÜñ÷ïõí ðëçñïöïñßåò ãÞñáíóçò\n" + +#: src/chfn.c:107 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n" +"\t[ -h home_ph ] [ -o other ] [ user ]\n" +msgstr "" +"Usage: %s [ -f ðëÞñåò_üíïìá ] [ -r áñßèì_äùìáôßïõ ] [ -w ôçë_åñãáóßáò ]\n" +"\t[ -h ôçë_ïéêßáò ] [ -o Üëëï ] [ ÷ñÞóôçò ]\n" + +#: src/chfn.c:111 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n" +msgstr "" +"×ñÞóç: %s [ -f ðëÞñåò_üíïìá ] [ -r áñéèì_äùìáôßïõ ] [ -w ôçë_äùìáôßïõ ]\n" +"[ -h ôçë_ïéêßáò ]\n" + +#: src/chfn.c:163 src/chsh.c:119 +msgid "Enter the new value, or press return for the default\n" +msgstr "ÅéóÜãåôå ôçí íÝá ôéìÞ, Þ ðéÝóôå `return' ãéá ôçí ðñïêáèïñéóìÝíç\n" + +#: src/chfn.c:166 +msgid "Full Name" +msgstr "ÐëÞñåò üíïìá" + +#: src/chfn.c:168 +#, c-format +msgid "\tFull Name: %s\n" +msgstr "\tÐëÞñåò ¼íïìá: %s\n" + +#: src/chfn.c:171 +msgid "Room Number" +msgstr "Áñéèìüò äùìáôßïõ" + +#: src/chfn.c:173 +#, c-format +msgid "\tRoom Number: %s\n" +msgstr "\tÁñéèìüò Äùìáôßïõ: %s\n" + +#: src/chfn.c:176 +msgid "Work Phone" +msgstr "ÔçëÝöùíï Åñãáóßáò" + +#: src/chfn.c:178 +#, c-format +msgid "\tWork Phone: %s\n" +msgstr "\tÔçëÝöùíï Åñãáóßáò: %s\n" + +#: src/chfn.c:181 +msgid "Home Phone" +msgstr "ÔçëÝöùíï Ïéêßáò" + +#: src/chfn.c:183 +#, c-format +msgid "\tHome Phone: %s\n" +msgstr "\tÔçëÝöùíï ïéêßáò: %s\n" + +#: src/chfn.c:186 +msgid "Other" +msgstr "Áëëï" + +#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330 +#: src/chfn.c:391 src/passwd.c:1226 +#, c-format +msgid "%s: Permission denied.\n" +msgstr "%s: ¶äåéá áðïññßöèçêå.\n" + +#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277 +#, c-format +msgid "%s: Unknown user %s\n" +msgstr "%s: Áãíùóôïò ï ÷ñÞóôçò %s\n" + +#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207 +#, c-format +msgid "%s: Cannot determine your user name.\n" +msgstr "%s: Äåí åßíáé äõíáôüí íá êáèïñéóôåß ôï üíïìá ÷ñÞóôç óáò.\n" + +#: src/chfn.c:373 src/chsh.c:250 +#, c-format +msgid "%s: cannot change user `%s' on NIS client.\n" +msgstr "%s: áäõíáìßá áëëáãÞò ÷ñÞóôç `%s' óôïí NIS åîõðçñåôïýìåíï.\n" + +#: src/chfn.c:378 src/chsh.c:257 +#, c-format +msgid "%s: `%s' is the NIS master for this client.\n" +msgstr "%s: `%s' åßíáé ï êýñéïò äéáêïìéóôÞò NIS ãé'áõôüí ôïí åîõðçñåôïýìåíï.\n" + +#: src/chfn.c:453 +#, c-format +msgid "Changing the user information for %s\n" +msgstr "ÁëëáãÞ ðëçñïöïñéþí ÷ñÞóôç ãéá ôïí %s\n" + +#: src/chfn.c:462 +#, c-format +msgid "%s: invalid name: \"%s\"\n" +msgstr "%s: Ìç Ýãêõñï üíïìá: `%s'\n" + +#: src/chfn.c:467 +#, c-format +msgid "%s: invalid room number: \"%s\"\n" +msgstr "%s: Ìç Ýãêõñïò áñéèìüò äùìáôßïõ: `%s'\n" + +#: src/chfn.c:472 +#, c-format +msgid "%s: invalid work phone: \"%s\"\n" +msgstr "%s: Ìç Ýãêõñï ôçëÝöùíï åñãáóßáò: `%s'\n" + +#: src/chfn.c:477 +#, c-format +msgid "%s: invalid home phone: \"%s\"\n" +msgstr "%s: Ìç Ýãêõñï ôçëÝöùíï ïéêßáò: `%s'\n" + +#: src/chfn.c:482 +#, c-format +msgid "%s: \"%s\" contains illegal characters\n" +msgstr "%s: \"%s\" ðåñéÝ÷åé ìç Ýãêõñïõò ÷áñáêôÞñåò\n" + +#: src/chfn.c:494 +#, c-format +msgid "%s: fields too long\n" +msgstr "%s: Ðïëý ìáêñéÜ ðåäßá\n" + +#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388 +msgid "Cannot change ID to root.\n" +msgstr "Áäõíáìßá áëëáãÞò ôáõôüôçôáò ÷ñÞóôç óå root.\n" + +#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880 +msgid "Cannot lock the password file; try again later.\n" +msgstr "Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí. ÄïêéìÜóôå áñãüôåñá.\n" + +#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885 +msgid "Cannot open the password file.\n" +msgstr "Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí.\n" + +#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313 +#, c-format +msgid "%s: %s not found in /etc/passwd\n" +msgstr "%s: Ï %s äåí âñÝèçêå óôï /etc/passwd\n" + +#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920 +#: src/passwd.c:960 +msgid "Error updating the password entry.\n" +msgstr "ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí.\n" + +#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933 +msgid "Cannot commit password file changes.\n" +msgstr "Áäõíáìßá åéóáãùãÞò ôùí áëëáãþí óôï áñ÷åßï óõíèçìáôéêþí.\n" + +#: src/chfn.c:592 src/chsh.c:431 +msgid "Cannot unlock the password file.\n" +msgstr "Áäõíáìßá îåêëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/chpasswd.c:76 +#, c-format +msgid "usage: %s [-e]\n" +msgstr "÷ñÞóç: %s [-e]\n" + +#: src/chpasswd.c:132 src/pwconv.c:104 +#, c-format +msgid "%s: can't lock shadow file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118 +#: src/pwunconv.c:123 +#, c-format +msgid "%s: can't open shadow file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/chpasswd.c:159 src/newusers.c:415 +#, c-format +msgid "%s: line %d: line too long\n" +msgstr "%s: ãñáììÞ %d: ðïëý ìåãÜëç ãñáììÞ\n" + +#: src/chpasswd.c:179 +#, c-format +msgid "%s: line %d: missing new password\n" +msgstr "%s: ãñáììÞ %d: Ýëëåéøç íÝïõ óõíèçìáôéêïý\n" + +#: src/chpasswd.c:195 +#, c-format +msgid "%s: line %d: unknown user %s\n" +msgstr "%s: ãñáììÞ %d: Üãíùóôïò ÷ñÞóôçò %s\n" + +#: src/chpasswd.c:247 +#, c-format +msgid "%s: line %d: cannot update password entry\n" +msgstr "%s: ãñáììÞ %d: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óõíèçìáôéêïý\n" + +#: src/chpasswd.c:263 src/newusers.c:535 +#, c-format +msgid "%s: error detected, changes ignored\n" +msgstr "%s: Áíé÷íÝõôçêå óöÜëìá, ïé áëëáãÝò áãíïÞèçêáí\n" + +#: src/chpasswd.c:274 +#, c-format +msgid "%s: error updating shadow file\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#: src/chpasswd.c:282 +#, c-format +msgid "%s: error updating password file\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï áñ÷åßï óõíèçìáôéêþí\n" + +#: src/chsh.c:105 +#, c-format +msgid "Usage: %s [ -s shell ] [ name ]\n" +msgstr "×ñÞóç: %s [ -s öëïéüò ] [ üíïìá ]\n" + +#: src/chsh.c:120 +msgid "Login Shell" +msgstr "ÊÝëõöïò Åéóüäïõ" + +#: src/chsh.c:273 src/chsh.c:286 +#, c-format +msgid "You may not change the shell for %s.\n" +msgstr "Äåí ìðïñåßôå íá áëëÜîåôå ôï öëïéü ãéá ôï(í) %s.\n" + +#: src/chsh.c:315 +#, c-format +msgid "Changing the login shell for %s\n" +msgstr "ÁëëÜãÞ ôïõ öëïéïý ãéá ôïí %s\n" + +#: src/chsh.c:327 +#, c-format +msgid "%s: Invalid entry: %s\n" +msgstr "%s: Ìç Ýãêõñç êáôá÷þñçóç: %s\n" + +#: src/chsh.c:332 +#, c-format +msgid "%s is an invalid shell.\n" +msgstr "%s äåí åßíáé Ýãêõñïò öëïéüò.\n" + +#: src/dpasswd.c:69 +#, c-format +msgid "Usage: %s [ -(a|d) ] shell\n" +msgstr "×ñÞóç: %s [ -(ald) ] öëïéüò\n" + +#: src/dpasswd.c:134 +msgid "Shell password: " +msgstr "Óõíèçìáôéêü öëïéïý: " + +#: src/dpasswd.c:140 +msgid "re-enter Shell password: " +msgstr "ÅðáíåéóÜãåôå ôï óõíèçìáôéêü öëïéïý: " + +#: src/dpasswd.c:147 +#, c-format +msgid "%s: Passwords do not match, try again.\n" +msgstr "%s: Ôá óõíèçìáôéêÜ äåí ôáéñéÜæïõí, äïêéìÜóôå îáíÜ.\n" + +#: src/dpasswd.c:167 +#, c-format +msgid "%s: can't create %s" +msgstr "%s: áäõíáìßá äçìéïõñãßáò ôïõ %s" + +#: src/dpasswd.c:172 +#, c-format +msgid "%s: can't open %s" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ %s" + +#: src/dpasswd.c:200 +#, c-format +msgid "%s: Shell %s not found.\n" +msgstr "%s: Ï öëïéüò %s äåí âñÝèçêå.\n" + +#: src/expiry.c:84 +msgid "Usage: expiry { -f | -c }\n" +msgstr "×ñÞóç: expiry { -f | -c }\n" + +#: src/expiry.c:137 +#, c-format +msgid "%s: WARNING! Must be set-UID root!\n" +msgstr "" +"%s: ÐÑÏÓÏ×Ç! ÐñÝðåé íá Ý÷åé ôåèåß ôï bit ðáñá÷þñçóçò ôáõôüôçôáò root!\n" + +#: src/expiry.c:148 +#, c-format +msgid "%s: unknown user\n" +msgstr "%s: Üãíùóôïò ÷ñÞóôçò\n" + +#: src/faillog.c:79 +#, c-format +msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n" +msgstr "" +"÷ñÞóç: %s [-a|-u ÷ñÞóôçò] [-m ìåã] [-r] [-t ìÝñåò] [-l äåõôåñüëåðôá_êëåéä]\n" + +#: src/faillog.c:134 src/lastlog.c:94 +#, c-format +msgid "Unknown User: %s\n" +msgstr "Áãíùóôïò ÷ñÞóôçò: %s\n" + +#: src/faillog.c:215 +msgid "Username Failures Maximum Latest\n" +msgstr "¼íïìá_×ñÞóôç Áðïôõ÷ßåò ÌÝãéóôï Ôåëåõôáßá\n" + +#: src/faillog.c:232 +#, c-format +msgid " %s on %s" +msgstr " %s óôï %s" + +#: src/faillog.c:236 +#, c-format +msgid " [%lds left]" +msgstr " [%lds áðÝìåéíáí]" + +#: src/faillog.c:239 +#, c-format +msgid " [%lds lock]" +msgstr " [%lds êëåßäùìá]" + +#: src/gpasswd.c:89 +#, c-format +msgid "usage: %s [-r|-R] group\n" +msgstr "÷ñÞóç: %s [-r|-R] ïìÜäá\n" + +#: src/gpasswd.c:90 +#, c-format +msgid " %s [-a user] group\n" +msgstr " %s [-a ÷ñÞóôçò] ïìÜäá\n" + +#: src/gpasswd.c:91 +#, c-format +msgid " %s [-d user] group\n" +msgstr " %s [-d ÷ñÞóôçò] ïìÜäá\n" + +#: src/gpasswd.c:93 +#, c-format +msgid " %s [-A user,...] [-M user,...] group\n" +msgstr " %s [-A ÷ñÞóôçò,...] [-M ÷ñÞóôçò,...] ïìÜäá\n" + +#: src/gpasswd.c:96 +#, c-format +msgid " %s [-M user,...] group\n" +msgstr " %s [-M ÷ñÞóôçò,...] ïìÜäá\n" + +#: src/gpasswd.c:160 src/gpasswd.c:245 +#, c-format +msgid "%s: unknown user %s\n" +msgstr "%s: Üãíùóôïò ÷ñÞóôçò %s\n" + +#: src/gpasswd.c:172 +msgid "Permission denied.\n" +msgstr "¶äåéá áðïññßöèçêå.\n" + +#: src/gpasswd.c:257 +#, c-format +msgid "%s: shadow group passwords required for -A\n" +msgstr "%s: óêéþäç óõíèçìáôéêÜ ïìÜäùí áðáéôïýíôáé ãéá ôï -A\n" + +#: src/gpasswd.c:308 +msgid "Who are you?\n" +msgstr "Ðïéïò åßóáé;\n" + +#: src/gpasswd.c:328 src/newgrp.c:251 +#, c-format +msgid "unknown group: %s\n" +msgstr "Üãíùóôç ïìÜäá: %s\n" + +#: src/gpasswd.c:436 +#, c-format +msgid "Adding user %s to group %s\n" +msgstr "ÐñïóèÞêç ôïõ ÷ñÞóôç %s óôçí ïìÜäá %s\n" + +#: src/gpasswd.c:453 +#, c-format +msgid "Removing user %s from group %s\n" +msgstr "ÄéáãñÜöç ôïõ ÷ñÞóôç %s áðü ôçí ïìÜäá %s\n" + +#: src/gpasswd.c:466 +#, c-format +msgid "%s: unknown member %s\n" +msgstr "%s: Üãíùóôï ìÝëïò %s\n" + +#: src/gpasswd.c:513 +#, c-format +msgid "%s: Not a tty\n" +msgstr "%s: Äåí åßíáé tty\n" + +#. +#. * A new password is to be entered and it must be encrypted, +#. * etc. The password will be prompted for twice, and both +#. * entries must be identical. There is no need to validate +#. * the old password since the invoker is either the group +#. * owner, or root. +#. +#: src/gpasswd.c:535 +#, c-format +msgid "Changing the password for group %s\n" +msgstr "ÁëëáãÞ ôïõ óõíèÞìáôïò ãéá ôçí ïìÜäá %s\n" + +#: src/gpasswd.c:538 +msgid "New Password: " +msgstr "ÍÝï Óõíèçìáôéêü: " + +#: src/gpasswd.c:543 src/passwd.c:422 +msgid "Re-enter new password: " +msgstr "ÅðáíåéóÜãåôå ôï íÝï óõíèçìáôéêü: " + +#: src/gpasswd.c:555 +msgid "They don't match; try again" +msgstr "Äåí ôáéñéÜæïõí. ÄïêéìÜóôå îáíÜ" + +#: src/gpasswd.c:559 +#, c-format +msgid "%s: Try again later\n" +msgstr "%s: ÎáíáäïêéìÜóôå áñãüôåñá\n" + +#: src/gpasswd.c:590 +#, c-format +msgid "%s: can't get lock\n" +msgstr "%s: Áäõíáìßá äçìéïõñãßáò êëåéäþìáôïò\n" + +#: src/gpasswd.c:596 +#, c-format +msgid "%s: can't get shadow lock\n" +msgstr "" +"%s: Áäõíáìßá äçìéïõñãßáò êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/gpasswd.c:602 +#, c-format +msgid "%s: can't open file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ %s\n" + +#: src/gpasswd.c:614 +#, c-format +msgid "%s: can't update entry\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò\n" + +#: src/gpasswd.c:620 +#, c-format +msgid "%s: can't update shadow entry\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#: src/gpasswd.c:626 +#, c-format +msgid "%s: can't re-write file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ\n" + +#: src/gpasswd.c:632 +#, c-format +msgid "%s: can't re-write shadow file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/gpasswd.c:640 +#, c-format +msgid "%s: can't unlock file\n" +msgstr "%s: áäõíáìßá îåêëåéäþìáôïò áñ÷åßïõ\n" + +#: src/gpasswd.c:645 +#, c-format +msgid "%s: can't update DBM files\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò ôùí DBM áñ÷åßùí\n" + +#: src/gpasswd.c:652 +#, c-format +msgid "%s: can't update DBM shadow files\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò ôùí DBM áñ÷åßùí óêéùäþí óõíèçìáôéêþí\n" + +#: src/groupadd.c:105 +msgid "usage: groupadd [-g gid [-o]] group\n" +msgstr "÷ñÞóç: groupadd [-g gid [-o]] ïìÜäá\n" + +#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230 +#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675 +#, c-format +msgid "%s: error adding new group entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n" + +#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942 +#: src/usermod.c:551 src/usermod.c:687 +#, c-format +msgid "%s: cannot add new dbm group entry\n" +msgstr "%s: áäõíáìßá ðñïóèÞêçò íÝáò dbm êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n" + +#: src/groupadd.c:258 src/useradd.c:996 +#, c-format +msgid "%s: name %s is not unique\n" +msgstr "%s: Ôï üíïìá %s äåí åßíáé ìïíáäéêü\n" + +#: src/groupadd.c:273 +#, c-format +msgid "%s: gid %ld is not unique\n" +msgstr "%s: Ôï gid %ld äåí åßíáé ìïíáäéêü\n" + +#: src/groupadd.c:297 +#, c-format +msgid "%s: can't get unique gid\n" +msgstr "%s: áäõíáìßá åýñåóçò ìïíáäéêïý gid\n" + +#. +#. * All invalid group names land here. +#. +#: src/groupadd.c:321 src/groupmod.c:341 +#, c-format +msgid "%s: %s is a not a valid group name\n" +msgstr "%s: Ôï %s äåí åßíáé Ýãêõñï üíïìá ïìÜäáò\n" + +#: src/groupadd.c:350 src/groupmod.c:367 +#, c-format +msgid "%s: invalid group %s\n" +msgstr "%s: Ìç Ýãêõñç ïìÜäá `%s'\n" + +#: src/groupadd.c:367 src/useradd.c:1272 +#, c-format +msgid "%s: -O requires NAME=VALUE\n" +msgstr "%s: -O áðáéôåß ¼ÍÏÌÁ=ÔÉÌÇ\n" + +#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381 +#: src/userdel.c:303 src/usermod.c:563 +#, c-format +msgid "%s: cannot rewrite group file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ ïìÜäùí\n" + +#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389 +#: src/userdel.c:309 src/usermod.c:700 +#, c-format +msgid "%s: cannot rewrite shadow group file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389 +#, c-format +msgid "%s: unable to lock group file\n" +msgstr "%s: Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n" + +#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432 +#, c-format +msgid "%s: unable to open group file\n" +msgstr "%s: Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n" + +#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398 +#, c-format +msgid "%s: unable to lock shadow group file\n" +msgstr "%s: Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442 +#, c-format +msgid "%s: unable to open shadow group file\n" +msgstr "%s: Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/groupadd.c:518 +#, c-format +msgid "%s: group %s exists\n" +msgstr "%s: Ç ïìÜäá %s õðÜñ÷åé\n" + +#: src/groupdel.c:86 +msgid "usage: groupdel group\n" +msgstr "÷ñÞóç: groupdel ïìÜäá\n" + +#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234 +#, c-format +msgid "%s: error removing group entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò ïìÜäáò\n" + +#: src/groupdel.c:116 src/groupmod.c:206 +#, c-format +msgid "%s: error removing group dbm entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï dbm áñ÷åßï ïìÜäùí\n" + +#: src/groupdel.c:131 +#, c-format +msgid "%s: error removing shadow group entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí " +"ïìÜäùí\n" + +#: src/groupdel.c:144 src/groupmod.c:252 +#, c-format +msgid "%s: error removing shadow group dbm entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#. +#. * Can't remove the group. +#. +#: src/groupdel.c:248 +#, c-format +msgid "%s: cannot remove user's primary group.\n" +msgstr "%s: áäõíáìßá áöáßñåóçò ôçò ðñùôáñ÷éêÞò ïìÜäáò ôïõ ÷ñÞóôç.\n" + +#: src/groupdel.c:305 src/groupmod.c:501 +#, c-format +msgid "%s: group %s does not exist\n" +msgstr "%s: Ç ïìÜäá %s äåí õðÜñ÷åé\n" + +#: src/groupdel.c:319 src/groupmod.c:517 +#, c-format +msgid "%s: group %s is a NIS group\n" +msgstr "%s: Ç ïìÜäá %s åßíáé NIS ïìÜäá\n" + +#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016 +#, c-format +msgid "%s: %s is the NIS master\n" +msgstr "%s: Ï %s åßíáé ï êýñéïò äéáêïìéóôÞò NIS\n" + +#: src/groupmod.c:105 +msgid "usage: groupmod [-g gid [-o]] [-n name] group\n" +msgstr "÷ñÞóç: groupmod [-g gid [-o]] [-n üíïìá] ïìÜäá\n" + +#: src/groupmod.c:165 +#, fuzzy, c-format +msgid "%s: %s not found in /etc/group\n" +msgstr "%s: Ï %s äåí âñÝèçêå óôï /etc/passwd\n" + +#: src/groupmod.c:246 +#, c-format +msgid "%s: cannot add new dbm shadow group entry\n" +msgstr "" +"%s: áäõíáìßá ðñïóèÞêçò íÝáò dbm êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí " +"ïìÜäùí\n" + +#: src/groupmod.c:299 +#, c-format +msgid "%s: %ld is not a unique gid\n" +msgstr "%s: Ôï %ld äåí åßíáé ìïíáäéêü gid\n" + +#: src/groupmod.c:330 +#, c-format +msgid "%s: %s is not a unique name\n" +msgstr "%s: Ôï %s äåí åßíáé ìïíáäéêü üíïìá\n" + +#: src/groups.c:62 +#, c-format +msgid "unknown user %s\n" +msgstr "Üãíùóôïò ÷ñÞóôçò: %s\n" + +#: src/grpck.c:98 +#, c-format +msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n" +msgstr "×ñÞóç: %s [ -r ] [ group [ gshadow ] ]\n" + +#: src/grpck.c:100 +#, c-format +msgid "Usage: %s [ -r ] [ group ]\n" +msgstr "×ñÞóç: %s [ -r ] [ group ]\n" + +#: src/grpck.c:119 src/pwck.c:119 +msgid "No" +msgstr "Ï÷é" + +#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225 +#, c-format +msgid "%s: cannot lock file %s\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ %s\n" + +#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241 +#: src/pwck.c:250 +#, c-format +msgid "%s: cannot open file %s\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ %s\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:298 +msgid "invalid group file entry\n" +msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï ïìÜäùí\n" + +#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517 +#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517 +#: src/pwck.c:541 +#, c-format +msgid "delete line `%s'? " +msgstr "äéáãñáöÞ ãñáììÞò `%s'; " + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:361 +msgid "duplicate group entry\n" +msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n" + +#: src/grpck.c:378 +#, c-format +msgid "invalid group name `%s'\n" +msgstr "Ìç Ýãêõñï üíïìá ïìÜäáò `%s'\n" + +#: src/grpck.c:388 +#, c-format +msgid "group %s: bad GID (%d)\n" +msgstr "ïìÜäá %s: ëÜèïò GID (%d)\n" + +#: src/grpck.c:414 +#, c-format +msgid "group %s: no user %s\n" +msgstr "ïìÜäá %s: äåí õðÜñ÷åé ÷ñÞóôçò %s\n" + +#: src/grpck.c:416 src/grpck.c:585 +#, c-format +msgid "delete member `%s'? " +msgstr "äéáãñáöÞ ìÝëïõò `%s'; " + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:453 +msgid "invalid shadow group file entry\n" +msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:516 +msgid "duplicate shadow group entry\n" +msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/grpck.c:533 +msgid "no matching group file entry\n" +msgstr "Äåí âñÝèçêå êáôá÷þñçóç óôï áñ÷åßï ïìÜäùí ðïõ íá ôáéñéÜæåé\n" + +#: src/grpck.c:553 +#, c-format +msgid "shadow group %s: no administrative user %s\n" +msgstr "óêéþäçò ïìÜäá %s: Äåí õðÜñ÷åé äéá÷åéñéóôÞò ÷ñÞóôçò %s\n" + +#: src/grpck.c:555 +#, c-format +msgid "delete administrative member `%s'? " +msgstr "äéáãñáöÞ äéá÷åéñéóôéêïý ìÝëïõò `%s'; " + +#: src/grpck.c:583 +#, c-format +msgid "shadow group %s: no user %s\n" +msgstr "óêéþäçò ïìÜäá %s: äåí õðÜñ÷åé ÷ñÞóôçò %s\n" + +#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580 +#, c-format +msgid "%s: cannot update file %s\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò áñ÷åßïõ %s\n" + +#: src/grpck.c:640 src/pwck.c:606 +#, c-format +msgid "%s: the files have been updated; run mkpasswd\n" +msgstr "%s: ôá áñ÷åßá áíáíåþèçêáí. ÅêôåëÝóôå mkpasswd\n" + +#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611 +#, c-format +msgid "%s: no changes\n" +msgstr "%s: êáìéÜ áëëáãÞ\n" + +#: src/grpck.c:644 src/pwck.c:610 +#, c-format +msgid "%s: the files have been updated\n" +msgstr "%s: ôá áñ÷åßá áíáíåþèçêáí\n" + +#: src/grpconv.c:62 src/grpunconv.c:63 +#, c-format +msgid "%s: can't lock group file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n" + +#: src/grpconv.c:67 src/grpunconv.c:68 +#, c-format +msgid "%s: can't open group file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ ïìÜäùí\n" + +#: src/grpconv.c:72 src/grpunconv.c:73 +#, c-format +msgid "%s: can't lock shadow group file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/grpconv.c:77 src/grpunconv.c:78 +#, c-format +msgid "%s: can't open shadow group file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#. +#. * This shouldn't happen (the entry exists) but... +#. +#: src/grpconv.c:93 +#, c-format +msgid "%s: can't remove shadow group %s\n" +msgstr "" +"%s: áäõíáìßá áöáßñåóçò ôçò ïìÜäáò %s, áðü ôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" +"ïìÜäùí\n" + +#: src/grpconv.c:134 src/pwconv.c:160 +#, c-format +msgid "%s: can't update shadow entry for %s\n" +msgstr "" +"%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ãéá ôïí " +"%s\n" + +#: src/grpconv.c:143 src/grpunconv.c:94 +#, c-format +msgid "%s: can't update entry for group %s\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò ãéá ôçí ïìÜäá %s\n" + +#: src/grpconv.c:150 src/grpunconv.c:102 +#, c-format +msgid "%s: can't update shadow group file\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/grpconv.c:154 src/grpunconv.c:107 +#, c-format +msgid "%s: can't update group file\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò ãéá ôï áñ÷åßï ïìÜäùí\n" + +#: src/grpconv.c:169 src/grpunconv.c:128 +#, c-format +msgid "%s: not configured for shadow group support.\n" +msgstr "%s: Äåí åßíáé äéáìïñöùìÝíï ãéá óêéþäç óõíèçìáôéêÜ ïìÜäùí.\n" + +#: src/grpunconv.c:112 +#, c-format +msgid "%s: can't delete shadow group file\n" +msgstr "" +"%s: Äåí åßíáé äõíáôüí íá äéáãñáöåß ôï áñ÷åßï óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/id.c:56 +msgid "usage: id [ -a ]\n" +msgstr "÷ñÞóç: id [ -a ]\n" + +#: src/id.c:58 +msgid "usage: id\n" +msgstr "÷ñÞóç: id\n" + +#: src/id.c:118 +#, c-format +msgid "uid=%d(%s)" +msgstr "" + +#: src/id.c:120 +#, c-format +msgid "uid=%d" +msgstr "" + +#: src/id.c:124 +#, c-format +msgid " gid=%d(%s)" +msgstr "" + +#: src/id.c:126 +#, c-format +msgid " gid=%d" +msgstr "" + +#: src/id.c:136 +#, c-format +msgid " euid=%d(%s)" +msgstr "" + +#: src/id.c:138 +#, c-format +msgid " euid=%d" +msgstr "" + +#: src/id.c:143 +#, c-format +msgid " egid=%d(%s)" +msgstr "" + +#: src/id.c:145 +#, c-format +msgid " egid=%d" +msgstr "" + +#. +#. * Start off the group message. It will be of the format +#. * +#. * groups=###(aaa),###(aaa),###(aaa) +#. * +#. * where "###" is a numerical value and "aaa" is the +#. * corresponding name for each respective numerical value. +#. +#: src/id.c:166 +msgid " groups=" +msgstr " ïìÜäåò=" + +#: src/lastlog.c:167 +msgid "Username Port From Latest\n" +msgstr "¼íïìá_×ñÞóôç Èýñá Áðü Ôåëåõôáßá\n" + +#: src/lastlog.c:169 +msgid "Username Port Latest\n" +msgstr "¼íïìá_×ñÞóôç Èýñá Ôåëåõôáßá\n" + +#: src/lastlog.c:183 +msgid "**Never logged in**" +msgstr "**ÊáìéÜ åßóïäïò óôï óýóôçìá**" + +#: src/login.c:198 +#, c-format +msgid "usage: %s [-p] [name]\n" +msgstr "÷ñÞóç: %s [-p] [üíïìá]\n" + +#: src/login.c:201 +#, c-format +msgid " %s [-p] [-h host] [-f name]\n" +msgstr " %s [-p] [-h óýóôçìá] [-f üíïìá]\n" + +#: src/login.c:203 +#, c-format +msgid " %s [-p] -r host\n" +msgstr " %s [-p] -r óýóôçìá\n" + +#: src/login.c:286 +msgid "Invalid login time\n" +msgstr "ÅóöáëìÝíç þñá åéóüäïõ\n" + +#: src/login.c:341 +msgid "" +"\n" +"System closed for routine maintenance\n" +msgstr "" +"\n" +"Ôï óýóôçìá Ýêëåéóå ãéá óõíôÞñçóç ñïõôßíáò\n" + +#: src/login.c:351 +msgid "" +"\n" +"[Disconnect bypassed -- root login allowed.]\n" +msgstr "" +"\n" +"[ÐáñÜêáìøç áðïóýíäåóçò -- Ç åßóïäïò ôïõ root åðåôñÜðç.]\n" + +#: src/login.c:390 +#, c-format +msgid "" +"\n" +"Login timed out after %d seconds.\n" +msgstr "" +"\n" +"Ç äéáäéêáóßá åéóüäïõ ôåñìáôßóôçêå ìåôÜ áðü %d äåõôåñüëåðôá.\n" + +#: src/login.c:692 +#, c-format +msgid " on `%.100s' from `%.200s'" +msgstr " óôï `%.100s' áðü `%.200s'" + +#: src/login.c:694 +#, c-format +msgid " on `%.100s'" +msgstr " óôï `%.100s'" + +#: src/login.c:834 +#, c-format +msgid "" +"\n" +"%s login: " +msgstr "" +"\n" +"%s login: " + +#: src/login.c:836 +msgid "login: " +msgstr "login: " + +#: src/login.c:1026 src/sulogin.c:231 +msgid "Login incorrect" +msgstr "Äéáäéêáóßá åéóüäïõ áðÝôõ÷å" + +#: src/login.c:1213 +msgid "Warning: login re-enabled after temporary lockout.\n" +msgstr "" +"Ðñïåéäïðïßçóç: Ç åßóïäïò åðáíåíåñãïðïéÞèçêå ìåôÜ áðü ðñïóùñéíü áðïêëåéóìü.\n" + +#: src/login.c:1223 +#, c-format +msgid "Last login: %s on %s" +msgstr "Ôåëåõôáßá åßóïäïò: %s óôï %s" + +#: src/login.c:1226 +#, c-format +msgid "Last login: %.19s on %s" +msgstr "Ôåëåõôáßá åßóïäïò: %.19s óôï %s" + +#: src/login.c:1231 +#, c-format +msgid " from %.*s" +msgstr " áðü %.*s" + +#: src/login.c:1303 +msgid "Starting rad_login\n" +msgstr "¸íáñîç rad_login\n" + +#: src/mkpasswd.c:49 +#, c-format +msgid "%s: no DBM database on system - no action performed\n" +msgstr "" +"%s: Äåí õðÜñ÷åé DBM âÜóç äåäïìÝíùí óôï óýóôçìá - êáìéÜ åíÝñãåéá äåí " +"åêôåëåßôáé\n" + +#: src/mkpasswd.c:245 src/mkpasswd.c:249 +#, c-format +msgid "%s: cannot overwrite file %s\n" +msgstr "%s: áäõíáìßá åããñáöÞò ðÜíù áðü ôï áñ÷åßï %s\n" + +#: src/mkpasswd.c:263 +#, c-format +msgid "%s: cannot open DBM files for %s\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò DBM áñ÷åßùí ãéá ôï %s\n" + +#: src/mkpasswd.c:296 +#, c-format +msgid "%s: the beginning with " +msgstr "%s: ç áñ÷Þ ìå " + +#: src/mkpasswd.c:321 +#, c-format +msgid "%s: error parsing line \"%s\"\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí åðåîåñãáóßá ôçò ãñáììÞò \"%s\"\n" + +#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332 +msgid "adding record for name " +msgstr "ðñïóèÞêç êáôá÷þñçóçò ãéá üíïìá " + +#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349 +#, c-format +msgid "%s: error adding record for " +msgstr "%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç êáôá÷þñçóçò ãéá " + +#: src/mkpasswd.c:367 +#, c-format +msgid "added %d entries, longest was %d\n" +msgstr "ðñïóôÝèçêáí %d êáôá÷ùñÞóåéò, ç ìåãáëýôåñç Þôáí %d\n" + +#: src/mkpasswd.c:382 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n" +msgstr "×ñÞóç: %s [ -vf ] [ -p|g|sp|sg ] áñ÷åßï\n" + +#: src/mkpasswd.c:384 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n" +msgstr "×ñÞóç: %s [ -vf ] [ -p|g|sp ] áñ÷åßï\n" + +#: src/mkpasswd.c:387 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g ] file\n" +msgstr "×ñÞóç: %s [ -vf ] [ -p|g ] áñ÷åßï\n" + +#: src/newgrp.c:66 +msgid "usage: newgrp [ - ] [ group ]\n" +msgstr "÷ñÞóç: newgrp [ - ] [ ïìÜäá ]\n" + +#: src/newgrp.c:68 +#, fuzzy +msgid "usage: sg group [[-c] command ]\n" +msgstr "÷ñÞóç: sg ïìÜäá [ åíôïëÞ ]\n" + +#: src/newgrp.c:125 +#, c-format +msgid "unknown uid: %d\n" +msgstr "Üãíùóôï uid: %d\n" + +#: src/newgrp.c:201 +#, c-format +msgid "unknown gid: %ld\n" +msgstr "Üãíùóôï gid: %ld\n" + +#: src/newgrp.c:245 +#, c-format +msgid "unknown gid: %d\n" +msgstr "Üãíùóôï gid: %d\n" + +#: src/newgrp.c:323 src/newgrp.c:332 +msgid "Sorry.\n" +msgstr "ËõðÜìáé.\n" + +#: src/newgrp.c:364 +msgid "too many groups\n" +msgstr "ðÜñá ðïëëÝò ïìÜäåò\n" + +#: src/newusers.c:76 +#, c-format +msgid "Usage: %s [ input ]\n" +msgstr "×ñÞóç: %s [ åßóïäïò ]\n" + +#: src/newusers.c:364 +#, c-format +msgid "%s: can't lock /etc/passwd.\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ /etc/passwd.\n" + +#: src/newusers.c:375 +#, c-format +msgid "%s: can't lock files, try again later\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò áñ÷åßùí, îáíáäïêéìÜóôå áñãüôåñá\n" + +#: src/newusers.c:390 +#, c-format +msgid "%s: can't open files\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôùí áñ÷åßùí\n" + +#: src/newusers.c:435 +#, c-format +msgid "%s: line %d: invalid line\n" +msgstr "%s: ãñáììÞ %d: ìç Ýãêõñç ãñáììÞ\n" + +#: src/newusers.c:453 +#, c-format +msgid "%s: line %d: can't create GID\n" +msgstr "%s: ãñáììÞ %d: áäõíáìßá äçìéïõñãßáò GID\n" + +#: src/newusers.c:469 +#, c-format +msgid "%s: line %d: can't create UID\n" +msgstr "%s: ãñáììÞ %d: áäõíáìßá äçìéïõñãßáò UID\n" + +#: src/newusers.c:481 +#, c-format +msgid "%s: line %d: cannot find user %s\n" +msgstr "%s: ãñáììÞ %d: áäõíáìßá åýñåóçò ÷ñÞóôç %s\n" + +#: src/newusers.c:489 +#, c-format +msgid "%s: line %d: can't update password\n" +msgstr "%s: ãñáììÞ %d: áäõíáìßá áíáíÝùóç óõíèçìáôéêïý\n" + +#: src/newusers.c:506 +#, c-format +msgid "%s: line %d: mkdir failed\n" +msgstr "%s: ãñáììÞ %d: áðïôõ÷ßá äçìéïõñãßáò êáôáëüãïõ(mkdir)\n" + +#: src/newusers.c:510 +#, c-format +msgid "%s: line %d: chown failed\n" +msgstr "%s: ãñáììÞ %d: áðïôõ÷ßá áëëáãÞò éäéïêôÞôç(chown)\n" + +#: src/newusers.c:519 +#, c-format +msgid "%s: line %d: can't update entry\n" +msgstr "%s: ãñáììÞ %d: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò\n" + +#: src/newusers.c:550 +#, c-format +msgid "%s: error updating files\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí åíçìÝñùóç áñ÷åßùí\n" + +#: src/passwd.c:239 +#, c-format +msgid "usage: %s [ -f | -s ] [ name ]\n" +msgstr "÷ñÞóç: %s [ -f | -s ] [ üíïìá ]\n" + +#: src/passwd.c:242 +#, c-format +msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n" +msgstr "" +" %s [ -x ìåã. ] [ -n åëÜ÷. ] [ -w ðñïåéä. ] [ -i áíåíåñãü ] üíïìá\n" + +#: src/passwd.c:245 +#, c-format +msgid " %s { -l | -u | -d | -S | -e } name\n" +msgstr " %s { -l | -u | -d | -S | -e } üíïìá\n" + +#: src/passwd.c:347 +#, c-format +msgid "User %s has a TCFS key, his old password is required.\n" +msgstr "Ï ÷ñÞóôçò %s Ý÷åé êëåéäß TCFS, áðáéôåßôáé ôï ðáëéü óõíèçìáôéêü.\n" + +#: src/passwd.c:348 +msgid "You can use -t option to force the change.\n" +msgstr "" +"Ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå ôçí -t ðáñÜìåôñï ãéá íá åîáíáãêÜóåôå ôçí\n" +"ðñáãìáôïðïßçóç ôçò áëëáãÞò.\n" + +#: src/passwd.c:354 +msgid "Old password: " +msgstr "Ðáëéü Óõíèçìáôéêü: " + +#: src/passwd.c:361 +#, c-format +msgid "Incorrect password for `%s'\n" +msgstr "ÅóöáëìÝíï óõíèçìáôéêü ãéá ôïí `%s'\n" + +#: src/passwd.c:374 +#, c-format +msgid "Warning: user %s has a TCFS key.\n" +msgstr "Ðñïåéäïðïßçóç: Ï ÷ñÞóôçò %s Ý÷åé êëåéäß TCFS.\n" + +#: src/passwd.c:392 +#, c-format +msgid "" +"Enter the new password (minimum of %d, maximum of %d characters)\n" +"Please use a combination of upper and lower case letters and numbers.\n" +msgstr "" +"ÅéóÜãåôå ôï íÝï óõíèçìáôéêü (åëÜ÷éóôï %d, ìÝãéóôï %d ÷áñáêôÞñåò)\n" +"Ðáñáêáëþ ÷ñçóéìïðïéÞóôå Ýíá óõíäõáóìü áðü êåöáëáßá êáé ìéêñÜ ãñÜììáôá\n" +"êáèþò êáé áñéèìïýò.\n" + +#: src/passwd.c:399 +msgid "New password: " +msgstr "ÍÝï Óõíèçìáôéêü: " + +#: src/passwd.c:409 +msgid "Try again.\n" +msgstr "ÎáíáäïêéìÜóôå.\n" + +#: src/passwd.c:418 +msgid "" +"\n" +"Warning: weak password (enter it again to use it anyway).\n" +msgstr "" +"\n" +"Ðñïóï÷Þ: áäýíáìï óõíèçìáôéêü (åéóÜãåôÝ ôï ðÜëé ãéá íá ôï ÷ñçóéìïðïéÞóåôå).\n" + +#: src/passwd.c:427 +msgid "They don't match; try again.\n" +msgstr "Äåí ôáéñéÜæïõí. ÄïêéìÜóôå îáíÜ.\n" + +#: src/passwd.c:512 src/passwd.c:528 +#, c-format +msgid "The password for %s cannot be changed.\n" +msgstr "Ôï óõíèçìáôéêü ãéá ôïí %s äåí ìðïñåß íá áëëÜîåé.\n" + +#: src/passwd.c:556 +#, c-format +msgid "Sorry, the password for %s cannot be changed yet.\n" +msgstr "Óõãíþìç, ôï óõíèçìáôéêü ãéá ôïí %s äåí ìðïñåß íá áëëÜîåé áêüìç.\n" + +#: src/passwd.c:693 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: äåí õðÜñ÷åé åëåýèåñç ìíÞìç\n" + +#: src/passwd.c:845 +msgid "Cannot lock the TCFS key database; try again later\n" +msgstr "Áäõíáìßá êëåéäþìáôïò ôçò âÜóçò êëåéäéþí ôïõ TCFS. ÄïêéìÜóôå áñãüôåñá\n" + +#: src/passwd.c:851 +msgid "Cannot open the TCFS key database.\n" +msgstr "Áäõíáìßá áíïßãìáôïò ôçò âÜóçò êëåéäéþí ôïõ TCFS.\n" + +#: src/passwd.c:857 +msgid "Error updating the TCFS key database.\n" +msgstr "ÓöÜëìá êáôÜ ôçí áíáíÝùóç ôçò âÜóçò êëåéäéþí ôïõ TCFS.\n" + +#: src/passwd.c:862 +msgid "Cannot commit TCFS changes.\n" +msgstr "Áäõíáìßá õëïðïßçóçò ôùí áëëáãþí óôï TCFS.\n" + +#: src/passwd.c:1069 +#, c-format +msgid "%s: Cannot execute %s" +msgstr "%s: Áäõíáìßá åêôÝëåóçò ôïõ %s" + +#: src/passwd.c:1176 +#, c-format +msgid "%s: repository %s not supported\n" +msgstr "%s: ç áðïèÞêç %s äåí õðïóôçñßæåôáé\n" + +#: src/passwd.c:1263 +#, c-format +msgid "%s: Permission denied\n" +msgstr "%s: ¶äåéá áðïññßöèçêå\n" + +#: src/passwd.c:1287 +#, c-format +msgid "You may not change the password for %s.\n" +msgstr "Äåí ìðïñåßôå íá áëëÜîåôå ôï óõíèçìáôéêü ãéá ôï(í) %s.\n" + +#: src/passwd.c:1352 +#, c-format +msgid "Changing password for %s\n" +msgstr "ÁëëáãÞ óõíèçìáôéêïý ãéá ôïí %s\n" + +#: src/passwd.c:1356 +#, c-format +msgid "The password for %s is unchanged.\n" +msgstr "Ôï óõíèçìáôéêü ãéá ôïí %s äåí Üëëáîå.\n" + +#: src/passwd.c:1412 +msgid "Password changed.\n" +msgstr "Ôï óõíèçìáôéêü Üëëáîå.\n" + +#: src/pwck.c:98 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n" +msgstr "×ñÞóç: %s [ -qr ] [ passwd [ shadow ] ]\n" + +#: src/pwck.c:100 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd ]\n" +msgstr "×ñÞóç: %s [ -qr ] [ passwd ]\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:285 +msgid "invalid password file entry\n" +msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï óõíèçìáôéêþí\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:347 +msgid "duplicate password entry\n" +msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n" + +#: src/pwck.c:363 +#, c-format +msgid "invalid user name `%s'\n" +msgstr "Ìç Ýãêõñï üíïìá ÷ñÞóôç `%s'\n" + +#: src/pwck.c:373 +#, c-format +msgid "user %s: bad UID (%d)\n" +msgstr "÷ñÞóôçò %s: ëáíèáóìÝíï UID (%d)\n" + +#. +#. * No primary group, just give a warning +#. +#: src/pwck.c:388 +#, c-format +msgid "user %s: no group %d\n" +msgstr "÷ñÞóôçò %s: êáìéÜ ïìÜäá %d\n" + +#. +#. * Home directory doesn't exist, give a warning +#. +#: src/pwck.c:403 +#, c-format +msgid "user %s: directory %s does not exist\n" +msgstr "÷ñÞóôçò %s: ï êáôÜëïãïò %s äåí õðÜñ÷åé\n" + +#. +#. * Login shell doesn't exist, give a warning +#. +#: src/pwck.c:418 +#, c-format +msgid "user %s: program %s does not exist\n" +msgstr "÷ñÞóôçò %s: ôï ðñüãñáììá %s äåí õðÜñ÷åé\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:454 +msgid "invalid shadow password file entry\n" +msgstr "Ìç Ýãêõñç êáôá÷þñçóç óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:516 +msgid "duplicate shadow password entry\n" +msgstr "áíôéãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#. +#. * Tell the user this entry has no matching +#. * /etc/passwd entry and ask them to delete it. +#. +#: src/pwck.c:540 +msgid "no matching password file entry\n" +msgstr "Äåí âñÝèçêå êáôá÷þñçóç óôï áñ÷åßï óõíèçìáôéêþí ðïõ íá ôáéñßáæåé\n" + +#: src/pwck.c:557 +#, c-format +msgid "user %s: last password change in the future\n" +msgstr "÷ñÞóôçò %s: ôåëåõôáßá áëëáãÞ óõíèçìáôéêïý óôï ìÝëëïí\n" + +#: src/pwconv.c:94 src/pwunconv.c:108 +#, c-format +msgid "%s: can't lock passwd file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/pwconv.c:99 src/pwunconv.c:113 +#, c-format +msgid "%s: can't open passwd file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/pwconv.c:126 +#, c-format +msgid "%s: can't remove shadow entry for %s\n" +msgstr "" +"áäõíáìßá áöáßñåóçò êáôá÷þñçóçò ãéá ôïí %s, áðü ôï áñ÷åßï óêéùäþí " +"óõíèçìáôéêþí\n" + +#: src/pwconv.c:169 +#, c-format +msgid "%s: can't update passwd entry for %s\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò óõíèçìáôéêïý ãéá ôïí %s\n" + +#: src/pwconv.c:176 +#, c-format +msgid "%s: can't update shadow file\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/pwconv.c:180 +#, c-format +msgid "%s: can't update passwd file\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/pwunconv.c:62 +#, c-format +msgid "%s: Shadow passwords are not configured.\n" +msgstr "%s: Ôá óêéþäç óõíèçìáôéêÜ äåí Ý÷ïõí äéáìïñöùèåß.\n" + +#: src/pwunconv.c:171 +#, c-format +msgid "%s: can't update entry for user %s\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò êáôá÷þñçóçò ãéá ôïí ÷ñÞóôç %s\n" + +#: src/pwunconv.c:188 +#, c-format +msgid "%s: can't delete shadow password file\n" +msgstr "%s: Äåí åßíáé äõíáôüí íá äéáãñáöåß ôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#: src/su.c:140 +msgid "Sorry." +msgstr "ËõðÜìáé." + +#: src/su.c:222 +#, c-format +msgid "%s: must be run from a terminal\n" +msgstr "%s: ðñÝðåé íá åêôåëåóôåß áðü ôåñìáôéêü\n" + +#: src/su.c:311 +#, c-format +msgid "%s: pam_start: error %d\n" +msgstr "%s: pam_start: óöÜëìá %d\n" + +#: src/su.c:337 +#, c-format +msgid "Unknown id: %s\n" +msgstr "Áãíùóôç ôáõôüôçôá: %s\n" + +#. access denied (-1) or unexpected value +#: src/su.c:372 src/su.c:387 +#, c-format +msgid "You are not authorized to su %s\n" +msgstr "Äåí Ý÷åôå Üäåéá ãéá su %s\n" + +#. require own password +#: src/su.c:383 +msgid "(Enter your own password.)" +msgstr "(ÅéóÜãåôå ôï äéêü óáò óõíèçìáôéêü.)" + +#: src/su.c:404 +#, c-format +msgid "%s: permission denied (shell).\n" +msgstr "%s: Üäåéá áðïññßöèçêå (öëïéüò)\n" + +#: src/su.c:428 +#, c-format +msgid "" +"%s: %s\n" +"(Ignored)\n" +msgstr "" +"%s: %s\n" +"(ÁãíïÞèçêå)\n" + +#: src/su.c:628 +msgid "No shell\n" +msgstr "Äåí õðÜñ÷åé öëïéüò\n" + +#. must be a password file! +#: src/sulogin.c:136 +msgid "No password file\n" +msgstr "Äåí õðÜñ÷åé áñ÷åßï óõíèçìáôéêþí\n" + +#. +#. * Fail secure +#. +#: src/sulogin.c:178 +msgid "No password entry for 'root'\n" +msgstr "Äåí õðÜñ÷åé êáôá÷þñçóç óõíèçìáôéêïý ãéá ôïí 'root'\n" + +#. +#. * Here we prompt for the root password, or if no password is +#. * given we just exit. +#. +#. get a password for root +#: src/sulogin.c:192 +msgid "" +"\n" +"Type control-d to proceed with normal startup,\n" +"(or give root password for system maintenance):" +msgstr "" +"\n" +"ÐëçêôñïëïãÞóôå control-d ãéá íá óõíå÷ßóåôå ìå ôçí êáíïíéêÞ Ýíáñîç,\n" +"(Þ äþóôå ôï óõíèçìáôéêü ôïõ root ãéá óõíôÞñçóç ôïõ óõóôÞìáôïò):" + +#. make new environment active +#: src/sulogin.c:241 +msgid "Entering System Maintenance Mode\n" +msgstr "¸íáñîç ÊáôÜóôáóçò ÓõíôÞñçóçò ÓõóôÞìáôïò\n" + +#: src/useradd.c:243 +#, c-format +msgid "%s: rebuild the group database\n" +msgstr "%s: åðáíáêôßóôå ôçí âÜóç äåäïìÝíùí ïìÜäùí\n" + +#: src/useradd.c:250 +#, c-format +msgid "%s: rebuild the shadow group database\n" +msgstr "%s: åðáíáêôßóôå ôçí âÜóç äåäïìÝíùí ôùí óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/useradd.c:287 src/usermod.c:967 +#, c-format +msgid "%s: invalid numeric argument `%s'\n" +msgstr "%s: Ìç Ýãêõñç áñéèìçôéêÞ ðáñÜìåôñïò `%s'\n" + +#: src/useradd.c:343 +#, c-format +msgid "%s: unknown gid %s\n" +msgstr "%s: Üãíùóôï gid %s\n" + +#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254 +#: src/usermod.c:1098 +#, c-format +msgid "%s: unknown group %s\n" +msgstr "%s: Üãíùóôç ïìÜäá %s\n" + +#: src/useradd.c:418 +#, c-format +msgid "group=%s,%ld basedir=%s skel=%s\n" +msgstr "ïìÜäá=%s,%ld âáóéêüò_êáôáë=%s óêåë=%s\n" + +#: src/useradd.c:421 +#, c-format +msgid "shell=%s " +msgstr "öëïéüò=%s " + +#: src/useradd.c:423 +#, c-format +msgid "inactive=%ld expire=%s" +msgstr "áíåíåñãü=%ld ëÞîç=%s" + +#: src/useradd.c:427 +#, c-format +msgid "GROUP=%ld\n" +msgstr "ÏÌÁÄÁ=%ld\n" + +#: src/useradd.c:428 +#, c-format +msgid "HOME=%s\n" +msgstr "ÌÇÔÑÉÊÏÓ_ÊÁÔÁËÏÃÏÓ=%s\n" + +#: src/useradd.c:430 +#, c-format +msgid "INACTIVE=%ld\n" +msgstr "ÁÍÅÍÅÑÃÏÓ=%ld\n" + +#: src/useradd.c:431 +#, c-format +msgid "EXPIRE=%s\n" +msgstr "ËÇÎÇ=%s\n" + +#: src/useradd.c:433 +#, c-format +msgid "SHELL=%s\n" +msgstr "ÊÅËÕÖÏÓ=%s\n" + +#: src/useradd.c:434 +#, c-format +msgid "SKEL=%s\n" +msgstr "ÓÊÅË=%s\n" + +#: src/useradd.c:470 +#, c-format +msgid "%s: cannot create new defaults file\n" +msgstr "%s: áäõíáìßá äçìéïõñãßáò íÝïõ áñ÷åßïõ ðñïêáèïñéóìÝíùí ñõèìßóåùí\n" + +#: src/useradd.c:564 src/useradd.c:575 +#, c-format +msgid "%s: rename: %s" +msgstr "%s: ìåôïíïìáóßá: %s" + +#: src/useradd.c:662 src/usermod.c:274 +#, c-format +msgid "%s: group `%s' is a NIS group.\n" +msgstr "%s: Ç ïìÜäá `%s' åßíáé NIS ïìÜäá.\n" + +#: src/useradd.c:670 src/usermod.c:282 +#, c-format +msgid "%s: too many groups specified (max %d).\n" +msgstr "%s: Ðñïóäéïñßóôçêáí õðåñâïëéêÝò ïìÜäåò (ìåã. %d).\n" + +#: src/useradd.c:702 src/usermod.c:314 +#, c-format +msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n" +msgstr "÷ñÞóç: %s\t[-u uid [-o]] [-g ïìÜäá] [-G ïìÜäá,...] \n" + +#: src/useradd.c:705 +msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n" +msgstr "" +"\t\t[-d ìçôñéêüò_êáôÜëïãïò] [-s öëïéüò] [-c ó÷üëéï]\n" +"\t\t[-m [-k êáíüíáò]]\n" + +#: src/useradd.c:708 src/usermod.c:320 +msgid "[-f inactive] [-e expire ] " +msgstr "[-f áíåíåñãü] [-e ëÞîç ] " + +#: src/useradd.c:711 +msgid "[-A program] " +msgstr "[-A ðñüãñáììá] " + +#: src/useradd.c:713 +msgid "[-p passwd] name\n" +msgstr "[-p óõíèçìáôéêü] üíïìá\n" + +#: src/useradd.c:715 +#, c-format +msgid " %s\t-D [-g group] [-b base] [-s shell]\n" +msgstr " %s\t-D [-g ïìÜäá] [-b âÜóç] [-s öëïéüò]\n" + +#: src/useradd.c:718 +msgid "\t\t[-f inactive] [-e expire ]\n" +msgstr "\t\t[-f áíåíåñãü] [-e ëÞîç ]\n" + +#: src/useradd.c:815 src/usermod.c:472 +#, c-format +msgid "%s: error locking group file\n" +msgstr "%s: ÓöÜëìá êáôÜ ôï êëåßäùìá ôïõ áñ÷åßïõ ïìÜäùí\n" + +#: src/useradd.c:819 src/usermod.c:477 +#, c-format +msgid "%s: error opening group file\n" +msgstr "%s: ÓöÜëìá êáôÜ ôï Üíïéãìá ôïõ áñ÷åßïõ ïìÜäùí\n" + +#: src/useradd.c:824 src/usermod.c:584 +#, c-format +msgid "%s: error locking shadow group file\n" +msgstr "%s: ÓöÜëìá êáôÜ ôï êëåßäùìá ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/useradd.c:829 src/usermod.c:590 +#, c-format +msgid "%s: error opening shadow group file\n" +msgstr "%s: ÓöÜëìá êáôÜ ôï Üíïéãìá ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/useradd.c:1001 +#, c-format +msgid "%s: uid %d is not unique\n" +msgstr "%s: Ôï uid %d äåí åßíáé ìïíáäéêü\n" + +#: src/useradd.c:1031 +#, c-format +msgid "%s: can't get unique uid\n" +msgstr "%s: áäõíáìßá åõñåóçò ìïíáäéêïý uid\n" + +#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057 +#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157 +#, c-format +msgid "%s: invalid field `%s'\n" +msgstr "%s: Ìç Ýãêõñï ðåäßï `%s'\n" + +#: src/useradd.c:1153 +#, c-format +msgid "%s: invalid base directory `%s'\n" +msgstr "%s: Ìç Ýãêõñïò êáôÜëïãïò âÜóçò `%s'\n" + +#: src/useradd.c:1163 +#, c-format +msgid "%s: invalid comment `%s'\n" +msgstr "%s: Ìç Ýãêõñï ó÷üëéï `%s'\n" + +#: src/useradd.c:1173 +#, c-format +msgid "%s: invalid home directory `%s'\n" +msgstr "%s: Ìç Ýãêõñïò ìçôñéêüò êáôÜëïãïò ÷ñÞóôç `%s'\n" + +#: src/useradd.c:1191 src/usermod.c:1080 +#, c-format +msgid "%s: invalid date `%s'\n" +msgstr "%s: Ìç Ýãêõñç çìåñïìçíßá `%s'\n" + +#: src/useradd.c:1203 +#, c-format +msgid "%s: shadow passwords required for -e\n" +msgstr "%s: óêéþäç óõíèçìáôéêÜ áðáéôïýíôáé ãéá ôï -e\n" + +#: src/useradd.c:1218 +#, c-format +msgid "%s: shadow passwords required for -f\n" +msgstr "%s: óêéþäç óõíèçìáôéêÜ áðáéôïýíôáé ãéá -f\n" + +#: src/useradd.c:1292 +#, c-format +msgid "%s: invalid shell `%s'\n" +msgstr "%s: Ìç Ýãêõñïò öëïéüò `%s'\n" + +#: src/useradd.c:1333 +#, c-format +msgid "%s: invalid user name `%s'\n" +msgstr "%s: Ìç Ýãêõñï üíïìá ÷ñÞóôç `%s'\n" + +#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225 +#, c-format +msgid "%s: cannot rewrite password file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230 +#, c-format +msgid "%s: cannot rewrite shadow password file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265 +#, c-format +msgid "%s: unable to lock password file\n" +msgstr "%s: Áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269 +#, c-format +msgid "%s: unable to open password file\n" +msgstr "%s: Áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ óõíèçìáôéêþí\n" + +#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274 +#, c-format +msgid "%s: cannot lock shadow password file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279 +#, c-format +msgid "%s: cannot open shadow password file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí\n" + +#: src/useradd.c:1529 src/usermod.c:1366 +#, c-format +msgid "%s: error adding authentication method\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç ìåèüäïõ åîáêñßâùóçò\n" + +#: src/useradd.c:1552 +#, c-format +msgid "%s: error adding new password entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n" + +#: src/useradd.c:1567 +#, c-format +msgid "%s: error updating password dbm entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï dbm áñ÷åßï óõíèçìáôéêþí\n" + +#: src/useradd.c:1583 src/usermod.c:1425 +#, c-format +msgid "%s: error adding new shadow password entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí " +"óõíèçìáôéêþí\n" + +#: src/useradd.c:1599 src/usermod.c:1440 +#, c-format +msgid "%s: error updating shadow passwd dbm entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóåùí óôï dbm áñ÷åßï óêéùäþí " +"óõíèçìáôéêþí\n" + +#: src/useradd.c:1631 +#, c-format +msgid "%s: cannot create directory %s\n" +msgstr "%s: áäõíáìßá äçìéïõñãßáò êáôáëüãïõ %s\n" + +#: src/useradd.c:1708 src/usermod.c:1203 +#, c-format +msgid "%s: user %s exists\n" +msgstr "%s: Ï ÷ñÞóôçò %s õðÜñ÷åé\n" + +#: src/useradd.c:1738 +#, c-format +msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n" +msgstr "" + +#: src/userdel.c:127 +#, c-format +msgid "usage: %s [-r] name\n" +msgstr "÷ñÞóç: %s [-r] üíïìá\n" + +#: src/userdel.c:178 src/userdel.c:260 +#, c-format +msgid "%s: error updating group entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí áíáíÝùóç êáôá÷ùñÞóçò ïìÜäáò\n" + +#: src/userdel.c:188 src/userdel.c:269 +#, c-format +msgid "%s: cannot update dbm group entry\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò ôçò dbm êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n" + +#: src/userdel.c:215 +#, fuzzy, c-format +msgid "%s: cannot remove dbm group entry\n" +msgstr "%s: áäõíáìßá áíáíÝùóçò ôçò dbm êáôá÷þñçóçò óôï áñ÷åßï ïìÜäùí\n" + +#: src/userdel.c:300 +#, c-format +msgid "%s: cannot rewrite TCFS key file\n" +msgstr "%s: áäõíáìßá åðáíåããñáöÞò ôïõ áñ÷åßïõ êëåéäéþí ôïõ TCFS\n" + +#: src/userdel.c:380 +#, c-format +msgid "%s: cannot lock TCFS key file\n" +msgstr "%s: áäõíáìßá êëåéäþìáôïò ôïõ áñ÷åßïõ êëåéäéþí ôïõ TCFS\n" + +#: src/userdel.c:384 +#, c-format +msgid "%s: cannot open TCFS key file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò ôïõ áñ÷åßïõ êëåéäéþí ôïõ TCFS\n" + +#: src/userdel.c:393 +#, c-format +msgid "%s: cannot open group file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ ïìÜäùí\n" + +#: src/userdel.c:403 +#, c-format +msgid "%s: cannot open shadow group file\n" +msgstr "%s: áäõíáìßá áíïßãìáôïò áñ÷åßïõ óêéùäþí óõíèçìáôéêþí ïìÜäùí\n" + +#: src/userdel.c:434 src/userdel.c:449 +#, c-format +msgid "%s: error deleting authentication\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ åîáêñßâùóçò\n" + +#: src/userdel.c:458 +#, c-format +msgid "%s: error deleting password entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n" + +#: src/userdel.c:461 +#, c-format +msgid "%s: error deleting shadow password entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#: src/userdel.c:470 +#, c-format +msgid "%s: error deleting TCFS entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò ôïõ TCFS\n" + +#: src/userdel.c:483 +#, c-format +msgid "%s: error deleting password dbm entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï dbm áñ÷åßï óõíèçìáôéêþí\n" + +#: src/userdel.c:502 +#, c-format +msgid "%s: error deleting shadow passwd dbm entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ êáôá÷þñçóçò óôï dbm áñ÷åßï óêéùäþí " +"óõíèçìáôéêþí\n" + +#: src/userdel.c:543 +#, c-format +msgid "%s: user %s is currently logged in\n" +msgstr "%s: Ï ÷ñÞóôçò %s âñßóêåôáé óôï óýóôçìá\n" + +#: src/userdel.c:660 +#, c-format +msgid "%s: warning: %s not owned by %s, not removing\n" +msgstr "%s: ðñïåéäïðïßçóç: Ôï %s äåí áíÞêåé óôïí %s, äåí äéáãñÜöåôáé\n" + +#: src/userdel.c:666 +#, c-format +msgid "%s: warning: can't remove " +msgstr "%s: ðñïåéäïðïßçóç: áäõíáìßá äéáãñáöÞò " + +#: src/userdel.c:741 src/usermod.c:994 +#, c-format +msgid "%s: user %s does not exist\n" +msgstr "%s: Ï ÷ñÞóôçò %s äåí õðÜñ÷åé\n" + +#: src/userdel.c:755 src/usermod.c:1010 +#, c-format +msgid "%s: user %s is a NIS user\n" +msgstr "%s: Ï ÷ñÞóôçò %s åßíáé NIS ÷ñÞóôçò\n" + +#: src/userdel.c:792 +#, c-format +msgid "%s: %s not owned by %s, not removing\n" +msgstr "%s: Ôï %s äåí áíÞêåé óôïí %s, äåí áöáéñåßôáé\n" + +#: src/userdel.c:815 +#, c-format +msgid "%s: not removing directory %s (would remove home of user %s)\n" +msgstr "" +"%s: Äåí äéáãñÜöåôáé ï êáôÜëïãïò %s (èá áöáéñïýóå ôïí ìçôñéêü êáôÜëïãï ôïõ " +"÷ñÞóôç %s)\n" + +#: src/userdel.c:828 +#, c-format +msgid "%s: error removing directory %s\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ ôïõ êáôáëüãïõ %s\n" + +#: src/usermod.c:317 +msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n" +msgstr "" +"\t\t[-d ìçôñéêüò_êáôÜëïãïò [-m]] [-s öëïéüò] [-c ó÷üëéï]\n" +"\t\t[-l íÝï_üíïìá]\n" + +#: src/usermod.c:323 +msgid "[-A {DEFAULT|program},... ] " +msgstr "[-A {DEFAULT|ðñüãñáììá},... ] " + +#: src/usermod.c:325 +#, fuzzy +msgid "[-p passwd] [-L|-U] name\n" +msgstr "[-p óõíèçìáôéêü] üíïìá\n" + +#: src/usermod.c:504 +#, c-format +msgid "%s: out of memory in update_group\n" +msgstr "%s: äåí õðÜñ÷åé åëåýèåñç ìíÞìç óôï update_group\n" + +#: src/usermod.c:627 +#, c-format +msgid "%s: out of memory in update_gshadow\n" +msgstr "%s: óôï update_gshadow\n" + +#: src/usermod.c:1180 +#, c-format +msgid "%s: no flags given\n" +msgstr "%s: Äåí äüèçêáí åíäåßîåéò\n" + +#: src/usermod.c:1187 +#, c-format +msgid "%s: shadow passwords required for -e and -f\n" +msgstr "%s: óêéþäç óõíèçìáôéêÜ áðáéôïýíôáé ãéá ôï -e êáé -f\n" + +#: src/usermod.c:1208 +#, c-format +msgid "%s: uid %ld is not unique\n" +msgstr "%s: Ôï uid %ld äåí åßíáé ìïíáäéêü\n" + +#: src/usermod.c:1356 +#, c-format +msgid "%s: error deleting authentication method\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí äéáãñáöÞ ìåèüäïõ åîáêñßâùóçò\n" + +#: src/usermod.c:1376 +#, c-format +msgid "%s: error changing authentication method\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí áëëáãÞ ìåèüäïõ åîáêñßâùóçò\n" + +#: src/usermod.c:1393 +#, c-format +msgid "%s: error changing password entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí áëëáãÞ êáôá÷þñçóçò óõíèçìáôéêïý\n" + +#: src/usermod.c:1399 +#, c-format +msgid "%s: error removing password entry\n" +msgstr "%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óõíèçìáôéêþí\n" + +#: src/usermod.c:1407 +#, c-format +msgid "%s: error adding password dbm entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí ðñïóèÞêç íÝáò êáôá÷þñçóçò óôï dbm áñ÷åßï óõíèçìáôéêþí\n" + +#: src/usermod.c:1414 +#, c-format +msgid "%s: error removing passwd dbm entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò áðü ôï dbm áñ÷åßï óõíèçìáôéêþí\n" + +#: src/usermod.c:1431 +#, c-format +msgid "%s: error removing shadow password entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï áñ÷åßï óêéùäþí óõíèçìáôéêþí\n" + +#: src/usermod.c:1446 +#, c-format +msgid "%s: error removing shadow passwd dbm entry\n" +msgstr "" +"%s: ÓöÜëìá êáôÜ ôçí áöáßñåóç êáôá÷þñçóçò óôï dbm áñ÷åßï óêéùäþí " +"óõíèçìáôéêþí\n" + +#: src/usermod.c:1477 +#, c-format +msgid "%s: directory %s exists\n" +msgstr "%s: ï êáôÜëïãïò %s õðÜñ÷åé\n" + +#: src/usermod.c:1484 +#, c-format +msgid "%s: can't create %s\n" +msgstr "%s: áäõíáìßá äçìéïõñãßáò ôïõ %s\n" + +#: src/usermod.c:1490 +#, c-format +msgid "%s: can't chown %s\n" +msgstr "%s: Áäõíáìßá áëëáãÞò éäéïêôÞôç(chown) ôïõ %s\n" + +#: src/usermod.c:1506 +#, c-format +msgid "%s: cannot rename directory %s to %s\n" +msgstr "%s: áäõíáìßá ìåôïíïìáóßáò ôïõ êáôáëüãïõ %s óå %s\n" + +#. better leave it alone +#: src/usermod.c:1603 +#, c-format +msgid "%s: warning: %s not owned by %s\n" +msgstr "%s: ðñïåéäïðïßçóç: Ôï %s äåí áíÞêåé óôïí %s\n" + +#: src/usermod.c:1609 +msgid "failed to change mailbox owner" +msgstr "áðïôõ÷ßá áëëáãÞò ôïõ éäéïêôÞôç ôïõ ãñáììáôïêéâùôßïõ" + +#: src/usermod.c:1616 +msgid "failed to rename mailbox" +msgstr "áðïôõ÷ßá ìåôïíïìáóßáò ãñáììáôïêéâùôßïõ" + +#: src/vipw.c:102 +#, c-format +msgid "" +"\n" +"%s: %s is unchanged\n" +msgstr "" +"\n" +"%s: Ôï %s äåí Üëëáîå\n" + +#: src/vipw.c:127 +#, fuzzy +msgid "Couldn't lock file" +msgstr "%s: áäõíáìßá îåêëåéäþìáôïò áñ÷åßïõ\n" + +#: src/vipw.c:134 +msgid "Couldn't make backup" +msgstr "" + +#: src/vipw.c:187 +#, c-format +msgid "%s: can't restore %s: %s (your changes are in %s)\n" +msgstr "%s: áäõíáìßá åðáíáöïñÜò %s: %s (ïé áëëáãÝò åßíáé óôï %s)\n" + +#: src/vipw.c:226 +msgid "" +"Usage:\n" +"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n" +"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n" +msgstr "" +"×ñÞóç:\n" +"`vipw' óýíôáóåé ôï /etc/passwd `vipw -s' óõíôÜóóåé ôï /etc/shadow\n" +"`vigr' óýíôáóåé ôï /etc/group `vigr -s' óõíôÜóóåé ôï /etc/gshadow\n" + +#~ msgid "Incorrect password for %s.\n" +#~ msgstr "ÅóöáëìÝíï óõíèçìáôéêü ãéá ôïí %s.\n" + +#~ msgid "group not found\n" +#~ msgstr "ç ïìÜäá äåí âñÝèçêå\n" diff --git a/current/po/fr.gmo b/current/po/fr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..93f5fb5347b7498bc8f95aeac433e156012a3633 GIT binary patch literal 40067 zcmcJY37nl(dH*jcO9ldh5D4o_V369R-}2m_f($U?*zlAC+qnYrX{++~tL zQb7?xKu}Q;!D>-!-4LM#t+g(#6x*V=s}sxDd1x>Gnp$7&Sch{EZ0nC_gR_D1>hcskASCQ zp8}5t59`fjUICr}9s~9}`yhA(_A9~T!Oh^AU>WQK-wJL6KMgJeXP=$P41k-!EO-le z5%?)^KKML%8h9FkPXd=ad^LCi_6Df!r+sQfpa`@2Bp`!Voz@M+Kke*!A}(G*fubRH=CRiOC13!DYs1s(-{0Hny7 zN1gjWfa2FrL88j^oMZEOE_fXF5r;cK@oN{T@;m^(5`4(UCKMpGY-vA{~|KaRMQTa-D9w@%71(i+?RQV=Bg}W0}xDPw~mqCU5 zJ}AB)hA@e59w`1?0xkx}Ko5L3D876K6u-U?D&7~tIpFaNET5Kus+V=3;%S0P_kK|E zKLJWE|K7R30IGb)FSOw<1Yvb%I|!>XcYq4_IH>%73sm@DgUa{Gi)=dQf@ffV4JiM; zp#0whDxZ&m%IDWWZ1QxvGO6csHo}`Xneme*;uLeg>)@PC%I{-Ah5q zXAuzQ1yTKprtem;bD)R)CQy8MKdAEj zIjHhK3!VfXyUb!1RD73%O0VGD-vlZ@zXy8Y=bigMfmB`Q*P!BEbfInc8^Gn*$H8O4 z4}yyC2~hR)58#QQh{T84p!l@V;W|+DQUi|y-vx^A9|9%Ee*>Z-GQV{8-ivI1aV04E zyaAjIJ_M?Ke*&Hc{ynICz5pto*%w>)i$S?x3(EZ_@Ri_)K-J423tY_bTXtZwFB+na4naW_|#Q?#vYyF9H?*8c_KtgW}iQ!IQx! zoc}kR`*Wbe&%D&iUq7gDL!k1x6QpTo_JOFB%p;)k^L_Ai@X(dE+-HO0*X5x2z612Y z+rcxzkARBzX;5ua4ys&>K!slh9s*tgs=n8OYCk1Ve0?1_2Yjn@e+;CH%RC8+FFyxW z-psJ=-;M)SzSW@WdmE_oy$+lK-T@vCz5{#(_+F4MAoDP&a(y2>44eWL@AF_Ec*qqt zA6d}k6I8iMpz`@kSfc35$p$NjM#J+gUZ)BQ2E&ndf>ed{}7ZseG@zz{4Y@Qdd8@2Kj(vz%d0@e zdmAV|JOcKD{|wFqd)C_abRwwsvIbQ98v`XzH-n;k27Cd;=SGB2SAnYPeG;gEGW5}ag|MP0F=C62&(+ofX9F>Q1ovCrEmTK z6d$HQ-^sj4q$%*RQk_?O82Lr`1|tBHl8y0JXD_|XjB=b+;QgGQ8oBtN5bUy$t1AhRjeVzVVTkn@SEP^NCey6j40Gx~cNl^9o zJg9L0?eMIvmY-LGYByUz$=7w@kzm8wZ*unALGkaMpyctxpyK@`I0O7FsCM~fQ1bW< z@KW#vQ2ZXe)~0g}sCt_Kv*14P4Dh4iE5N@7=Yih^J#Yp}>LhR;sQMUkSOi6P7kDc8 z1b9C9O=q9E-L|K5K-J4?a5;D_sCs$8;U9tu_cW+<4$0YcJ@91gD?rK7R#5VOC%6cF z0u=p^z*E3Oc3AnD14<6pf(yVVD1G+irR?{5PY?ysEv*P!xo ze!<4O9#lQ<0u|4D!E?c{fa1q*oPC~e)7=ItzT3dX;1l2~@W-Iav2YCC0qy`5-+Mr{ zzbC;#@K>PXJ%8NRR}Q=Y``w_SbNDMz@hzCJ?m6&6?C$_qfPVvC3?5gsxDiym_kxP= zPeIkg3!vKJz;!nLEuixKPEheb1@?iz0_TBe?zHZspz?nc*bjaTyafC^Q2CryvV6J% zRDHel@ zt!nu&42tenQ04tJcq#ZiDE^#Vv*9K|@#%4Ae*v6}eaZDUpF2S1`#wGVnE#F@aO0Mq#mG8dY*V}>0b+; z58ebyz8(i(0sb5u01w@3@jOuVQE>KmgG;dg1*rHB+Gq294(MUO5?lb5z(Mc#SaW6?iJ{n?Y0m&i#H+`TrcK z^#2W94ffw;>%9h^iTw`nmEgmm%JC&o_5N?5_&4ij%eRX_$>(c8rSleWKKLl8`hEsH z5uEkTtJj07zxzPt`|F_O_8Cz1^>a}5bM_rp zo~{6o#NGsFfH#AOgLi<6?_Tf{@FQRk_+#)0@E4%k!NGUh{_iC4Z0wgidlj6I{XtOa ze+4`S{2r+MKM$(BN8e@RSpXi3eKjb$*MNv@rUZ)LKLM*?&s%JMZU8At=8wS*;AMB) z^4t%qe*etbe*mgo&b-H_HxE1u`xRgxSOw>S?*dhxFM>+%+u$(x3+I2yTdjWC396j$ z168gk!Arq^1XZ5X-)8IgVsH`m3Gis}e()IZBjAPLXF>7zMbHC}e!C675L}FX9e57- z22gVFFsO2T8I)Z90GtmVLSvc>E(TSu*Mc*_n?dpUZtx`Vr74Chfn(j))kaK?SMea#1t!~IXfIrm#Y)z{tNvEchbrT3V#KLwtE{U1T4`!i5{ zI_G{nj=U07z25`Q0^bKJ{Nvzk@UOsL@Lxd1bL4w$dCvls|Bay1-41$S15`Qg1;v-g z!7IRLLGg9*1GauPf(Kzg60-&q{&4)5v()*f8Z+xe$ZrtbjycgFX#Jbn1ivO z?c6?#T|de6o1EKH5H@G7lLx=oI`?g$WUp>q?Vr~GXX1XOqY1orh!&%^@sx8s2fNzT z&5l;``5nxy*l%+*KLrc!`)J(1#P>;{+R7;|oV&`CGz_q%-mqx}s3(v^q53;Ft7 zXk)&~_p_Lf6YeKq79)K`H>(fzV-VU z_-4%S^ZfzvVa#5P`WF4h`FA>SLo!!f_)`vH0K`#$Cu<_n$RunEluzW0ESU{1w+ z3e$^uC+?%*?>O23?#3{w-s(e{Kh6;P!{$@h;5u;5TD5`n<~d zt#Iz=V&BO3Db9W`xEXUT=3@MYz+Yj$jQKare_-@G)W!2{zW>s=(5HcCVP1{j{h0NR zW}d@4@EgV4h|%w@&RyTv>kq$oSukVX5x!SI^9;Bb^AM(iUHbM@m|d6;Vv3jn++T+I z2;cvWIUJ+k|HCZBY{wMwZ-V2PTQGl(c?h>2P`@0e4>Ki8>~{||-@yJ}%)^*tF*)28 zWAt0*@WXun5VIEZG-f02XJFP~9>IPc*oQfoZ~czpyJ9~xp9VemEjS%>6z21ob1`>g zg5TwQe1fpggLi&Ii@^eiyS7zpsJ%ZNa?Te9;Ghc^7V+h z&MtTovkLc9!GFi}VlKcw3v&dfjQJ#P*ML`mU&Q1wk7MRz^g9nf{f-5{Vm~um!7DMJ z!JOgT2EluwIS%s|d|!b11HKnvT9`f9F9)y2%;Ni>Ft6u(HW>WY^YJ3)65Nk*jzfIE zmG9HQL&3Yin=ty_jQJ|&ZI~Zn&c^6B-}&qN&6wZ8{yJIs&E1o?6PS>O~3B-7QBX^uT~0;0cbYtX^?L(U#d2s8mrd5I;6#l@0D}K zO4G08DtRBejeBZ7T>d)e@X+R=rxin)eB_tJs|ID%E;9SMnOoT)o+<&F|?aqH#)2 zY}KY$%QYIis&yNG!=@OEe(qqVXLGJzDOSb@y9ws_gyFlDy~sh6#IWwK*FcX_+Wy!|fPI>#abN(9fYP}b}72L=X| z*htJ~a*!n6k9W?5-fHun3|Z*zMJcm&T0x_k3}Q+@VLX(zF_ZZ?tGpXM+QnWk+tQzc z{%p`6-`f`!6#1)GkU|)|a-xbjc{#PDur8@7e2^g8gx8$#Jtqjc0-P*1n)O_>S{Kol z-ckYC_Q#rALrXQk6N^7yEG+LWgdhFA9ANYOR^Vzstm{~v7Sua1kNgCoELv~F^2YLv z^1QuwV9~;boau{OJQD$4i;Wkph5|N`!6#FQlJD)Qw(6!4nBp0>4|WmqShDmyFi)3QMQ zi!!l!#ro0V(bZ>o-bf3H-9h{Fo7qjntBjgF!xC*rBqb`znl{}+a{~8#sR*ZB+WB0i zkGxJOsUQ{SR`v{JJLFCEq6G{%W@FXLr?$h(J20p+}e4jd}p zIZ+WYzgV$5k(dI z3T9|g*ip74ATOCvn#M(FyS#Q%D-c#)ZkGl`f2*HMYdfQwt!gXK6Xg*t^;cmDV*VQV z6#TJVtJG{HWm`l>FgC8dY=gJc-_ylgj88|te^sE^O~VW2E8QwWitg!~2s)*2JS-Oz zauLRvVDz*kodw85H0jqPosedMYxk0F22Ztmv7Dn4Or9c@t!U~@U6@qGD@wD6RCNW7 zxjQogiY~D?`FL1c)fnqy~l zRmK2yZ>*FXcZ7bu&ZLf}$Dqv1weYSqi}_qrqn)zfoT$3~G(o3!(AMnQD8kal+GZP3 zS}U~Cnr3`JnF}e$iav7<+kkC?p;z}jnL&%vF+$UpjnF&Eqj(}+NII}Fqztp8itnCg zNY(RzpS^ zsN7Nq2~iJyx@0%>53}1bAMIq3;ZYP-PYY8bPMG9ae z2ngI#BdZQ+A2Tp)cQys@Kptc_8NFHKjI@1wbcUd2*BYZ{5adpsrd@?dMq6o>{dzIa z6m^`hO0z?LSn4Z#(3v&M_L$8YNQYo%plbT+_Pnxa$YNkRucig}7J}Jf-VVuD53jOW z?(EG>x1+ZaP8Mgi05Bav&uI$dr~WTtr zwwR9SN@5kC%~&m0-e%Ux2R*AEdtEsxcBj>&HfOKjG$k#4YhGLTceIL>M{71#B?Rnk z_fK>cX)@dN-J(r`G7#DZiJ3(>yON(>VN-Cl-KdkZlyem~U0^l0=I4uO*Mirtb^YE#z*5$Rv`x}MfQ?V* z{-#yQ?O@8r9K%f0Y*j>EUCKLPR&4f{qDa(0r+7Nf#-d1!_q53vimu7nHAK_Fx?w}0 z4w4;D;7VIT^N0E`aF%+vbsBf+NEWTXy2Xo*U3cIY@3{lFu;Y%UYS%$jnfX?oSz)uZ zhZ-7Zi;PBWbEf?p6pUFTlFEuLM(>xP(`t1X-^%qvD>e>oyL|1)kkN&WR;^a8oAGk3 zBkl73~i&$E84JvnFZf4%RQJ;BpRIqvTGAr_V zzrk8=)oZl$w>gnx=_H?L^P%aj8X6rQT7?RM$~X*Zchc(CRa&6xzlL9SWF)(aM*~*a zSzo|rB8z0;(p(|Ti8#ofNM@y58rGD+Zo@?*5(3-70YqZ9oj7}sJ6}ZEAzJjm&P5+VNROfxS14Ef;5O8&f**F%vxm zo0R2NS)+nprn__)kyT>n_UGpItcx0Uj`EdvFfua38VxdP^ya3c({?n)mkMADgaH)m z(e!_I_^h4zWIoulYx(m%IHrM*`r&4aJ!i2{S#?W|zhx*FO!DN81B^s_|K3QoKo34t znJm_;6*Kg&qG`q`0Ip_D$aJ|1t*mI_F_agyZGDdl(@xjc`Z|-fM`bqfl$sS-)meC) zBC~q^+D+@0Gb8NDNa>myjSg32hDTSd+&FwS?xGlW$1?_JIBUL22f^-in5g)>-OSU5 z-A18pD>_r5@OCTJoNeQdCVI5!z@nwWc6!1+ zbTmghHfUQpv&MY0fM;``8F8W+rnX|-4;)=lN1QMxNvxwIG5twTW|RfIfQl_@S!>ab z^=LIST8&26^G*Mwx?y;1&V`stSRf+Kdz1$B5d^n0AS1$k;vm!HxUU`Y;9{z|C$pAO zR}hqptVP!9nILCgtoPb%JM)yE-x!<`IR!Nzxg;0s!eb-|WtawyTnB67PT|r*0X4O! z){Lnux9%RJCfDoILwtE#eL+(}A(*~>?dH+2s2(Q^l6fP@dOvH)<0^{i*9Y^RprbZt z7$SweJ~~yD*>L&Lnl+|~F)#v$zBHKjf=!D^O!JSd^jK7y z`g3~=b2+o*nwrg=^BeQVIIL#Q!`UNFIw4jqZ>vZ8E;D)+x#lKYG1`npNnRsELWIK);R6-@9dNtpJvu~;G4;<=h8=IQ9t ze(vC#$&XpbNfS(t8NY08?>HY;Nhk6cBiP%h9SF_dM(3!Cl^UxsQ3lNU$vrxXHm0*@ zd2gTCgVIEZC!{9B5&e8mhgGVv9z$ctVC_Qfn_#ARL1S^aj>(z%T*EL`r{vlQLyF6E zzAXOh5acrYJWla6ICJCrWR8p3h+Qw`I@`de{*$hg!w>9UvYJqEXEt@Tv|86rr-rsH zGf{>xOlnyp<`c}gqaGj(Bx!DEoT8mz9gZUt^h6A)qf@7uYpN}2eLG{-F0&cbGG}9u z#AsffgzXB5M6_l}#`gN5RsB`uRHj|UW`Ji&F^V+hu9#EZk4vHhp&b-z+{R4QL}w<& zFjXRAkKh&tlng`ZU^q677jhG5h;*o3oX!i>1@UVeLTV>SHH(yNl zZQ;l$r)Wt%;v!nCaA|yA z)Tt)zs37q6AR|NL-~^hTx!7(jOV?{VIu7iVy*|dpUO)9$9OD#R{17K=sAk`i325Z3 z!@zEdXgeV<_5vESR-JT8(Y0zNZ8QhVn`Tl$5}|X*={BFl;#N1`bnu|GrD~PgqAh2z zJZ@1d6;{@bH1DYHHcLkJOyup3A4u5oHXdk#02`U0Ne(h8EqLr*c>SzD_Qc%jU|l11 zt_;@ZOUTSAWu_b0J+HCTFPTwXAf=kxcup+w$OIb)HbE)uVCy02W7MIlp(hLyGNx0g z1Z$@um^Knqz*x#g{W0+5EIEo!90@ljV23$%sljA>S>nDOQ#6il@D+TAEAjn7GV^0g z@p43y49@bnZ+L$K;Zc~k!HYIM)GG{E9Gs{8iV@Z}lB#kub zpc!rGq9g5gq!~C7Q8HARiUS0rL*<5ydz+tceL6ok<*$#lnd zxD|{UV*c6OUPViPqqF4<&vLumb>U z^<1UFQRgZXt*dnypQY^ejFswzBHjCi92l3=B^>IhmIhdSyQpUkllB&qt?WiWS3b}{ zBf}#@QPCC+EbP(61!B(X9?T#cp1Ye1xa?D`EHi6=ELScsHmcbrOU_%GT@(>3w_|=i zJH+CQ&P@$^OLi0)RvzGWq#UOVZR4m^Ta$jS#jLB0j6}iZ>&EQ*3@gSFUi-3*YT!J|x(_R=NK&p9xJ9Jg=9r}Ga~?gtc3_L{ z)U_o=>}j+?ZD}GsrTaxN7g=GDK&*^DDs1matO`?bS#AWe*Oq+5eoCS}#SqEdUwV#n zesH-w<<&H-qt8`c1s9icHU9?1=x#0<65U;zDj@#ky)eZQ!a5Ry8rLNzU0%XfS-63< zS+C482k9$ClR2~6XJRSk;%UvLT$!E~tc^Cg1K^vL(!pftMiI_(^p4$?rpXr3KSQ#n zZf)jEecZl+hPmeTEv*Qbe^mC9x17Wn3e>7Mv-x5@-zqkz*h9)%7Tetxtr%77MOcKi zxJgRt!jloK-}=TA+pWx$5FalayYf^m$5KPIxbb8PL+fwFFFvImjrKt!g*hcG7oZM= zjO#BEnbY;Dm^hfRKN5E_>SxVV(BNVe9%?FFj56&n%IA&K+>5f@klZ4az3yHVdJf^Z zfuVF*?{NV`q{B;662HFKxB?!U(-Mfg$m}&Kop8@_aWSw{FZBH{@vhV}NH5US^iXPfA?qkE-<3Y; z4BDZXXXkll{axIUH?4v;-kL<6jHKGE25F*+-LKL`7E)wa*lgX98ykg<(!_|KVl16V zR@>q6LuO1_?Om%W#_lEo{v<*mF=DF~aW5Hr2hu3=NKHx!<$ltHUz|ycB@-5yQ52WO zI$pgBcoHKq!vcmTQFe1RQ)%Le*!zrUFJV=fDU^Ki(~t&tu+;K{J6J=T*2{O$8)kum zn@>6cL1_z9_DB#KcCxCB8!kB2X0(B=vt+nFfA^FwXPMTbNQY3`=r+}?Wt`!O%g$(A z9Nbkc{MYymDP1~=KxcE@(`=12YFv7CWn`e=Xyo?L#C+|WI1x%*)vEhrt;Q4zK{<&n z+&lN60PX3yAwS7B=yeQ7k#lpQYf7sFhM9I!!Dl44#*0F`jKw;JQj48W#yB=Fn<8!I z5rH;-DwUS?TXFT!`i;XIHVlmnjcz={TjfvIbL^o1NOjQdzL#26Ld0xO#F|d*0tB3; z^NLlm9aFNn0-Nhq4&p!8)SyFb*E)`vmI^>sx|(f|%=tOy!~^#EV`J#_cW&c1p zy3%rjmo-D8vC1PSem#&!AS>henl>4r)y!aH{}P6{EZ`R$;;*0zCQC zKUt*%Hk)Z0FEdn<#x%W|yO!4>lJ)|r>46n^mcgE^XS9#%41?y(21xDK0?TduDBQ-?3#$ z(DJ3JhS|vLz?p76Mwh&GO`}aMr?MC6+GH!X_17`AC`h1X_g9z>Ar3U=u;#nwJIq8{ zRt_{o2k!ULk#Jru-nDj?3K}KT2GcpjX5Qil>OGhVnX8)!R%Z!h`$RADn6wf?NK5LR zsJfT7o^F42(7AsMmT}w07G2ZWpFnjO!5>u3T%k3&9eF)-p;}I!c6sMGmP<^T~?Z zl&+GZJo{s zy#vWW)Yik=*3wFz6<@RQz^1(&H=A3xQ(Xij=m)jN4Rc~WboX}B3a6;4P#ttug0bq*I}L%2HZ!o_lDb}ZS*D|Jbt zncCZovPX5yac>0hspac#e&LO1?ru!g%~Nchv&=TTxMg=tyTxYrHM&KB;z`ZvsHP|? z$AG9*=z#sCXLTk=!P+K~!5q-ttCoBk{rZ2TbqfWd2Cyq8F6UiS2tuXSBMvOE*%fM= zj@aRCRH`%sUSg6{`3VNSRIqsvt-U<9Xvw;YCvN>ionV`MoFLdHj*o5F7piER*xZ9o z)=-!qbH7{piANTnmod$W?I93Lp&D!%l-NX{itXw3p*8Hzj=k)yB<@Qz}dkLG@tW{UobPF`xu@$W*d@V zu3^)0J~54;e4;Sy#+KKg_vy{BOfhCrKTmFA#F6@-UZVv`v)+zNd8(|X5tm5H)vgt! z?})>&Y3ULjO?Wdcf}P;bdw~uQPt5SabFw?t~gb>Zdz~I+x8R$9@u9qqUuqv zZgp(Xx4hI~$$61G52;mOM3G!1y5nF;t1_i4tLiRz+es_Q_KNv|lLwV?fU*0$i|g*3 zA9xz(@;T&*HD0Y-Pc^4BGI9f>WlWRJcIFLcrtY#fLDdP>C}jskEa#^Nt->v~_^$4GvNC1jDA-CVBU0qs7m(PKlxnBTDBy z*m#aQ({L}N8)^6SQX%M=J8wox5E9y$fGcB*j>&}tQA?@BDX7WVsLGyJV`YW4BGUt> z$y@Z*x+Y3Y_OenJs(2mSn1b15dk*O5Vp&M&!Z7xDrS<80K+BBiefySxAxp+$hKIU= zUm0s-rd^grjPWl`nOnOot6A=to}E2t^SD6p*1%Y`Vn$09KikX}OWcf#=cmiQREmbn zA@mm--!^E-yz5;ra4$QyQpwqF^DqHt)shbqNKct@wmm4CU~Tv?fvPt4FoCi5M2Fkv z4tSf)!6D*O9#BMjnSfKvdaRo0wSP_5z@s_2>spO`tK=`>CZ+xA;W#ivOoQq2bcSh& zO+w5rd5%ARc%No>p0ZU!De$VPDN%hqWwh?pa4Zbz}l#zN#M)L`@f2Zl zN=XKSt5nP*w7~`;BO*@!$K@tVKkyA0Ur)rSN}tahO!sE2Bap*1B>aMTrD9IE-P-5P|_XXps6J!ERywr*zF2)t$4 zxv@_<2e&OG%F&|`=^99;<4&-Kk$0ok#0J$BRO@hwnUXnmV2|NiPP3feh=y|^TQgm$ z17cTDuH5Ri2o~=tLf8ULuV_Y{akBU*L8BJ5pV?lVb^y+0YWJ{2my^D(|6pCf%_02^ zWA@-1ZK&>HldkA_;TscE?2`NO!=~;ML+p)-7>Qel+HT*NhZz)P$T&=Vk+O4O5E8SmJGh zOE8JNn0p+_^me7wn@FaYj3DvWggNn-cx}SCaM#Z~F|pZ8PMJ+7-+g53@sQL2^W!d}yM>ixfu2+9?A@hu(UV zBDj?U`2jsjVg5x{qQ2;}&74E5(^gDdGO325c~OwKiFGwl>8; z7EJ4@stIbnb8r(gJ239(H|yC(aT&(7r4Ty4>4uc%*^TR4x)|luU+7|MPYlsN`|IY9Uk_o{ZCDg+w!&QYrFaSsqv4o%){}AGsnc_9_ml{XSeW-Y!Vvc0sYXu3mL{+fyT?1s zN;>;kZc#S%gopE0i%o9XYiMRz$-58sIS(du+qC^=9)d`{=P{Ok&LiNtF8swfX@_O; z*|_@2sMbvN$Gu%Vk&~^wSd>8pg!MQL?EzI}6uu{8a+grbZ8;3y0txFndK9E5MOPE&frht$g`KlxMv*5@eKmg=yxwk-(|bdn0C~ovOD;qs1N{ ziCC-pFe9&M8A?vc{m8Z`%_%QNK5kwUUjal%B}NivdMq`hS4!YzI%#{#!wIECwvB?o OZ0G6KEEZSV^7g-ncve#Y literal 0 HcmV?d00001 diff --git a/current/po/fr.po b/current/po/fr.po new file mode 100644 index 00000000..0af05aee --- /dev/null +++ b/current/po/fr.po @@ -0,0 +1,2417 @@ +# shadow fr.po +# Copyright (C) 1999 Free Software Foundation, Inc. +# Vincent Renardias , 1999 +# Patches, suggestions, etc welcome. +# +msgid "" +msgstr "" +"Project-Id-Version: shadow 19990709\n" +"POT-Creation-Date: 2000-09-02 20:40+0200\n" +"PO-Revision-Date: 1999-07-09 20:02+0200\n" +"Last-Translator: Vincent Renardias \n" +"Language-Team: Vincent Renardias \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libmisc/addgrps.c:60 +#, c-format +msgid "Warning: unknown group %s\n" +msgstr "Avertissement: le groupe %s est inconnu\n" + +#: libmisc/addgrps.c:71 +msgid "Warning: too many groups\n" +msgstr "Avertissement: trop de groupes\n" + +#: libmisc/age.c:104 +msgid "Your password has expired." +msgstr "Votre mot de passe a expiré." + +#: libmisc/age.c:107 +msgid "Your password is inactive." +msgstr "Votre mot de passe est désactivé." + +#: libmisc/age.c:110 +msgid "Your login has expired." +msgstr "Votre compte a expiré." + +#: libmisc/age.c:127 +msgid " Contact the system administrator.\n" +msgstr " Contactez l'administrateur système.\n" + +#: libmisc/age.c:130 +msgid " Choose a new password.\n" +msgstr " Choisissez un nouveau mot de passe.\n" + +#: libmisc/age.c:228 +#, c-format +msgid "Your password will expire in %ld days.\n" +msgstr "Votre mot de passe expirera dans %ld jours.\n" + +#: libmisc/age.c:230 +msgid "Your password will expire tomorrow.\n" +msgstr "Votre mot de passe expirera demain.\n" + +#: libmisc/age.c:232 +msgid "Your password will expire today.\n" +msgstr "Votre mot de passe expirera aujourd'hui.\n" + +#: libmisc/chowntty.c:110 +#, c-format +msgid "Unable to change tty %s" +msgstr "Impossible de changer le tty %s" + +#: libmisc/env.c:160 +msgid "Environment overflow\n" +msgstr "Dépassement de l'environnement\n" + +#: libmisc/env.c:200 +#, c-format +msgid "You may not change $%s\n" +msgstr "Vous ne pouvez pas changer $%s\n" + +#: libmisc/failure.c:238 +#, c-format +msgid "%d %s since last login. Last was %s on %s.\n" +msgstr "%d %s depuis la dernière connexion. La dernière fut le %s sur %s.\n" + +#: libmisc/failure.c:239 +msgid "failures" +msgstr "échecs" + +#: libmisc/failure.c:239 +msgid "failure" +msgstr "échec" + +#: libmisc/limits.c:397 +msgid "Too many logins.\n" +msgstr "Trop de connexions.\n" + +#: libmisc/login_desrpc.c:63 +#, c-format +msgid "Password does not decrypt secret key for %s.\n" +msgstr "Le mot de passe ne décrypte pas le clé secréte pour %s.\n" + +#: libmisc/login_desrpc.c:69 +#, c-format +msgid "Could not set %s's secret key: is the keyserv daemon running?\n" +msgstr "" +"Impossible de changer la clé secréte de %s : le daemon keyserv " +"fonctionne-t-il?\n" + +#: libmisc/mail.c:62 libmisc/mail.c:77 +msgid "You have new mail." +msgstr "Vous avez des nouveaux messages." + +#: libmisc/mail.c:73 +msgid "No mail." +msgstr "Pas de courier." + +#: libmisc/mail.c:75 +msgid "You have mail." +msgstr "Vous avez du courier." + +#: libmisc/obscure.c:281 src/passwd.c:309 +#, c-format +msgid "Bad password: %s. " +msgstr "Mauvais mot de passe: %s. " + +#: libmisc/pam_pass.c:42 +#, c-format +msgid "passwd: pam_start() failed, error %d\n" +msgstr "passwd: échec de pam_start(), erreur %d\n" + +#: libmisc/pam_pass.c:49 +#, c-format +msgid "passwd: %s\n" +msgstr "passwd: %s\n" + +#: libmisc/setupenv.c:205 +#, c-format +msgid "Unable to cd to \"%s\"\n" +msgstr "Impossible d'aller dans \"%s\"\n" + +#: libmisc/setupenv.c:213 +msgid "No directory, logging in with HOME=/" +msgstr "Pas de répertoire, connexion avec HOME=/" + +#: libmisc/shell.c:78 +#, c-format +msgid "Executing shell %s\n" +msgstr "Exécution du shell %s\n" + +#. +#. * Obviously something is really wrong - I can't figure out +#. * how to execute this stupid shell, so I might as well give +#. * up in disgust ... +#. +#: libmisc/shell.c:122 +#, c-format +msgid "Cannot execute %s" +msgstr "Impossible d'exécuter %s" + +#: libmisc/suauth.c:99 +msgid "Access to su to that account DENIED.\n" +msgstr "Accès à su à partir de ce compte REFUSÉ.\n" + +#: libmisc/suauth.c:106 +msgid "Password authentication bypassed.\n" +msgstr "Authentification par mot de passe court-circuitée.\n" + +#: libmisc/suauth.c:113 +msgid "Please enter your OWN password as authentication.\n" +msgstr "Entrez VOTRE mot de passe comme identification.\n" + +#: libmisc/sub.c:61 +#, c-format +msgid "Invalid root directory \"%s\"\n" +msgstr "Répertoire root \"%s\" non valide\n" + +#: libmisc/sub.c:73 +#, c-format +msgid "Can't change root directory to \"%s\"\n" +msgstr "Impossible de changer le répertoire racine en \"%s\"\n" + +#: libmisc/xmalloc.c:28 +#, c-format +msgid "malloc(%d) failed\n" +msgstr "échec de malloc(%d)\n" + +#: lib/dialchk.c:71 +msgid "Dialup Password: " +msgstr "Mot de passe dialup : " + +#: lib/getdef.c:253 +msgid "Could not allocate space for config info.\n" +msgstr "Impossible d'allouer l'espace pour l'information sur la conf.\n" + +#. +#. * Item was never found. +#. +#: lib/getdef.c:307 +#, c-format +msgid "configuration error - unknown item '%s' (notify administrator)\n" +msgstr "" +"erreur de configuration - élément '%s' inconnu (avertissez " +"l'administrateur)\n" + +#: lib/getdef.c:394 +#, c-format +msgid "error - lookup '%s' failed\n" +msgstr "erreur - échec de la recherche de '%s'\n" + +#: lib/getdef.c:402 +#, c-format +msgid "%s not found\n" +msgstr "%s non trouvé\n" + +#. +#. * get the password from her, and set the salt for +#. * the decryption from the group file. +#. +#: lib/pwauth.c:54 src/newgrp.c:305 +msgid "Password: " +msgstr "Mot de passe: " + +#: lib/pwauth.c:56 +#, c-format +msgid "%s's Password: " +msgstr "Mot de passe de %s: " + +#: lib/pwauth.c:270 +msgid "(Echo on) " +msgstr "" + +#: lib/strerror.c:20 +#, c-format +msgid "Unknown error %d" +msgstr "Erreur %d inconnue" + +#: src/chage.c:156 +#, c-format +msgid "" +"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n" +" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n" +msgstr "" +"Usage: %s [ -l ] [ -m min_jourss ] [ -M max_jours ]\n" +" [ -W avertissement ] [ -I inactif ] [ -E expire ] [ -d dernier_jour ]\n" +" utilisateur\n" + +#: src/chage.c:158 +#, c-format +msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n" +msgstr "" +"Usage: %s [ -l ] [ -m min_jours ] [ -M max_jours ] [ -d dernier_jour ] " +"utilisateur\n" + +#: src/chage.c:193 +msgid "" +"Enter the new value, or press return for the default\n" +"\n" +msgstr "" +"Entrez la nouvelle valeur ou tapes Entrée pour la valeur par défaut\n" +"\n" + +#: src/chage.c:196 +msgid "Minimum Password Age" +msgstr "Age minimum du mot de passe" + +#: src/chage.c:201 +msgid "Maximum Password Age" +msgstr "Age maximum du mot de passe" + +#: src/chage.c:207 +msgid "Last Password Change (YYYY-MM-DD)" +msgstr "Dernier changement de mot de passe (YYYY-MM-DD)" + +#: src/chage.c:216 +msgid "Password Expiration Warning" +msgstr "Avertissement d'expiration de mot de passe" + +#: src/chage.c:221 +msgid "Password Inactive" +msgstr "Mot de passe désactivé" + +#: src/chage.c:227 +msgid "Account Expiration Date (YYYY-MM-DD)" +msgstr "Date d'expiration du compte (YYYY-MM-DD)" + +#. +#. * Start with the easy numbers - the number of days before the +#. * password can be changed, the number of days after which the +#. * password must be chaged, the number of days before the +#. * password expires that the user is told, and the number of +#. * days after the password expires that the account becomes +#. * unusable. +#. +#: src/chage.c:281 +#, c-format +msgid "Minimum:\t%ld\n" +msgstr "Minimum :\t%ld\n" + +#: src/chage.c:282 +#, c-format +msgid "Maximum:\t%ld\n" +msgstr "Maximum :\t%ld\n" + +#: src/chage.c:284 +#, c-format +msgid "Warning:\t%ld\n" +msgstr "Avertissement :\t%ld\n" + +#: src/chage.c:285 +#, c-format +msgid "Inactive:\t%ld\n" +msgstr "Désactivé :\t%ld\n" + +#. +#. * The "last change" date is either "Never" or the date the +#. * password was last modified. The date is the number of +#. * days since 1/1/1970. +#. +#: src/chage.c:294 +msgid "Last Change:\t\t" +msgstr "Dernier changement :\t\t" + +#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340 +msgid "Never\n" +msgstr "Jamais\n" + +#. +#. * The password expiration date is determined from the last +#. * change date plus the number of days the password is valid +#. * for. +#. +#: src/chage.c:308 +msgid "Password Expires:\t" +msgstr "Expiration du mot de passe :\t" + +#. +#. * The account becomes inactive if the password is expired +#. * for more than "inactdays". The expiration date is calculated +#. * and the number of inactive days is added. The resulting date +#. * is when the active will be disabled. +#. +#: src/chage.c:324 +#, fuzzy +msgid "Password Inactive:\t" +msgstr "Mot de passe désactivé" + +#. +#. * The account will expire on the given date regardless of the +#. * password expiring or not. +#. +#: src/chage.c:338 +#, fuzzy +msgid "Account Expires:\t" +msgstr "Expiration du mot de passe :\t" + +#: src/chage.c:486 +#, c-format +msgid "%s: do not include \"l\" with other flags\n" +msgstr "%s : ne pas include \"l\" avec les autres drapeaux\n" + +#: src/chage.c:498 src/chage.c:610 src/login.c:529 +#, c-format +msgid "%s: permission denied\n" +msgstr "%s : permission refusée\n" + +#: src/chage.c:510 src/chpasswd.c:120 +#, c-format +msgid "%s: can't lock password file\n" +msgstr "%s: impossible de vérouiller de fichier de mots de passe\n" + +#: src/chage.c:516 src/chpasswd.c:124 +#, c-format +msgid "%s: can't open password file\n" +msgstr "%s: impossible d'ouvrir le fichier de mots de passe\n" + +#: src/chage.c:523 +#, c-format +msgid "%s: unknown user: %s\n" +msgstr "%s: utilisateur inconnu: %s\n" + +#: src/chage.c:542 +#, c-format +msgid "%s: can't lock shadow password file\n" +msgstr "%s : impossible de vérouiller le fichier shadow password\n" + +#: src/chage.c:549 +#, c-format +msgid "%s: can't open shadow password file\n" +msgstr "%s : impossible d'ouvrir le fichier shadow password\n" + +#: src/chage.c:631 +#, c-format +msgid "Changing the aging information for %s\n" +msgstr "Changement des informations sur l'age pour %s\n" + +#: src/chage.c:633 +#, c-format +msgid "%s: error changing fields\n" +msgstr "%s : erreur lors du changement des champs\n" + +#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183 +#, c-format +msgid "%s: can't update password file\n" +msgstr "%s : impossible de mettre à jour le fichier passwd\n" + +#: src/chage.c:690 src/pwunconv.c:178 +#, c-format +msgid "%s: can't update shadow password file\n" +msgstr "%s : impossible de mettre à jour le fichier shadow password\n" + +#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409 +#: src/passwd.c:825 src/passwd.c:926 +msgid "Error updating the DBM password entry.\n" +msgstr "Erreur durant la mise à jour de l'entrée du mot de passe DBM.\n" + +#: src/chage.c:771 +#, c-format +msgid "%s: can't rewrite shadow password file\n" +msgstr "%s : impossible de re-écrire le fichier shadow password\n" + +#: src/chage.c:785 +#, c-format +msgid "%s: can't rewrite password file\n" +msgstr "%s : impossible de re-écrire le fichier password\n" + +#: src/chage.c:836 +#, c-format +msgid "%s: no aging information present\n" +msgstr "%s : aucune information sur l'age\n" + +#: src/chfn.c:107 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n" +"\t[ -h home_ph ] [ -o other ] [ user ]\n" +msgstr "" +"Usage: %s [ -f nom_complet ] [ -r no_bureau ] [ -w tel_bureau ]\n" +"\t[ -h tel_perso ] [ -o autre ] [ utilisateur ]\n" + +#: src/chfn.c:111 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n" +msgstr "Usage: %s [ -f nom_complet ] [ -w no_bureau ] [ -h tel_bureau ]\n" + +#: src/chfn.c:163 src/chsh.c:119 +msgid "Enter the new value, or press return for the default\n" +msgstr "Entrez la nouvelle valeur ou tapez Entrée pour le défaut\n" + +#: src/chfn.c:166 +msgid "Full Name" +msgstr "Nom complet" + +#: src/chfn.c:168 +#, c-format +msgid "\tFull Name: %s\n" +msgstr "\tNom complet : %s\n" + +#: src/chfn.c:171 +msgid "Room Number" +msgstr "No de bureau" + +#: src/chfn.c:173 +#, c-format +msgid "\tRoom Number: %s\n" +msgstr "\tNo de bureau : %s\n" + +#: src/chfn.c:176 +msgid "Work Phone" +msgstr "Téléphone travail" + +#: src/chfn.c:178 +#, c-format +msgid "\tWork Phone: %s\n" +msgstr "\tTéléphone travail : %s\n" + +#: src/chfn.c:181 +msgid "Home Phone" +msgstr "Téléphone perso" + +#: src/chfn.c:183 +#, c-format +msgid "\tHome Phone: %s\n" +msgstr "\tTéléphone perso : %s\n" + +#: src/chfn.c:186 +msgid "Other" +msgstr "Autre" + +#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330 +#: src/chfn.c:391 src/passwd.c:1226 +#, c-format +msgid "%s: Permission denied.\n" +msgstr "%s: Permission refusée.\n" + +#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277 +#, c-format +msgid "%s: Unknown user %s\n" +msgstr "%s: Utilisateur %s inconnu\n" + +#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207 +#, c-format +msgid "%s: Cannot determine your user name.\n" +msgstr "%s: Impossible de déterminer votre nom d'utilisateur.\n" + +#: src/chfn.c:373 src/chsh.c:250 +#, c-format +msgid "%s: cannot change user `%s' on NIS client.\n" +msgstr "%s: impossible de changer l'utilisateur `%' sur le client NIS.\n" + +#: src/chfn.c:378 src/chsh.c:257 +#, c-format +msgid "%s: `%s' is the NIS master for this client.\n" +msgstr "%s: `%s' est le maître NIS pour ce client.\n" + +#: src/chfn.c:453 +#, c-format +msgid "Changing the user information for %s\n" +msgstr "Changement de l'information utilisateur pour %s\n" + +#: src/chfn.c:462 +#, c-format +msgid "%s: invalid name: \"%s\"\n" +msgstr "%s : nom non valide : \"%s\"\n" + +#: src/chfn.c:467 +#, c-format +msgid "%s: invalid room number: \"%s\"\n" +msgstr "%s : no de bureau non valide : \"%s\"\n" + +#: src/chfn.c:472 +#, c-format +msgid "%s: invalid work phone: \"%s\"\n" +msgstr "%s : téléphone du bureau non valide : \"%s\"\n" + +#: src/chfn.c:477 +#, c-format +msgid "%s: invalid home phone: \"%s\"\n" +msgstr "%s : téléphone perso non valide : \"%s\"\n" + +#: src/chfn.c:482 +#, c-format +msgid "%s: \"%s\" contains illegal characters\n" +msgstr "%s : \"%s\" contient des caractères non valide\n" + +#: src/chfn.c:494 +#, c-format +msgid "%s: fields too long\n" +msgstr "%s: champs trop longs\n" + +#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388 +msgid "Cannot change ID to root.\n" +msgstr "Impossible de changer l'ID en root.\n" + +#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880 +msgid "Cannot lock the password file; try again later.\n" +msgstr "" +"Impossible de vérouiller le fichier de mots de passe; essayez plus tard.\n" + +#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885 +msgid "Cannot open the password file.\n" +msgstr "Impossible d'ouvrir le fichier de mots de passe.\n" + +#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313 +#, c-format +msgid "%s: %s not found in /etc/passwd\n" +msgstr "%s: %s non trouvé dans /etc/passwd\n" + +#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920 +#: src/passwd.c:960 +msgid "Error updating the password entry.\n" +msgstr "Erreur durant la mise à jour du mot de passe.\n" + +#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933 +msgid "Cannot commit password file changes.\n" +msgstr "Impossible de valider le changement de mot de passe.\n" + +#: src/chfn.c:592 src/chsh.c:431 +msgid "Cannot unlock the password file.\n" +msgstr "Impossible de dévérouiller le fichier de mots de passe.\n" + +#: src/chpasswd.c:76 +#, c-format +msgid "usage: %s [-e]\n" +msgstr "usage: %s [-e]\n" + +#: src/chpasswd.c:132 src/pwconv.c:104 +#, c-format +msgid "%s: can't lock shadow file\n" +msgstr "%s: impossible de vérouiller le fichier shadow\n" + +#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118 +#: src/pwunconv.c:123 +#, c-format +msgid "%s: can't open shadow file\n" +msgstr "%s: impossible d'ouvrir le fichier shadow\n" + +#: src/chpasswd.c:159 src/newusers.c:415 +#, c-format +msgid "%s: line %d: line too long\n" +msgstr "%s: ligne %d: ligne trop longue\n" + +#: src/chpasswd.c:179 +#, c-format +msgid "%s: line %d: missing new password\n" +msgstr "%s: ligne %d: nouveau mot de passe manquant\n" + +#: src/chpasswd.c:195 +#, c-format +msgid "%s: line %d: unknown user %s\n" +msgstr "%s: ligne %d: utilisateur %s inconnu\n" + +#: src/chpasswd.c:247 +#, c-format +msgid "%s: line %d: cannot update password entry\n" +msgstr "%s: ligne %d: impossible de mettre le mot de passe à jour\n" + +#: src/chpasswd.c:263 src/newusers.c:535 +#, c-format +msgid "%s: error detected, changes ignored\n" +msgstr "%s: erreur détectée; changements ignorés\n" + +#: src/chpasswd.c:274 +#, c-format +msgid "%s: error updating shadow file\n" +msgstr "%s: erreur lors de la mise à jour du fichier shadow\n" + +#: src/chpasswd.c:282 +#, c-format +msgid "%s: error updating password file\n" +msgstr "%s: erreur lors de la mise à jour du fichier de mots de passe\n" + +#: src/chsh.c:105 +#, c-format +msgid "Usage: %s [ -s shell ] [ name ]\n" +msgstr "Usage: %s [ -s shell ] [ nom ]\n" + +#: src/chsh.c:120 +msgid "Login Shell" +msgstr "Shell de login" + +#: src/chsh.c:273 src/chsh.c:286 +#, c-format +msgid "You may not change the shell for %s.\n" +msgstr "Vous ne pouvez pas changer le shell de %s.\n" + +#: src/chsh.c:315 +#, c-format +msgid "Changing the login shell for %s\n" +msgstr "Changement du shell de login pour %s\n" + +#: src/chsh.c:327 +#, c-format +msgid "%s: Invalid entry: %s\n" +msgstr "%s: Entrée non valide : %s\n" + +#: src/chsh.c:332 +#, c-format +msgid "%s is an invalid shell.\n" +msgstr "%s n'est pas un shell valide.\n" + +#: src/dpasswd.c:69 +#, c-format +msgid "Usage: %s [ -(a|d) ] shell\n" +msgstr "Usage: %s [ -(a|d) ] shell\n" + +#: src/dpasswd.c:134 +msgid "Shell password: " +msgstr "Mot de passe shell : " + +#: src/dpasswd.c:140 +msgid "re-enter Shell password: " +msgstr "Confirmez le mot de passe shell : " + +#: src/dpasswd.c:147 +#, c-format +msgid "%s: Passwords do not match, try again.\n" +msgstr "%s : Les mots de passe ne correspondent pas, essayez encore.\n" + +#: src/dpasswd.c:167 +#, c-format +msgid "%s: can't create %s" +msgstr "%s: impossible de créer %s" + +#: src/dpasswd.c:172 +#, c-format +msgid "%s: can't open %s" +msgstr "%s : impossible d'ouvrir %s" + +#: src/dpasswd.c:200 +#, c-format +msgid "%s: Shell %s not found.\n" +msgstr "%s : Shell %s non trouvé.\n" + +#: src/expiry.c:84 +msgid "Usage: expiry { -f | -c }\n" +msgstr "Usage : expiry { -f | -c }\n" + +#: src/expiry.c:137 +#, c-format +msgid "%s: WARNING! Must be set-UID root!\n" +msgstr "%s: AVERTISSEMENT! Devrait être set-UID root!\n" + +#: src/expiry.c:148 +#, c-format +msgid "%s: unknown user\n" +msgstr "%s : utilisateur inconnu\n" + +#: src/faillog.c:79 +#, c-format +msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n" +msgstr "usage: %s [-a|-u utilisateur] [-m max] [-r] [-t jours] [-l sec_ver]\n" + +#: src/faillog.c:134 src/lastlog.c:94 +#, c-format +msgid "Unknown User: %s\n" +msgstr "Utilisateur %s inconnu\n" + +#: src/faillog.c:215 +msgid "Username Failures Maximum Latest\n" +msgstr "Utilisateur Échecs Maximum Dernier\n" + +#: src/faillog.c:232 +#, c-format +msgid " %s on %s" +msgstr " %s sur %s" + +#: src/faillog.c:236 +#, c-format +msgid " [%lds left]" +msgstr " [%lds restant]" + +#: src/faillog.c:239 +#, c-format +msgid " [%lds lock]" +msgstr " [%lds verrou]" + +#: src/gpasswd.c:89 +#, c-format +msgid "usage: %s [-r|-R] group\n" +msgstr "usage: %s [-r|-R] groupe\n" + +#: src/gpasswd.c:90 +#, c-format +msgid " %s [-a user] group\n" +msgstr " %s [-a utilisateur] groupe\n" + +#: src/gpasswd.c:91 +#, c-format +msgid " %s [-d user] group\n" +msgstr " %s [-d utilisateur] groupe\n" + +#: src/gpasswd.c:93 +#, c-format +msgid " %s [-A user,...] [-M user,...] group\n" +msgstr " %s [-A utilisateur,...] [-M utilisateur,...] groupe\n" + +#: src/gpasswd.c:96 +#, c-format +msgid " %s [-M user,...] group\n" +msgstr " %s [-M utilisateur,...] groupe\n" + +#: src/gpasswd.c:160 src/gpasswd.c:245 +#, c-format +msgid "%s: unknown user %s\n" +msgstr "%s : utilisateur %s inconnu\n" + +#: src/gpasswd.c:172 +msgid "Permission denied.\n" +msgstr "Permission refusée.\n" + +#: src/gpasswd.c:257 +#, c-format +msgid "%s: shadow group passwords required for -A\n" +msgstr "%s : mots de passe shadow nécessaires pour -A\n" + +#: src/gpasswd.c:308 +msgid "Who are you?\n" +msgstr "Qui êtes vous?\n" + +#: src/gpasswd.c:328 src/newgrp.c:251 +#, c-format +msgid "unknown group: %s\n" +msgstr "groupe inconnu : %s\n" + +#: src/gpasswd.c:436 +#, c-format +msgid "Adding user %s to group %s\n" +msgstr "Ajout de l'utilisateur %s au groupe %s\n" + +#: src/gpasswd.c:453 +#, c-format +msgid "Removing user %s from group %s\n" +msgstr "Retrait de l'utilisateur %s du groupe %s\n" + +#: src/gpasswd.c:466 +#, c-format +msgid "%s: unknown member %s\n" +msgstr "%s : membre %s inconnu\n" + +#: src/gpasswd.c:513 +#, c-format +msgid "%s: Not a tty\n" +msgstr "%s : N'est pas un tty\n" + +#. +#. * A new password is to be entered and it must be encrypted, +#. * etc. The password will be prompted for twice, and both +#. * entries must be identical. There is no need to validate +#. * the old password since the invoker is either the group +#. * owner, or root. +#. +#: src/gpasswd.c:535 +#, c-format +msgid "Changing the password for group %s\n" +msgstr "Changement du mot de passe pour le group %s\n" + +#: src/gpasswd.c:538 +msgid "New Password: " +msgstr "Nouveau mot de passe : " + +#: src/gpasswd.c:543 src/passwd.c:422 +msgid "Re-enter new password: " +msgstr "Nouveau mot de passe (à nouveau) : " + +#: src/gpasswd.c:555 +msgid "They don't match; try again" +msgstr "Ils ne sont pas identiques; essayez à nouveau" + +#: src/gpasswd.c:559 +#, c-format +msgid "%s: Try again later\n" +msgstr "%s: Essayez à nouveau plus tard\n" + +#: src/gpasswd.c:590 +#, c-format +msgid "%s: can't get lock\n" +msgstr "%s : impossible d'obtenir le verrou\n" + +#: src/gpasswd.c:596 +#, c-format +msgid "%s: can't get shadow lock\n" +msgstr "%s : impossible d'obtenir le verrou sur shadow\n" + +#: src/gpasswd.c:602 +#, c-format +msgid "%s: can't open file\n" +msgstr "%s : impossible d'ouvrir le fichier\n" + +#: src/gpasswd.c:614 +#, c-format +msgid "%s: can't update entry\n" +msgstr "%s : impossible de mettre à jour l'entrée\n" + +#: src/gpasswd.c:620 +#, c-format +msgid "%s: can't update shadow entry\n" +msgstr "%s : impossible de mettre à jour l'entrée shadow\n" + +#: src/gpasswd.c:626 +#, c-format +msgid "%s: can't re-write file\n" +msgstr "%s : impossible de re-écrire le fichier\n" + +#: src/gpasswd.c:632 +#, c-format +msgid "%s: can't re-write shadow file\n" +msgstr "%s : impossible de re-écrire le fichier shadow\n" + +#: src/gpasswd.c:640 +#, c-format +msgid "%s: can't unlock file\n" +msgstr "%s : impossible de dévérouiller le fichier\n" + +#: src/gpasswd.c:645 +#, c-format +msgid "%s: can't update DBM files\n" +msgstr "%s : impossible de mettre à jours les fichiers DBM\n" + +#: src/gpasswd.c:652 +#, c-format +msgid "%s: can't update DBM shadow files\n" +msgstr "%s : impossible de mettre à jours les fichiers DBM shadow\n" + +#: src/groupadd.c:105 +msgid "usage: groupadd [-g gid [-o]] group\n" +msgstr "usage: groupadd [-g gid [-o]] groupe\n" + +#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230 +#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675 +#, c-format +msgid "%s: error adding new group entry\n" +msgstr "%s : erreur durant l'addition du nouveau groupe\n" + +#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942 +#: src/usermod.c:551 src/usermod.c:687 +#, c-format +msgid "%s: cannot add new dbm group entry\n" +msgstr "%s : impossible d'ajouter une nouvelle entrée pour le groupe dbm\n" + +#: src/groupadd.c:258 src/useradd.c:996 +#, c-format +msgid "%s: name %s is not unique\n" +msgstr "%s : le nom %s n'est pas unique\n" + +#: src/groupadd.c:273 +#, c-format +msgid "%s: gid %ld is not unique\n" +msgstr "%s : le gid %ld n'est pas unique\n" + +#: src/groupadd.c:297 +#, c-format +msgid "%s: can't get unique gid\n" +msgstr "%s : impossible d'obtenir un gid unique\n" + +#. +#. * All invalid group names land here. +#. +#: src/groupadd.c:321 src/groupmod.c:341 +#, c-format +msgid "%s: %s is a not a valid group name\n" +msgstr "%s : %s n'est pas un nom de groupe valide\n" + +#: src/groupadd.c:350 src/groupmod.c:367 +#, c-format +msgid "%s: invalid group %s\n" +msgstr "%s : groupe %s non valide\n" + +#: src/groupadd.c:367 src/useradd.c:1272 +#, c-format +msgid "%s: -O requires NAME=VALUE\n" +msgstr "%s : -O requiert NAME=VALEUR\n" + +#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381 +#: src/userdel.c:303 src/usermod.c:563 +#, c-format +msgid "%s: cannot rewrite group file\n" +msgstr "%s : impossible de re-écrire le fichier group\n" + +#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389 +#: src/userdel.c:309 src/usermod.c:700 +#, c-format +msgid "%s: cannot rewrite shadow group file\n" +msgstr "%s : impossible de re-écrire le fichier shadow group\n" + +#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389 +#, c-format +msgid "%s: unable to lock group file\n" +msgstr "%s : impossible de vérouiller le fichier group\n" + +#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432 +#, c-format +msgid "%s: unable to open group file\n" +msgstr "%s : impossible d'ouvrir le fichier group\n" + +#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398 +#, c-format +msgid "%s: unable to lock shadow group file\n" +msgstr "%s : impossible de vérouiller le fichier group\n" + +#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442 +#, c-format +msgid "%s: unable to open shadow group file\n" +msgstr "%s : impossible d'ouvrir le fichier shadow group\n" + +#: src/groupadd.c:518 +#, c-format +msgid "%s: group %s exists\n" +msgstr "%s : le groupe %s existe\n" + +#: src/groupdel.c:86 +msgid "usage: groupdel group\n" +msgstr "usage: groupdel groupe\n" + +#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234 +#, c-format +msgid "%s: error removing group entry\n" +msgstr "%s : erreur lors de retrait de l'entrée du groupe\n" + +#: src/groupdel.c:116 src/groupmod.c:206 +#, c-format +msgid "%s: error removing group dbm entry\n" +msgstr "%s : erreur lors du retrait de l'entrée dbm du groupe\n" + +#: src/groupdel.c:131 +#, c-format +msgid "%s: error removing shadow group entry\n" +msgstr "%s : erreur lors du retrait de l'entrée shadow du groupe\n" + +#: src/groupdel.c:144 src/groupmod.c:252 +#, c-format +msgid "%s: error removing shadow group dbm entry\n" +msgstr "%s : erreur lors du retrait de l'entrée dbm shadow du groupe\n" + +#. +#. * Can't remove the group. +#. +#: src/groupdel.c:248 +#, c-format +msgid "%s: cannot remove user's primary group.\n" +msgstr "%s : impossible d'enlever l'utilisateur de son groupe primaire.\n" + +#: src/groupdel.c:305 src/groupmod.c:501 +#, c-format +msgid "%s: group %s does not exist\n" +msgstr "%s : le groupe %s n'existe pas\n" + +#: src/groupdel.c:319 src/groupmod.c:517 +#, c-format +msgid "%s: group %s is a NIS group\n" +msgstr "%s : le groupe %s est un groupe NIS\n" + +#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016 +#, c-format +msgid "%s: %s is the NIS master\n" +msgstr "%s : %s est le maître NIS\n" + +#: src/groupmod.c:105 +msgid "usage: groupmod [-g gid [-o]] [-n name] group\n" +msgstr "usage : groupmod [-g gid [-o]] [-n nom] groupe\n" + +#: src/groupmod.c:165 +#, c-format +msgid "%s: %s not found in /etc/group\n" +msgstr "%s : %s non trouvé dans /etc/group\n" + +#: src/groupmod.c:246 +#, c-format +msgid "%s: cannot add new dbm shadow group entry\n" +msgstr "%s : impossible d'ajouter une nouvelle entrée dbm shadow group\n" + +#: src/groupmod.c:299 +#, c-format +msgid "%s: %ld is not a unique gid\n" +msgstr "%s : %ld n'est pas un gid unique\n" + +#: src/groupmod.c:330 +#, c-format +msgid "%s: %s is not a unique name\n" +msgstr "%s : %s n'est pas un nom unique\n" + +#: src/groups.c:62 +#, c-format +msgid "unknown user %s\n" +msgstr "utilisateur %s inconnu\n" + +#: src/grpck.c:98 +#, c-format +msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n" +msgstr "Usage : %s [ -r ] ] groupe [ gshadow ] ]\n" + +#: src/grpck.c:100 +#, c-format +msgid "Usage: %s [ -r ] [ group ]\n" +msgstr "Usage: %s [ -r ] [ groupe ]\n" + +#: src/grpck.c:119 src/pwck.c:119 +msgid "No" +msgstr "Non" + +#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225 +#, c-format +msgid "%s: cannot lock file %s\n" +msgstr "%s : impossible de vérouiller le fichier %s\n" + +#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241 +#: src/pwck.c:250 +#, c-format +msgid "%s: cannot open file %s\n" +msgstr "%s : impossible d'ouvrir le fichier %s\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:298 +msgid "invalid group file entry\n" +msgstr "entrée dans le fichier group non valide\n" + +#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517 +#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517 +#: src/pwck.c:541 +#, c-format +msgid "delete line `%s'? " +msgstr "effacer la ligne `%s'? " + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:361 +msgid "duplicate group entry\n" +msgstr "entrée de groupe dupliquée\n" + +#: src/grpck.c:378 +#, c-format +msgid "invalid group name `%s'\n" +msgstr "nom de groupe `%s' non valide\n" + +#: src/grpck.c:388 +#, c-format +msgid "group %s: bad GID (%d)\n" +msgstr "groupe %s : mauvais GID (%d)\n" + +#: src/grpck.c:414 +#, c-format +msgid "group %s: no user %s\n" +msgstr "groupe %s : pas d'utilisateur %s\n" + +#: src/grpck.c:416 src/grpck.c:585 +#, c-format +msgid "delete member `%s'? " +msgstr "effacer le membre `%s'? " + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:453 +msgid "invalid shadow group file entry\n" +msgstr "entrée non valide dans le fichier shadow group\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:516 +msgid "duplicate shadow group entry\n" +msgstr "entrée dupliquée dans le fichier shadow group\n" + +#: src/grpck.c:533 +msgid "no matching group file entry\n" +msgstr "aucune entrée dans le fichier group correspondante\n" + +#: src/grpck.c:553 +#, c-format +msgid "shadow group %s: no administrative user %s\n" +msgstr "groupe shadow %s : aucun administrateur %s\n" + +#: src/grpck.c:555 +#, c-format +msgid "delete administrative member `%s'? " +msgstr "effacer le membre administrateur `%s' ?" + +#: src/grpck.c:583 +#, c-format +msgid "shadow group %s: no user %s\n" +msgstr "groupe shadow %s : aucun utilisateur %s\n" + +#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580 +#, c-format +msgid "%s: cannot update file %s\n" +msgstr "%s : impossible de mettre à jour le fichier %s\n" + +#: src/grpck.c:640 src/pwck.c:606 +#, c-format +msgid "%s: the files have been updated; run mkpasswd\n" +msgstr "%s : les fichiers ont été mis à jour; exécutez mkpasswd\n" + +#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611 +#, c-format +msgid "%s: no changes\n" +msgstr "" + +#: src/grpck.c:644 src/pwck.c:610 +#, c-format +msgid "%s: the files have been updated\n" +msgstr "" + +#: src/grpconv.c:62 src/grpunconv.c:63 +#, c-format +msgid "%s: can't lock group file\n" +msgstr "" + +#: src/grpconv.c:67 src/grpunconv.c:68 +#, c-format +msgid "%s: can't open group file\n" +msgstr "" + +#: src/grpconv.c:72 src/grpunconv.c:73 +#, c-format +msgid "%s: can't lock shadow group file\n" +msgstr "" + +#: src/grpconv.c:77 src/grpunconv.c:78 +#, c-format +msgid "%s: can't open shadow group file\n" +msgstr "" + +#. +#. * This shouldn't happen (the entry exists) but... +#. +#: src/grpconv.c:93 +#, c-format +msgid "%s: can't remove shadow group %s\n" +msgstr "" + +#: src/grpconv.c:134 src/pwconv.c:160 +#, c-format +msgid "%s: can't update shadow entry for %s\n" +msgstr "" + +#: src/grpconv.c:143 src/grpunconv.c:94 +#, c-format +msgid "%s: can't update entry for group %s\n" +msgstr "" + +#: src/grpconv.c:150 src/grpunconv.c:102 +#, c-format +msgid "%s: can't update shadow group file\n" +msgstr "" + +#: src/grpconv.c:154 src/grpunconv.c:107 +#, c-format +msgid "%s: can't update group file\n" +msgstr "" + +#: src/grpconv.c:169 src/grpunconv.c:128 +#, c-format +msgid "%s: not configured for shadow group support.\n" +msgstr "" + +#: src/grpunconv.c:112 +#, c-format +msgid "%s: can't delete shadow group file\n" +msgstr "" + +#: src/id.c:56 +msgid "usage: id [ -a ]\n" +msgstr "Usage : id [ -a ]\n" + +#: src/id.c:58 +msgid "usage: id\n" +msgstr "Usage : id\n" + +#: src/id.c:118 +#, c-format +msgid "uid=%d(%s)" +msgstr "uid=%d(%s)" + +#: src/id.c:120 +#, c-format +msgid "uid=%d" +msgstr "uid=%d" + +#: src/id.c:124 +#, c-format +msgid " gid=%d(%s)" +msgstr " gid=%d(%s)" + +#: src/id.c:126 +#, c-format +msgid " gid=%d" +msgstr " gid=%d" + +#: src/id.c:136 +#, c-format +msgid " euid=%d(%s)" +msgstr " euid=%d(%s)" + +#: src/id.c:138 +#, c-format +msgid " euid=%d" +msgstr " euid=%d" + +#: src/id.c:143 +#, c-format +msgid " egid=%d(%s)" +msgstr " egid=%d(%s)" + +#: src/id.c:145 +#, c-format +msgid " egid=%d" +msgstr " egid=%d" + +#. +#. * Start off the group message. It will be of the format +#. * +#. * groups=###(aaa),###(aaa),###(aaa) +#. * +#. * where "###" is a numerical value and "aaa" is the +#. * corresponding name for each respective numerical value. +#. +#: src/id.c:166 +msgid " groups=" +msgstr " groupes=" + +#: src/lastlog.c:167 +msgid "Username Port From Latest\n" +msgstr "Utilisateur Port Venant de Dernière\n" + +#: src/lastlog.c:169 +msgid "Username Port Latest\n" +msgstr "Utilisateur Port Dernière\n" + +#: src/lastlog.c:183 +msgid "**Never logged in**" +msgstr "**Jamais connecté**" + +#: src/login.c:198 +#, c-format +msgid "usage: %s [-p] [name]\n" +msgstr "Usage : %s [-p] [nom]\n" + +#: src/login.c:201 +#, c-format +msgid " %s [-p] [-h host] [-f name]\n" +msgstr " %s [-p] [-h hôte] [-f nom]\n" + +#: src/login.c:203 +#, c-format +msgid " %s [-p] -r host\n" +msgstr " %s [-p] -r hôte\n" + +#: src/login.c:286 +msgid "Invalid login time\n" +msgstr "Heure de connexion non valide\n" + +#: src/login.c:341 +msgid "" +"\n" +"System closed for routine maintenance\n" +msgstr "" +"\n" +"Système fermé pour maintenance\n" + +#: src/login.c:351 +msgid "" +"\n" +"[Disconnect bypassed -- root login allowed.]\n" +msgstr "" +"\n" +"[Disconnexion court-circuitée -- login root authorisé.]\n" + +#: src/login.c:390 +#, c-format +msgid "" +"\n" +"Login timed out after %d seconds.\n" +msgstr "" +"\n" +"Tentative de connexion: délai de %s secondes dépassé.\n" + +#: src/login.c:692 +#, c-format +msgid " on `%.100s' from `%.200s'" +msgstr " sur `%.100s' à partir de `%.200s'" + +#: src/login.c:694 +#, c-format +msgid " on `%.100s'" +msgstr " sur `%.100s'" + +#: src/login.c:834 +#, c-format +msgid "" +"\n" +"%s login: " +msgstr "" +"\n" +"% login: " + +#: src/login.c:836 +msgid "login: " +msgstr "login: " + +#: src/login.c:1026 src/sulogin.c:231 +msgid "Login incorrect" +msgstr "Login incorrect" + +#: src/login.c:1213 +msgid "Warning: login re-enabled after temporary lockout.\n" +msgstr "Avertissement: login réactivé après une désactivation temporaire.\n" + +#: src/login.c:1223 +#, c-format +msgid "Last login: %s on %s" +msgstr "Dernière connexion : le %s sur %s" + +#: src/login.c:1226 +#, c-format +msgid "Last login: %.19s on %s" +msgstr "Dernière connexion : le %.19s sur %s" + +#: src/login.c:1231 +#, c-format +msgid " from %.*s" +msgstr " à partir de %.*s" + +#: src/login.c:1303 +msgid "Starting rad_login\n" +msgstr "Démarrage de rad_login\n" + +#: src/mkpasswd.c:49 +#, c-format +msgid "%s: no DBM database on system - no action performed\n" +msgstr "%s : pas de base de données DBM sur le système - aucune action prise\n" + +#: src/mkpasswd.c:245 src/mkpasswd.c:249 +#, c-format +msgid "%s: cannot overwrite file %s\n" +msgstr "%s : impossible d'écraser le fichier %s\n" + +#: src/mkpasswd.c:263 +#, c-format +msgid "%s: cannot open DBM files for %s\n" +msgstr "%s : impossible d'ouvrir les fichiers DBM pour %s\n" + +#: src/mkpasswd.c:296 +#, c-format +msgid "%s: the beginning with " +msgstr "" + +#: src/mkpasswd.c:321 +#, c-format +msgid "%s: error parsing line \"%s\"\n" +msgstr "%s : erreur lors l'analyse de la ligne \"%s\"\n" + +#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332 +msgid "adding record for name " +msgstr "" + +#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349 +#, c-format +msgid "%s: error adding record for " +msgstr "" + +#: src/mkpasswd.c:367 +#, c-format +msgid "added %d entries, longest was %d\n" +msgstr "%d entrées ajoutées, la plus longue fut %d\n" + +#: src/mkpasswd.c:382 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n" +msgstr "Usage : %s [ -vf ] [ -p|g|sp|sg ] fichier\n" + +#: src/mkpasswd.c:384 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n" +msgstr "Usage : %s [ -vf ] [ -p|g|sp ] fichier\n" + +#: src/mkpasswd.c:387 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g ] file\n" +msgstr "Usage : %s [ -vf ] [ -p|g ] fichier\n" + +#: src/newgrp.c:66 +msgid "usage: newgrp [ - ] [ group ]\n" +msgstr "Usage : newgrp [ - ] [ groupe ]\n" + +#: src/newgrp.c:68 +#, fuzzy +msgid "usage: sg group [[-c] command ]\n" +msgstr "Usage : sg groupe [ commande ]\n" + +#: src/newgrp.c:125 +#, c-format +msgid "unknown uid: %d\n" +msgstr "uid inconnue : %d\n" + +#: src/newgrp.c:201 +#, c-format +msgid "unknown gid: %ld\n" +msgstr "gid inconnu : %ld\n" + +#: src/newgrp.c:245 +#, c-format +msgid "unknown gid: %d\n" +msgstr "gid inconnu : %d\n" + +#: src/newgrp.c:323 src/newgrp.c:332 +msgid "Sorry.\n" +msgstr "Désolé ;-)\n" + +#: src/newgrp.c:364 +msgid "too many groups\n" +msgstr "trop de groupes\n" + +#: src/newusers.c:76 +#, c-format +msgid "Usage: %s [ input ]\n" +msgstr "Usage : %s [ entrée ] \n" + +#: src/newusers.c:364 +#, c-format +msgid "%s: can't lock /etc/passwd.\n" +msgstr "%s : impossible de vérouiller /etc/passwd.\n" + +#: src/newusers.c:375 +#, c-format +msgid "%s: can't lock files, try again later\n" +msgstr "%s : impossible de vérouiller les fichiers, essayez plus tard\n" + +#: src/newusers.c:390 +#, c-format +msgid "%s: can't open files\n" +msgstr "%s : impossible d'ouvrir les fichiers\n" + +#: src/newusers.c:435 +#, c-format +msgid "%s: line %d: invalid line\n" +msgstr "%s : ligne %d : ligne non valide\n" + +#: src/newusers.c:453 +#, c-format +msgid "%s: line %d: can't create GID\n" +msgstr "%s : ligne %d : impossible de créer le GID\n" + +#: src/newusers.c:469 +#, c-format +msgid "%s: line %d: can't create UID\n" +msgstr "%s : ligne %d : impossible de créer le GID\n" + +#: src/newusers.c:481 +#, c-format +msgid "%s: line %d: cannot find user %s\n" +msgstr "%s : ligne %d : impossible de trouver l'utilisateur %s\n" + +#: src/newusers.c:489 +#, c-format +msgid "%s: line %d: can't update password\n" +msgstr "%s : ligne %d : impossible de mettre le mot de passe à jour\n" + +#: src/newusers.c:506 +#, c-format +msgid "%s: line %d: mkdir failed\n" +msgstr "%s : ligne %d : échec de mkdir\n" + +#: src/newusers.c:510 +#, c-format +msgid "%s: line %d: chown failed\n" +msgstr "%s : ligne %d : échec de chown\n" + +#: src/newusers.c:519 +#, c-format +msgid "%s: line %d: can't update entry\n" +msgstr "%s : ligne %d : impossible de mettre l'entrée à jour\n" + +#: src/newusers.c:550 +#, c-format +msgid "%s: error updating files\n" +msgstr "%s : erreur lors de la mise à jour des fichiers\n" + +#: src/passwd.c:239 +#, c-format +msgid "usage: %s [ -f | -s ] [ name ]\n" +msgstr "Usage : %s [ -f | -s ] [ nom ]\n" + +#: src/passwd.c:242 +#, c-format +msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n" +msgstr " %s [ -x max ] [ -n min ] [ -w avert ] [ -i inact ] nom\n" + +#: src/passwd.c:245 +#, c-format +msgid " %s { -l | -u | -d | -S | -e } name\n" +msgstr " %s { -l | -u | -d | -S | -e } nom\n" + +#: src/passwd.c:347 +#, c-format +msgid "User %s has a TCFS key, his old password is required.\n" +msgstr "" +"L'utilisateur %s a une clé TCFS, son ancien mot de passe est nécessaire.\n" + +#: src/passwd.c:348 +msgid "You can use -t option to force the change.\n" +msgstr "Vous pouvez utiliser l'option -t pour forcer le changement.\n" + +#: src/passwd.c:354 +msgid "Old password: " +msgstr "Ancien mot de passe : " + +#: src/passwd.c:361 +#, c-format +msgid "Incorrect password for `%s'\n" +msgstr "Mot de passe incorrect pour `%s'\n" + +#: src/passwd.c:374 +#, c-format +msgid "Warning: user %s has a TCFS key.\n" +msgstr "Avertissement : l'utilisateur %s a une clé TCFS.\n" + +#: src/passwd.c:392 +#, c-format +msgid "" +"Enter the new password (minimum of %d, maximum of %d characters)\n" +"Please use a combination of upper and lower case letters and numbers.\n" +msgstr "" +"Entrez le nouveau mot de passe (minimum de %d, maximum de %d\n" +"caractères). Utilisez une combinaison de lettres en majuscule/minuscule\n" +"et de nombres.\n" + +#: src/passwd.c:399 +msgid "New password: " +msgstr "Nouveau mot de passe : " + +#: src/passwd.c:409 +msgid "Try again.\n" +msgstr "Essaye encore...\n" + +#: src/passwd.c:418 +msgid "" +"\n" +"Warning: weak password (enter it again to use it anyway).\n" +msgstr "" +"\n" +"Avertissement : mot de passe simpliste (tapez le à nouveau pour l'utiliser\n" +"quand même).\n" + +#: src/passwd.c:427 +msgid "They don't match; try again.\n" +msgstr "Ils ne sont pas identique; essaye encore...\n" + +#: src/passwd.c:512 src/passwd.c:528 +#, c-format +msgid "The password for %s cannot be changed.\n" +msgstr "Le mot de passe pour %s ne peut être changé.\n" + +#: src/passwd.c:556 +#, c-format +msgid "Sorry, the password for %s cannot be changed yet.\n" +msgstr "Désolé, le mot de passe pour %s ne peux pas encore être changé.\n" + +#: src/passwd.c:693 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s : plus de mémoire\n" + +#: src/passwd.c:845 +msgid "Cannot lock the TCFS key database; try again later\n" +msgstr "" +"Impossible de vérouiller la base de données de clés TCFS; essayez à\n" +"nouveau plus tard\n" + +#: src/passwd.c:851 +msgid "Cannot open the TCFS key database.\n" +msgstr "Impossible d'ouvrir la base de clés TCFS.\n" + +#: src/passwd.c:857 +msgid "Error updating the TCFS key database.\n" +msgstr "Erreur lors de la mise à jour de la base de clés TCFS.\n" + +#: src/passwd.c:862 +msgid "Cannot commit TCFS changes.\n" +msgstr "Impossible de valider les changements TCFS.\n" + +#: src/passwd.c:1069 +#, c-format +msgid "%s: Cannot execute %s" +msgstr "%s : Impossible d'exécuter %s" + +#: src/passwd.c:1176 +#, c-format +msgid "%s: repository %s not supported\n" +msgstr "" + +#: src/passwd.c:1263 +#, c-format +msgid "%s: Permission denied\n" +msgstr "%s : Permission refusée\n" + +#: src/passwd.c:1287 +#, c-format +msgid "You may not change the password for %s.\n" +msgstr "Vous ne pouvez pas changer le mot de passe de %s.\n" + +#: src/passwd.c:1352 +#, c-format +msgid "Changing password for %s\n" +msgstr "Changement du mot de passe de %s\n" + +#: src/passwd.c:1356 +#, c-format +msgid "The password for %s is unchanged.\n" +msgstr "Le mot de passe pour %s est inchangé.\n" + +#: src/passwd.c:1412 +msgid "Password changed.\n" +msgstr "Mot de passe changé.\n" + +#: src/pwck.c:98 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n" +msgstr "Usage : %s [ -qr ] [ passwd [ shadow ] ]\n" + +#: src/pwck.c:100 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd ]\n" +msgstr "Usage : %s [ -qr ] [ passwd ]\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:285 +msgid "invalid password file entry\n" +msgstr "entrée non valide dans le fichier password\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:347 +msgid "duplicate password entry\n" +msgstr "entrée dupliquée dans password\n" + +#: src/pwck.c:363 +#, c-format +msgid "invalid user name `%s'\n" +msgstr "nom d'utilisateur `%s' non valide\n" + +#: src/pwck.c:373 +#, c-format +msgid "user %s: bad UID (%d)\n" +msgstr "utilisateur %s : mauvais UID (%d)\n" + +#. +#. * No primary group, just give a warning +#. +#: src/pwck.c:388 +#, c-format +msgid "user %s: no group %d\n" +msgstr "utilisateur %s : aucun groupe %d\n" + +#. +#. * Home directory doesn't exist, give a warning +#. +#: src/pwck.c:403 +#, c-format +msgid "user %s: directory %s does not exist\n" +msgstr "utilisateur %s : le répertoire %s n'existe pas\n" + +#. +#. * Login shell doesn't exist, give a warning +#. +#: src/pwck.c:418 +#, c-format +msgid "user %s: program %s does not exist\n" +msgstr "utilisateur %s : le programme %s n'existe pas\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:454 +msgid "invalid shadow password file entry\n" +msgstr "entrée shadow password non valide\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:516 +msgid "duplicate shadow password entry\n" +msgstr "entrée shadow password dupliquée\n" + +#. +#. * Tell the user this entry has no matching +#. * /etc/passwd entry and ask them to delete it. +#. +#: src/pwck.c:540 +msgid "no matching password file entry\n" +msgstr "aucune entrée correspondante dans le fichier password\n" + +#: src/pwck.c:557 +#, c-format +msgid "user %s: last password change in the future\n" +msgstr "" +"utilisateur %s : date du dernier changement de mot de passe dans le futur\n" + +#: src/pwconv.c:94 src/pwunconv.c:108 +#, c-format +msgid "%s: can't lock passwd file\n" +msgstr "%s : impossible de vérouiller le fichier passwd\n" + +#: src/pwconv.c:99 src/pwunconv.c:113 +#, c-format +msgid "%s: can't open passwd file\n" +msgstr "%s : impossible d'ouvrir le fichier passwd\n" + +#: src/pwconv.c:126 +#, c-format +msgid "%s: can't remove shadow entry for %s\n" +msgstr "%s : impossible d'enlever l'entrée shadow pour %s\n" + +#: src/pwconv.c:169 +#, c-format +msgid "%s: can't update passwd entry for %s\n" +msgstr "%s : impossible de mettre à jour le mot de passe de %s\n" + +#: src/pwconv.c:176 +#, c-format +msgid "%s: can't update shadow file\n" +msgstr "%s : impossible de mettre à jour le fichier shadow\n" + +#: src/pwconv.c:180 +#, c-format +msgid "%s: can't update passwd file\n" +msgstr "%s : impossible de mettre à jour le fichier passwd\n" + +#: src/pwunconv.c:62 +#, c-format +msgid "%s: Shadow passwords are not configured.\n" +msgstr "%s : Les mots de passe shadow ne sont pas configurés.\n" + +#: src/pwunconv.c:171 +#, c-format +msgid "%s: can't update entry for user %s\n" +msgstr "%s : impossible de mettre à jour l'entrée %s\n" + +#: src/pwunconv.c:188 +#, c-format +msgid "%s: can't delete shadow password file\n" +msgstr "%s : impossible d'effacer le fichier shadow\n" + +#: src/su.c:140 +msgid "Sorry." +msgstr "Désolé ;-)" + +#: src/su.c:222 +#, c-format +msgid "%s: must be run from a terminal\n" +msgstr "%s : doit être lancé à partir d'un terminal\n" + +#: src/su.c:311 +#, c-format +msgid "%s: pam_start: error %d\n" +msgstr "%s : pam_start : erreur %d\n" + +#: src/su.c:337 +#, c-format +msgid "Unknown id: %s\n" +msgstr "ID inconnue : %s\n" + +#. access denied (-1) or unexpected value +#: src/su.c:372 src/su.c:387 +#, fuzzy, c-format +msgid "You are not authorized to su %s\n" +msgstr "Vous n'êtes pas authorisés " + +#. require own password +#: src/su.c:383 +msgid "(Enter your own password.)" +msgstr "(Entrez votre propre mot de passe.)" + +#: src/su.c:404 +#, c-format +msgid "%s: permission denied (shell).\n" +msgstr "%s : permission refusée (shell).\n" + +#: src/su.c:428 +#, c-format +msgid "" +"%s: %s\n" +"(Ignored)\n" +msgstr "" +"%s: %s\n" +"(Ignoré)\n" + +#: src/su.c:628 +msgid "No shell\n" +msgstr "Pas de shell\n" + +#. must be a password file! +#: src/sulogin.c:136 +msgid "No password file\n" +msgstr "Pas de fichier de mot de passe\n" + +#. +#. * Fail secure +#. +#: src/sulogin.c:178 +msgid "No password entry for 'root'\n" +msgstr "Pas d'entrée pour le mot de passe de 'root'\n" + +#. +#. * Here we prompt for the root password, or if no password is +#. * given we just exit. +#. +#. get a password for root +#: src/sulogin.c:192 +msgid "" +"\n" +"Type control-d to proceed with normal startup,\n" +"(or give root password for system maintenance):" +msgstr "" +"\n" +"Tapez control-d pour procéder au démarrage normal,\n" +"(ou donnez le mot de passe de root pour la maintenance) : " + +#. make new environment active +#: src/sulogin.c:241 +msgid "Entering System Maintenance Mode\n" +msgstr "Entrée du système en mode maintenance\n" + +#: src/useradd.c:243 +#, c-format +msgid "%s: rebuild the group database\n" +msgstr "%s : reconstruction de la base de données des groupes\n" + +#: src/useradd.c:250 +#, c-format +msgid "%s: rebuild the shadow group database\n" +msgstr "%s : reconstruction de la base de données des groupes shadow\n" + +#: src/useradd.c:287 src/usermod.c:967 +#, c-format +msgid "%s: invalid numeric argument `%s'\n" +msgstr "%s : argument numérique `%s' non valide\n" + +#: src/useradd.c:343 +#, c-format +msgid "%s: unknown gid %s\n" +msgstr "%s : gid %s inconnu\n" + +#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254 +#: src/usermod.c:1098 +#, c-format +msgid "%s: unknown group %s\n" +msgstr "%s : groupe %s inconnu\n" + +#: src/useradd.c:418 +#, c-format +msgid "group=%s,%ld basedir=%s skel=%s\n" +msgstr "group=%s,%ld rép_base=%s skel=%s\n" + +#: src/useradd.c:421 +#, c-format +msgid "shell=%s " +msgstr "shell=%s " + +#: src/useradd.c:423 +#, c-format +msgid "inactive=%ld expire=%s" +msgstr "inactif=%ld expire=%s" + +#: src/useradd.c:427 +#, c-format +msgid "GROUP=%ld\n" +msgstr "GROUP=%ld\n" + +#: src/useradd.c:428 +#, c-format +msgid "HOME=%s\n" +msgstr "HOME=%s\n" + +#: src/useradd.c:430 +#, c-format +msgid "INACTIVE=%ld\n" +msgstr "INACTIVE=%ld\n" + +#: src/useradd.c:431 +#, c-format +msgid "EXPIRE=%s\n" +msgstr "EXPIRE=%s\n" + +#: src/useradd.c:433 +#, c-format +msgid "SHELL=%s\n" +msgstr "SHELL=%s\n" + +#: src/useradd.c:434 +#, c-format +msgid "SKEL=%s\n" +msgstr "SKEL=%s\n" + +#: src/useradd.c:470 +#, c-format +msgid "%s: cannot create new defaults file\n" +msgstr "%s : impossible de créer un nouveau fichier de défauts\n" + +#: src/useradd.c:564 src/useradd.c:575 +#, c-format +msgid "%s: rename: %s" +msgstr "%s : rename : %s" + +#: src/useradd.c:662 src/usermod.c:274 +#, c-format +msgid "%s: group `%s' is a NIS group.\n" +msgstr "%s : le groupe `%s' est un groupe NIS.\n" + +#: src/useradd.c:670 src/usermod.c:282 +#, c-format +msgid "%s: too many groups specified (max %d).\n" +msgstr "%s : trop de groupes spécifiés (max %d).\n" + +#: src/useradd.c:702 src/usermod.c:314 +#, c-format +msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n" +msgstr "Usage : %s\t[-u uid [-o]] [-g groupe] [-G groupe,...] \n" + +#: src/useradd.c:705 +msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n" +msgstr "\t\t[-d home] [-s shell] [-c commentaire] [-m [-k template]]\n" + +#: src/useradd.c:708 src/usermod.c:320 +msgid "[-f inactive] [-e expire ] " +msgstr "[-f inactif] [-e expire ] " + +#: src/useradd.c:711 +msgid "[-A program] " +msgstr "[-A program] " + +#: src/useradd.c:713 +msgid "[-p passwd] name\n" +msgstr "[-p mot-de-passe] nom\n" + +#: src/useradd.c:715 +#, c-format +msgid " %s\t-D [-g group] [-b base] [-s shell]\n" +msgstr " %s\t-D [-g groupe] [-b base] [-s shell]\n" + +#: src/useradd.c:718 +msgid "\t\t[-f inactive] [-e expire ]\n" +msgstr "\t\t[-f inactif] [-e expire ]\n" + +#: src/useradd.c:815 src/usermod.c:472 +#, c-format +msgid "%s: error locking group file\n" +msgstr "%s : erreur lors du vérouillage du fichier de groupe\n" + +#: src/useradd.c:819 src/usermod.c:477 +#, c-format +msgid "%s: error opening group file\n" +msgstr "%s : erreur lors d'ouverture du fichier de groupe\n" + +#: src/useradd.c:824 src/usermod.c:584 +#, c-format +msgid "%s: error locking shadow group file\n" +msgstr "%s : erreur lors du vérouillage du fichier shadow group\n" + +#: src/useradd.c:829 src/usermod.c:590 +#, c-format +msgid "%s: error opening shadow group file\n" +msgstr "%s : erreur lors de l'ouverture du fichier shadow group\n" + +#: src/useradd.c:1001 +#, c-format +msgid "%s: uid %d is not unique\n" +msgstr "%s : l'uid %d n'est pas unique\n" + +#: src/useradd.c:1031 +#, c-format +msgid "%s: can't get unique uid\n" +msgstr "%s : impossible d'obtenir un uid unique\n" + +#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057 +#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157 +#, c-format +msgid "%s: invalid field `%s'\n" +msgstr "%s : champs `%s' non valide\n" + +#: src/useradd.c:1153 +#, c-format +msgid "%s: invalid base directory `%s'\n" +msgstr "%s : répertoire de base non valide `%s'\n" + +#: src/useradd.c:1163 +#, c-format +msgid "%s: invalid comment `%s'\n" +msgstr "%s : commentaire `%s' non valide\n" + +#: src/useradd.c:1173 +#, c-format +msgid "%s: invalid home directory `%s'\n" +msgstr "%s : répertoire personnel `%s' non valide\n" + +#: src/useradd.c:1191 src/usermod.c:1080 +#, c-format +msgid "%s: invalid date `%s'\n" +msgstr "%s : date `%s' non valide\n" + +#: src/useradd.c:1203 +#, c-format +msgid "%s: shadow passwords required for -e\n" +msgstr "%s : mots de passe shadow nécessaires pour -e\n" + +#: src/useradd.c:1218 +#, c-format +msgid "%s: shadow passwords required for -f\n" +msgstr "%s : mots de passe shadow nécessaires pour -f\n" + +#: src/useradd.c:1292 +#, c-format +msgid "%s: invalid shell `%s'\n" +msgstr "%s : shell `%s' non valide\n" + +#: src/useradd.c:1333 +#, c-format +msgid "%s: invalid user name `%s'\n" +msgstr "%s : nom d'utilisateur `%s' non valide\n" + +#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225 +#, c-format +msgid "%s: cannot rewrite password file\n" +msgstr "%s : impossible de reécrire le fichier de mots de passe\n" + +#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230 +#, c-format +msgid "%s: cannot rewrite shadow password file\n" +msgstr "%s : impossible de reécrire le fichier shadow\n" + +#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265 +#, c-format +msgid "%s: unable to lock password file\n" +msgstr "%s : impossible de vérouiller le fichier de mots de passe\n" + +#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269 +#, c-format +msgid "%s: unable to open password file\n" +msgstr "%s : impossible d'ouvrir le fichier de mots de passe\n" + +#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274 +#, c-format +msgid "%s: cannot lock shadow password file\n" +msgstr "%s : impossible de vérouiller le fichier de mots de passe\n" + +#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279 +#, c-format +msgid "%s: cannot open shadow password file\n" +msgstr "%s : impossible d'ouvrir le fichier shadow\n" + +#: src/useradd.c:1529 src/usermod.c:1366 +#, c-format +msgid "%s: error adding authentication method\n" +msgstr "%s : erreur lors de l'ajout de la méthode d'authentification\n" + +#: src/useradd.c:1552 +#, c-format +msgid "%s: error adding new password entry\n" +msgstr "%s : erreur lors de l'ajout de la nouvelle entrée\n" + +#: src/useradd.c:1567 +#, c-format +msgid "%s: error updating password dbm entry\n" +msgstr "%s : erreur lors de la mise à jour de l'entrée dbm\n" + +#: src/useradd.c:1583 src/usermod.c:1425 +#, c-format +msgid "%s: error adding new shadow password entry\n" +msgstr "%s : erreur lors de l'ajout de la nouvelle entrée shadow\n" + +#: src/useradd.c:1599 src/usermod.c:1440 +#, c-format +msgid "%s: error updating shadow passwd dbm entry\n" +msgstr "%s : erreur lors de la mise à jour de l'entrée shadow passwd dbm\n" + +#: src/useradd.c:1631 +#, c-format +msgid "%s: cannot create directory %s\n" +msgstr "%s : impossible de créer le répertoire %s\n" + +#: src/useradd.c:1708 src/usermod.c:1203 +#, c-format +msgid "%s: user %s exists\n" +msgstr "%s : l'utilisateur %s existe\n" + +#: src/useradd.c:1738 +#, c-format +msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n" +msgstr "" +"%s : avertissement : CREATE_HOME non supporté, utilisez -m à la place.\n" + +#: src/userdel.c:127 +#, c-format +msgid "usage: %s [-r] name\n" +msgstr "Usage : %s [-r] nom\n" + +#: src/userdel.c:178 src/userdel.c:260 +#, c-format +msgid "%s: error updating group entry\n" +msgstr "%s : erreur lors de la mise à jour de l'entrée group\n" + +#: src/userdel.c:188 src/userdel.c:269 +#, c-format +msgid "%s: cannot update dbm group entry\n" +msgstr "%s : impossible de mettre à jour l'entrée dbm group\n" + +#: src/userdel.c:215 +#, fuzzy, c-format +msgid "%s: cannot remove dbm group entry\n" +msgstr "%s : impossible de mettre à jour l'entrée dbm group\n" + +#: src/userdel.c:300 +#, c-format +msgid "%s: cannot rewrite TCFS key file\n" +msgstr "%s : impossible de reécrire le fichier de clés TCFS\n" + +#: src/userdel.c:380 +#, c-format +msgid "%s: cannot lock TCFS key file\n" +msgstr "%s : impossible de vérouiller le fichier de clés TCFS\n" + +#: src/userdel.c:384 +#, c-format +msgid "%s: cannot open TCFS key file\n" +msgstr "%s : impossible d'ouvrir le fichier de clés TCFS\n" + +#: src/userdel.c:393 +#, c-format +msgid "%s: cannot open group file\n" +msgstr "%s : impossible d'ouvrir le fichier group\n" + +#: src/userdel.c:403 +#, c-format +msgid "%s: cannot open shadow group file\n" +msgstr "%s : impossible d'ouvrir le fichier shadow group\n" + +#: src/userdel.c:434 src/userdel.c:449 +#, c-format +msgid "%s: error deleting authentication\n" +msgstr "%s : erreur lors de l'effacement de l'authentification\n" + +#: src/userdel.c:458 +#, c-format +msgid "%s: error deleting password entry\n" +msgstr "%s : erreur lors de la suppression de l'entrée dans /etc/passwd\n" + +#: src/userdel.c:461 +#, c-format +msgid "%s: error deleting shadow password entry\n" +msgstr "%s : erreur lors de la suppression de l'entrée dans /etc/shadow\n" + +#: src/userdel.c:470 +#, c-format +msgid "%s: error deleting TCFS entry\n" +msgstr "%s : erreur lors de l'effacement de l'entrée TCFS\n" + +#: src/userdel.c:483 +#, c-format +msgid "%s: error deleting password dbm entry\n" +msgstr "%s : erreur lors de l'effacement de l'entrée dbm du mot de passe\n" + +#: src/userdel.c:502 +#, c-format +msgid "%s: error deleting shadow passwd dbm entry\n" +msgstr "%s : erreur lors de l'effacement de l'entrée shadow passwd dbm\n" + +#: src/userdel.c:543 +#, c-format +msgid "%s: user %s is currently logged in\n" +msgstr "%s : l'utilisateur %s est connecté\n" + +#: src/userdel.c:660 +#, c-format +msgid "%s: warning: %s not owned by %s, not removing\n" +msgstr "%s : avertissement : %s n'appartient pas à %s, non enlevé\n" + +#: src/userdel.c:666 +#, c-format +msgid "%s: warning: can't remove " +msgstr "%s : impossible d'enlever " + +#: src/userdel.c:741 src/usermod.c:994 +#, c-format +msgid "%s: user %s does not exist\n" +msgstr "%s : l'utilisateur %s n'existe pas\n" + +#: src/userdel.c:755 src/usermod.c:1010 +#, c-format +msgid "%s: user %s is a NIS user\n" +msgstr "%s : le compte %s est un compte NIS\n" + +#: src/userdel.c:792 +#, c-format +msgid "%s: %s not owned by %s, not removing\n" +msgstr "%s : %s n'appartient pas à %s, non enlevé\n" + +#: src/userdel.c:815 +#, c-format +msgid "%s: not removing directory %s (would remove home of user %s)\n" +msgstr "" +"%s : répertoire %s non enlevé (cela enléverait le répertoire personnel de " +"%s)\n" + +#: src/userdel.c:828 +#, c-format +msgid "%s: error removing directory %s\n" +msgstr "%s : erreur lors de l'effacement du répertoire %s\n" + +#: src/usermod.c:317 +msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n" +msgstr "\t\t[-d home [-m]] [-s shell] [-c commentaire] [-l nouveau_nom]\n" + +#: src/usermod.c:323 +msgid "[-A {DEFAULT|program},... ] " +msgstr "[-A {DÉFAUT|programme},... ] " + +#: src/usermod.c:325 +#, fuzzy +msgid "[-p passwd] [-L|-U] name\n" +msgstr "[-p mot-de-passe] nom\n" + +#: src/usermod.c:504 +#, c-format +msgid "%s: out of memory in update_group\n" +msgstr "%s : plus de mémoire pour update_group\n" + +#: src/usermod.c:627 +#, c-format +msgid "%s: out of memory in update_gshadow\n" +msgstr "%s : plus de mémoire pour update_gshadow\n" + +#: src/usermod.c:1180 +#, c-format +msgid "%s: no flags given\n" +msgstr "%s : aucun drapeau donné\n" + +#: src/usermod.c:1187 +#, c-format +msgid "%s: shadow passwords required for -e and -f\n" +msgstr "%s : mots de passe shadow nécessaires pour -e ou -f\n" + +#: src/usermod.c:1208 +#, c-format +msgid "%s: uid %ld is not unique\n" +msgstr "%s : l'uid %ld n'est pas unique\n" + +#: src/usermod.c:1356 +#, c-format +msgid "%s: error deleting authentication method\n" +msgstr "%s : erreur lors de l'effacement de la méthode d'authentification\n" + +#: src/usermod.c:1376 +#, c-format +msgid "%s: error changing authentication method\n" +msgstr "%s : erreur lors du changement de la méthode d'authentification\n" + +#: src/usermod.c:1393 +#, c-format +msgid "%s: error changing password entry\n" +msgstr "%s : erreur lors du changement de l'entrée dans /etc/passwd\n" + +#: src/usermod.c:1399 +#, c-format +msgid "%s: error removing password entry\n" +msgstr "%s : erreur lors de l'effacement du mot de passe\n" + +#: src/usermod.c:1407 +#, c-format +msgid "%s: error adding password dbm entry\n" +msgstr "" + +#: src/usermod.c:1414 +#, c-format +msgid "%s: error removing passwd dbm entry\n" +msgstr "" + +#: src/usermod.c:1431 +#, c-format +msgid "%s: error removing shadow password entry\n" +msgstr "" + +#: src/usermod.c:1446 +#, c-format +msgid "%s: error removing shadow passwd dbm entry\n" +msgstr "" + +#: src/usermod.c:1477 +#, c-format +msgid "%s: directory %s exists\n" +msgstr "%s : le répertoire %s existe\n" + +#: src/usermod.c:1484 +#, c-format +msgid "%s: can't create %s\n" +msgstr "%s : impossible de créer %s\n" + +#: src/usermod.c:1490 +#, c-format +msgid "%s: can't chown %s\n" +msgstr "%s : impossible de changer le propriètaire de %s\n" + +#: src/usermod.c:1506 +#, c-format +msgid "%s: cannot rename directory %s to %s\n" +msgstr "%s : impossible de renommer le répertoire %s en %s\n" + +#. better leave it alone +#: src/usermod.c:1603 +#, c-format +msgid "%s: warning: %s not owned by %s\n" +msgstr "%s : avertissement : %s n'appartient pas à %s\n" + +#: src/usermod.c:1609 +msgid "failed to change mailbox owner" +msgstr "échec du changement de propriètaire de la mailbox" + +#: src/usermod.c:1616 +msgid "failed to rename mailbox" +msgstr "échec du renommage de la mailbox" + +#: src/vipw.c:102 +#, c-format +msgid "" +"\n" +"%s: %s is unchanged\n" +msgstr "" +"\n" +"%s : %s est inchangé\n" + +#: src/vipw.c:127 +msgid "Couldn't lock file" +msgstr "Impossible de vérouiller le fichier" + +#: src/vipw.c:134 +msgid "Couldn't make backup" +msgstr "Impossible de faire une sauvegarde" + +#: src/vipw.c:187 +#, c-format +msgid "%s: can't restore %s: %s (your changes are in %s)\n" +msgstr "%s : impossible de restaurer %s : %s (vos changements sont dans %s)\n" + +#: src/vipw.c:226 +msgid "" +"Usage:\n" +"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n" +"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n" +msgstr "" +"Usage :\n" +"`vipw' édite /etc/passwd `vipw -s' édite /etc/shadow\n" +"`vigr' édite /etc/group `vigr -s' édite /etc/gshadow\n" diff --git a/current/po/pl.gmo b/current/po/pl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..e4ee08ef4efb807f38e7443a552d5e20ed6be36c GIT binary patch literal 40513 zcmbuI37i~doxdBwg^Y6FcO@`n0+}HRhcHQikPHx#OkxfK37FJ$*Gzh*kD-qY(*#fu z5fl{gzyn=maY6Bjf#A7#E$*_o;;}0#`ge6@F{|tDBJ0KK|M|Y}Th&$F)sx`%C+|E} z@B4f2`>OotkbT~n;rF+DWirRXB?n|On_iL06!gOH`R+{SHSp(-(@)7{j_3Ufcp#jB z2f__D!hp z|J3R4dzuaR$9u=Lb;flsVn{e+X2(XF|EN5Xzm)q1>st_q(9n z`8bq2PeaA~MR+1SV2(}KJ}9}ha30(WJ@^n*Iz9=Nj{gni&$PLeP1p^Uu9rZ$zZoiB zZib5QLs0ql1XQ?w0p)KOo~S&Z3T3_&%DfC^|8}T!+V0+;ffS9*OOUM1%sj)ovj)oF zDwKQoK*jGdD0iQRir4=*^P|qR=C6T@$113J6rkka1{ID+Ayp~!ZKwYdlshxdvi>ZA zde1`HyBSLUqfqXB2P$8F0~MY_&bH>KL8a$fDEr%>!v6uNczwma{|YMo4x{l=d7TU8 z-bN_*w?f7DJ?{O}P;x(jO1D>@W94Q;xw{g|{8}jg9)ODHlkWX__rCwR*8DUm|5rf| z7NPRx4ygS56qGyPf(p-Xpz`OKe(V1Ll)nWifA4`u!!JYGe-ozt{~k_<&qKM}wb<&PPn%D=7w>;DPxWZsuRxtoVFzuD=(2g?1w zfycq`!EX3JP~ki7qDawDm6r#g^6d-oRq$I- z<@!fX|39GI-+P&rI~eNy6!;hLOn3mC?|3PE1@Bit<=2%^;e7*Cy}Au5ogReK;Af%i ze-*wGej6%(zXw%+UWAh0Z@H~U$3W>XguQST?1I-r#rIY?58ewEzo(({_j&j#xZeuv z?_p5kIsqO8XF}OK2P$4;a9>z~a<>7MPj|o>a3?h3go@XTP~kju(E8I2RZr$Zh2vr< z^G#6xT@97aH^SG$yP(`Vbfq1So(?H0nYY0Td$SGL z9`AS_RC(G2RlaV5%I}Xr)tASi%H{WA4?K9aO^1G{a$bb{!@J=b@II*e@lR0pe+5;Z zy4F~^*--h>4?Q>lPlLno0C*QX1l|XgE{{O@`xKOaFFO5W*IM__a2$k+XCBJGJE6+g z4yf=w16A&ygGz_J*V*(w5lVh8lz(d=O><@pDqTJb6`pUv!{AS#+O^+6#q)s6Y&!Qq zkN1n9+#i8zKW~C+&p!lJUOop^uD$~0-&62#_^(jq=J!tj`1RKPv!Lv+gbM!_=)s$z z!uMf#BzzLe{hvUEcNbLt|1b35v6tI&w*V>~FM$ew2`c^H4CVeKQ2Fysco2LRs=WWw z>Hpg4{|O$9{y|q*|7JkRpXGQFJcIZ3Q1$CAa3TCCJP`gI9sz#`m97VEu<`7M%D3~N z%(Ji$HlV`w5R|`7pNg0H{g(_cX zTxI32gbGguDjjcua{s+h?Zb9>4EzE-3qAwo-vO^!H&1 zT~7aTIGy*OLB(s|tPTHccmnTNK&8_)Q1O2d9t*z+RbHNja_<*V@jpCgbk0nsy ztHR^q-B9+o!+G%Q@HH?KSpUy~ir-c6Xt)*1|F=7S(V71zoQwXnVcVb2cN~V@=-&zF zz{jA%_q^l5Blf)?%6=Bg|986guS5C&C#ZUN)D|1=v*0PbuW@WR-Uk)Fzk@1wzjg0@ zd28==P~q4H7r>7}g>M%;6CN~b+s6SYxgtCnegMk9uRxW{T~PUS(wI%x0Vw-5cp7{N z&WHcx-VZKV{e^HL`gwRZ{A(zCKXN>@Xx}e^N{{Q{1@IG4>GGd&2J9&@XNSw+sql8F z@O&D|-uGb-e0ACKEU0{c9aKE7hf1FZ;OX!OQ0A|qaw>Z+^FDQ(PK)4d-V0Fie~)|rhI@YrD!%i!+H|@S z_VRuc^x$@QHvATpztbjc`?vtk<$VIm--n>$_j9Op>%PYNzXD4C8rTOPfvQ@Lc#cDEIcd&gTD2D0eS~ zC&5uD^E(_Lfhs58ckllTFXH{A>uo7@2KRmkR6gGi`{8%t!SIk9totWJ#rG0; zBrL;2;Vn@0W}q`k~s(wNUAD15|oH3>A)N zq1<}`cEP=Gv;F=7Q04C!DDzoR>2WSR8eR&O9yuugZiI)x2i*Io;c>kG!11?G<@NBl z*z!3OD&5Y9@@E}X{^#KSa1#Cnyam1*-r@K@xHs<)!V}=bP~rLqcrttz%H6%*YTY@~ zu^aA#{uxkm=RnC_1!cbql`e0D3g;tG<>m>vFU;I->(hSlJYJ83O23Uz<)H#!4c`G@ z1@D9V!H+?u-%fZId;-e7mz?=NcUX7#hsyWqju%6vUlA&vx4HL+pwjsXsC54xR5^ah z@$k3V`1CoR4{yeN6_h*w42$qZ_*$5KJ7aM8DAfC+J8iwa8!CT4@7});6`sBCvgzkR z#e2ZLkHDF{zZI(ec?7DSJq1;MpNF&HX?NRtvkvz0ej7X(eg-aq{{ZFhLGQ5jyAPhu z`yf>MUJsRDZ-Gj$_d~h!WoQ0hQ11N^DqRkGr%k6>Q2D+b%KfVy-v$-0kHOjSNvL@J z1}c4zewQsr3!vmKh4Oa<%Aebz-2EU_yuS)Bg3m&w$4T$D`MV6td=oqjPC%1hQ2ssw z=fHn~N~c5avF*qLDE%tjAO4l&r{Iyie-V1{8K`jo4l19IeUE+bhiWIUgr~r5Q0aL; zR6M@z_&ca_dE$F*JZD0+TT5UM+yYgu?}SS4d!hV!3cd#ZJ2dfqpUtObQ2BH@R6Wka zE;tUAZr8#?;O+2G_?J%q5vX`Q0nda#f{NFn@3-ySSy1jy!lU4A@CbN6JQ{u$Dqi1# za_9F@>37JzHvEgB{9Or^E<^A*cq3H!KM2o&UxUZPKRErPKR}zp`|D9ZM?HO-hH?~g$JlxIqJ#r?140Ka?TrKm$tpK^NASA2h>2Yx;1U+v6xSuOLIVwrgm zeX=X_O1KHW1NC~IZ-M`b`b%f;dZ@J6053ybh58&yzc0YQv5)3&*6IHRT#Z_R?tC~D zlUdF44)^{>%=Sa+cRIY&K1P4v$P-l{GvH({b|#Ow_ejt^Jm`3Li}^3n|A;di#Oy?8 z{z-T=s)*UU;4|=(s0&a_dH*210fxU}o)^3KA@~N=NN5OG@_r3G9DW`C2=!ysqp0i9 zn?UKe8C7=AU*P%UsL!Ip-{bD#eaQUEJ&*GIcK5s;evtR8;dIoePWVY~5lb*Q+sy==Q{uR6ke#Xg6!1<_}d;gxJ+OP0; zHu6WI>S){p4}^!og7lrxU2vm&{u26&P~Ua${qS;>>f|}->vsm+8?_J5kHHt<&CX2b zztbQ0+Y9{zP=Cq$7g6f#^;?48ai|SEAB|eh^BmMa@_ZZAZ!=s6zYMoKJ?VGxyssYk zosGJQ_Z;ePQ1_uSsJEdWK+#-e-i#`t!k^kp{l1A(n{X=XOxfdCf}eKJD|xTDXPJ$m z{uZ?!z1!eP@LV_#?vGl)b3c4PO221O$M9S+Z?qAPG(qNkgL}=)bn@>;V+l&_@@t&l zl|26o>T{?!q4djHWcrX9MEw=dTcCb3 zEHcX+e+WN;x*wTuz$@T8QFo#qLj65@9_p(+e;)PEJbxec8`M9b{u|YUdJAT2QP=bQ zTBzR)xE$Vy+LvdI1^$Rq-*O=;{2lBbjz#7O)NCpAK7e{N&;JGA1do9iz%i75hoioP z+Q$25oSyVwhdP<}hv12*^HHxwU4+u_-%#hF^2mHy8vNeM^E`Mhd<9Cs55wQv$IS6O zuX4}A#k?&G&Eok#^uX_6o_C;r!1FRViFya>P}DXfVaF6z_Z(uFhd-dchI%DR z{n~lhc`ICtx{K#g7{Du0A4lE9d;Iqi^zKLFw3y}_V$TbCo{r3+@NTDn7JSS-3kPDZ z-)~W0anE|cRe$*XH7YMJPyuCU0w7xO!KUV}OZ)r;DQ-t*8$={F1YdDIQ4cVl(})bB{tt9f68 zItcZ5Mwc-t&rk5Y6?Hr6tEdt59)Jy$eh;IrMV*EI0q{B0zoPCzeHzt=dJ%OR=Dnzo zqQc*C?xBI+Wjs$qy`ATSq(5!i#@?K_rCbcWjlIRIuHtXit8NJj1wCfHY`ItrN;SO{ zyizc+spJ=ftGZ(Lrm|AR+L%`hisJ>p7F^}*4SV^LpRMJ$2C^G?!8POgO5n-#qI#j= z4dO+=*IniP5(RA4mU1c7SY0j`y}^2MD5yA*_2tS~T%@bJ>J`c(`BJ}^;aO5%zUtLW z*)4u)B*=ATx|Yk>tL2M9&MVhzo!7!oTWHyT#~O6v{I0*c|()(j9~TlTE9&id48c#o(OV%B)(^V-PLKmOURcI zZ-f|+D~pD_A-`%eD=Zr^X>X&~dku+ljfbe$Tk?to$2?AW69nEq=WU+zq5_n#-n&Ra zugvc2>yu|IVs9n{N#WfX`^NTFHtb28xz0w!vbRDlsMeBJOzgK90|jl^1U{Zr-nAa} zVw=}n*PopJtkIvqyDo|-<*!_#6q3M;x0ESPp0An|)g7)-gSz`pB|M=m zOKWVByt*)>FmLYen>%Mtb!OtlGY()h&lpi_h+s8OZSV?ywPx#HpXV*t%YTIJ?35w;d)OhPm z?@F%{TwSMqta^isRtzk>Y|-*{1J-P@Uy>KO08c3@fj3#MS4<%{!8gg;?>VX9njl-R z1$bi;YN^Wrnvu$+ZAlfML6Z=*+NAX%%!8_zE1SR-{aSX*Y!5rO-En@bQUI#eJo%gp zN_jQ1a;;6=gQ3rKn~FSD=IWr!}*aq85BuUJ_xfhHKoHDtPMjzp^MUdU1_XD zdfFsV|DiyvU$lB~>EOlFJ#R&w5;;Wu3TnOUmM$^P;B+grnIfm6kjzQb?ANxSpDpA` zDd%_AFU=&ZTjW*fi_@zFga%FHbBmt!$!g|;0=Y)Ayq$(W*Jx{4OD zkwA4WI~KPpJ?D0sQESDp{>hRvp}mMZCpY2+IFSy8Y4t7AbfwNl+UTZ7+8A|+bki&?(#Ety zq~m5&`0H$UjC3XFov7p~psmr23_AF48n38ao5sadqGUBmO4)F>N>u6eRFlm3t;e)% zb^vEv3tCkAxOgG01UAT1M9K>6F7ow~DHyF$uaD-INfHmX zv)W9mwB%?L(twEsNO34V*PR2dyfr;bb)rM5jJuImE}gkcfKCyO8>bYFq$3^jz_~GH zRGmzEX;5F|=W=EkmK!SC(V~|Oa;r?j({@o?IBnOnS-lB;p~eKQJ%{P$Y&VgkSI<(+ z)%Qm^88g=)F&7N`^+K(htcembg>>!Wi`IB!!DI(xrC+P#yKnX6x@kzFvfi3ekwj zK%t%sycvZVcJ^ClJXP_A3;u``3@Q~Sz*Id3xSn6fxKzt${hCIO#h|vO?8Y4lIn@K3 za-nfGz5DTy-0F6A274CO+bqyQ9#-P zVTO?M#}vEH#>rHUdlI>j6iLa5NHPjeYPz(Gbq-cMCvx7@&c$Vw;wi4yXi0q6nGhn>LLB4cC4 zczlFzbMF~U=+ zmJ%M;bc-HxW^uaRWwY3oV$BTZ%|N3)tgH^R>f0Jt(|B~}!j*!o9Zz1obcqdex-m;0 zsm7*ovI?)2ps57HO3*H&qBWc^*#%ZF9390&AqnSC=uEnYW>IC>r>44*K;%l8KhkIk zf{{s9i^!T;m!k5=S6o}H7sn_qUaF_{v=ybITSuzYOLj5TXNyBCaDKtMZ1R$NM=dfD zH|vnjsBC7C6m;Lz6UIGmxwjWtPun7BjRzHW9N3zgag({(?6;WFrHpN<)jv_XkHX7r8ag*6j2?t!=E|o~Mv_;4^ZLh~vMD37h z)K&?G>UrX$r9a!CgqhQBo=C4&G23vswZBR*Uascddu9k#loca=~60|F-h+S>m`4P zc`y?4-6&(iaXVXbfn3+qT(Dw1U`k1;5@E zD|(kKnUz^&r@~<};aD>dFZ6R!NR$F>s$~|ty$8*5>^^R@ZN{=4bReX}vOR*wP6sC1 zZzfQo5!?Fg9h<46>p0pB!$dF@A)Ht>rD7XO&QVjlRP&>Skg$oI-@Y@@YA4}an|#w- zQ#DdONs&o7+BA17ymF;YLi0y;wM_%2_ZreH4ozgOy*t(kfi^L_$8N`csR9XKnmM2F z%ao0H&mXyD`eEg?cJWz7Vc~t;XCGDqb}P+{7!>hHl+7=~$+8z`9V$Gtc-XHhs95n# zo!si>eERK@+G$n3^Sd%j@_wN{9^aB3xO~;p)dLF^V_SD*KR(8y-Vk3YK%?`J9 zWFr|4HgoI2Y>$-CKuH~ItZ#ZTh5xwi908Ga+nC9YZkyvUn$!PidI>pazHCsnN(!j<=Sdhx>&nYX6IMF*@CD%i_Y0(E?&KI z-KvGmAiFY`tYm*#rp;3~nWck^7O!1;8Tyh~>dx)-PjjyUNlI z9nfJL*|&S_=I~3i;j*okIWS;Ke$YQ{TE@Jt3J=Iw{bbu|B#iU4j(u~_4bNF5^dn7k z=4Xx08)TN7XI3k1=rb!^(TsdsG!lfGE~+bBVNQxzO($adiLT5btCgV?XBYH3-aN`M zSk4TVo3rEDre9IsFd#PLE0YPQONfI&g+4um*6obR6ycdlL8jGlQ#%qt$7FL?W+kJc z&?*60Nm;98!jO5fUdbIXYB39{{nMISVa_*oS{4n%^FJx z`eNsE&4ze&^SD`N%_RfNmz(;rX4!yyP;rWU#=SL^s7dz0sn%iAyJ%@sUrjaV4_vZ% zlYx3nW!CPAb2ybIN7Ei1eX}By4Bm8r!JOrY^|Z3y$xJrG zF}ewqvMD-)!SlLkjGZ-y;B1wS>6)V8ak7No2WdNoT}O9g$CjavT`%J(Q>c+=l|yaP zx~e}C^mlFEnjfE-=>@qwdt$LOHSX}5XUx4`_TOS6b|fvkBb9`K&FGljkxHxG5og&2 zfUxM4TaUjjH;cn;uBzF4hGNuaspXcT7oVmJUJU3M=hre#Bbd}DKCekV?*lKEBv4vox z=W-gCr;=+mb0;EAc+9#_tH9P_W7a#qZG;EgNGHM=6WCTA-xHZ_)pV!wrE%6>ngK8e zYbSL^aae~Ev)*+|9vV#w@fJ0c(MWx^r&CVlSdXDGVYnEf`i(Ucy|A)4u42W=JT7PW zspFGvf|0~UI(QiWrC7O$K9A#HRSs*pKACfb)?wF6xz09xQ~ycV$+;A^YMJHd++kjw zIWAYUt*coH3roZyvZJNK*m6V6B%BF1dw|H2N^^U{$=NNe+i_Nfo`|7x^Eh(migGIM+TnO@3L^?u*o3s& zn&4b#*q-3N_BGTl*|5c2kIU7{i0np!Rme(t0-=o@Hs*ZxNX0K+<(ao@mkeCAXx;L) z+nn}wI)_Xp#IVyjb(xLZsOG}+%xr0swcU1aGOx36+M=OG*dwrvo!zE)Y}44(r%ZU} z(N1}6|JO^OZF@)#VHLfZ45+;x@-;uqxy$&mV3u3WrYke2rnZikyEUK9*gW40Wz3>@ zQmaL-K3>pve7F*7W+QkJX-E0nW|CN~>SWq#J&bLkTpnY7Y2q2K!&|Dh*g9ZJ`B3>9 zvj$YjG>zRM4OIe+jR8$a$Z966%l({U&v|T;cs(pAcE$ARnO*I6x{UH>tMHj~@61zp z_q^&@P%y*4u=Hw9DEa zBSPpBQP*lczPFV0DCg2-V}^{>O*UrQT7P>wK4W1{!H2bvHC9HSgfOY0sc@vDOA>a7 z8fxKC(pD6Tx*5dMj&kd!?rF(-V{h49x{2MkxY#DTy$^v$p&gB{Oh0bNX(lh}>tp7< z{x&&FN2S{ejO+Ys^kCjNCr(SM*MjL1nRiuNZ0lZ6+%?^PkS{ITI49ktY-L;T>gd*m zbHtP#nmzm^dQoJJc4XVU(T3SbC$)>^R=XRyUt)sPBChkw&R6;4_4*nHIUTylk;=Gq z%}C4^X=7}9blWcIK)7ueTyFI@XX#{E+k$r_RnR?$s3N$wiq1=Y>~Nh$CzDdnCyKB2 z-V`c3qUaBMq%?0nFWy zD}JfU+4?dQv_+LMKbNmp8{Ufi&ar$jkfaTtT@xld#yft01bj3h3B6IuZbm`&?-9@kNQT4NrdQI(gE{o+$^UV?=tCb7$ z)$%##oON#Ryr!(eHXKxX2Ux<?n`H?n8;Vh%C_;Cww5aa!>qaz^74eck}-{&Zj_wy@>qGa z-X=%6@v}}c?bh3*Ydp9{j&|9At+q{aWCb49BKq(Tw7}(gl`(h zRD&_@;`rGujGDsBa1FmWR?6>U4$pzVO1(Bo+6AK|Xo-?M;b%wl5?()^r=&2faaZEF z+kynbb$ok{7F;*t@W*W8awD!#AHvU^KdSNM4!cu9{l%JsHM;XT`Npc~5KUXH(wJoA zPLS=cd0kiJR&qzG5j?JoCsd9dK1(dtrJm6sSK`*(gbC3oW8N|$&IjITu(Ob-fU%9! z@J8tUAD?{A-k4imZtU2eZOAR8wS>Kk(NJ%%*9aOD<$}>K`BBob;!a*_F|OC|aEGow zZpxkR&^63cvq&W_o7r1*V{Q_jxJJjlv`WLYUA+_=Tf%rXg*M@auF^d|SsP;yD?b*y zP}ib2QXx=Di(ISQy%1NbA|W;QZLV+vWNLwzana6JNH<@k0cIB4`KBGhiVtFBPPeYw zt)Cpq2c(*cs4WhZP0w4SqDT#`kD8oo#77fcI4FkYO2YQO-FUe{`ujV|(WSeg0&Pjo zf0_608dF}ntB+4|=Z?TP@7$S}s=a~dHDnOKaYxsvVAUuN6yT^TvqwmEFxrtOwIZh~ zV^b$Qs-h_HX@gpYTC?cxy)Eif3)o9 zHE<@VaH}pKL{1tP#`1R4R^w(l8hKovP~j*lx?i!;tP*fXkv#? z>z?HtFIM9|n_GQYuUG36e$fhZr*DE*Y{d6AtXMiQIJjsbchuId{O}Xjco6Yod1M!M zYFv_h&Z|u@1{gIloQzd4-{cN=_CooINeVYDEahLRgnpDhlco){J&4TKa-9!r(M3OH zsmU;nWa^{aXS0)7d0~iJVwy~3oo7oZbi2mM;vx37Y;ll#7glsRneszhErGfdUq!=A zn{HcCHOkhL>UL&R?yjFQH*|fK?Q6pnjM6-e>YA27dE+m9p0JHZ35N}OmS)k!C2O{F z&Dzx)20o#^`RN{mDy;x`9OTLq!D^n`{G7KY?M|RAqJFN@*p+LR4^uq6TtNrFsC{GR zc3>DtC9KIm+wVT-H4BGoiVaUBR3~@o)S_HVGib3=9rLTED`m1iR;OvGk5wjXlf}Gk zl8dgEMJ{!gH#yQKPv+9X$%ht?n+9H+*Xd5x8rys9?O0uYyN1^N}$~38SIAU7> zuE<3WwuJVDiCCeI7n@ENl(MFen<9atbV!eWOAzGZ9t%d9y2my&TymAIb74pc(r$bz zcPgQgfhi0vd6Y1Gft~NL;WkwxVcI#N+r-k-;?EV^(};(KeUB2jEik+BMUFB)rIMs2 zV~c6LvZtp79ZhLFZ4OQOeZAaf*W`%bHzVN?($+6lQ&=Hq50+GsK!_g_c}2 z(~C*EKYNlgEza*r8a2bTn}U!Gl}+JfNmhEdmHDK#Fn}-1uQp42lH_fc($g=;%vh7= z3H6$;*pxMwWD;&}uGYs}QZda2lCjKt zDS01`bfSVErA>NvBwBadhNRb#gkYU?>lDfs!L~5An0FeJw27%9-R)?g&DL(BU-EOY zzN)=4x!#B69Oa-{9kLBvv)y_@`*4Xu5ss6!p21pCSa_H)yXkz3d}|lcIc-}dJ0)Jb zTzc-e%SGvxUX`Y>knTgWHFEVmS$orcN?Nq_DlAJbNtK@YDn0TjOVVKuXtm2+*ln;Y z%M2%PuIoniZfM7LPLY*!S}~*v$@zA{kh{9&91|@~^c$14pg>jSpLMo_9aVWZrr51q zysZlx%0z-q;YXU?D4X`gki{*jb zrHMMfJK^-uBy7>{Yl&{pyhss_yyzS-HGQ=SE$hh_jvnM=*PRoAiSjaP`oo4RU94GD zw3}8R&!;6~%Qmz@DI^NAx z3O(yIi<7K8JjiE_)=6BRb!pzh@`4sEpwv3osXNE_N#1mb5WWvWeVm*DNZPqjO zw!OK+Z4EbTgr78S4%A``$>CsvDF}mgGcmA%!n?RwxXao>!sk3f&CV;@t!wX%(=!TE zyP=&kCuVYSf9>#*5~6L?4o+}L&TOnQaM7MCJ+`EoVZ|?g$K%7YwRVU*8FMNtycKR7 zp3F8_2}uur=y$lOYfnnM;aC(Antrzyp6-eZP}>}>J-I^vVsQ;Oj+?lMu-Dc1 zATS*_L$vR~#&^9^=eP>1cF)lth1-HINT#@Z@trKiF4{wL9jXFRWUF4Q5n3l>fq;Do zw}*;ZulKmm4!q}&Wk>DKkKIdE>CTPrs)Z8NBjLBlR7+E*Lj92k#&14EHR)*ad5gUeVWh2 z#c#Ez$b?tl?U6Mbm*|Kb=aDq&(g`883gsM46RoA)SF?KdCAJIa^|l4nG0p{cSV)dF67fjoJzIubCFa}u#JQv7-F6*qq0pK-&!C%bP5rGdwsY2_?Pj}* zdCIo9O;a5h-0j%F)Jbh0w=I8lTKz~7OpJD>a?#eXj$4my>q};=(YC19CYJ7hn^;HR zZPRDQQq2ulX{HPwtZcTyHgzyYp|)vFq+8q1js{a%YVNr=JEySbB*$n;^Qp{C0cnco zu5ot$cJQ@5RAurc3LX)fO5mzjXM6AuZSQE@^- zTUD8!_2zsQUqYwnBNSD>jHLolw%70TBdjzfL(d(2cMw6NY=(+itrhE9g*q}8fXpc$ zZ^NPsSFapgx^nOe+J25k(jn+L9)}^q<9JrCXEnd@M*b2VMcWnjz|G{;h(hxYm0-Im zwqb`0r}9{r^9PA`V&~tSDly>+7d0t>cGT4-%lT6bb(D<2MyBI-@||mN4#c#`W}zF2 z_1ssO@N@R0nl*`L9QM?8)Q%L(j~DV2I%5$zYr1}px0z!Hk#4LZFkQM?Se-OJ&Tl&q z5_2tPuVus*vu3y4|4Q5Y+Gasg4nO;RTJ<^Uw zAM^&XVWi!{h@@;MyDK_bMYl}%lyIo&eypH`o=@pZlnwOBlVo_Hvp?7zt!Ax1k?lNT z43E#aQ3?fmScGa9(l%*J0^Ls7PzHnPdDN8Ss9a8_K^+fvl(c&lcsna) zwzN3q%SiXa_)>Z}xbXQVp&dU{aDp8gMHAx=qO6vrRF%%cW~!w&%h)m=;P|?5*k5#W z%w47gx137m!vO16Ewb1Cmn~YmY01hJ=JHGOm~w{mREw6ay<+{K`$7Qakf`bWb9gI0 zwki;omd$2fk7zXAois<1oAt^xE-}+^(ZL?mb4}<<@|Q&p7EyHaz}H6uTC{8f;3e93 zC&E`G-0^3QM`|RidK}tMH(cdrs?yFjnP+pH4Y5AxCY_$2{#NU@bl7R`(8V+qnJs{t9CzT=~hYOKvVPDK^taZ7kxZaf&#(BifW}>i}hen#WKMowdwGCC7LMcWKfd$B9Oc zL*FzkX6~QbN``Kc*lv_T2j`AEV&I8FIqD=VEih3qyAXgJtp?Yv}=NO z+nOm@8oJPi5;S~TXAX$Qx*jv$utRn`+=$-=$gEnq{{EHAsGoFV(dP(k3fN96kDHu< z_OlJ{_8QM@7Z9cdU+v=1A>+dar`=V9qExfC`kZY-tbFFcH0Ru#pCqter8yaQDk0?# zQfqaic_$$pmDppavEhPC88c+*WJuUHX#Lbqs~AoYPW2(xplYrnv>q2le$bQy&5lfr zpKGoGP&DErGgDNYjQeT@6FxS_(z*uofA&pr*kZglp0&D| z{JH_VPYMG6yO8GHn>Y_|-`DFDy_zh7RMV;DJEe*gs^)d`z3@FIgT1|Am99_Vqrl`{Tf1aT}73`9R;@|V>9iUO$*6%l0GNw z>Flh^p5Hf}49>d?H?|VGztLw8+<2pGVw;qVWHuzM@{($aR)xCC0Mtx&qcH}tY>M*~ zcEE0!5!Y#sd7`d|#jj|;SZ7(VzR;4e-K-_) zNse#J@k#~wy;gO1~hzAfv<};%q}9Me;n5RGWTr-5=$MvE_gYE^0;Ok zd}je!@{cueH>KW%mn)(X(yl)HLeH#wFpQbdiMeJw4m>g+S4cBZr3`0=QI}&v64`Zq zw3|L6wAL(sXgNZqO~WRJ2X@@_T%R+wm3?Z{aP80yqSCB}&N7S1=C|vVo<6fs(%ro! zjr>k~-NcO2&Oa3UksE;$UBYSt4#d8U1&|(hdXclD8mt{;RJ&~9|vr$1XY_Zh>w{|P+M;FK_ zZimpB#crK5H|2D*TfH*thGT4TMBiV?PTHCGW@b5jd%-PEXpd)?*%CxAx{(pucCzL} z3k>CBo8s>43+xJQ&oXt#4Mkb|46UbqtmO`J$*qvxIvOpknzF3*T9azMRGey~KBjek z>X%6(9+XJUO);4`9lN|vsaJc@Twg?cj5UrDQ(sfT)ZAp8l+C1eb2Dy@JDaf{+vYGx zy!jck%uM^z?=@J;kAL$)JzaSAjjgL@Yh>4Pj73J(=JOBa#3rWByvDx%fVZx^+V4M1 zOpf@hL$Dj!2BSBW1?1u>~_z m6=;`r&z@#|hdxkX!X39`YJ+W_%r`5NF0u(>Zc?`S{Qm(@dDO)K literal 0 HcmV?d00001 diff --git a/current/po/pl.po b/current/po/pl.po new file mode 100644 index 00000000..94fcd677 --- /dev/null +++ b/current/po/pl.po @@ -0,0 +1,2414 @@ +# shadow.pot Polish translation. +# Copyright (C) 1999 Free Software Foundation, Inc. +# Arkadiusz Mi¶kiewicz , 1999. +# +msgid "" +msgstr "" +"Project-Id-Version: shadow-981228\n" +"POT-Creation-Date: 2000-09-02 20:40+0200\n" +"PO-Revision-Date: 1999-03-02 22:29+01:00\n" +"Last-Translator: Arkadiusz Mi¶kiewicz \n" +"Language-Team: PL \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso8859-2\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libmisc/addgrps.c:60 +#, c-format +msgid "Warning: unknown group %s\n" +msgstr "Ostrze¿enie: nieznana grupa %s\n" + +#: libmisc/addgrps.c:71 +msgid "Warning: too many groups\n" +msgstr "Ostrze¿enie: zbyt wiele grup\n" + +#: libmisc/age.c:104 +msgid "Your password has expired." +msgstr "Twoje has³o straci³o wa¿no¶æ." + +#: libmisc/age.c:107 +msgid "Your password is inactive." +msgstr "Twoje has³o jest nieaktywne." + +#: libmisc/age.c:110 +msgid "Your login has expired." +msgstr "Twoje konto straci³o wa¿no¶æ." + +#: libmisc/age.c:127 +msgid " Contact the system administrator.\n" +msgstr " Skontaktuj siê z administratorem systemu.\n" + +#: libmisc/age.c:130 +msgid " Choose a new password.\n" +msgstr " Wybierz nowe has³o.\n" + +#: libmisc/age.c:228 +#, c-format +msgid "Your password will expire in %ld days.\n" +msgstr "Twoje has³o straci wa¿no¶æ w ci±gu %ld dni.\n" + +#: libmisc/age.c:230 +msgid "Your password will expire tomorrow.\n" +msgstr "Jutro twoje has³o straci wa¿no¶æ.\n" + +#: libmisc/age.c:232 +msgid "Your password will expire today.\n" +msgstr "Dzi¶ twoje has³o straci wa¿no¶æ.\n" + +#: libmisc/chowntty.c:110 +#, c-format +msgid "Unable to change tty %s" +msgstr "Nie mo¿na zmieniæ tty %s" + +#: libmisc/env.c:160 +msgid "Environment overflow\n" +msgstr "Przepe³nienie ¶rodowiska\n" + +#: libmisc/env.c:200 +#, c-format +msgid "You may not change $%s\n" +msgstr "Nie mo¿esz zmieniaæ $%s\n" + +#: libmisc/failure.c:238 +#, c-format +msgid "%d %s since last login. Last was %s on %s.\n" +msgstr "" +"%d %s od ostatniego logowania. Ostatnie logowanie: dnia %s na terminalu " +"%s.\n" + +#: libmisc/failure.c:239 +msgid "failures" +msgstr "niepowodzenia" + +#: libmisc/failure.c:239 +msgid "failure" +msgstr "niepowodzenie" + +#: libmisc/limits.c:397 +msgid "Too many logins.\n" +msgstr "Zbyt wiele otwartych sesji.\n" + +#: libmisc/login_desrpc.c:63 +#, c-format +msgid "Password does not decrypt secret key for %s.\n" +msgstr "Tym has³em nie mo¿na zdeszyfrowaæ tajnego klucza dla %s.\n" + +#: libmisc/login_desrpc.c:69 +#, c-format +msgid "Could not set %s's secret key: is the keyserv daemon running?\n" +msgstr "Nie mogê ustawiæ tajnego klucza dla %s: czy serwer kluczy dzia³a?\n" + +#: libmisc/mail.c:62 libmisc/mail.c:77 +msgid "You have new mail." +msgstr "Masz now± pocztê." + +#: libmisc/mail.c:73 +msgid "No mail." +msgstr "Nie masz poczty." + +#: libmisc/mail.c:75 +msgid "You have mail." +msgstr "Masz pocztê." + +#: libmisc/obscure.c:281 src/passwd.c:309 +#, c-format +msgid "Bad password: %s. " +msgstr "Z³e has³o: %s. " + +#: libmisc/pam_pass.c:42 +#, c-format +msgid "passwd: pam_start() failed, error %d\n" +msgstr "passwd: pam_start() nie powiod³o siê, b³±d %d\n" + +#: libmisc/pam_pass.c:49 +#, c-format +msgid "passwd: %s\n" +msgstr "passwd: %s\n" + +#: libmisc/setupenv.c:205 +#, c-format +msgid "Unable to cd to \"%s\"\n" +msgstr "Nie mogê zmieniæ katalogu na \"%s\"\n" + +#: libmisc/setupenv.c:213 +msgid "No directory, logging in with HOME=/" +msgstr "Brak katalogu, logujê z HOME=/" + +#: libmisc/shell.c:78 +#, c-format +msgid "Executing shell %s\n" +msgstr "Uruchamiam pow³okê %s\n" + +#. +#. * Obviously something is really wrong - I can't figure out +#. * how to execute this stupid shell, so I might as well give +#. * up in disgust ... +#. +#: libmisc/shell.c:122 +#, c-format +msgid "Cannot execute %s" +msgstr "Nie mogê uruchomiæ %s" + +#: libmisc/suauth.c:99 +msgid "Access to su to that account DENIED.\n" +msgstr "Dostêp do polecenia su z tego konta ZABRONIONY.\n" + +#: libmisc/suauth.c:106 +msgid "Password authentication bypassed.\n" +msgstr "Uwierzytelnianie na podstawie has³a pominiête.\n" + +#: libmisc/suauth.c:113 +msgid "Please enter your OWN password as authentication.\n" +msgstr "Proszê wpisz swoje W£ASNE has³o jako has³o uwierzytelniaj±ce.\n" + +#: libmisc/sub.c:61 +#, c-format +msgid "Invalid root directory \"%s\"\n" +msgstr "Nieprawid³owy katalog g³ówny \"%s\"\n" + +#: libmisc/sub.c:73 +#, c-format +msgid "Can't change root directory to \"%s\"\n" +msgstr "Nie mogê zmieniæ g³ównego katalogu na \"%s\"\n" + +#: libmisc/xmalloc.c:28 +#, c-format +msgid "malloc(%d) failed\n" +msgstr "malloc(%d) nie powiod³o siê\n" + +#: lib/dialchk.c:71 +msgid "Dialup Password: " +msgstr "Has³o dostêpu modemowego: " + +#: lib/getdef.c:253 +msgid "Could not allocate space for config info.\n" +msgstr "Nie mogê przydzieliæ miejsca dla informacji o konfiguracji.\n" + +#. +#. * Item was never found. +#. +#: lib/getdef.c:307 +#, c-format +msgid "configuration error - unknown item '%s' (notify administrator)\n" +msgstr "" +"b³±d w konfiguracji - nieznana pozycja '%s' (powiadom administratora)\n" + +#: lib/getdef.c:394 +#, c-format +msgid "error - lookup '%s' failed\n" +msgstr "b³±d - wyszukiwanie '%s' niepowiod³o siê\n" + +#: lib/getdef.c:402 +#, c-format +msgid "%s not found\n" +msgstr "%s nie znaleziony\n" + +#. +#. * get the password from her, and set the salt for +#. * the decryption from the group file. +#. +#: lib/pwauth.c:54 src/newgrp.c:305 +msgid "Password: " +msgstr "Has³o: " + +#: lib/pwauth.c:56 +#, c-format +msgid "%s's Password: " +msgstr "Has³o u¿ytkownika %s: " + +#: lib/pwauth.c:270 +msgid "(Echo on) " +msgstr "" + +#: lib/strerror.c:20 +#, c-format +msgid "Unknown error %d" +msgstr "Nieznany b³±d %d" + +#: src/chage.c:156 +#, c-format +msgid "" +"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n" +" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n" +msgstr "" +"U¿ycie: %s [ -l ] [ -m min_dni ] [ -M maks_dni ] [ -W ostrze¿ ]\n" +" [ -I nieaktywne ] [ -E utrata_wa¿no¶ci ] [ -d ostatni_dzieñ ] u¿ytkownik\n" + +#: src/chage.c:158 +#, c-format +msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n" +msgstr "" +"U¿ycie: %s [ -l ] [ -m min_dni ] [ -M maks_dni ] [ -d ostatni_dzieñ ] " +"u¿ytkownik\n" + +#: src/chage.c:193 +msgid "" +"Enter the new value, or press return for the default\n" +"\n" +msgstr "" +"Wpisz now± warto¶æ lub wci¶nij return by przyj±c warto¶æ domy¶ln±\n" +"\n" + +#: src/chage.c:196 +msgid "Minimum Password Age" +msgstr "Minimalny wiek has³a" + +#: src/chage.c:201 +msgid "Maximum Password Age" +msgstr "Maksymalny wiek has³a" + +#: src/chage.c:207 +msgid "Last Password Change (YYYY-MM-DD)" +msgstr "Ostatnia zmiana has³a (RRRR-MM-DD)" + +#: src/chage.c:216 +msgid "Password Expiration Warning" +msgstr "Ostrze¿enie o utracie wa¿no¶ci has³a" + +#: src/chage.c:221 +msgid "Password Inactive" +msgstr "Has³o nieaktywne" + +#: src/chage.c:227 +msgid "Account Expiration Date (YYYY-MM-DD)" +msgstr "Data utraty wa¿no¶ci konta (RRRR-MM-DD)" + +#. +#. * Start with the easy numbers - the number of days before the +#. * password can be changed, the number of days after which the +#. * password must be chaged, the number of days before the +#. * password expires that the user is told, and the number of +#. * days after the password expires that the account becomes +#. * unusable. +#. +#: src/chage.c:281 +#, c-format +msgid "Minimum:\t%ld\n" +msgstr "Minimum:\t%ld\n" + +#: src/chage.c:282 +#, c-format +msgid "Maximum:\t%ld\n" +msgstr "Maksimim:\t%ld\n" + +#: src/chage.c:284 +#, c-format +msgid "Warning:\t%ld\n" +msgstr "Ostrze¿enie:\t%ld\n" + +#: src/chage.c:285 +#, c-format +msgid "Inactive:\t%ld\n" +msgstr "Nieaktywne:\t%ld\n" + +#. +#. * The "last change" date is either "Never" or the date the +#. * password was last modified. The date is the number of +#. * days since 1/1/1970. +#. +#: src/chage.c:294 +msgid "Last Change:\t\t" +msgstr "Ostatnia zmiana:\t\t" + +#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340 +msgid "Never\n" +msgstr "Nigdy\n" + +#. +#. * The password expiration date is determined from the last +#. * change date plus the number of days the password is valid +#. * for. +#. +#: src/chage.c:308 +msgid "Password Expires:\t" +msgstr "Has³o traci wa¿no¶æ:\t" + +#. +#. * The account becomes inactive if the password is expired +#. * for more than "inactdays". The expiration date is calculated +#. * and the number of inactive days is added. The resulting date +#. * is when the active will be disabled. +#. +#: src/chage.c:324 +#, fuzzy +msgid "Password Inactive:\t" +msgstr "Has³o nieaktywne:\t" + +#. +#. * The account will expire on the given date regardless of the +#. * password expiring or not. +#. +#: src/chage.c:338 +#, fuzzy +msgid "Account Expires:\t" +msgstr "Has³o traci wa¿no¶æ:\t" + +#: src/chage.c:486 +#, c-format +msgid "%s: do not include \"l\" with other flags\n" +msgstr "%s: nie ³±cz \"l\" z innymi flagami\n" + +#: src/chage.c:498 src/chage.c:610 src/login.c:529 +#, c-format +msgid "%s: permission denied\n" +msgstr "%s: odmowa dostêpu\n" + +#: src/chage.c:510 src/chpasswd.c:120 +#, c-format +msgid "%s: can't lock password file\n" +msgstr "%s: nie mogê zablokowaæ pliku z has³ami\n" + +#: src/chage.c:516 src/chpasswd.c:124 +#, c-format +msgid "%s: can't open password file\n" +msgstr "%s: nie mogê otworzyæ pliku z has³ami\n" + +#: src/chage.c:523 +#, c-format +msgid "%s: unknown user: %s\n" +msgstr "%s: nieznany u¿ytkownik: %s\n" + +#: src/chage.c:542 +#, c-format +msgid "%s: can't lock shadow password file\n" +msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n" + +#: src/chage.c:549 +#, c-format +msgid "%s: can't open shadow password file\n" +msgstr "%s: nie mogê otworzyæ pliku z ukrytymi has³ami\n" + +#: src/chage.c:631 +#, c-format +msgid "Changing the aging information for %s\n" +msgstr "Zmieniam informacjê o u¿ytkowniku %s\n" + +#: src/chage.c:633 +#, c-format +msgid "%s: error changing fields\n" +msgstr "%s: b³±d podczas zmieniania pól\n" + +#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183 +#, c-format +msgid "%s: can't update password file\n" +msgstr "%s: nie mogê zaktualizowaæ pliku z has³ami\n" + +#: src/chage.c:690 src/pwunconv.c:178 +#, c-format +msgid "%s: can't update shadow password file\n" +msgstr "%s: nie mogê zaktualizowaæ pliku z ukrytymi has³ami\n" + +#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409 +#: src/passwd.c:825 src/passwd.c:926 +msgid "Error updating the DBM password entry.\n" +msgstr "B³±d podczas aktualizacki bazy hase³ DBM.\n" + +#: src/chage.c:771 +#, c-format +msgid "%s: can't rewrite shadow password file\n" +msgstr "%s: nie mogê przepisaæ pliku z ukrytymi has³ami\n" + +#: src/chage.c:785 +#, c-format +msgid "%s: can't rewrite password file\n" +msgstr "%s: nie mogê przepisaæ pliku z has³ami\n" + +#: src/chage.c:836 +#, c-format +msgid "%s: no aging information present\n" +msgstr "%s: brak informacji\n" + +#: src/chfn.c:107 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n" +"\t[ -h home_ph ] [ -o other ] [ user ]\n" +msgstr "" +"U¿ycie: %s [ -f imiê_nazwisko ] [ -r nr_pokoju ] [ -w tel_praca ]\n" +"\t[ -h tel_dom ] [ -o inne ] [ u¿ytkownik ]\n" + +#: src/chfn.c:111 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n" +msgstr "" +"U¿ycie: %s [ -f imiê_nazwisko ] [ -r nr_pokoju ] [ -w tel_praca ] [ -h " +"tel_dom ]\n" + +#: src/chfn.c:163 src/chsh.c:119 +msgid "Enter the new value, or press return for the default\n" +msgstr "Wpisz now± warto¶æ lub wci¶nij return by przyj±c warto¶æ standardow±\n" + +#: src/chfn.c:166 +msgid "Full Name" +msgstr "Imiê i nazwisko" + +#: src/chfn.c:168 +#, c-format +msgid "\tFull Name: %s\n" +msgstr "\tImiê i nazwisko: %s\n" + +#: src/chfn.c:171 +msgid "Room Number" +msgstr "Numer pokoju" + +#: src/chfn.c:173 +#, c-format +msgid "\tRoom Number: %s\n" +msgstr "\tNumer pokoju: %s\n" + +#: src/chfn.c:176 +msgid "Work Phone" +msgstr "Telefon do pracy" + +#: src/chfn.c:178 +#, c-format +msgid "\tWork Phone: %s\n" +msgstr "\tTelefon do pracy: %s\n" + +#: src/chfn.c:181 +msgid "Home Phone" +msgstr "Telefon domowy" + +#: src/chfn.c:183 +#, c-format +msgid "\tHome Phone: %s\n" +msgstr "\tTelefon domowy: %s\n" + +#: src/chfn.c:186 +msgid "Other" +msgstr "Inne" + +#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330 +#: src/chfn.c:391 src/passwd.c:1226 +#, c-format +msgid "%s: Permission denied.\n" +msgstr "%s: Brak praw dostêpu.\n" + +#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277 +#, c-format +msgid "%s: Unknown user %s\n" +msgstr "%s: Nieznany u¿ytkownik %s\n" + +#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207 +#, c-format +msgid "%s: Cannot determine your user name.\n" +msgstr "%s: Nie mogê ustaliæ twojej nazwy u¿ytkownika.\n" + +#: src/chfn.c:373 src/chsh.c:250 +#, c-format +msgid "%s: cannot change user `%s' on NIS client.\n" +msgstr "%s: nie mogê zmieniæ u¿ytkownika `%s' na kliencie NIS.\n" + +#: src/chfn.c:378 src/chsh.c:257 +#, c-format +msgid "%s: `%s' is the NIS master for this client.\n" +msgstr "%s: `%s' jest nadrzêdnym serwerm NIS dla tego klienta.\n" + +#: src/chfn.c:453 +#, c-format +msgid "Changing the user information for %s\n" +msgstr "Zmieniam informacjê o u¿ytkowniku %s\n" + +#: src/chfn.c:462 +#, c-format +msgid "%s: invalid name: \"%s\"\n" +msgstr "%s: nieprawid³owa nazwa: \"%s\"\n" + +#: src/chfn.c:467 +#, c-format +msgid "%s: invalid room number: \"%s\"\n" +msgstr "%s: nieprawid³owy numer pokoju: \"%s\"\n" + +#: src/chfn.c:472 +#, c-format +msgid "%s: invalid work phone: \"%s\"\n" +msgstr "%s: nieprawid³owy numer telefonu do pracy: \"%s\"\n" + +#: src/chfn.c:477 +#, c-format +msgid "%s: invalid home phone: \"%s\"\n" +msgstr "%s: nieprawid³owy numer telefonu domowego: \"%s\"\n" + +#: src/chfn.c:482 +#, c-format +msgid "%s: \"%s\" contains illegal characters\n" +msgstr "%s: \"%s\" zawiera nieprawid³owe znaki\n" + +#: src/chfn.c:494 +#, c-format +msgid "%s: fields too long\n" +msgstr "%s: pola zbyt d³ugie\n" + +#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388 +msgid "Cannot change ID to root.\n" +msgstr "Nie mogê zmieniæ ID na root.\n" + +#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880 +msgid "Cannot lock the password file; try again later.\n" +msgstr "Nie mogê zablokowaæ pliku z has³ami; spróbuj pó¼niej.\n" + +#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885 +msgid "Cannot open the password file.\n" +msgstr "Nie mogê otworzyæ pliku z has³ami.\n" + +#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313 +#, c-format +msgid "%s: %s not found in /etc/passwd\n" +msgstr "%s: %s nie znaleziony w /etc/passwd\n" + +#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920 +#: src/passwd.c:960 +msgid "Error updating the password entry.\n" +msgstr "B³±d podczas aktualizacji wpisu do bazy hase³.\n" + +#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933 +msgid "Cannot commit password file changes.\n" +msgstr "Wprowadzenie zmian do pliku passwd jest niemo¿liwe.\n" + +#: src/chfn.c:592 src/chsh.c:431 +msgid "Cannot unlock the password file.\n" +msgstr "Nie mogê usun±c blokady z pliku z has³ami.\n" + +#: src/chpasswd.c:76 +#, c-format +msgid "usage: %s [-e]\n" +msgstr "u¿ycie: %s [-e]\n" + +#: src/chpasswd.c:132 src/pwconv.c:104 +#, c-format +msgid "%s: can't lock shadow file\n" +msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n" + +#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118 +#: src/pwunconv.c:123 +#, c-format +msgid "%s: can't open shadow file\n" +msgstr "%s: nie mogê otworzyæ pliku z ukrytymi has³ami\n" + +#: src/chpasswd.c:159 src/newusers.c:415 +#, c-format +msgid "%s: line %d: line too long\n" +msgstr "%s: linia %d: linia zbyt d³uga\n" + +#: src/chpasswd.c:179 +#, c-format +msgid "%s: line %d: missing new password\n" +msgstr "%s: linia %d: brakuje nowego has³a\n" + +#: src/chpasswd.c:195 +#, c-format +msgid "%s: line %d: unknown user %s\n" +msgstr "%s: linia %d: nieznany u¿ytkownik %s\n" + +#: src/chpasswd.c:247 +#, c-format +msgid "%s: line %d: cannot update password entry\n" +msgstr "%s: linia %d: nie mogê zaktualizowaæ wpisu do bazy hase³\n" + +#: src/chpasswd.c:263 src/newusers.c:535 +#, c-format +msgid "%s: error detected, changes ignored\n" +msgstr "%s: wykryto b³±d, zignorowano modyfikacje\n" + +#: src/chpasswd.c:274 +#, c-format +msgid "%s: error updating shadow file\n" +msgstr "%s: b³±d podczas aktualizacji pliku z ukrytymi has³ami\n" + +#: src/chpasswd.c:282 +#, c-format +msgid "%s: error updating password file\n" +msgstr "%s: b³±d podczas aktualizacji pliku z has³ami\n" + +#: src/chsh.c:105 +#, c-format +msgid "Usage: %s [ -s shell ] [ name ]\n" +msgstr "U¿ycie: %s [ -s pow³oka ] [ nazwa ]\n" + +#: src/chsh.c:120 +msgid "Login Shell" +msgstr "Pow³oka logowania" + +#: src/chsh.c:273 src/chsh.c:286 +#, c-format +msgid "You may not change the shell for %s.\n" +msgstr "Nie mo¿esz zmieniaæ pow³oki dla %s.\n" + +#: src/chsh.c:315 +#, c-format +msgid "Changing the login shell for %s\n" +msgstr "Zmieniam pow³okê logowania dla %s\n" + +#: src/chsh.c:327 +#, c-format +msgid "%s: Invalid entry: %s\n" +msgstr "%s: Nieprawid³owy wpis: %s\n" + +#: src/chsh.c:332 +#, c-format +msgid "%s is an invalid shell.\n" +msgstr "%s jest nieprawid³ow± pow³ok±.\n" + +#: src/dpasswd.c:69 +#, c-format +msgid "Usage: %s [ -(a|d) ] shell\n" +msgstr "U¿ycie: %s [ -(a|d) ] pow³oka\n" + +#: src/dpasswd.c:134 +msgid "Shell password: " +msgstr "Has³o pow³oki: " + +#: src/dpasswd.c:140 +msgid "re-enter Shell password: " +msgstr "Wpisz ponownie has³o pow³oki: " + +#: src/dpasswd.c:147 +#, c-format +msgid "%s: Passwords do not match, try again.\n" +msgstr "%s: Has³a nie pasuj±, spróbuj ponownie.\n" + +#: src/dpasswd.c:167 +#, c-format +msgid "%s: can't create %s" +msgstr "%s: nie mogê utworzyæ %s" + +#: src/dpasswd.c:172 +#, c-format +msgid "%s: can't open %s" +msgstr "%s: nie mogê otworzyæ %s" + +#: src/dpasswd.c:200 +#, c-format +msgid "%s: Shell %s not found.\n" +msgstr "%s: Pow³oka %s nie znaleziona.\n" + +#: src/expiry.c:84 +msgid "Usage: expiry { -f | -c }\n" +msgstr "U¿ycie: expiry { -f | -c }\n" + +#: src/expiry.c:137 +#, c-format +msgid "%s: WARNING! Must be set-UID root!\n" +msgstr "%s: OSTRZE¯ENIE! Program musi posiadaæ SUID root!\n" + +#: src/expiry.c:148 +#, c-format +msgid "%s: unknown user\n" +msgstr "%s: nieznany u¿ytkownik\n" + +#: src/faillog.c:79 +#, c-format +msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n" +msgstr "u¿ycie: %s [-a|-u u¿ytkownik] [-m maks] [-r] [-t dni] [-l bloksek]\n" + +#: src/faillog.c:134 src/lastlog.c:94 +#, c-format +msgid "Unknown User: %s\n" +msgstr "Nieznany u¿ytkownik: %s\n" + +#: src/faillog.c:215 +msgid "Username Failures Maximum Latest\n" +msgstr "U¿ytkownik Niepowodzenia Maksymalnie Ostatnio\n" + +#: src/faillog.c:232 +#, c-format +msgid " %s on %s" +msgstr " %s na %s" + +#: src/faillog.c:236 +#, c-format +msgid " [%lds left]" +msgstr " [%lds pozosta³o]" + +#: src/faillog.c:239 +#, c-format +msgid " [%lds lock]" +msgstr " [%lds blokada]" + +#: src/gpasswd.c:89 +#, c-format +msgid "usage: %s [-r|-R] group\n" +msgstr "u¿ycie: %s [-r|-R] grupa\n" + +#: src/gpasswd.c:90 +#, c-format +msgid " %s [-a user] group\n" +msgstr " %s [-a u¿ytkownik] grupa\n" + +#: src/gpasswd.c:91 +#, c-format +msgid " %s [-d user] group\n" +msgstr " %s [-d u¿ytkownik] grupa\n" + +#: src/gpasswd.c:93 +#, c-format +msgid " %s [-A user,...] [-M user,...] group\n" +msgstr " %s [-A u¿ytkownik,...] [-M u¿ytkownik,...] grupa\n" + +#: src/gpasswd.c:96 +#, c-format +msgid " %s [-M user,...] group\n" +msgstr " %s [-M u¿ytkownik,...] grupa\n" + +#: src/gpasswd.c:160 src/gpasswd.c:245 +#, c-format +msgid "%s: unknown user %s\n" +msgstr "%s: nieznany u¿ytkownik %s\n" + +#: src/gpasswd.c:172 +msgid "Permission denied.\n" +msgstr "Dostêp zabroniony.\n" + +#: src/gpasswd.c:257 +#, c-format +msgid "%s: shadow group passwords required for -A\n" +msgstr "%s: plik z ukrytymi has³ami grup wymagany dla -A\n" + +#: src/gpasswd.c:308 +msgid "Who are you?\n" +msgstr "Kim jeste¶?\n" + +#: src/gpasswd.c:328 src/newgrp.c:251 +#, c-format +msgid "unknown group: %s\n" +msgstr "nieznana grupa: %s\n" + +#: src/gpasswd.c:436 +#, c-format +msgid "Adding user %s to group %s\n" +msgstr "Dodajê nowego u¿ytkownika %s do grupy %s\n" + +#: src/gpasswd.c:453 +#, c-format +msgid "Removing user %s from group %s\n" +msgstr "Usuwam u¿ytkownika %s z grupy %s\n" + +#: src/gpasswd.c:466 +#, c-format +msgid "%s: unknown member %s\n" +msgstr "%s: nieznany cz³onek %s\n" + +#: src/gpasswd.c:513 +#, c-format +msgid "%s: Not a tty\n" +msgstr "%s: To nie tty\n" + +#. +#. * A new password is to be entered and it must be encrypted, +#. * etc. The password will be prompted for twice, and both +#. * entries must be identical. There is no need to validate +#. * the old password since the invoker is either the group +#. * owner, or root. +#. +#: src/gpasswd.c:535 +#, c-format +msgid "Changing the password for group %s\n" +msgstr "Zmieniam has³o dla grupy %s\n" + +#: src/gpasswd.c:538 +msgid "New Password: " +msgstr "Nowe has³o: " + +#: src/gpasswd.c:543 src/passwd.c:422 +msgid "Re-enter new password: " +msgstr "Wpisz has³o ponownie: " + +#: src/gpasswd.c:555 +msgid "They don't match; try again" +msgstr "Nie pasuj±; spróbuj ponownie" + +#: src/gpasswd.c:559 +#, c-format +msgid "%s: Try again later\n" +msgstr "%s: Spróbuj ponownie pó¼niej\n" + +#: src/gpasswd.c:590 +#, c-format +msgid "%s: can't get lock\n" +msgstr "%s: nie mogê zablokowaæ\n" + +#: src/gpasswd.c:596 +#, c-format +msgid "%s: can't get shadow lock\n" +msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n" + +#: src/gpasswd.c:602 +#, c-format +msgid "%s: can't open file\n" +msgstr "%s: nie mogê otworzyæ pliku\n" + +#: src/gpasswd.c:614 +#, c-format +msgid "%s: can't update entry\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu\n" + +#: src/gpasswd.c:620 +#, c-format +msgid "%s: can't update shadow entry\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu do pliku z ukrytymi has³ami\n" + +#: src/gpasswd.c:626 +#, c-format +msgid "%s: can't re-write file\n" +msgstr "%s: nie mogê przepisaæ pliku\n" + +#: src/gpasswd.c:632 +#, c-format +msgid "%s: can't re-write shadow file\n" +msgstr "%s: nie mogê przepisaæ pliku z ukrytymi has³ami\n" + +#: src/gpasswd.c:640 +#, c-format +msgid "%s: can't unlock file\n" +msgstr "%s: nie mogê usun±c blokady z pliku\n" + +#: src/gpasswd.c:645 +#, c-format +msgid "%s: can't update DBM files\n" +msgstr "%s: nie mogê zaktualizwoaæ plików DBM\n" + +#: src/gpasswd.c:652 +#, c-format +msgid "%s: can't update DBM shadow files\n" +msgstr "%s: nie mogê zaktualizowaæ pliku DBM z ukrytymi has³ami\n" + +#: src/groupadd.c:105 +msgid "usage: groupadd [-g gid [-o]] group\n" +msgstr "u¿ycie: groupadd [-g gid [-o]] grupa\n" + +#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230 +#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675 +#, c-format +msgid "%s: error adding new group entry\n" +msgstr "%s: b³±d podczas dodawania nowej grupy\n" + +#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942 +#: src/usermod.c:551 src/usermod.c:687 +#, c-format +msgid "%s: cannot add new dbm group entry\n" +msgstr "%s: nie mogê dodaæ nowego wpisu do bazy dbm grup\n" + +#: src/groupadd.c:258 src/useradd.c:996 +#, c-format +msgid "%s: name %s is not unique\n" +msgstr "%s: nazwa %s nie jest niepowtarzalny\n" + +#: src/groupadd.c:273 +#, c-format +msgid "%s: gid %ld is not unique\n" +msgstr "%s: gid %ld nie jest niepowtarzalny\n" + +#: src/groupadd.c:297 +#, c-format +msgid "%s: can't get unique gid\n" +msgstr "%s: nie mogê uzyskaæ niepowtarzalnego gid\n" + +#. +#. * All invalid group names land here. +#. +#: src/groupadd.c:321 src/groupmod.c:341 +#, c-format +msgid "%s: %s is a not a valid group name\n" +msgstr "%s: %s: nie jest prawid³ow± nazw± grupy\n" + +#: src/groupadd.c:350 src/groupmod.c:367 +#, c-format +msgid "%s: invalid group %s\n" +msgstr "%s: nieprawid³owa grupa %s\n" + +#: src/groupadd.c:367 src/useradd.c:1272 +#, c-format +msgid "%s: -O requires NAME=VALUE\n" +msgstr "%s: -O wymaga ZMIENNA=WARTO¦Æ\n" + +#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381 +#: src/userdel.c:303 src/usermod.c:563 +#, c-format +msgid "%s: cannot rewrite group file\n" +msgstr "%s: nie mogê przepisaæ pliku z grupami\n" + +#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389 +#: src/userdel.c:309 src/usermod.c:700 +#, c-format +msgid "%s: cannot rewrite shadow group file\n" +msgstr "%s: nie mogê przepisaæ pliku z ukrytymi grupami\n" + +#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389 +#, c-format +msgid "%s: unable to lock group file\n" +msgstr "%s: nie mogê zablokowaæ pliku z grupami\n" + +#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432 +#, c-format +msgid "%s: unable to open group file\n" +msgstr "%s: nie mogê otworzyæ pliku z grupami\n" + +#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398 +#, c-format +msgid "%s: unable to lock shadow group file\n" +msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi grupami\n" + +#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442 +#, c-format +msgid "%s: unable to open shadow group file\n" +msgstr "%s: nie mogê otworzyæ pliku z ukrytymi grupami\n" + +#: src/groupadd.c:518 +#, c-format +msgid "%s: group %s exists\n" +msgstr "%s: grupa %s istnieje\n" + +#: src/groupdel.c:86 +msgid "usage: groupdel group\n" +msgstr "u¿ycie: groupdel grupa\n" + +#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234 +#, c-format +msgid "%s: error removing group entry\n" +msgstr "%s: b³±d podczas usuwania grupy\n" + +#: src/groupdel.c:116 src/groupmod.c:206 +#, c-format +msgid "%s: error removing group dbm entry\n" +msgstr "%s: b³±d podczas usuwania wpisu dbm o grupie\n" + +#: src/groupdel.c:131 +#, c-format +msgid "%s: error removing shadow group entry\n" +msgstr "%s: b³±d podczas usuwania wpisu o ukrytej grupie\n" + +#: src/groupdel.c:144 src/groupmod.c:252 +#, c-format +msgid "%s: error removing shadow group dbm entry\n" +msgstr "%s: b³±d podczas usuwania wpisu dbm z pliku ukrytych grup\n" + +#. +#. * Can't remove the group. +#. +#: src/groupdel.c:248 +#, c-format +msgid "%s: cannot remove user's primary group.\n" +msgstr "%s: nie mogê usun±æ podstawowej grupy u¿ytkowników.\n" + +#: src/groupdel.c:305 src/groupmod.c:501 +#, c-format +msgid "%s: group %s does not exist\n" +msgstr "%s: grupa %s nie isnieje\n" + +#: src/groupdel.c:319 src/groupmod.c:517 +#, c-format +msgid "%s: group %s is a NIS group\n" +msgstr "%s: grupa %s jest grup± NIS\n" + +#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016 +#, c-format +msgid "%s: %s is the NIS master\n" +msgstr "%s: %s jest g³ównym serwerem NIS\n" + +#: src/groupmod.c:105 +msgid "usage: groupmod [-g gid [-o]] [-n name] group\n" +msgstr "u¿ycie: groupmod [-g gid [-o]] [-n nazwa] grupa\n" + +#: src/groupmod.c:165 +#, fuzzy, c-format +msgid "%s: %s not found in /etc/group\n" +msgstr "%s: %s nie znaleziony w /etc/passwd\n" + +#: src/groupmod.c:246 +#, c-format +msgid "%s: cannot add new dbm shadow group entry\n" +msgstr "%s: nie mogê dodaæ nowego wpisu dbm do pliku z ukrytymi grupami\n" + +#: src/groupmod.c:299 +#, c-format +msgid "%s: %ld is not a unique gid\n" +msgstr "%s: %ld nie jest niepowtarzalnym gid\n" + +#: src/groupmod.c:330 +#, c-format +msgid "%s: %s is not a unique name\n" +msgstr "%s: %s nie jest niepowtarzaln± nazw±\n" + +#: src/groups.c:62 +#, c-format +msgid "unknown user %s\n" +msgstr "nieznany u¿ytkownik %s\n" + +#: src/grpck.c:98 +#, c-format +msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n" +msgstr "U¿ycie: %s [ -r ] [ grupa [ gshadow ] ]\n" + +#: src/grpck.c:100 +#, c-format +msgid "Usage: %s [ -r ] [ group ]\n" +msgstr "U¿ycie: %s [ -r ] [ grupa ]\n" + +#: src/grpck.c:119 src/pwck.c:119 +msgid "No" +msgstr "Nie" + +#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225 +#, c-format +msgid "%s: cannot lock file %s\n" +msgstr "%s: nie mogê zablokowaæ pliku %s\n" + +#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241 +#: src/pwck.c:250 +#, c-format +msgid "%s: cannot open file %s\n" +msgstr "%s: nie mogê otworzyæ pliku %s\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:298 +msgid "invalid group file entry\n" +msgstr "nieprawid³owy wpis do pliku grup\n" + +#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517 +#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517 +#: src/pwck.c:541 +#, c-format +msgid "delete line `%s'? " +msgstr "usun±c liniê `%s'? " + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:361 +msgid "duplicate group entry\n" +msgstr "duplikat wpisu grup\n" + +#: src/grpck.c:378 +#, c-format +msgid "invalid group name `%s'\n" +msgstr "nieprawid³owa nazwa grupy `%s'\n" + +#: src/grpck.c:388 +#, c-format +msgid "group %s: bad GID (%d)\n" +msgstr "grupa %s: z³y GID (%d)\n" + +#: src/grpck.c:414 +#, c-format +msgid "group %s: no user %s\n" +msgstr "grupa %s: nie ma u¿ytkownika %s\n" + +#: src/grpck.c:416 src/grpck.c:585 +#, c-format +msgid "delete member `%s'? " +msgstr "skasowaæ cz³onka `%s'? " + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:453 +msgid "invalid shadow group file entry\n" +msgstr "nieprawid³owy wpis do pliku z ukrytymi has³ami\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:516 +msgid "duplicate shadow group entry\n" +msgstr "duplikuj±cy siê wpis w pliku ukrytych grup\n" + +#: src/grpck.c:533 +msgid "no matching group file entry\n" +msgstr "brak pasuj±cego wpisu w pliku grup\n" + +#: src/grpck.c:553 +#, c-format +msgid "shadow group %s: no administrative user %s\n" +msgstr "ukryta grupa %s: brak u¿ytkownika administracyjnego %s\n" + +#: src/grpck.c:555 +#, c-format +msgid "delete administrative member `%s'? " +msgstr "usun±æ cz³onka administracyjnego `%s'? " + +#: src/grpck.c:583 +#, c-format +msgid "shadow group %s: no user %s\n" +msgstr "ukryta grupa %s: nie ma u¿ytkownika %s\n" + +#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580 +#, c-format +msgid "%s: cannot update file %s\n" +msgstr "%s: nie mogê zaktualizowaæ pliku %s\n" + +#: src/grpck.c:640 src/pwck.c:606 +#, c-format +msgid "%s: the files have been updated; run mkpasswd\n" +msgstr "%s: pliki zosta³y zaktualizowane; uruchom mkpasswd\n" + +#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611 +#, c-format +msgid "%s: no changes\n" +msgstr "%s: bez zmian\n" + +#: src/grpck.c:644 src/pwck.c:610 +#, c-format +msgid "%s: the files have been updated\n" +msgstr "%s: pliku zost³y zaktualizowane\n" + +#: src/grpconv.c:62 src/grpunconv.c:63 +#, c-format +msgid "%s: can't lock group file\n" +msgstr "%s: nie mogê zablokowaæ pliku z grupami\n" + +#: src/grpconv.c:67 src/grpunconv.c:68 +#, c-format +msgid "%s: can't open group file\n" +msgstr "%s: nie mogê otworzyæ pliku z grupami\n" + +#: src/grpconv.c:72 src/grpunconv.c:73 +#, c-format +msgid "%s: can't lock shadow group file\n" +msgstr "%s: nie mogê zablokowaæ pliku z przes³oniêtymi grupami\n" + +#: src/grpconv.c:77 src/grpunconv.c:78 +#, c-format +msgid "%s: can't open shadow group file\n" +msgstr "%s: nie mogê otworzyæ pliku z przes³oniêtymi grupami\n" + +#. +#. * This shouldn't happen (the entry exists) but... +#. +#: src/grpconv.c:93 +#, c-format +msgid "%s: can't remove shadow group %s\n" +msgstr "%s: nie mogê usun±æ ukrytej grupy %s\n" + +#: src/grpconv.c:134 src/pwconv.c:160 +#, c-format +msgid "%s: can't update shadow entry for %s\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu ukrytej grupy dla %s\n" + +#: src/grpconv.c:143 src/grpunconv.c:94 +#, c-format +msgid "%s: can't update entry for group %s\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu dla grupy %s\n" + +#: src/grpconv.c:150 src/grpunconv.c:102 +#, c-format +msgid "%s: can't update shadow group file\n" +msgstr "%s: nie mogê zaktualizowaæ pliku z ukrytymi grupami\n" + +#: src/grpconv.c:154 src/grpunconv.c:107 +#, c-format +msgid "%s: can't update group file\n" +msgstr "%s: nie mogê zaktualizowaæ pliku z grupami\n" + +#: src/grpconv.c:169 src/grpunconv.c:128 +#, c-format +msgid "%s: not configured for shadow group support.\n" +msgstr "%s: nie skonfigurowany dla wsparcia ukrytych grup.\n" + +#: src/grpunconv.c:112 +#, c-format +msgid "%s: can't delete shadow group file\n" +msgstr "%s: nie mogê skasowaæ pliku z ukrytymi grupami\n" + +#: src/id.c:56 +msgid "usage: id [ -a ]\n" +msgstr "u¿ycie: id [ -a ]\n" + +#: src/id.c:58 +msgid "usage: id\n" +msgstr "u¿ycie: id\n" + +#: src/id.c:118 +#, c-format +msgid "uid=%d(%s)" +msgstr "uid=%d(%s)" + +#: src/id.c:120 +#, c-format +msgid "uid=%d" +msgstr "uid=%d" + +#: src/id.c:124 +#, c-format +msgid " gid=%d(%s)" +msgstr " gid=%d(%s)" + +#: src/id.c:126 +#, c-format +msgid " gid=%d" +msgstr " gid=%d" + +#: src/id.c:136 +#, c-format +msgid " euid=%d(%s)" +msgstr " euid=%d(%s)" + +#: src/id.c:138 +#, c-format +msgid " euid=%d" +msgstr " euid=%d" + +#: src/id.c:143 +#, c-format +msgid " egid=%d(%s)" +msgstr " egid=%d(%s)" + +#: src/id.c:145 +#, c-format +msgid " egid=%d" +msgstr " egid=%d" + +#. +#. * Start off the group message. It will be of the format +#. * +#. * groups=###(aaa),###(aaa),###(aaa) +#. * +#. * where "###" is a numerical value and "aaa" is the +#. * corresponding name for each respective numerical value. +#. +#: src/id.c:166 +msgid " groups=" +msgstr " grupy=" + +#: src/lastlog.c:167 +msgid "Username Port From Latest\n" +msgstr "U¿ytkownik Port Z Ostatnio\n" + +#: src/lastlog.c:169 +msgid "Username Port Latest\n" +msgstr "U¿ytkownik Port Ostatnio\n" + +#: src/lastlog.c:183 +msgid "**Never logged in**" +msgstr "**Nigdy nie zalogowany**" + +#: src/login.c:198 +#, c-format +msgid "usage: %s [-p] [name]\n" +msgstr "u¿ycie: %s [-p] [nazwa]\n" + +#: src/login.c:201 +#, c-format +msgid " %s [-p] [-h host] [-f name]\n" +msgstr " %s [-p] [-h host] [-f nazwa]\n" + +#: src/login.c:203 +#, c-format +msgid " %s [-p] -r host\n" +msgstr " %s [-p] -r host\n" + +#: src/login.c:286 +msgid "Invalid login time\n" +msgstr "Nieprawid³owy czas logowania\n" + +#: src/login.c:341 +msgid "" +"\n" +"System closed for routine maintenance\n" +msgstr "" +"\n" +"System zamkniêty do rutynowej konserwacji.\n" + +#: src/login.c:351 +msgid "" +"\n" +"[Disconnect bypassed -- root login allowed.]\n" +msgstr "" +"\n" +"[Roz³±czenie pominiête -- zezwolenie na logowanie siê root-a.]\n" + +#: src/login.c:390 +#, c-format +msgid "" +"\n" +"Login timed out after %d seconds.\n" +msgstr "" +"\n" +"Limit czasu logowania przekroczony po %d sekundach.\n" + +#: src/login.c:692 +#, c-format +msgid " on `%.100s' from `%.200s'" +msgstr " na `%s.100s' z `%.200s'" + +#: src/login.c:694 +#, c-format +msgid " on `%.100s'" +msgstr " na `%.100s'" + +#: src/login.c:834 +#, c-format +msgid "" +"\n" +"%s login: " +msgstr "" +"\n" +"%s login: " + +#: src/login.c:836 +msgid "login: " +msgstr "login: " + +#: src/login.c:1026 src/sulogin.c:231 +msgid "Login incorrect" +msgstr "Nieprawid³owe logowanie" + +#: src/login.c:1213 +msgid "Warning: login re-enabled after temporary lockout.\n" +msgstr "Ostrze¿enie: logowanie ponownie odblokowanie po czasowej blokadzie.\n" + +#: src/login.c:1223 +#, c-format +msgid "Last login: %s on %s" +msgstr "Ostatnie logowanie: %s na %s" + +#: src/login.c:1226 +#, c-format +msgid "Last login: %.19s on %s" +msgstr "Ostatnie logowanie: %s na %s" + +#: src/login.c:1231 +#, c-format +msgid " from %.*s" +msgstr " z %.*s" + +#: src/login.c:1303 +msgid "Starting rad_login\n" +msgstr "Startujê rad_login\n" + +#: src/mkpasswd.c:49 +#, c-format +msgid "%s: no DBM database on system - no action performed\n" +msgstr "" +"%s: nie ma bazy DBM na tym systemie - ¿adna akcja nie zosta³a podjêta\n" + +#: src/mkpasswd.c:245 src/mkpasswd.c:249 +#, c-format +msgid "%s: cannot overwrite file %s\n" +msgstr "%s: nie mogê nadpisaæ pliku %s\n" + +#: src/mkpasswd.c:263 +#, c-format +msgid "%s: cannot open DBM files for %s\n" +msgstr "%s: nie mogê otworzyæ plików DBM dla %s\n" + +#: src/mkpasswd.c:296 +#, c-format +msgid "%s: the beginning with " +msgstr "%s: rozpoczyna siê od " + +#: src/mkpasswd.c:321 +#, c-format +msgid "%s: error parsing line \"%s\"\n" +msgstr "%s: b³±d podczas przetwarzania lini \"%s\"\n" + +#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332 +msgid "adding record for name " +msgstr "dodajê rekord do nazwy " + +#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349 +#, c-format +msgid "%s: error adding record for " +msgstr "%s: b³±d podczas dodawania rekordu dla " + +#: src/mkpasswd.c:367 +#, c-format +msgid "added %d entries, longest was %d\n" +msgstr "dodano %d wpisów, najd³u¿szy by³ %d\n" + +#: src/mkpasswd.c:382 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n" +msgstr "U¿ycie: %s [ -vf ] [ -p|g|sp|sg ] plik\n" + +#: src/mkpasswd.c:384 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n" +msgstr "U¿ycie: %s [ -vf ] [ -p|g|sp ] plik\n" + +#: src/mkpasswd.c:387 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g ] file\n" +msgstr "U¿ycie: %s [ -vf ] [ -p|g ] plik\n" + +#: src/newgrp.c:66 +msgid "usage: newgrp [ - ] [ group ]\n" +msgstr "u¿ycie: newgrp [ - ] [ grupa ]\n" + +#: src/newgrp.c:68 +#, fuzzy +msgid "usage: sg group [[-c] command ]\n" +msgstr "u¿ycie: sg grupa [ komenda ]\n" + +#: src/newgrp.c:125 +#, c-format +msgid "unknown uid: %d\n" +msgstr "nieznany uid: %d\n" + +#: src/newgrp.c:201 +#, c-format +msgid "unknown gid: %ld\n" +msgstr "nieznany gid: %ld\n" + +#: src/newgrp.c:245 +#, c-format +msgid "unknown gid: %d\n" +msgstr "nieznany gid: %d\n" + +#: src/newgrp.c:323 src/newgrp.c:332 +msgid "Sorry.\n" +msgstr "Wybacz.\n" + +#: src/newgrp.c:364 +msgid "too many groups\n" +msgstr "zbyt wiele grup\n" + +#: src/newusers.c:76 +#, c-format +msgid "Usage: %s [ input ]\n" +msgstr "U¿ycie: %s [ wej¶cie ]\n" + +#: src/newusers.c:364 +#, c-format +msgid "%s: can't lock /etc/passwd.\n" +msgstr "%s: nie mogê zablokowaæ /etc/passwd.\n" + +#: src/newusers.c:375 +#, c-format +msgid "%s: can't lock files, try again later\n" +msgstr "%s: nie mogê zablokowaæ plików, spróbuj pó¼niej\n" + +#: src/newusers.c:390 +#, c-format +msgid "%s: can't open files\n" +msgstr "%s: nie mogê otworzyæ plików\n" + +#: src/newusers.c:435 +#, c-format +msgid "%s: line %d: invalid line\n" +msgstr "%s: linia %d: nieprawid³owa linia\n" + +#: src/newusers.c:453 +#, c-format +msgid "%s: line %d: can't create GID\n" +msgstr "%s: linia %d: nie mogê utworzyæ GID\n" + +#: src/newusers.c:469 +#, c-format +msgid "%s: line %d: can't create UID\n" +msgstr "%s: linia %d: nie mogê utworzyæ UID\n" + +#: src/newusers.c:481 +#, c-format +msgid "%s: line %d: cannot find user %s\n" +msgstr "%s: linia %d: nie mogê znale¶æ u¿ytkownika %s\n" + +#: src/newusers.c:489 +#, c-format +msgid "%s: line %d: can't update password\n" +msgstr "%s: linia %d: nie mogê zaktualizowaæ pliku z has³ami\n" + +#: src/newusers.c:506 +#, c-format +msgid "%s: line %d: mkdir failed\n" +msgstr "%s: linia %d: mkdir nie powiod³o siê\n" + +#: src/newusers.c:510 +#, c-format +msgid "%s: line %d: chown failed\n" +msgstr "%s: linia %d: chown nie powiod³o siê\n" + +#: src/newusers.c:519 +#, c-format +msgid "%s: line %d: can't update entry\n" +msgstr "%s: linia %d: nie mogê zaktualizowaæ wpisu\n" + +#: src/newusers.c:550 +#, c-format +msgid "%s: error updating files\n" +msgstr "%s: b³±d podczas aktualizowania plików\n" + +#: src/passwd.c:239 +#, c-format +msgid "usage: %s [ -f | -s ] [ name ]\n" +msgstr "u¿ycie: %s [ -f | -s ] [ nazwa ]\n" + +#: src/passwd.c:242 +#, c-format +msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n" +msgstr " %s [ -x maks ] [ -n min ] [ -w ostrz ] [ -i nieakty ] nazwa\n" + +#: src/passwd.c:245 +#, c-format +msgid " %s { -l | -u | -d | -S | -e } name\n" +msgstr " %s { -l | -u | -d | -S | -e } nazwa\n" + +#: src/passwd.c:347 +#, c-format +msgid "User %s has a TCFS key, his old password is required.\n" +msgstr "U¿ytkownik %s posiada klucz TCFS, jego stare has³o jest wymagane.\n" + +#: src/passwd.c:348 +msgid "You can use -t option to force the change.\n" +msgstr "Nie mo¿esz u¿ywaæ opcji -t by wymusiæ zmianê.\n" + +#: src/passwd.c:354 +msgid "Old password: " +msgstr "Stare has³o: " + +#: src/passwd.c:361 +#, c-format +msgid "Incorrect password for `%s'\n" +msgstr "Nieprawid³owe has³o `%s'\n" + +#: src/passwd.c:374 +#, c-format +msgid "Warning: user %s has a TCFS key.\n" +msgstr "Ostrze¿enie: u¿ytkownik %s posiada klucz TCFS.\n" + +#: src/passwd.c:392 +#, c-format +msgid "" +"Enter the new password (minimum of %d, maximum of %d characters)\n" +"Please use a combination of upper and lower case letters and numbers.\n" +msgstr "" +"Wpisz nowe has³o (minimum %d, maksimum %d znaków)\n" +"Proszê u¿yj kombinacji wielkich i ma³ych znaków oraz cyfr.\n" + +#: src/passwd.c:399 +msgid "New password: " +msgstr "Nowe has³o: " + +#: src/passwd.c:409 +msgid "Try again.\n" +msgstr "Spróbuj ponownie.\n" + +#: src/passwd.c:418 +msgid "" +"\n" +"Warning: weak password (enter it again to use it anyway).\n" +msgstr "" +"\n" +"Ostrze¿enie: s³abe has³o (jednak wpisz je ponowie je¶li chcesz go u¿yæ).\n" + +#: src/passwd.c:427 +msgid "They don't match; try again.\n" +msgstr "Nie pasuj±; spróbuj ponownie.\n" + +#: src/passwd.c:512 src/passwd.c:528 +#, c-format +msgid "The password for %s cannot be changed.\n" +msgstr "Has³o dla %s nie mo¿e byæ zmienione.\n" + +#: src/passwd.c:556 +#, c-format +msgid "Sorry, the password for %s cannot be changed yet.\n" +msgstr "Wybacz, has³o dla %s nie mo¿e byæ jeszcze zmienione.\n" + +#: src/passwd.c:693 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: brak pamiêci\n" + +#: src/passwd.c:845 +msgid "Cannot lock the TCFS key database; try again later\n" +msgstr "Nie mogê zablokowaæ bazy kluczy TCFS; spróbuj ponownie\n" + +#: src/passwd.c:851 +msgid "Cannot open the TCFS key database.\n" +msgstr "Nie mogê otworzyæ bazy kluczy TCFS.\n" + +#: src/passwd.c:857 +msgid "Error updating the TCFS key database.\n" +msgstr "B³±d podczas aktualizacji bazy kluczy TCFS.\n" + +#: src/passwd.c:862 +msgid "Cannot commit TCFS changes.\n" +msgstr "Nie mogê potwierdziæ zmian TCFS.\n" + +#: src/passwd.c:1069 +#, c-format +msgid "%s: Cannot execute %s" +msgstr "%s: Nie mogê wykonaæ %s" + +#: src/passwd.c:1176 +#, c-format +msgid "%s: repository %s not supported\n" +msgstr "%s: ropozytorium %s nie jest obs³ugiwane\n" + +#: src/passwd.c:1263 +#, c-format +msgid "%s: Permission denied\n" +msgstr "%s: Dostêp zabroniony\n" + +#: src/passwd.c:1287 +#, c-format +msgid "You may not change the password for %s.\n" +msgstr "Nie mo¿esz zmieniaæ has³a dla %s.\n" + +#: src/passwd.c:1352 +#, c-format +msgid "Changing password for %s\n" +msgstr "Zmieniam has³o dla %s\n" + +#: src/passwd.c:1356 +#, c-format +msgid "The password for %s is unchanged.\n" +msgstr "Has³o dla %s pozostaje niezmienione.\n" + +#: src/passwd.c:1412 +msgid "Password changed.\n" +msgstr "Has³o zmienione.\n" + +#: src/pwck.c:98 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n" +msgstr "U¿ycie: %s [ -qr ] [ has³o [ shadow ] ]\n" + +#: src/pwck.c:100 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd ]\n" +msgstr "U¿ycie: %s [ -qr ] [ has³o ]\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:285 +msgid "invalid password file entry\n" +msgstr "nieprawid³owy wpis do pliku z has³ami\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:347 +msgid "duplicate password entry\n" +msgstr "duplikuj±cy siê wpis w pliku z has³ami\n" + +#: src/pwck.c:363 +#, c-format +msgid "invalid user name `%s'\n" +msgstr "nieprawid³owa nazwa u¿ytkownika `%s'\n" + +#: src/pwck.c:373 +#, c-format +msgid "user %s: bad UID (%d)\n" +msgstr "u¿ytkownik %s: z³y UID (%d)\n" + +#. +#. * No primary group, just give a warning +#. +#: src/pwck.c:388 +#, c-format +msgid "user %s: no group %d\n" +msgstr "u¿ytkownik %s: brak grupy %d\n" + +#. +#. * Home directory doesn't exist, give a warning +#. +#: src/pwck.c:403 +#, c-format +msgid "user %s: directory %s does not exist\n" +msgstr "u¿ytkownik %s: katalog %s nie istnieje\n" + +#. +#. * Login shell doesn't exist, give a warning +#. +#: src/pwck.c:418 +#, c-format +msgid "user %s: program %s does not exist\n" +msgstr "u¿ytkownik %s: program %s nie istnieje\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:454 +msgid "invalid shadow password file entry\n" +msgstr "nieprawid³owy wpis w pliku z has³ami\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:516 +msgid "duplicate shadow password entry\n" +msgstr "duplikuj±cy siê wpis w pliku z ukrytymi has³ami\n" + +#. +#. * Tell the user this entry has no matching +#. * /etc/passwd entry and ask them to delete it. +#. +#: src/pwck.c:540 +msgid "no matching password file entry\n" +msgstr "brak pasuj±cego wpisu w pliku z has³ami\n" + +#: src/pwck.c:557 +#, c-format +msgid "user %s: last password change in the future\n" +msgstr "u¿ytkownik %s: ostatnia zmiana has³a w przysz³o¶ci\n" + +#: src/pwconv.c:94 src/pwunconv.c:108 +#, c-format +msgid "%s: can't lock passwd file\n" +msgstr "%s: nie mogê zablokowaæ pliku z has³ami\n" + +#: src/pwconv.c:99 src/pwunconv.c:113 +#, c-format +msgid "%s: can't open passwd file\n" +msgstr "%s: nie mogê otworzyæ pliku z has³ami\n" + +#: src/pwconv.c:126 +#, c-format +msgid "%s: can't remove shadow entry for %s\n" +msgstr "%s: nie mogê usun±æ wpisu z pliku z ukrytymi has³ami dla %s\n" + +#: src/pwconv.c:169 +#, c-format +msgid "%s: can't update passwd entry for %s\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu do pliku z has³ami dla %s\n" + +#: src/pwconv.c:176 +#, c-format +msgid "%s: can't update shadow file\n" +msgstr "%s: nie mogê zaktualizowaæ pliku z ukrytymi has³ami\n" + +#: src/pwconv.c:180 +#, c-format +msgid "%s: can't update passwd file\n" +msgstr "%s: nie mogê zaktualizowaæ pliku z has³ami\n" + +#: src/pwunconv.c:62 +#, c-format +msgid "%s: Shadow passwords are not configured.\n" +msgstr "%s: Przes³oniête has³a nie s± skonfigurowane.\n" + +#: src/pwunconv.c:171 +#, c-format +msgid "%s: can't update entry for user %s\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu dla u¿ytkownika %s\n" + +#: src/pwunconv.c:188 +#, c-format +msgid "%s: can't delete shadow password file\n" +msgstr "%s: nie mogê skasowaæ pliku z ukrytymi has³ami\n" + +#: src/su.c:140 +msgid "Sorry." +msgstr "Wybacz." + +#: src/su.c:222 +#, c-format +msgid "%s: must be run from a terminal\n" +msgstr "%s: musisz uruchamiaæ z terminala\n" + +#: src/su.c:311 +#, c-format +msgid "%s: pam_start: error %d\n" +msgstr "%s: pam_start: b³±d %d\n" + +#: src/su.c:337 +#, c-format +msgid "Unknown id: %s\n" +msgstr "Nieznany id: %s\n" + +#. access denied (-1) or unexpected value +#: src/su.c:372 src/su.c:387 +#, c-format +msgid "You are not authorized to su %s\n" +msgstr "Nie masz autoryzacji by u¿ywaæ su %s\n" + +#. require own password +#: src/su.c:383 +msgid "(Enter your own password.)" +msgstr "(Wpisz swoje w³asne has³o.)" + +#: src/su.c:404 +#, c-format +msgid "%s: permission denied (shell).\n" +msgstr "%s: dostêp zabroniony (pow³oka).\n" + +#: src/su.c:428 +#, c-format +msgid "" +"%s: %s\n" +"(Ignored)\n" +msgstr "" +"%s: %s\n" +"(Zignorowano)\n" + +#: src/su.c:628 +msgid "No shell\n" +msgstr "Brak pow³oki\n" + +#. must be a password file! +#: src/sulogin.c:136 +msgid "No password file\n" +msgstr "Brak pliku z has³ami\n" + +#. +#. * Fail secure +#. +#: src/sulogin.c:178 +msgid "No password entry for 'root'\n" +msgstr "Brak wpisu do bazy hase³ dla 'root'\n" + +#. +#. * Here we prompt for the root password, or if no password is +#. * given we just exit. +#. +#. get a password for root +#: src/sulogin.c:192 +msgid "" +"\n" +"Type control-d to proceed with normal startup,\n" +"(or give root password for system maintenance):" +msgstr "" +"\n" +"Wpisz control-d by kontynuowaæ normalny start,\n" +"(lub podaj has³o root-a by przej¶æ do trybu utrzymania systemu):" + +#. make new environment active +#: src/sulogin.c:241 +msgid "Entering System Maintenance Mode\n" +msgstr "Wchodzê w tryb utrzymania systemu\n" + +#: src/useradd.c:243 +#, c-format +msgid "%s: rebuild the group database\n" +msgstr "%s: przebuduj bazê grup\n" + +#: src/useradd.c:250 +#, c-format +msgid "%s: rebuild the shadow group database\n" +msgstr "%s: przebuduj bazê przes³oniêtych hase³\n" + +#: src/useradd.c:287 src/usermod.c:967 +#, c-format +msgid "%s: invalid numeric argument `%s'\n" +msgstr "%s: nieprawid³owy argument numeryczny `%s'\n" + +#: src/useradd.c:343 +#, c-format +msgid "%s: unknown gid %s\n" +msgstr "%s: nieznany gid %s\n" + +#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254 +#: src/usermod.c:1098 +#, c-format +msgid "%s: unknown group %s\n" +msgstr "%s: nieznana grupa %s\n" + +#: src/useradd.c:418 +#, c-format +msgid "group=%s,%ld basedir=%s skel=%s\n" +msgstr "grupa=%s,%ld kat_baz=%s skel=%s\n" + +#: src/useradd.c:421 +#, c-format +msgid "shell=%s " +msgstr "pow³oka=%s " + +#: src/useradd.c:423 +#, c-format +msgid "inactive=%ld expire=%s" +msgstr "nieaktywne=%ld wyga¶niêcie=%s" + +#: src/useradd.c:427 +#, c-format +msgid "GROUP=%ld\n" +msgstr "GRUPA=%ld\n" + +#: src/useradd.c:428 +#, c-format +msgid "HOME=%s\n" +msgstr "KAT_DOM=%s\n" + +#: src/useradd.c:430 +#, c-format +msgid "INACTIVE=%ld\n" +msgstr "NIEAKTYWNE=%ld\n" + +#: src/useradd.c:431 +#, c-format +msgid "EXPIRE=%s\n" +msgstr "WYGA¦NIÊCIE=%s\n" + +#: src/useradd.c:433 +#, c-format +msgid "SHELL=%s\n" +msgstr "POW£OKA=%s\n" + +#: src/useradd.c:434 +#, c-format +msgid "SKEL=%s\n" +msgstr "SKEL=%s\n" + +#: src/useradd.c:470 +#, c-format +msgid "%s: cannot create new defaults file\n" +msgstr "%s: nie mogê utworzyæ nowego pliku ze standardowymi ustawieniami\n" + +#: src/useradd.c:564 src/useradd.c:575 +#, c-format +msgid "%s: rename: %s" +msgstr "%s: zmiana nazwy: %s" + +#: src/useradd.c:662 src/usermod.c:274 +#, c-format +msgid "%s: group `%s' is a NIS group.\n" +msgstr "%s: grupa `%s' jest grup± NIS.\n" + +#: src/useradd.c:670 src/usermod.c:282 +#, c-format +msgid "%s: too many groups specified (max %d).\n" +msgstr "%s: podano zbyt wiele grup (maks %d).\n" + +#: src/useradd.c:702 src/usermod.c:314 +#, c-format +msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n" +msgstr "u¿ycie: %s\t[-u uid [-o]] [-g grupa] [-G grupa,...] \n" + +#: src/useradd.c:705 +msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n" +msgstr "\t\t[-d kat_dom] [-s pow³oka] [-c komentarz] [-m [-k wzór]]\n" + +#: src/useradd.c:708 src/usermod.c:320 +msgid "[-f inactive] [-e expire ] " +msgstr "[-f nieaktywne] [-e utrata_wa¿no¶ci ]" + +#: src/useradd.c:711 +msgid "[-A program] " +msgstr "[-A program] " + +#: src/useradd.c:713 +msgid "[-p passwd] name\n" +msgstr "[-p has³o] nazwa\n" + +#: src/useradd.c:715 +#, c-format +msgid " %s\t-D [-g group] [-b base] [-s shell]\n" +msgstr " %s\t-D [-g grupa] [-b baza] [-s pow³oka]\n" + +#: src/useradd.c:718 +msgid "\t\t[-f inactive] [-e expire ]\n" +msgstr "\t\t[-f nieaktywne] [-e utrata_wa¿no¶ci ]\n" + +#: src/useradd.c:815 src/usermod.c:472 +#, c-format +msgid "%s: error locking group file\n" +msgstr "%s: b³±d podczas blokowania pliku z grupami\n" + +#: src/useradd.c:819 src/usermod.c:477 +#, c-format +msgid "%s: error opening group file\n" +msgstr "%s: b³±d podczas otwierania pliku z grupami\n" + +#: src/useradd.c:824 src/usermod.c:584 +#, c-format +msgid "%s: error locking shadow group file\n" +msgstr "%s: b³±d podczas blokowania pliku z ukrytymi has³ami\n" + +#: src/useradd.c:829 src/usermod.c:590 +#, c-format +msgid "%s: error opening shadow group file\n" +msgstr "%s: b³±d podczas otwierania pliku z ukrytymi grupami\n" + +#: src/useradd.c:1001 +#, c-format +msgid "%s: uid %d is not unique\n" +msgstr "%s: uid %d nie jest niepowtarzalny\n" + +#: src/useradd.c:1031 +#, c-format +msgid "%s: can't get unique uid\n" +msgstr "%s: nie mogê uzyskaæ niepowtarzalnego uid\n" + +#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057 +#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157 +#, c-format +msgid "%s: invalid field `%s'\n" +msgstr "%s: nieprawid³owe pole `%s'\n" + +#: src/useradd.c:1153 +#, c-format +msgid "%s: invalid base directory `%s'\n" +msgstr "%s: nieprawid³owy katalog bazowy `%s'\n" + +#: src/useradd.c:1163 +#, c-format +msgid "%s: invalid comment `%s'\n" +msgstr "%s: nieprawid³owy komentarz `%s'\n" + +#: src/useradd.c:1173 +#, c-format +msgid "%s: invalid home directory `%s'\n" +msgstr "%s: nieprawid³owy katalog domowy `%s'\n" + +#: src/useradd.c:1191 src/usermod.c:1080 +#, c-format +msgid "%s: invalid date `%s'\n" +msgstr "%s: nieprawid³owa data `%s'\n" + +#: src/useradd.c:1203 +#, c-format +msgid "%s: shadow passwords required for -e\n" +msgstr "%s: ukryte has³a wymagane dla -e\n" + +#: src/useradd.c:1218 +#, c-format +msgid "%s: shadow passwords required for -f\n" +msgstr "%s: ukryte has³a wymagane dla -f\n" + +#: src/useradd.c:1292 +#, c-format +msgid "%s: invalid shell `%s'\n" +msgstr "%s: nieprawid³owa pow³oka `%s'\n" + +#: src/useradd.c:1333 +#, c-format +msgid "%s: invalid user name `%s'\n" +msgstr "%s: nieprawid³owa nazwa u¿ytkownika `%s'\n" + +#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225 +#, c-format +msgid "%s: cannot rewrite password file\n" +msgstr "%s: nie mogê przepisaæ pliku z has³ami\n" + +#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230 +#, c-format +msgid "%s: cannot rewrite shadow password file\n" +msgstr "%s: nie mogê przepisaæ pliku z ukrytymi has³ami\n" + +#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265 +#, c-format +msgid "%s: unable to lock password file\n" +msgstr "%s: nie mogê zablokowaæ pliku z has³ami\n" + +#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269 +#, c-format +msgid "%s: unable to open password file\n" +msgstr "%s: nie mogê otworzyæ pliku z has³ami\n" + +#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274 +#, c-format +msgid "%s: cannot lock shadow password file\n" +msgstr "%s: nie mogê zablokowaæ pliku z ukrytymi has³ami\n" + +#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279 +#, c-format +msgid "%s: cannot open shadow password file\n" +msgstr "%s: nie mogê otworzyæ pliku z ukrytymi has³ami\n" + +#: src/useradd.c:1529 src/usermod.c:1366 +#, c-format +msgid "%s: error adding authentication method\n" +msgstr "%s: b³±d podczas dodawania metody uwierzytelniania\n" + +#: src/useradd.c:1552 +#, c-format +msgid "%s: error adding new password entry\n" +msgstr "%s: b³±d podczas dodawania nowego wpisu do pliku z has³ami\n" + +#: src/useradd.c:1567 +#, c-format +msgid "%s: error updating password dbm entry\n" +msgstr "%s: b³±d podczas aktualizacji wpisu dbm do pliku z has³ami\n" + +#: src/useradd.c:1583 src/usermod.c:1425 +#, c-format +msgid "%s: error adding new shadow password entry\n" +msgstr "%s: b³±d podczas dodawania nowego wpisu do pliku z ukrytymi has³ami\n" + +#: src/useradd.c:1599 src/usermod.c:1440 +#, c-format +msgid "%s: error updating shadow passwd dbm entry\n" +msgstr "%s: b³±d podczas aktualizacji wpisu dbm do pliku z ukrytymi has³ami\n" + +#: src/useradd.c:1631 +#, c-format +msgid "%s: cannot create directory %s\n" +msgstr "%s: nie mogê utworzyæ katalogu %s\n" + +#: src/useradd.c:1708 src/usermod.c:1203 +#, c-format +msgid "%s: user %s exists\n" +msgstr "%s: u¿ytkownik %s istnieje\n" + +#: src/useradd.c:1738 +#, c-format +msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n" +msgstr "" + +#: src/userdel.c:127 +#, c-format +msgid "usage: %s [-r] name\n" +msgstr "u¿ycie: %s [-r] nazwa\n" + +#: src/userdel.c:178 src/userdel.c:260 +#, c-format +msgid "%s: error updating group entry\n" +msgstr "%s: b³±d podczas aktualizacji wpisu grupy\n" + +#: src/userdel.c:188 src/userdel.c:269 +#, c-format +msgid "%s: cannot update dbm group entry\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu dbm do pliku z grupami\n" + +#: src/userdel.c:215 +#, fuzzy, c-format +msgid "%s: cannot remove dbm group entry\n" +msgstr "%s: nie mogê zaktualizowaæ wpisu dbm do pliku z grupami\n" + +#: src/userdel.c:300 +#, c-format +msgid "%s: cannot rewrite TCFS key file\n" +msgstr "%s: nie mogê przepisaæ pliku klucza TCFS\n" + +#: src/userdel.c:380 +#, c-format +msgid "%s: cannot lock TCFS key file\n" +msgstr "%s: nie mogê zablokowaæ pliku klucza TCFS\n" + +#: src/userdel.c:384 +#, c-format +msgid "%s: cannot open TCFS key file\n" +msgstr "%s: nie mogê otworzyæ pliku klucza TCFS\n" + +#: src/userdel.c:393 +#, c-format +msgid "%s: cannot open group file\n" +msgstr "%s: nie mogê otworzyæ pliku z grupami\n" + +#: src/userdel.c:403 +#, c-format +msgid "%s: cannot open shadow group file\n" +msgstr "%s: nie mogê otworzyæ pliku z przes³oniêtymi grupami\n" + +#: src/userdel.c:434 src/userdel.c:449 +#, c-format +msgid "%s: error deleting authentication\n" +msgstr "%s: b³±d podczas usuwania informacji uwierzytelniaj±cej\n" + +#: src/userdel.c:458 +#, c-format +msgid "%s: error deleting password entry\n" +msgstr "%s: b³±d podczas usuwania wpisu do pliku z has³ami\n" + +#: src/userdel.c:461 +#, c-format +msgid "%s: error deleting shadow password entry\n" +msgstr "%s: b³±d podczas usuwania wpisu do pliku z ukrytymi has³ami\n" + +#: src/userdel.c:470 +#, c-format +msgid "%s: error deleting TCFS entry\n" +msgstr "%s: b³±d podczas usuwania wpisu TCFS\n" + +#: src/userdel.c:483 +#, c-format +msgid "%s: error deleting password dbm entry\n" +msgstr "%s: b³±d podczas usuwania wpisu dbm do pliku z has³ami\n" + +#: src/userdel.c:502 +#, c-format +msgid "%s: error deleting shadow passwd dbm entry\n" +msgstr "%s: b³±d podczas usuwania wpisy dbm z pliku z ukrytymi has³ami\n" + +#: src/userdel.c:543 +#, c-format +msgid "%s: user %s is currently logged in\n" +msgstr "%s: u¿ytkownik %s jest aktualnie zalogowany\n" + +#: src/userdel.c:660 +#, c-format +msgid "%s: warning: %s not owned by %s, not removing\n" +msgstr "%s: ostrze¿enie: w³a¶cicielem %s nie jest %s, nie usuwam\n" + +#: src/userdel.c:666 +#, c-format +msgid "%s: warning: can't remove " +msgstr "%s: ostrze¿enie: nie mogê usun±æ " + +#: src/userdel.c:741 src/usermod.c:994 +#, c-format +msgid "%s: user %s does not exist\n" +msgstr "%s: u¿ytkownik %s nie istnieje\n" + +#: src/userdel.c:755 src/usermod.c:1010 +#, c-format +msgid "%s: user %s is a NIS user\n" +msgstr "%s: u¿ytkownik %s jest u¿ytkownikiem NIS\n" + +#: src/userdel.c:792 +#, c-format +msgid "%s: %s not owned by %s, not removing\n" +msgstr "%s: w³a¶cicielem %s nie jest %s, nie usuwam\n" + +#: src/userdel.c:815 +#, c-format +msgid "%s: not removing directory %s (would remove home of user %s)\n" +msgstr "%s: nie usuwam katalogu %s (would remove home of user %s)\n" + +#: src/userdel.c:828 +#, c-format +msgid "%s: error removing directory %s\n" +msgstr "%s: b³±d podczas usuwania katalogu %s\n" + +#: src/usermod.c:317 +msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n" +msgstr "\t\t[-d kat_dom [-m]] [-s pow³oka] [-c komentarz] [-l nowa_nazwa]\n" + +#: src/usermod.c:323 +msgid "[-A {DEFAULT|program},... ] " +msgstr "[-A {DEFAULT|program},... ] " + +#: src/usermod.c:325 +#, fuzzy +msgid "[-p passwd] [-L|-U] name\n" +msgstr "[-p has³o] nazwa\n" + +#: src/usermod.c:504 +#, c-format +msgid "%s: out of memory in update_group\n" +msgstr "%s: zabrak³o pamiêci w pdate_group\n" + +#: src/usermod.c:627 +#, c-format +msgid "%s: out of memory in update_gshadow\n" +msgstr "%s: zabrak³o pamiêci w update_gshadow\n" + +#: src/usermod.c:1180 +#, c-format +msgid "%s: no flags given\n" +msgstr "%s: nie podano flag\n" + +#: src/usermod.c:1187 +#, c-format +msgid "%s: shadow passwords required for -e and -f\n" +msgstr "%s: ukryte has³a wymagane dla -e i -f\n" + +#: src/usermod.c:1208 +#, c-format +msgid "%s: uid %ld is not unique\n" +msgstr "%s: uid %ld nie jest niepowtarzalny\n" + +#: src/usermod.c:1356 +#, c-format +msgid "%s: error deleting authentication method\n" +msgstr "%s: b³±d podczas usuwania metody uwierzytelniania\n" + +#: src/usermod.c:1376 +#, c-format +msgid "%s: error changing authentication method\n" +msgstr "%s: b³±d podczas zmiany metody uwierzytelniania\n" + +#: src/usermod.c:1393 +#, c-format +msgid "%s: error changing password entry\n" +msgstr "%s: b³±d podczas zmiany wpisu w pliku z has³ami\n" + +#: src/usermod.c:1399 +#, c-format +msgid "%s: error removing password entry\n" +msgstr "%s: b³±d podczas usuwania wpisu z pliku z has³ami\n" + +#: src/usermod.c:1407 +#, c-format +msgid "%s: error adding password dbm entry\n" +msgstr "%s: b³±d podczas dodawania wpisu dbm do pliku z has³ami\n" + +#: src/usermod.c:1414 +#, c-format +msgid "%s: error removing passwd dbm entry\n" +msgstr "%s: b³±d podczas usuwania wpisu dbm z pliku z has³ami\n" + +#: src/usermod.c:1431 +#, c-format +msgid "%s: error removing shadow password entry\n" +msgstr "%s: b³±d podczas usuwania wpisu z pliku z ukrytymi has³ami\n" + +#: src/usermod.c:1446 +#, c-format +msgid "%s: error removing shadow passwd dbm entry\n" +msgstr "%s: b³±d podczas usuwania wpisu dbm z pliku z ukrytymi has³ami\n" + +#: src/usermod.c:1477 +#, c-format +msgid "%s: directory %s exists\n" +msgstr "%s: katalog %s isnieje\n" + +#: src/usermod.c:1484 +#, c-format +msgid "%s: can't create %s\n" +msgstr "%s: nie mogê utworzyæ %s\n" + +#: src/usermod.c:1490 +#, c-format +msgid "%s: can't chown %s\n" +msgstr "%s: nie mogê zmieniæ w³a¶ciciela %s\n" + +#: src/usermod.c:1506 +#, c-format +msgid "%s: cannot rename directory %s to %s\n" +msgstr "%s: nie mogê zmieniæ nazwy katalogu z %s na %s\n" + +#. better leave it alone +#: src/usermod.c:1603 +#, c-format +msgid "%s: warning: %s not owned by %s\n" +msgstr "%s: ostrze¿enie: w³a¶cicielem %s nie jest %s\n" + +#: src/usermod.c:1609 +msgid "failed to change mailbox owner" +msgstr "nie powiod³a siê zmiana w³a¶ciciela skrzynki pocztowej" + +#: src/usermod.c:1616 +msgid "failed to rename mailbox" +msgstr "zmiana nazwy skrzynki pocztowej nie powiod³a siê" + +#: src/vipw.c:102 +#, c-format +msgid "" +"\n" +"%s: %s is unchanged\n" +msgstr "" +"\n" +"%s: %s jest niezmieniony\n" + +#: src/vipw.c:127 +#, fuzzy +msgid "Couldn't lock file" +msgstr "%s: nie mogê usun±c blokady z pliku\n" + +#: src/vipw.c:134 +msgid "Couldn't make backup" +msgstr "" + +#: src/vipw.c:187 +#, c-format +msgid "%s: can't restore %s: %s (your changes are in %s)\n" +msgstr "%s: nie mogê odzyskaæ %s: %s (twoje zmiany s± w %s)\n" + +#: src/vipw.c:226 +msgid "" +"Usage:\n" +"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n" +"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n" +msgstr "" +"U¿ycie:\n" +"`vipw' edytuje /etc/passwd `vipw -s' edytuje /etc/shadow\n" +"`vigr' edytuje /etc/group `vigr -s' edytuje /etc/gshadow\n" + +#~ msgid "Incorrect password for %s.\n" +#~ msgstr "Nieprawid³owe has³o dla %s.\n" + +#~ msgid "group not found\n" +#~ msgstr "grupa nie znaleziona\n" diff --git a/current/po/shadow.pot b/current/po/shadow.pot new file mode 100644 index 00000000..7faa7116 --- /dev/null +++ b/current/po/shadow.pot @@ -0,0 +1,2368 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2000-09-02 20:40+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: libmisc/addgrps.c:60 +#, c-format +msgid "Warning: unknown group %s\n" +msgstr "" + +#: libmisc/addgrps.c:71 +msgid "Warning: too many groups\n" +msgstr "" + +#: libmisc/age.c:104 +msgid "Your password has expired." +msgstr "" + +#: libmisc/age.c:107 +msgid "Your password is inactive." +msgstr "" + +#: libmisc/age.c:110 +msgid "Your login has expired." +msgstr "" + +#: libmisc/age.c:127 +msgid " Contact the system administrator.\n" +msgstr "" + +#: libmisc/age.c:130 +msgid " Choose a new password.\n" +msgstr "" + +#: libmisc/age.c:228 +#, c-format +msgid "Your password will expire in %ld days.\n" +msgstr "" + +#: libmisc/age.c:230 +msgid "Your password will expire tomorrow.\n" +msgstr "" + +#: libmisc/age.c:232 +msgid "Your password will expire today.\n" +msgstr "" + +#: libmisc/chowntty.c:110 +#, c-format +msgid "Unable to change tty %s" +msgstr "" + +#: libmisc/env.c:160 +msgid "Environment overflow\n" +msgstr "" + +#: libmisc/env.c:200 +#, c-format +msgid "You may not change $%s\n" +msgstr "" + +#: libmisc/failure.c:238 +#, c-format +msgid "%d %s since last login. Last was %s on %s.\n" +msgstr "" + +#: libmisc/failure.c:239 +msgid "failures" +msgstr "" + +#: libmisc/failure.c:239 +msgid "failure" +msgstr "" + +#: libmisc/limits.c:397 +msgid "Too many logins.\n" +msgstr "" + +#: libmisc/login_desrpc.c:63 +#, c-format +msgid "Password does not decrypt secret key for %s.\n" +msgstr "" + +#: libmisc/login_desrpc.c:69 +#, c-format +msgid "Could not set %s's secret key: is the keyserv daemon running?\n" +msgstr "" + +#: libmisc/mail.c:62 libmisc/mail.c:77 +msgid "You have new mail." +msgstr "" + +#: libmisc/mail.c:73 +msgid "No mail." +msgstr "" + +#: libmisc/mail.c:75 +msgid "You have mail." +msgstr "" + +#: libmisc/obscure.c:281 src/passwd.c:309 +#, c-format +msgid "Bad password: %s. " +msgstr "" + +#: libmisc/pam_pass.c:42 +#, c-format +msgid "passwd: pam_start() failed, error %d\n" +msgstr "" + +#: libmisc/pam_pass.c:49 +#, c-format +msgid "passwd: %s\n" +msgstr "" + +#: libmisc/setupenv.c:205 +#, c-format +msgid "Unable to cd to \"%s\"\n" +msgstr "" + +#: libmisc/setupenv.c:213 +msgid "No directory, logging in with HOME=/" +msgstr "" + +#: libmisc/shell.c:78 +#, c-format +msgid "Executing shell %s\n" +msgstr "" + +#. +#. * Obviously something is really wrong - I can't figure out +#. * how to execute this stupid shell, so I might as well give +#. * up in disgust ... +#. +#: libmisc/shell.c:122 +#, c-format +msgid "Cannot execute %s" +msgstr "" + +#: libmisc/suauth.c:99 +msgid "Access to su to that account DENIED.\n" +msgstr "" + +#: libmisc/suauth.c:106 +msgid "Password authentication bypassed.\n" +msgstr "" + +#: libmisc/suauth.c:113 +msgid "Please enter your OWN password as authentication.\n" +msgstr "" + +#: libmisc/sub.c:61 +#, c-format +msgid "Invalid root directory \"%s\"\n" +msgstr "" + +#: libmisc/sub.c:73 +#, c-format +msgid "Can't change root directory to \"%s\"\n" +msgstr "" + +#: libmisc/xmalloc.c:28 +#, c-format +msgid "malloc(%d) failed\n" +msgstr "" + +#: lib/dialchk.c:71 +msgid "Dialup Password: " +msgstr "" + +#: lib/getdef.c:253 +msgid "Could not allocate space for config info.\n" +msgstr "" + +#. +#. * Item was never found. +#. +#: lib/getdef.c:307 +#, c-format +msgid "configuration error - unknown item '%s' (notify administrator)\n" +msgstr "" + +#: lib/getdef.c:394 +#, c-format +msgid "error - lookup '%s' failed\n" +msgstr "" + +#: lib/getdef.c:402 +#, c-format +msgid "%s not found\n" +msgstr "" + +#. +#. * get the password from her, and set the salt for +#. * the decryption from the group file. +#. +#: lib/pwauth.c:54 src/newgrp.c:305 +msgid "Password: " +msgstr "" + +#: lib/pwauth.c:56 +#, c-format +msgid "%s's Password: " +msgstr "" + +#: lib/pwauth.c:270 +msgid "(Echo on) " +msgstr "" + +#: lib/strerror.c:20 +#, c-format +msgid "Unknown error %d" +msgstr "" + +#: src/chage.c:156 +#, c-format +msgid "" +"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n" +" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n" +msgstr "" + +#: src/chage.c:158 +#, c-format +msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n" +msgstr "" + +#: src/chage.c:193 +msgid "" +"Enter the new value, or press return for the default\n" +"\n" +msgstr "" + +#: src/chage.c:196 +msgid "Minimum Password Age" +msgstr "" + +#: src/chage.c:201 +msgid "Maximum Password Age" +msgstr "" + +#: src/chage.c:207 +msgid "Last Password Change (YYYY-MM-DD)" +msgstr "" + +#: src/chage.c:216 +msgid "Password Expiration Warning" +msgstr "" + +#: src/chage.c:221 +msgid "Password Inactive" +msgstr "" + +#: src/chage.c:227 +msgid "Account Expiration Date (YYYY-MM-DD)" +msgstr "" + +#. +#. * Start with the easy numbers - the number of days before the +#. * password can be changed, the number of days after which the +#. * password must be chaged, the number of days before the +#. * password expires that the user is told, and the number of +#. * days after the password expires that the account becomes +#. * unusable. +#. +#: src/chage.c:281 +#, c-format +msgid "Minimum:\t%ld\n" +msgstr "" + +#: src/chage.c:282 +#, c-format +msgid "Maximum:\t%ld\n" +msgstr "" + +#: src/chage.c:284 +#, c-format +msgid "Warning:\t%ld\n" +msgstr "" + +#: src/chage.c:285 +#, c-format +msgid "Inactive:\t%ld\n" +msgstr "" + +#. +#. * The "last change" date is either "Never" or the date the +#. * password was last modified. The date is the number of +#. * days since 1/1/1970. +#. +#: src/chage.c:294 +msgid "Last Change:\t\t" +msgstr "" + +#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340 +msgid "Never\n" +msgstr "" + +#. +#. * The password expiration date is determined from the last +#. * change date plus the number of days the password is valid +#. * for. +#. +#: src/chage.c:308 +msgid "Password Expires:\t" +msgstr "" + +#. +#. * The account becomes inactive if the password is expired +#. * for more than "inactdays". The expiration date is calculated +#. * and the number of inactive days is added. The resulting date +#. * is when the active will be disabled. +#. +#: src/chage.c:324 +msgid "Password Inactive:\t" +msgstr "" + +#. +#. * The account will expire on the given date regardless of the +#. * password expiring or not. +#. +#: src/chage.c:338 +msgid "Account Expires:\t" +msgstr "" + +#: src/chage.c:486 +#, c-format +msgid "%s: do not include \"l\" with other flags\n" +msgstr "" + +#: src/chage.c:498 src/chage.c:610 src/login.c:529 +#, c-format +msgid "%s: permission denied\n" +msgstr "" + +#: src/chage.c:510 src/chpasswd.c:120 +#, c-format +msgid "%s: can't lock password file\n" +msgstr "" + +#: src/chage.c:516 src/chpasswd.c:124 +#, c-format +msgid "%s: can't open password file\n" +msgstr "" + +#: src/chage.c:523 +#, c-format +msgid "%s: unknown user: %s\n" +msgstr "" + +#: src/chage.c:542 +#, c-format +msgid "%s: can't lock shadow password file\n" +msgstr "" + +#: src/chage.c:549 +#, c-format +msgid "%s: can't open shadow password file\n" +msgstr "" + +#: src/chage.c:631 +#, c-format +msgid "Changing the aging information for %s\n" +msgstr "" + +#: src/chage.c:633 +#, c-format +msgid "%s: error changing fields\n" +msgstr "" + +#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183 +#, c-format +msgid "%s: can't update password file\n" +msgstr "" + +#: src/chage.c:690 src/pwunconv.c:178 +#, c-format +msgid "%s: can't update shadow password file\n" +msgstr "" + +#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409 +#: src/passwd.c:825 src/passwd.c:926 +msgid "Error updating the DBM password entry.\n" +msgstr "" + +#: src/chage.c:771 +#, c-format +msgid "%s: can't rewrite shadow password file\n" +msgstr "" + +#: src/chage.c:785 +#, c-format +msgid "%s: can't rewrite password file\n" +msgstr "" + +#: src/chage.c:836 +#, c-format +msgid "%s: no aging information present\n" +msgstr "" + +#: src/chfn.c:107 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n" +"\t[ -h home_ph ] [ -o other ] [ user ]\n" +msgstr "" + +#: src/chfn.c:111 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n" +msgstr "" + +#: src/chfn.c:163 src/chsh.c:119 +msgid "Enter the new value, or press return for the default\n" +msgstr "" + +#: src/chfn.c:166 +msgid "Full Name" +msgstr "" + +#: src/chfn.c:168 +#, c-format +msgid "\tFull Name: %s\n" +msgstr "" + +#: src/chfn.c:171 +msgid "Room Number" +msgstr "" + +#: src/chfn.c:173 +#, c-format +msgid "\tRoom Number: %s\n" +msgstr "" + +#: src/chfn.c:176 +msgid "Work Phone" +msgstr "" + +#: src/chfn.c:178 +#, c-format +msgid "\tWork Phone: %s\n" +msgstr "" + +#: src/chfn.c:181 +msgid "Home Phone" +msgstr "" + +#: src/chfn.c:183 +#, c-format +msgid "\tHome Phone: %s\n" +msgstr "" + +#: src/chfn.c:186 +msgid "Other" +msgstr "" + +#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330 +#: src/chfn.c:391 src/passwd.c:1226 +#, c-format +msgid "%s: Permission denied.\n" +msgstr "" + +#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277 +#, c-format +msgid "%s: Unknown user %s\n" +msgstr "" + +#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207 +#, c-format +msgid "%s: Cannot determine your user name.\n" +msgstr "" + +#: src/chfn.c:373 src/chsh.c:250 +#, c-format +msgid "%s: cannot change user `%s' on NIS client.\n" +msgstr "" + +#: src/chfn.c:378 src/chsh.c:257 +#, c-format +msgid "%s: `%s' is the NIS master for this client.\n" +msgstr "" + +#: src/chfn.c:453 +#, c-format +msgid "Changing the user information for %s\n" +msgstr "" + +#: src/chfn.c:462 +#, c-format +msgid "%s: invalid name: \"%s\"\n" +msgstr "" + +#: src/chfn.c:467 +#, c-format +msgid "%s: invalid room number: \"%s\"\n" +msgstr "" + +#: src/chfn.c:472 +#, c-format +msgid "%s: invalid work phone: \"%s\"\n" +msgstr "" + +#: src/chfn.c:477 +#, c-format +msgid "%s: invalid home phone: \"%s\"\n" +msgstr "" + +#: src/chfn.c:482 +#, c-format +msgid "%s: \"%s\" contains illegal characters\n" +msgstr "" + +#: src/chfn.c:494 +#, c-format +msgid "%s: fields too long\n" +msgstr "" + +#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388 +msgid "Cannot change ID to root.\n" +msgstr "" + +#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880 +msgid "Cannot lock the password file; try again later.\n" +msgstr "" + +#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885 +msgid "Cannot open the password file.\n" +msgstr "" + +#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313 +#, c-format +msgid "%s: %s not found in /etc/passwd\n" +msgstr "" + +#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920 +#: src/passwd.c:960 +msgid "Error updating the password entry.\n" +msgstr "" + +#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933 +msgid "Cannot commit password file changes.\n" +msgstr "" + +#: src/chfn.c:592 src/chsh.c:431 +msgid "Cannot unlock the password file.\n" +msgstr "" + +#: src/chpasswd.c:76 +#, c-format +msgid "usage: %s [-e]\n" +msgstr "" + +#: src/chpasswd.c:132 src/pwconv.c:104 +#, c-format +msgid "%s: can't lock shadow file\n" +msgstr "" + +#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118 +#: src/pwunconv.c:123 +#, c-format +msgid "%s: can't open shadow file\n" +msgstr "" + +#: src/chpasswd.c:159 src/newusers.c:415 +#, c-format +msgid "%s: line %d: line too long\n" +msgstr "" + +#: src/chpasswd.c:179 +#, c-format +msgid "%s: line %d: missing new password\n" +msgstr "" + +#: src/chpasswd.c:195 +#, c-format +msgid "%s: line %d: unknown user %s\n" +msgstr "" + +#: src/chpasswd.c:247 +#, c-format +msgid "%s: line %d: cannot update password entry\n" +msgstr "" + +#: src/chpasswd.c:263 src/newusers.c:535 +#, c-format +msgid "%s: error detected, changes ignored\n" +msgstr "" + +#: src/chpasswd.c:274 +#, c-format +msgid "%s: error updating shadow file\n" +msgstr "" + +#: src/chpasswd.c:282 +#, c-format +msgid "%s: error updating password file\n" +msgstr "" + +#: src/chsh.c:105 +#, c-format +msgid "Usage: %s [ -s shell ] [ name ]\n" +msgstr "" + +#: src/chsh.c:120 +msgid "Login Shell" +msgstr "" + +#: src/chsh.c:273 src/chsh.c:286 +#, c-format +msgid "You may not change the shell for %s.\n" +msgstr "" + +#: src/chsh.c:315 +#, c-format +msgid "Changing the login shell for %s\n" +msgstr "" + +#: src/chsh.c:327 +#, c-format +msgid "%s: Invalid entry: %s\n" +msgstr "" + +#: src/chsh.c:332 +#, c-format +msgid "%s is an invalid shell.\n" +msgstr "" + +#: src/dpasswd.c:69 +#, c-format +msgid "Usage: %s [ -(a|d) ] shell\n" +msgstr "" + +#: src/dpasswd.c:134 +msgid "Shell password: " +msgstr "" + +#: src/dpasswd.c:140 +msgid "re-enter Shell password: " +msgstr "" + +#: src/dpasswd.c:147 +#, c-format +msgid "%s: Passwords do not match, try again.\n" +msgstr "" + +#: src/dpasswd.c:167 +#, c-format +msgid "%s: can't create %s" +msgstr "" + +#: src/dpasswd.c:172 +#, c-format +msgid "%s: can't open %s" +msgstr "" + +#: src/dpasswd.c:200 +#, c-format +msgid "%s: Shell %s not found.\n" +msgstr "" + +#: src/expiry.c:84 +msgid "Usage: expiry { -f | -c }\n" +msgstr "" + +#: src/expiry.c:137 +#, c-format +msgid "%s: WARNING! Must be set-UID root!\n" +msgstr "" + +#: src/expiry.c:148 +#, c-format +msgid "%s: unknown user\n" +msgstr "" + +#: src/faillog.c:79 +#, c-format +msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n" +msgstr "" + +#: src/faillog.c:134 src/lastlog.c:94 +#, c-format +msgid "Unknown User: %s\n" +msgstr "" + +#: src/faillog.c:215 +msgid "Username Failures Maximum Latest\n" +msgstr "" + +#: src/faillog.c:232 +#, c-format +msgid " %s on %s" +msgstr "" + +#: src/faillog.c:236 +#, c-format +msgid " [%lds left]" +msgstr "" + +#: src/faillog.c:239 +#, c-format +msgid " [%lds lock]" +msgstr "" + +#: src/gpasswd.c:89 +#, c-format +msgid "usage: %s [-r|-R] group\n" +msgstr "" + +#: src/gpasswd.c:90 +#, c-format +msgid " %s [-a user] group\n" +msgstr "" + +#: src/gpasswd.c:91 +#, c-format +msgid " %s [-d user] group\n" +msgstr "" + +#: src/gpasswd.c:93 +#, c-format +msgid " %s [-A user,...] [-M user,...] group\n" +msgstr "" + +#: src/gpasswd.c:96 +#, c-format +msgid " %s [-M user,...] group\n" +msgstr "" + +#: src/gpasswd.c:160 src/gpasswd.c:245 +#, c-format +msgid "%s: unknown user %s\n" +msgstr "" + +#: src/gpasswd.c:172 +msgid "Permission denied.\n" +msgstr "" + +#: src/gpasswd.c:257 +#, c-format +msgid "%s: shadow group passwords required for -A\n" +msgstr "" + +#: src/gpasswd.c:308 +msgid "Who are you?\n" +msgstr "" + +#: src/gpasswd.c:328 src/newgrp.c:251 +#, c-format +msgid "unknown group: %s\n" +msgstr "" + +#: src/gpasswd.c:436 +#, c-format +msgid "Adding user %s to group %s\n" +msgstr "" + +#: src/gpasswd.c:453 +#, c-format +msgid "Removing user %s from group %s\n" +msgstr "" + +#: src/gpasswd.c:466 +#, c-format +msgid "%s: unknown member %s\n" +msgstr "" + +#: src/gpasswd.c:513 +#, c-format +msgid "%s: Not a tty\n" +msgstr "" + +#. +#. * A new password is to be entered and it must be encrypted, +#. * etc. The password will be prompted for twice, and both +#. * entries must be identical. There is no need to validate +#. * the old password since the invoker is either the group +#. * owner, or root. +#. +#: src/gpasswd.c:535 +#, c-format +msgid "Changing the password for group %s\n" +msgstr "" + +#: src/gpasswd.c:538 +msgid "New Password: " +msgstr "" + +#: src/gpasswd.c:543 src/passwd.c:422 +msgid "Re-enter new password: " +msgstr "" + +#: src/gpasswd.c:555 +msgid "They don't match; try again" +msgstr "" + +#: src/gpasswd.c:559 +#, c-format +msgid "%s: Try again later\n" +msgstr "" + +#: src/gpasswd.c:590 +#, c-format +msgid "%s: can't get lock\n" +msgstr "" + +#: src/gpasswd.c:596 +#, c-format +msgid "%s: can't get shadow lock\n" +msgstr "" + +#: src/gpasswd.c:602 +#, c-format +msgid "%s: can't open file\n" +msgstr "" + +#: src/gpasswd.c:614 +#, c-format +msgid "%s: can't update entry\n" +msgstr "" + +#: src/gpasswd.c:620 +#, c-format +msgid "%s: can't update shadow entry\n" +msgstr "" + +#: src/gpasswd.c:626 +#, c-format +msgid "%s: can't re-write file\n" +msgstr "" + +#: src/gpasswd.c:632 +#, c-format +msgid "%s: can't re-write shadow file\n" +msgstr "" + +#: src/gpasswd.c:640 +#, c-format +msgid "%s: can't unlock file\n" +msgstr "" + +#: src/gpasswd.c:645 +#, c-format +msgid "%s: can't update DBM files\n" +msgstr "" + +#: src/gpasswd.c:652 +#, c-format +msgid "%s: can't update DBM shadow files\n" +msgstr "" + +#: src/groupadd.c:105 +msgid "usage: groupadd [-g gid [-o]] group\n" +msgstr "" + +#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230 +#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675 +#, c-format +msgid "%s: error adding new group entry\n" +msgstr "" + +#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942 +#: src/usermod.c:551 src/usermod.c:687 +#, c-format +msgid "%s: cannot add new dbm group entry\n" +msgstr "" + +#: src/groupadd.c:258 src/useradd.c:996 +#, c-format +msgid "%s: name %s is not unique\n" +msgstr "" + +#: src/groupadd.c:273 +#, c-format +msgid "%s: gid %ld is not unique\n" +msgstr "" + +#: src/groupadd.c:297 +#, c-format +msgid "%s: can't get unique gid\n" +msgstr "" + +#. +#. * All invalid group names land here. +#. +#: src/groupadd.c:321 src/groupmod.c:341 +#, c-format +msgid "%s: %s is a not a valid group name\n" +msgstr "" + +#: src/groupadd.c:350 src/groupmod.c:367 +#, c-format +msgid "%s: invalid group %s\n" +msgstr "" + +#: src/groupadd.c:367 src/useradd.c:1272 +#, c-format +msgid "%s: -O requires NAME=VALUE\n" +msgstr "" + +#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381 +#: src/userdel.c:303 src/usermod.c:563 +#, c-format +msgid "%s: cannot rewrite group file\n" +msgstr "" + +#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389 +#: src/userdel.c:309 src/usermod.c:700 +#, c-format +msgid "%s: cannot rewrite shadow group file\n" +msgstr "" + +#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389 +#, c-format +msgid "%s: unable to lock group file\n" +msgstr "" + +#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432 +#, c-format +msgid "%s: unable to open group file\n" +msgstr "" + +#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398 +#, c-format +msgid "%s: unable to lock shadow group file\n" +msgstr "" + +#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442 +#, c-format +msgid "%s: unable to open shadow group file\n" +msgstr "" + +#: src/groupadd.c:518 +#, c-format +msgid "%s: group %s exists\n" +msgstr "" + +#: src/groupdel.c:86 +msgid "usage: groupdel group\n" +msgstr "" + +#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234 +#, c-format +msgid "%s: error removing group entry\n" +msgstr "" + +#: src/groupdel.c:116 src/groupmod.c:206 +#, c-format +msgid "%s: error removing group dbm entry\n" +msgstr "" + +#: src/groupdel.c:131 +#, c-format +msgid "%s: error removing shadow group entry\n" +msgstr "" + +#: src/groupdel.c:144 src/groupmod.c:252 +#, c-format +msgid "%s: error removing shadow group dbm entry\n" +msgstr "" + +#. +#. * Can't remove the group. +#. +#: src/groupdel.c:248 +#, c-format +msgid "%s: cannot remove user's primary group.\n" +msgstr "" + +#: src/groupdel.c:305 src/groupmod.c:501 +#, c-format +msgid "%s: group %s does not exist\n" +msgstr "" + +#: src/groupdel.c:319 src/groupmod.c:517 +#, c-format +msgid "%s: group %s is a NIS group\n" +msgstr "" + +#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016 +#, c-format +msgid "%s: %s is the NIS master\n" +msgstr "" + +#: src/groupmod.c:105 +msgid "usage: groupmod [-g gid [-o]] [-n name] group\n" +msgstr "" + +#: src/groupmod.c:165 +#, c-format +msgid "%s: %s not found in /etc/group\n" +msgstr "" + +#: src/groupmod.c:246 +#, c-format +msgid "%s: cannot add new dbm shadow group entry\n" +msgstr "" + +#: src/groupmod.c:299 +#, c-format +msgid "%s: %ld is not a unique gid\n" +msgstr "" + +#: src/groupmod.c:330 +#, c-format +msgid "%s: %s is not a unique name\n" +msgstr "" + +#: src/groups.c:62 +#, c-format +msgid "unknown user %s\n" +msgstr "" + +#: src/grpck.c:98 +#, c-format +msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n" +msgstr "" + +#: src/grpck.c:100 +#, c-format +msgid "Usage: %s [ -r ] [ group ]\n" +msgstr "" + +#: src/grpck.c:119 src/pwck.c:119 +msgid "No" +msgstr "" + +#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225 +#, c-format +msgid "%s: cannot lock file %s\n" +msgstr "" + +#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241 +#: src/pwck.c:250 +#, c-format +msgid "%s: cannot open file %s\n" +msgstr "" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:298 +msgid "invalid group file entry\n" +msgstr "" + +#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517 +#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517 +#: src/pwck.c:541 +#, c-format +msgid "delete line `%s'? " +msgstr "" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:361 +msgid "duplicate group entry\n" +msgstr "" + +#: src/grpck.c:378 +#, c-format +msgid "invalid group name `%s'\n" +msgstr "" + +#: src/grpck.c:388 +#, c-format +msgid "group %s: bad GID (%d)\n" +msgstr "" + +#: src/grpck.c:414 +#, c-format +msgid "group %s: no user %s\n" +msgstr "" + +#: src/grpck.c:416 src/grpck.c:585 +#, c-format +msgid "delete member `%s'? " +msgstr "" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:453 +msgid "invalid shadow group file entry\n" +msgstr "" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:516 +msgid "duplicate shadow group entry\n" +msgstr "" + +#: src/grpck.c:533 +msgid "no matching group file entry\n" +msgstr "" + +#: src/grpck.c:553 +#, c-format +msgid "shadow group %s: no administrative user %s\n" +msgstr "" + +#: src/grpck.c:555 +#, c-format +msgid "delete administrative member `%s'? " +msgstr "" + +#: src/grpck.c:583 +#, c-format +msgid "shadow group %s: no user %s\n" +msgstr "" + +#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580 +#, c-format +msgid "%s: cannot update file %s\n" +msgstr "" + +#: src/grpck.c:640 src/pwck.c:606 +#, c-format +msgid "%s: the files have been updated; run mkpasswd\n" +msgstr "" + +#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611 +#, c-format +msgid "%s: no changes\n" +msgstr "" + +#: src/grpck.c:644 src/pwck.c:610 +#, c-format +msgid "%s: the files have been updated\n" +msgstr "" + +#: src/grpconv.c:62 src/grpunconv.c:63 +#, c-format +msgid "%s: can't lock group file\n" +msgstr "" + +#: src/grpconv.c:67 src/grpunconv.c:68 +#, c-format +msgid "%s: can't open group file\n" +msgstr "" + +#: src/grpconv.c:72 src/grpunconv.c:73 +#, c-format +msgid "%s: can't lock shadow group file\n" +msgstr "" + +#: src/grpconv.c:77 src/grpunconv.c:78 +#, c-format +msgid "%s: can't open shadow group file\n" +msgstr "" + +#. +#. * This shouldn't happen (the entry exists) but... +#. +#: src/grpconv.c:93 +#, c-format +msgid "%s: can't remove shadow group %s\n" +msgstr "" + +#: src/grpconv.c:134 src/pwconv.c:160 +#, c-format +msgid "%s: can't update shadow entry for %s\n" +msgstr "" + +#: src/grpconv.c:143 src/grpunconv.c:94 +#, c-format +msgid "%s: can't update entry for group %s\n" +msgstr "" + +#: src/grpconv.c:150 src/grpunconv.c:102 +#, c-format +msgid "%s: can't update shadow group file\n" +msgstr "" + +#: src/grpconv.c:154 src/grpunconv.c:107 +#, c-format +msgid "%s: can't update group file\n" +msgstr "" + +#: src/grpconv.c:169 src/grpunconv.c:128 +#, c-format +msgid "%s: not configured for shadow group support.\n" +msgstr "" + +#: src/grpunconv.c:112 +#, c-format +msgid "%s: can't delete shadow group file\n" +msgstr "" + +#: src/id.c:56 +msgid "usage: id [ -a ]\n" +msgstr "" + +#: src/id.c:58 +msgid "usage: id\n" +msgstr "" + +#: src/id.c:118 +#, c-format +msgid "uid=%d(%s)" +msgstr "" + +#: src/id.c:120 +#, c-format +msgid "uid=%d" +msgstr "" + +#: src/id.c:124 +#, c-format +msgid " gid=%d(%s)" +msgstr "" + +#: src/id.c:126 +#, c-format +msgid " gid=%d" +msgstr "" + +#: src/id.c:136 +#, c-format +msgid " euid=%d(%s)" +msgstr "" + +#: src/id.c:138 +#, c-format +msgid " euid=%d" +msgstr "" + +#: src/id.c:143 +#, c-format +msgid " egid=%d(%s)" +msgstr "" + +#: src/id.c:145 +#, c-format +msgid " egid=%d" +msgstr "" + +#. +#. * Start off the group message. It will be of the format +#. * +#. * groups=###(aaa),###(aaa),###(aaa) +#. * +#. * where "###" is a numerical value and "aaa" is the +#. * corresponding name for each respective numerical value. +#. +#: src/id.c:166 +msgid " groups=" +msgstr "" + +#: src/lastlog.c:167 +msgid "Username Port From Latest\n" +msgstr "" + +#: src/lastlog.c:169 +msgid "Username Port Latest\n" +msgstr "" + +#: src/lastlog.c:183 +msgid "**Never logged in**" +msgstr "" + +#: src/login.c:198 +#, c-format +msgid "usage: %s [-p] [name]\n" +msgstr "" + +#: src/login.c:201 +#, c-format +msgid " %s [-p] [-h host] [-f name]\n" +msgstr "" + +#: src/login.c:203 +#, c-format +msgid " %s [-p] -r host\n" +msgstr "" + +#: src/login.c:286 +msgid "Invalid login time\n" +msgstr "" + +#: src/login.c:341 +msgid "" +"\n" +"System closed for routine maintenance\n" +msgstr "" + +#: src/login.c:351 +msgid "" +"\n" +"[Disconnect bypassed -- root login allowed.]\n" +msgstr "" + +#: src/login.c:390 +#, c-format +msgid "" +"\n" +"Login timed out after %d seconds.\n" +msgstr "" + +#: src/login.c:692 +#, c-format +msgid " on `%.100s' from `%.200s'" +msgstr "" + +#: src/login.c:694 +#, c-format +msgid " on `%.100s'" +msgstr "" + +#: src/login.c:834 +#, c-format +msgid "" +"\n" +"%s login: " +msgstr "" + +#: src/login.c:836 +msgid "login: " +msgstr "" + +#: src/login.c:1026 src/sulogin.c:231 +msgid "Login incorrect" +msgstr "" + +#: src/login.c:1213 +msgid "Warning: login re-enabled after temporary lockout.\n" +msgstr "" + +#: src/login.c:1223 +#, c-format +msgid "Last login: %s on %s" +msgstr "" + +#: src/login.c:1226 +#, c-format +msgid "Last login: %.19s on %s" +msgstr "" + +#: src/login.c:1231 +#, c-format +msgid " from %.*s" +msgstr "" + +#: src/login.c:1303 +msgid "Starting rad_login\n" +msgstr "" + +#: src/mkpasswd.c:49 +#, c-format +msgid "%s: no DBM database on system - no action performed\n" +msgstr "" + +#: src/mkpasswd.c:245 src/mkpasswd.c:249 +#, c-format +msgid "%s: cannot overwrite file %s\n" +msgstr "" + +#: src/mkpasswd.c:263 +#, c-format +msgid "%s: cannot open DBM files for %s\n" +msgstr "" + +#: src/mkpasswd.c:296 +#, c-format +msgid "%s: the beginning with " +msgstr "" + +#: src/mkpasswd.c:321 +#, c-format +msgid "%s: error parsing line \"%s\"\n" +msgstr "" + +#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332 +msgid "adding record for name " +msgstr "" + +#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349 +#, c-format +msgid "%s: error adding record for " +msgstr "" + +#: src/mkpasswd.c:367 +#, c-format +msgid "added %d entries, longest was %d\n" +msgstr "" + +#: src/mkpasswd.c:382 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n" +msgstr "" + +#: src/mkpasswd.c:384 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n" +msgstr "" + +#: src/mkpasswd.c:387 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g ] file\n" +msgstr "" + +#: src/newgrp.c:66 +msgid "usage: newgrp [ - ] [ group ]\n" +msgstr "" + +#: src/newgrp.c:68 +msgid "usage: sg group [[-c] command ]\n" +msgstr "" + +#: src/newgrp.c:125 +#, c-format +msgid "unknown uid: %d\n" +msgstr "" + +#: src/newgrp.c:201 +#, c-format +msgid "unknown gid: %ld\n" +msgstr "" + +#: src/newgrp.c:245 +#, c-format +msgid "unknown gid: %d\n" +msgstr "" + +#: src/newgrp.c:323 src/newgrp.c:332 +msgid "Sorry.\n" +msgstr "" + +#: src/newgrp.c:364 +msgid "too many groups\n" +msgstr "" + +#: src/newusers.c:76 +#, c-format +msgid "Usage: %s [ input ]\n" +msgstr "" + +#: src/newusers.c:364 +#, c-format +msgid "%s: can't lock /etc/passwd.\n" +msgstr "" + +#: src/newusers.c:375 +#, c-format +msgid "%s: can't lock files, try again later\n" +msgstr "" + +#: src/newusers.c:390 +#, c-format +msgid "%s: can't open files\n" +msgstr "" + +#: src/newusers.c:435 +#, c-format +msgid "%s: line %d: invalid line\n" +msgstr "" + +#: src/newusers.c:453 +#, c-format +msgid "%s: line %d: can't create GID\n" +msgstr "" + +#: src/newusers.c:469 +#, c-format +msgid "%s: line %d: can't create UID\n" +msgstr "" + +#: src/newusers.c:481 +#, c-format +msgid "%s: line %d: cannot find user %s\n" +msgstr "" + +#: src/newusers.c:489 +#, c-format +msgid "%s: line %d: can't update password\n" +msgstr "" + +#: src/newusers.c:506 +#, c-format +msgid "%s: line %d: mkdir failed\n" +msgstr "" + +#: src/newusers.c:510 +#, c-format +msgid "%s: line %d: chown failed\n" +msgstr "" + +#: src/newusers.c:519 +#, c-format +msgid "%s: line %d: can't update entry\n" +msgstr "" + +#: src/newusers.c:550 +#, c-format +msgid "%s: error updating files\n" +msgstr "" + +#: src/passwd.c:239 +#, c-format +msgid "usage: %s [ -f | -s ] [ name ]\n" +msgstr "" + +#: src/passwd.c:242 +#, c-format +msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n" +msgstr "" + +#: src/passwd.c:245 +#, c-format +msgid " %s { -l | -u | -d | -S | -e } name\n" +msgstr "" + +#: src/passwd.c:347 +#, c-format +msgid "User %s has a TCFS key, his old password is required.\n" +msgstr "" + +#: src/passwd.c:348 +msgid "You can use -t option to force the change.\n" +msgstr "" + +#: src/passwd.c:354 +msgid "Old password: " +msgstr "" + +#: src/passwd.c:361 +#, c-format +msgid "Incorrect password for `%s'\n" +msgstr "" + +#: src/passwd.c:374 +#, c-format +msgid "Warning: user %s has a TCFS key.\n" +msgstr "" + +#: src/passwd.c:392 +#, c-format +msgid "" +"Enter the new password (minimum of %d, maximum of %d characters)\n" +"Please use a combination of upper and lower case letters and numbers.\n" +msgstr "" + +#: src/passwd.c:399 +msgid "New password: " +msgstr "" + +#: src/passwd.c:409 +msgid "Try again.\n" +msgstr "" + +#: src/passwd.c:418 +msgid "" +"\n" +"Warning: weak password (enter it again to use it anyway).\n" +msgstr "" + +#: src/passwd.c:427 +msgid "They don't match; try again.\n" +msgstr "" + +#: src/passwd.c:512 src/passwd.c:528 +#, c-format +msgid "The password for %s cannot be changed.\n" +msgstr "" + +#: src/passwd.c:556 +#, c-format +msgid "Sorry, the password for %s cannot be changed yet.\n" +msgstr "" + +#: src/passwd.c:693 +#, c-format +msgid "%s: out of memory\n" +msgstr "" + +#: src/passwd.c:845 +msgid "Cannot lock the TCFS key database; try again later\n" +msgstr "" + +#: src/passwd.c:851 +msgid "Cannot open the TCFS key database.\n" +msgstr "" + +#: src/passwd.c:857 +msgid "Error updating the TCFS key database.\n" +msgstr "" + +#: src/passwd.c:862 +msgid "Cannot commit TCFS changes.\n" +msgstr "" + +#: src/passwd.c:1069 +#, c-format +msgid "%s: Cannot execute %s" +msgstr "" + +#: src/passwd.c:1176 +#, c-format +msgid "%s: repository %s not supported\n" +msgstr "" + +#: src/passwd.c:1263 +#, c-format +msgid "%s: Permission denied\n" +msgstr "" + +#: src/passwd.c:1287 +#, c-format +msgid "You may not change the password for %s.\n" +msgstr "" + +#: src/passwd.c:1352 +#, c-format +msgid "Changing password for %s\n" +msgstr "" + +#: src/passwd.c:1356 +#, c-format +msgid "The password for %s is unchanged.\n" +msgstr "" + +#: src/passwd.c:1412 +msgid "Password changed.\n" +msgstr "" + +#: src/pwck.c:98 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n" +msgstr "" + +#: src/pwck.c:100 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd ]\n" +msgstr "" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:285 +msgid "invalid password file entry\n" +msgstr "" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:347 +msgid "duplicate password entry\n" +msgstr "" + +#: src/pwck.c:363 +#, c-format +msgid "invalid user name `%s'\n" +msgstr "" + +#: src/pwck.c:373 +#, c-format +msgid "user %s: bad UID (%d)\n" +msgstr "" + +#. +#. * No primary group, just give a warning +#. +#: src/pwck.c:388 +#, c-format +msgid "user %s: no group %d\n" +msgstr "" + +#. +#. * Home directory doesn't exist, give a warning +#. +#: src/pwck.c:403 +#, c-format +msgid "user %s: directory %s does not exist\n" +msgstr "" + +#. +#. * Login shell doesn't exist, give a warning +#. +#: src/pwck.c:418 +#, c-format +msgid "user %s: program %s does not exist\n" +msgstr "" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:454 +msgid "invalid shadow password file entry\n" +msgstr "" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:516 +msgid "duplicate shadow password entry\n" +msgstr "" + +#. +#. * Tell the user this entry has no matching +#. * /etc/passwd entry and ask them to delete it. +#. +#: src/pwck.c:540 +msgid "no matching password file entry\n" +msgstr "" + +#: src/pwck.c:557 +#, c-format +msgid "user %s: last password change in the future\n" +msgstr "" + +#: src/pwconv.c:94 src/pwunconv.c:108 +#, c-format +msgid "%s: can't lock passwd file\n" +msgstr "" + +#: src/pwconv.c:99 src/pwunconv.c:113 +#, c-format +msgid "%s: can't open passwd file\n" +msgstr "" + +#: src/pwconv.c:126 +#, c-format +msgid "%s: can't remove shadow entry for %s\n" +msgstr "" + +#: src/pwconv.c:169 +#, c-format +msgid "%s: can't update passwd entry for %s\n" +msgstr "" + +#: src/pwconv.c:176 +#, c-format +msgid "%s: can't update shadow file\n" +msgstr "" + +#: src/pwconv.c:180 +#, c-format +msgid "%s: can't update passwd file\n" +msgstr "" + +#: src/pwunconv.c:62 +#, c-format +msgid "%s: Shadow passwords are not configured.\n" +msgstr "" + +#: src/pwunconv.c:171 +#, c-format +msgid "%s: can't update entry for user %s\n" +msgstr "" + +#: src/pwunconv.c:188 +#, c-format +msgid "%s: can't delete shadow password file\n" +msgstr "" + +#: src/su.c:140 +msgid "Sorry." +msgstr "" + +#: src/su.c:222 +#, c-format +msgid "%s: must be run from a terminal\n" +msgstr "" + +#: src/su.c:311 +#, c-format +msgid "%s: pam_start: error %d\n" +msgstr "" + +#: src/su.c:337 +#, c-format +msgid "Unknown id: %s\n" +msgstr "" + +#. access denied (-1) or unexpected value +#: src/su.c:372 src/su.c:387 +#, c-format +msgid "You are not authorized to su %s\n" +msgstr "" + +#. require own password +#: src/su.c:383 +msgid "(Enter your own password.)" +msgstr "" + +#: src/su.c:404 +#, c-format +msgid "%s: permission denied (shell).\n" +msgstr "" + +#: src/su.c:428 +#, c-format +msgid "" +"%s: %s\n" +"(Ignored)\n" +msgstr "" + +#: src/su.c:628 +msgid "No shell\n" +msgstr "" + +#. must be a password file! +#: src/sulogin.c:136 +msgid "No password file\n" +msgstr "" + +#. +#. * Fail secure +#. +#: src/sulogin.c:178 +msgid "No password entry for 'root'\n" +msgstr "" + +#. +#. * Here we prompt for the root password, or if no password is +#. * given we just exit. +#. +#. get a password for root +#: src/sulogin.c:192 +msgid "" +"\n" +"Type control-d to proceed with normal startup,\n" +"(or give root password for system maintenance):" +msgstr "" + +#. make new environment active +#: src/sulogin.c:241 +msgid "Entering System Maintenance Mode\n" +msgstr "" + +#: src/useradd.c:243 +#, c-format +msgid "%s: rebuild the group database\n" +msgstr "" + +#: src/useradd.c:250 +#, c-format +msgid "%s: rebuild the shadow group database\n" +msgstr "" + +#: src/useradd.c:287 src/usermod.c:967 +#, c-format +msgid "%s: invalid numeric argument `%s'\n" +msgstr "" + +#: src/useradd.c:343 +#, c-format +msgid "%s: unknown gid %s\n" +msgstr "" + +#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254 +#: src/usermod.c:1098 +#, c-format +msgid "%s: unknown group %s\n" +msgstr "" + +#: src/useradd.c:418 +#, c-format +msgid "group=%s,%ld basedir=%s skel=%s\n" +msgstr "" + +#: src/useradd.c:421 +#, c-format +msgid "shell=%s " +msgstr "" + +#: src/useradd.c:423 +#, c-format +msgid "inactive=%ld expire=%s" +msgstr "" + +#: src/useradd.c:427 +#, c-format +msgid "GROUP=%ld\n" +msgstr "" + +#: src/useradd.c:428 +#, c-format +msgid "HOME=%s\n" +msgstr "" + +#: src/useradd.c:430 +#, c-format +msgid "INACTIVE=%ld\n" +msgstr "" + +#: src/useradd.c:431 +#, c-format +msgid "EXPIRE=%s\n" +msgstr "" + +#: src/useradd.c:433 +#, c-format +msgid "SHELL=%s\n" +msgstr "" + +#: src/useradd.c:434 +#, c-format +msgid "SKEL=%s\n" +msgstr "" + +#: src/useradd.c:470 +#, c-format +msgid "%s: cannot create new defaults file\n" +msgstr "" + +#: src/useradd.c:564 src/useradd.c:575 +#, c-format +msgid "%s: rename: %s" +msgstr "" + +#: src/useradd.c:662 src/usermod.c:274 +#, c-format +msgid "%s: group `%s' is a NIS group.\n" +msgstr "" + +#: src/useradd.c:670 src/usermod.c:282 +#, c-format +msgid "%s: too many groups specified (max %d).\n" +msgstr "" + +#: src/useradd.c:702 src/usermod.c:314 +#, c-format +msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n" +msgstr "" + +#: src/useradd.c:705 +msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n" +msgstr "" + +#: src/useradd.c:708 src/usermod.c:320 +msgid "[-f inactive] [-e expire ] " +msgstr "" + +#: src/useradd.c:711 +msgid "[-A program] " +msgstr "" + +#: src/useradd.c:713 +msgid "[-p passwd] name\n" +msgstr "" + +#: src/useradd.c:715 +#, c-format +msgid " %s\t-D [-g group] [-b base] [-s shell]\n" +msgstr "" + +#: src/useradd.c:718 +msgid "\t\t[-f inactive] [-e expire ]\n" +msgstr "" + +#: src/useradd.c:815 src/usermod.c:472 +#, c-format +msgid "%s: error locking group file\n" +msgstr "" + +#: src/useradd.c:819 src/usermod.c:477 +#, c-format +msgid "%s: error opening group file\n" +msgstr "" + +#: src/useradd.c:824 src/usermod.c:584 +#, c-format +msgid "%s: error locking shadow group file\n" +msgstr "" + +#: src/useradd.c:829 src/usermod.c:590 +#, c-format +msgid "%s: error opening shadow group file\n" +msgstr "" + +#: src/useradd.c:1001 +#, c-format +msgid "%s: uid %d is not unique\n" +msgstr "" + +#: src/useradd.c:1031 +#, c-format +msgid "%s: can't get unique uid\n" +msgstr "" + +#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057 +#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157 +#, c-format +msgid "%s: invalid field `%s'\n" +msgstr "" + +#: src/useradd.c:1153 +#, c-format +msgid "%s: invalid base directory `%s'\n" +msgstr "" + +#: src/useradd.c:1163 +#, c-format +msgid "%s: invalid comment `%s'\n" +msgstr "" + +#: src/useradd.c:1173 +#, c-format +msgid "%s: invalid home directory `%s'\n" +msgstr "" + +#: src/useradd.c:1191 src/usermod.c:1080 +#, c-format +msgid "%s: invalid date `%s'\n" +msgstr "" + +#: src/useradd.c:1203 +#, c-format +msgid "%s: shadow passwords required for -e\n" +msgstr "" + +#: src/useradd.c:1218 +#, c-format +msgid "%s: shadow passwords required for -f\n" +msgstr "" + +#: src/useradd.c:1292 +#, c-format +msgid "%s: invalid shell `%s'\n" +msgstr "" + +#: src/useradd.c:1333 +#, c-format +msgid "%s: invalid user name `%s'\n" +msgstr "" + +#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225 +#, c-format +msgid "%s: cannot rewrite password file\n" +msgstr "" + +#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230 +#, c-format +msgid "%s: cannot rewrite shadow password file\n" +msgstr "" + +#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265 +#, c-format +msgid "%s: unable to lock password file\n" +msgstr "" + +#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269 +#, c-format +msgid "%s: unable to open password file\n" +msgstr "" + +#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274 +#, c-format +msgid "%s: cannot lock shadow password file\n" +msgstr "" + +#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279 +#, c-format +msgid "%s: cannot open shadow password file\n" +msgstr "" + +#: src/useradd.c:1529 src/usermod.c:1366 +#, c-format +msgid "%s: error adding authentication method\n" +msgstr "" + +#: src/useradd.c:1552 +#, c-format +msgid "%s: error adding new password entry\n" +msgstr "" + +#: src/useradd.c:1567 +#, c-format +msgid "%s: error updating password dbm entry\n" +msgstr "" + +#: src/useradd.c:1583 src/usermod.c:1425 +#, c-format +msgid "%s: error adding new shadow password entry\n" +msgstr "" + +#: src/useradd.c:1599 src/usermod.c:1440 +#, c-format +msgid "%s: error updating shadow passwd dbm entry\n" +msgstr "" + +#: src/useradd.c:1631 +#, c-format +msgid "%s: cannot create directory %s\n" +msgstr "" + +#: src/useradd.c:1708 src/usermod.c:1203 +#, c-format +msgid "%s: user %s exists\n" +msgstr "" + +#: src/useradd.c:1738 +#, c-format +msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n" +msgstr "" + +#: src/userdel.c:127 +#, c-format +msgid "usage: %s [-r] name\n" +msgstr "" + +#: src/userdel.c:178 src/userdel.c:260 +#, c-format +msgid "%s: error updating group entry\n" +msgstr "" + +#: src/userdel.c:188 src/userdel.c:269 +#, c-format +msgid "%s: cannot update dbm group entry\n" +msgstr "" + +#: src/userdel.c:215 +#, c-format +msgid "%s: cannot remove dbm group entry\n" +msgstr "" + +#: src/userdel.c:300 +#, c-format +msgid "%s: cannot rewrite TCFS key file\n" +msgstr "" + +#: src/userdel.c:380 +#, c-format +msgid "%s: cannot lock TCFS key file\n" +msgstr "" + +#: src/userdel.c:384 +#, c-format +msgid "%s: cannot open TCFS key file\n" +msgstr "" + +#: src/userdel.c:393 +#, c-format +msgid "%s: cannot open group file\n" +msgstr "" + +#: src/userdel.c:403 +#, c-format +msgid "%s: cannot open shadow group file\n" +msgstr "" + +#: src/userdel.c:434 src/userdel.c:449 +#, c-format +msgid "%s: error deleting authentication\n" +msgstr "" + +#: src/userdel.c:458 +#, c-format +msgid "%s: error deleting password entry\n" +msgstr "" + +#: src/userdel.c:461 +#, c-format +msgid "%s: error deleting shadow password entry\n" +msgstr "" + +#: src/userdel.c:470 +#, c-format +msgid "%s: error deleting TCFS entry\n" +msgstr "" + +#: src/userdel.c:483 +#, c-format +msgid "%s: error deleting password dbm entry\n" +msgstr "" + +#: src/userdel.c:502 +#, c-format +msgid "%s: error deleting shadow passwd dbm entry\n" +msgstr "" + +#: src/userdel.c:543 +#, c-format +msgid "%s: user %s is currently logged in\n" +msgstr "" + +#: src/userdel.c:660 +#, c-format +msgid "%s: warning: %s not owned by %s, not removing\n" +msgstr "" + +#: src/userdel.c:666 +#, c-format +msgid "%s: warning: can't remove " +msgstr "" + +#: src/userdel.c:741 src/usermod.c:994 +#, c-format +msgid "%s: user %s does not exist\n" +msgstr "" + +#: src/userdel.c:755 src/usermod.c:1010 +#, c-format +msgid "%s: user %s is a NIS user\n" +msgstr "" + +#: src/userdel.c:792 +#, c-format +msgid "%s: %s not owned by %s, not removing\n" +msgstr "" + +#: src/userdel.c:815 +#, c-format +msgid "%s: not removing directory %s (would remove home of user %s)\n" +msgstr "" + +#: src/userdel.c:828 +#, c-format +msgid "%s: error removing directory %s\n" +msgstr "" + +#: src/usermod.c:317 +msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n" +msgstr "" + +#: src/usermod.c:323 +msgid "[-A {DEFAULT|program},... ] " +msgstr "" + +#: src/usermod.c:325 +msgid "[-p passwd] [-L|-U] name\n" +msgstr "" + +#: src/usermod.c:504 +#, c-format +msgid "%s: out of memory in update_group\n" +msgstr "" + +#: src/usermod.c:627 +#, c-format +msgid "%s: out of memory in update_gshadow\n" +msgstr "" + +#: src/usermod.c:1180 +#, c-format +msgid "%s: no flags given\n" +msgstr "" + +#: src/usermod.c:1187 +#, c-format +msgid "%s: shadow passwords required for -e and -f\n" +msgstr "" + +#: src/usermod.c:1208 +#, c-format +msgid "%s: uid %ld is not unique\n" +msgstr "" + +#: src/usermod.c:1356 +#, c-format +msgid "%s: error deleting authentication method\n" +msgstr "" + +#: src/usermod.c:1376 +#, c-format +msgid "%s: error changing authentication method\n" +msgstr "" + +#: src/usermod.c:1393 +#, c-format +msgid "%s: error changing password entry\n" +msgstr "" + +#: src/usermod.c:1399 +#, c-format +msgid "%s: error removing password entry\n" +msgstr "" + +#: src/usermod.c:1407 +#, c-format +msgid "%s: error adding password dbm entry\n" +msgstr "" + +#: src/usermod.c:1414 +#, c-format +msgid "%s: error removing passwd dbm entry\n" +msgstr "" + +#: src/usermod.c:1431 +#, c-format +msgid "%s: error removing shadow password entry\n" +msgstr "" + +#: src/usermod.c:1446 +#, c-format +msgid "%s: error removing shadow passwd dbm entry\n" +msgstr "" + +#: src/usermod.c:1477 +#, c-format +msgid "%s: directory %s exists\n" +msgstr "" + +#: src/usermod.c:1484 +#, c-format +msgid "%s: can't create %s\n" +msgstr "" + +#: src/usermod.c:1490 +#, c-format +msgid "%s: can't chown %s\n" +msgstr "" + +#: src/usermod.c:1506 +#, c-format +msgid "%s: cannot rename directory %s to %s\n" +msgstr "" + +#. better leave it alone +#: src/usermod.c:1603 +#, c-format +msgid "%s: warning: %s not owned by %s\n" +msgstr "" + +#: src/usermod.c:1609 +msgid "failed to change mailbox owner" +msgstr "" + +#: src/usermod.c:1616 +msgid "failed to rename mailbox" +msgstr "" + +#: src/vipw.c:102 +#, c-format +msgid "" +"\n" +"%s: %s is unchanged\n" +msgstr "" + +#: src/vipw.c:127 +msgid "Couldn't lock file" +msgstr "" + +#: src/vipw.c:134 +msgid "Couldn't make backup" +msgstr "" + +#: src/vipw.c:187 +#, c-format +msgid "%s: can't restore %s: %s (your changes are in %s)\n" +msgstr "" + +#: src/vipw.c:226 +msgid "" +"Usage:\n" +"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n" +"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n" +msgstr "" diff --git a/current/po/stamp-cat-id b/current/po/stamp-cat-id new file mode 100644 index 00000000..9788f702 --- /dev/null +++ b/current/po/stamp-cat-id @@ -0,0 +1 @@ +timestamp diff --git a/current/po/sv.gmo b/current/po/sv.gmo new file mode 100644 index 0000000000000000000000000000000000000000..cc42273e0097a4a51f469cd7abe7aeab9ac4f79f GIT binary patch literal 39254 zcmchg2b`T%o%gSZ3mJM1orgfkBxHsvWe_2dgk(u0g@7T1XXZY0=Q6i(@12C92!gDF z$Sx=%!YYc2U0G>16a~eyu437x7-hh?{m)ipWfT# zr+e>sM}gl{FDVobffw&yC`3CH3iqHn1^sbHTaLj)(ccUAfRDjF;n(3_@Mli{9NY!{ z4zmh{{owBKNO%F^tH5boMvC=9^U;VWSo&V}!Thr#c_gW&Uyd(18r zrlX$&<^S1m4jhGj@HTiLyayfyABMZaA36RC?u`Bgr+?Aucfk|M?F;445pX9s7b;yR zLAg5%N^UV!ye@!>@8$3S_;$D(d;}`Lo`f^uccAk54^a7bz%e%dbD+$ZLB)F<9u9AW z0elaX`!B+S;j>P^Gl43f2jTv3KBNc>>mXTMxXhW~4wYZ;ha|P|I8;1;1NVhHlKJ9+ zQ28|ou_~;B`@riQ-wY-9KB#>E45Y{lzi{?DQ<%z+L!i=eisSiE=^KZVe?64kN1@X5 z6{!04&rZMNvE)7a04hFbL*-WqD*Q>Pbl(c)&%2@g`7D$_KXUs2hVo~> zSJ?RULzypd`d2~4XA=zIolxOC3ipRk!|CwXa6kBxGpyWnsB%6P%KieVbkv~o^)_ez zF?cZgr{JM*GnD-fue3Y@2I$X%%AXJ_JvTz-$Nf<8f76e@qOhI02- zsBk|7kAz=>0sIYAJa=7yAMkW2xvL!C0_FYzI1@ezkAlB}@_)~T)_yLO`B_lzBX|hB z4$9r%L&ft8kglol9Z1(&n0Bs>&k#Hu{UuQO@oK32x)&Y|KM4c)3#j<-u*mv*G*tas z0;y7kO;F|jFjRhg87kbL!an#r_&WFp_;Pr|;zEJ0r|=1=aDN9){{FS?pZcM~UjY^F zCaCd`+#<;M$9?)N^=>W_x9KL;xOl~DDl4Hf@e z;4bi;Q1$)8&ipe_{y**XKX>{U;9p_>(k0g4KF0&$4w&~tmD4d$@m&Gc-Y$a5r%h1l zx(O;?Z-Os_?}94t_d(_F6HxNsgEQc-o%yayZ96<1_F=vhD!ms%hO$BhDt+&OD(^?& zF7SI$;ry%)j8wzYdjuKZ6SIIcL7(tE{{I;E9+Y4b{G012RKETU z9sr+*D!1L%S^E>3 zx4}c;lTiLW1Le>2Q0d-fz0IFPpyGQnl>I_@GF%T;-`)(bfS-ov!k1rS*QeJ&D?{)h3L;3SCR6Thdsy=)fs=xaVl)In7gW$99G`Le}_4A0-wkRDNFv4}TgHYjp)A83({=TGWB1Qp9s~@u7L{wYN+(z4iAPOf{Nc$a0dJr$G(y^ zAAmAn0+p^hRJeCK^M~N+=)Vt@o_)t`y*~{ejlKz0FYkiNuP5OV@EK>nW7+zD3_Kq5 zW$+|;oil$34x#@(lz;nNW;q0pMIS=t$8AvY{G7A@B~-Y5<95DvGCUc5393E59V*>V z!i;fe5D&U~k~)t>?-Hx3oAyWvUj+femp+Jtp~43zt|a4viUR6HJqa`y|k z4?Jk2ZP$ZP<+d2Ay^ccF<5$A~-sAM2fs*?XR6F@SJOJ*!$+n+kpxn)asy7>;4?w>TD!evS{@w}| z-b0SxfeP;hsB}!f(vE{C!Q;?3q4MQEI2}IX%>N0_M_;(g_CpJx{J9XS-dqXyhi`}b z!H1yo;j8dq_-m+myzFW_ubK(f4o-q{zZS~=DyVqh?ew3Ad!T;?%Afy$O8@TH*m6A; z9*91I2f=IMq3~@`@q5(qhfwYDk5J(r{A$Zr!oARkQ0Z>Lec|gI?}5sP2cYuz%kU8R z3{-sn1Xa!lU+c;pDjgf(AiNfy20sE1gTHdz={g(U(NOhw2rB+{I1Ankm9Bq)%Ac>n zL*egW0C#_lZ3oA~z0q%gr@$sW0e%1~UO$0{!g{7t;eXrdf9~{Kq2jT_>#Vyz$AjQYF`omEhJ#S<*T5rT2<88c z&ipQ@@_G;aEBGi>d_D^$_hYE~_&XTD9bRwEkA$b9KLsjZ8c_aR1y6>z!Wr;Mcoh5< zl-zDN*?HIjjz>V{+Z?F+c^cdajyd}Vl)sZu{@ntPfFFg5=Qp9s^S4m>z1z)pJ##di zgZ?C_da(hjyf;FX*Bjt&@U4)f72XR~9)oY7uZ7Ft8u$>T$`*FH#p>S(2hjf#Dn5I? z(YE`OV1Pb^O7HcK_rqD}zXs>P=b_rw;kVlGhTtpEzY5NVcfu3l<52nd0^AMG{af4L z4MDZ@YoXG6Hirg`s?J#Vx1XAV^O%b?^hgNolxP~~wal=}zaUhtpbT=)wp`Q2}4&le6r zQ0Z6;m5(hbxm%#Z{TS?r-++?)Z>ap;?+z<}1eE*`RQ_KAWq%V?Io<)4-p|69!=FN> zci*?z^~5XS-sl%XwY!U8AG{Rq4#%O&=}NdKyxE!G4fjF+0jT!(7*u`xFSrOEa;L55 z5mdadgeu3kK;_5BpyKy+Xa9S6BKm#bYQtLu_eXyrRQl>r`THiQ{^TJj`5#01x943p zU4zj7zQ)G~USf3XYa{hT0va-#1Z8+YP9< zJ2O5_ymmqVZj{Q_|E@;AFY09&oaYVUM^QgQDINNK3N?nDe*b{F+kL+uegyq2xC#Cc z^##;Js2XPXquQvY=r2dT6s6y1Elhns9((=%-lA~6(@T3I-;137dibc5ITL;g{YGae z_cI;c2KBQT^B*nsVzz4A!SLe9uAdMrZa0xNFMYe$HI=_IcE) zsPCeFiaH0S-@l@+F<-3TaeF)JGfpo&g#H}V5Q;9${9eWX>*&+JGWv%x*uj~f2OmVK z?&`NE-ycVP7NvIaHuz)s7TKX5N4*m>{r)$KZo>56AA@Qa$6z-f^}qQ3Yt-L5*%f>b zp#1L)%+(I>boM3qO7yRSA4Z*yI?D;a8{UY1IqE*tFVXJ-Tc}4+Z$aIK+6}cc>K@c_ zDF1seAHVk+xW#>|y5&z;$O_}<{Yg)-_g)T=Rn z3F=tXM^XNFulsm8W@CIGgZes(ZnE%RC-*wO-;SC30Gu!0Zwf-DBYq)Lwiah1!|# zt5B!%eKK5*x`FT4q4b*$KjOZhMgI!af1>Wi?C(+UKs|vq`u&}S*|#~2@9(45Aa@|@0Mv2L{s-{i-StPA=LYv%(?IY^y8@ap!EBYvm5051=K<4e+Lh9=0D?GW3hg(Mjeh?hTU~= zNB9)f@6)JDP(!E&O22(kRb+OBOX1(43aCw}K~z85`%o>E|25sm+u(J`>;jAMLex%t zw^1+UTfc8v6#fPVs8?cs8|qxXSHKJ4NpKc?BTBz3(7z1z4Bzu$`uAHjPoxa?;rme3 zrO2HEzld6eI^4ON3!CoygYZ_=Tb=$3@M>gla{A4D>vtt;9_m-9Z==49nnbNa?jrav zsD&u~9&>K@gWt18g}dPOs9&RIqh60X8v7GaTlroMA3*81#-dPl{Ddo~hxxxb*~RF;%J(NxZ*Vf}_`VkPF4TXZ-iY~Mp{7k+H&6`5>eVP%H&9)_p8vOk z)>u@j=yN0(saLB}tu0L@s70GL)WT}CzAxo&DkoK(jR)XuWec8kB3{NV~i- zlG`YVu4t5-Q6Sre6O~G^j39=BnJx5-6tNX!^_n+WS+7@vWfRrmsOd!3)|=yLk-nL& zpi(cDYePYSZ%GB^RxnW;84GKrsMuHNTO#YAU9LvOpgz$K!qIlr3}zOCRy0zt6T2LiA=5tf9 ziOAdUvMqBosz4d%1M?L1=G?)-K?Sxnr86)y_IG zsUI^IirT1&d^)Rws{-1^)xp4o{#VrhR_T9Ha7~<0>R-J^EhK}_8LLyBf>13fE=x)Z z8)^`3B503AfvX5%k(?~I+Rd zo-wmE!?ZJMI}N&0iAuC9+H{j_i<)#6rma_sYV7ihnouiWJ`pLE&a&0lzqmw;jEb|p ziKHnGBX6T*GQbsH(tTunv{g8d zYob-(RHM-jPX;qvbB#eWs@6BsBiLXDmIuw~@(KFSRcH*nX!eTvXAe0cpgOWmLHd-!C zP=K){^@lhcTT^?S#cCe|DrH)^3!I4#ur6m?Yx!C7B4&Zh#*)xL5&@z{YCA8 zHH+t)Zt@5#bSYI*RV7=}W>{#CVLnnRlT$A2k+3$4xQ;0(ABr<;M#Kg~6LN={4api7 zqY9-)^Dr4gbVvEj*)v!OppdnZ3^ z1-BJAlMlvHai{*q^&(v=)^{V8pHO3EeGWP^A+gI#yRmf%&2>3t2B%&3%-(tCm9!bzC{K|nE3mD^Pt;7s z=uG-Vqo}q$|LmnES2E?CvP)%5o`}hkbhMq*B&+hWqf1B=Dl#C)qx@2L9=Q6J1eWVX zk6M}bBd=aMdzS&d5}LNosTx^NdX$0lW6GpDnf%(Iu_i1Q%`~kzT(z^wARFaQnM|PF zqPB9{q32SKCX9ueGjxs|W|*_XM3GT_glev_KQ76Xy(W>xXf&Ltv|HJhC?QixSD&+R zRWKe+_OMp|b$Y(-UQfQ8jwG(@odp$3^bX&6kQctO$SJzm&rC*VYCxw*@4~HbjG9Rg z)|mya|4}1iBHCz{t09G8;*<<+3arU8kOgYGptKU}C@$ag^v(<~(IeU3x_5fK#MF7y zA=TSE*UF}<`c5QMf|-1Xu3+ur>aCj{vPh^*6r*59WrkfH*O^Z>gV9P@a)ME_$pV?C z#{@SBC$O%y%Ohc1GskMw9;>@~M@CNVz~)@4*>y?8shvuwvsdUP8+)cK>Lo<$HT@td zDrlgxQ8FFDb|o*C94$wz{A?G{;Yl2ku1J_Eq{1=PuD5kIm(zj7K4e953L=(_qm!F2 z-D16?l`e^5FtvASS>Sr z?Isw2>J0vVgMi(SfPEvsD`FRLw#wL4v3M@lX%QOFOrPChneNA97iQN)(-&isc5$g& zDTiiuW31hn>GyoJmzb)+a$r610&dTl?Wax~GsEsSHVMxW_tDLIZ#KJ=p{mrD*)=9oY`&)p2S|kQ?Yk-i}h$ z?ISfOYId_UV!fGlnX`zRH%o7@nJImyJ8n%h8ug~%I z!5p{v3D-=QOJrK!CS;d!&~F-|PEa&!YevHpWzwUqKii@B!s)iph9owI@ac^K2BHY%eL-9JVDDgtX9s(e3imNhwc;Iee&@ zS&upJGI=I*GnxitA!l8~5qo5|I9*vxA#i%2c2gZUsqx|rY1Odi)?gerG@_9*y?!z1 z*TK`wqAx5qCUuUN)3A(9{x~>M3x`<;vv4zOUt7q@5Zqzyb2+u7?vTh7U7kO=OWed0 zV?AXsMxtjhc9Yu-{BAnqyQ%De=uK&bj7V|6?2R?-*vgPL$rVcu2;9a~?v%pYrDqi0 zES^xLLbZEXD$J3ICQI#hWs(vqafVCxU}L5OMmj#T38)?^by~7bfxP3C*uQgDE||A^ z!G=Z4moCV*&bdLO5@`lQM1z4UG2zT7^yd+=d%M5u`oKc}0&`kxb}4l#;0t$fc45w( zWf7YZNy6sLDa;!giCP>s)PvT9{@)%8*^e3-;dHDW%wMo<@q+nuPDmMp1v);reg1sy zK=xn6Z(!-tf%)@i7v|Zew9jTdOX|ScVKI)0a*#v2!a45jLaQWuPMq}ZIJT1(gp}EK zLAms`$ot)uLSH-oSAVb;jt)(XT+0jGwxC}`DXKR zNKII&;+rh?oT67Js+w=iWCwr&BhjkbxdY_ceJhfN9g@E4Ff%qY-O}`> z!92l?kh(8H^3?@!M#sdC0|y39JFVB%k!(CTRGx_D2IQC~WE#NR6I_Z=7AmT4|Mo9* z<(#QLx%(mFZ8y}NhPLR zuB-Lsi*d7j6t{Hz+HcY(DJkAutu@d4!Qe{vd-nm_w znJPR>Imq%oZEI&dn3!VjD=cT$<((3d<n2a=X8z+MfXmw*v6`~myH<-%ZS6ID0-r-fA978~S z1<#61GD)-@Ja>@y1bla{!yt+7>OLeZP*~mG&(O{I@l;*;wy@RJK zjP>eEvBckmq@Mjg7_M#Y>VbDnjB-R*#BigZp)j?nJlHelg`93 zC2)1Cu{|;xToT@r-_MpxadS)QF+E zqu=yU`^K3`o^LFUE7+MbpG%mg>KbR4U@Wmv7a-HW948AI^SEZ#;!>C!ley1mJ$9p% z8*IH!<0nHW_g^>?W;dbeE*0zUbG@nKV@++@z# zw`1%Nawmq7h$(e)ExK?~eImX=rxB^%EMG|kS+uddRG%gRh6TH%)!Dw8^J@vIxanP zPrTF&tLp=!yK4S|h4a=dS$(xLzDD<c^6oT8m+&p^w%bEl&q zT7S%#%w!6a@ngI%wj?v^i!_oQSNu9uP3vuYYul= zxhBTC=I-{EF2&`UftN9x?^&Y`xrs(a$NqlD)vQJcA~uf8x63B8E7r@l)45M=rCw*5 zY18TV`z_U4Y#T7Oe7Jsv*=uSR5^HxEM2!GzV?h_<*(&(9Jj80Y7;qR9^s{l5AzQz4svlNl?oB(MSeV=RzV)$} z%j}aFW(~9yj!pDf!%k7X5guh-#j%($lUVvuUjIx4+8SRsP&bc%Qm;PFwV7_;We|{e zqxqE?$L&1LlqF+*%6=fcTHZ2H>D2`Dy6_5p7#;V~=}D!nm?4pMSF6Ld-WR2P(<=;x z(qW8uGR?|1uO3(#zy5HZn7Tu^N0=lpPOLGGT^k*Jm`!xnxLWUYyN-7*CQ2RRx)<$2 zRXD*wsA-ThVTdd>8!|OBFQ!MJx~3<9ZVV&kEEB{ptfiG`+wc_%j6Zfo69 zBXO}q6*-gCd^h%?nEHUsBe8KFiOC(i?d{SQx&e8(D5~&c1K*>zt?!sr+gz9*<*CyI z&(-|Pu$2?lR>ojnb2w_VUEd|DH)COKG!iA;T#%5yH05%6Q_^XqdCksK(PWdKMzm zGM-TIm93orax;f;O=x;>rVo3b9EYn%W*7Kll-9kS5P$_l5oQmH&L-iqIxmE-*5^ywRne5L|HtBRBHg_&4f^vN5v4x>_&2xXlu?R1tS6DBh1 zl)C(2mEdb#uDyMiwsCWl%I8)r)Kq4D%961_7Wy*p($v@znX9IJmu7MRpBh_e>$tjL zbLFyt&1}}wR;s)hrJteF&>qxjS*x)!t*{uWg}3QXm$)WoT7{+sICoFgI1`W5tZ9+V zmsQuPjod;Uk81X0Qj<19l1C;uZf1?Q^B$|w^|)ITHg2(tQn_NHXDXJh*9yKv%KF=B z&E2hm>SjGxi{ryuJe|6rocCreSH#Y)T(Zc&lFc7_NFu{7Bspv%Jxo7lrFgbB-rTHn zPy1-?iIwvgSex_A>p=1(+*sO5xv{~<`IBoUN`)zip&*ts{a;8xChr%zLeuJ#>sa<^ z*!sNKfqKja%-43%{}{ibc)7t8P@ZDw;xqNd5%n8emZy%85i zmuZJEKB-F3z9veh5^GUWn@Y&%Wh+mzvZWPvIF^z1KF@)v%z2G3j(Dd8Q{}u6QX9ao zJYyeB3=}w{QKmv=N-`_nGcSy1+suQw1Mitjy|X0AFpXAunU+XQ8Ii4x26f1_$~bw} zG|$__hK%aSV{6wlSFH7R#AZ80OjYb1zbR{~jfWALG9)vp3Ilc_^8!k2d&b4L8{fy# zRp*522BnU?^lsyn(EDk3PW?<=Oiaw0OjIjOwB3l(&x;J&J>4RGDjlWzGVI*I6gx~J zznwXd6Yq|=nEFOt%*`y!xdXzKM5osS%1(D>DUMNABF@s@Vm?#5I-1|JUfEnKF;z2Lz^t@5iX5&En6mKkbv0B=C_7;1I*D6YhciEtnpI_L^fse0W2#1D zJNBAMcBWz4;dPwb!OUj6Gt633tB5u8A}wc&f(k+gG+9dPQN?yL2R%a}_L;15t zfVf@e*GJoDZX+^Qs7Gw9WzV*f>Xds`j+Drh6~lFITQzO%5gFgRCJo%aAKXk2Wun+Q zJuuTLO=~rqa^-4z1zQ2TnncpUZX?eU!Jb)@h-^=?8Lr|QomXQL-;CIlUM9`4SKIQ9 zB$4dQanl5BR+$T>3<9oGFW1KP%#bWMs}8+3RBLX9RSw(u3o6<~F%x|A@~~8Q&RFkp z+<`kIz1eK@XbHo+L-zmFL2VvqGp*ekjy9IfBGZ*N%21@EoNh=Mw$BuZ{tusxY&9BI>vEVY?U3(#UO7~NcPi^E)x zw;5NhB-&w|m9}}fMW8LH#NQ6tZI$rTUf4QNKH7_6yy} zrUGaF$JsJlr5a#OX7;k|FvmlNXU%3!g-+Z0ji&Y zr)*nw8@8+ox$xcXj7?oenUn>WcC?3TJEeH08^>WRs`idUJHWc*Fexuc&F<0A5OFRqy$*Vc+D1bst^+~lB3)Nauw6YjVayCjp)y{9eT!u?|3yRm<~OV0%> zERm8C&D;BWgFc%AO%v6^bZs_kql2>AWEfBI(6++yn%_e9KHJBpQ-s`O&$nuJddJx^ z=WoI2EQGd2lg++5<;YacIj5=9?cqR+HTR}Q>k)h8gPQ@`z3jKNOB^``eAcU^G#==k zZN=;k@#hOTuyn6bdG^bn>(lhR#JOjs?EY*W4pO^GHlvK0UZpZ4*Sl1|4QM9u={<8Z zfp4|9+DUml(nR_riRvUW=MC9K6$hH!iRDV0+j&kJIH|LH5N=DWRpAOFc|ZpG_rw_^ zw!gX`sP>YuS3+#;;wvb22CV~l6Y1Q81!WwYaq)43PGrN1f9*ItSt@B8(e$tWEmY0= z=k4O`>9DuAm2_HUf+y{q5>Ny!{i#+C8L(grVJpj}=rZeL?2~Uj<_L${MwO3WqG~5U z&)%I_7(a6DgZju=^7^!wH}2i(@Yd#KtPr)3v$41P>#EpsBiGv(Gi2o2ogUCsI$oJ7 zAyqRvnha$jXy2JK@UhX8|I#$4Dd{>*`fx8bpvE1k*+Ma)q=xmZtoto4*(SdqBYQxUDx2brTvDv8Zxnb0q|`9j)^GOBQEBr6#A)@jMuu$QpC?V&PF zi?S7?E=IkC^(|u=&s=isk_k%eBwxy&9s3TQcB0jXJ!s7wbz0ZG?Q@SpWAXHpQ`_>C zrnxS$=B=sOlQ(xtlnb%TxX^vKR_I?9U)<37X=MHgq&uuOk51>QuhwfHor;G=9-YqD zy(RC;D2_1hkk;z_f=qot$EqMby<*!EWM3UpiA^ zsnbm=gLCcMV`e7d0yr<(cGs2BaqaUlMK&HKvjmM~Dc4GN;?CZs(mg81f951iN6kjK zp8^bNAc-HV>a8lGWnDnyVtvXVlYypROq-f(3pj9ZR@XH619CO9FV*tt=Ay`&6)P5f zccr<QQonV?je{S{!b#JD{Mk*cp(sJdpt+haV?xU5hMLQFx%W#{AezYfpwYQ}CtIy-q z+@7TNbkd^{^_0)|ewAL!Q5>eOtD>haDe|F-m2Sb zZTH5cyN5KD-FAT9(skt;nObe#Qiv^59jA4&iYp|#7P8r%=IW8FH;Pl|?6O_Dmr5Ep zUA1}eN+Hi|#lB?h{VlV_@dYf?BP8)lqzj95n=e@+wdiP~rZr98zvf6RRU>f{c4Xs8 zDwj~>9*hRprH?M-9k5n4$s)i$gEga|nOwR@uvUye*wP+!PU3v>3rJfc8g}@DZB{;( zp@*<$_9hucV{W8*dtGBKe0L+`Z9BeD#$!n{q?+P%<9uvMFJWzY7`w!G(eBD=yReA+ zmzuAdV=5m;OCvV_LV>Qac_(Pb>6(r zH?u6Hyub2rl3tCT(i;(!h9*`)<9-@qa*NfouAo`*K~MKymPoNy@XuvancC@m`P=1OQ+E$)Z8vWv>NH6;a-;Jz9P`hfbVuVa2vRZSjja!nzYmjSvP)dY zLtEYBF{$w{ZDWJA{`Pe0t*yI1O(+ZE+xQAo_ukET!fRVS2aQwqe-wj1%h&Ad+Uzsj z?p(-9b8EU=#6QTTnBGMtW%`MB>y?G6!LjCX9(Ps{Yb z_))H#TI5K^A`7*vnf~=~<0n4pJKsb%aFdH5cE;#rx*+>UM7%CFk<$L3-m(NbR@mqs zdT7~TU-jxz2mfRSs{napF6+desKd|fC7Hp{1Q&E}mc))i{}>=Yi^<0e*h*o9DC&i8 z&TE#;B3=t&w|A(E37JK_rl>6VHMF@v?Oh1;19sq(lg5^|{-u$4O>C0r_6h84$Z5E@ z5bH#6mRaScvJc1@2rk~!K~)@2k{eMa2NnrV$`hlT8N*<9!tFtw96 z;KP^c@9AjNXXi8GRWWx#JD-5CRql73GLIq6J0*7gSaTX5c=_w)bj%@7Q$}uw(3ut| zhIu|u*7~agKHhr%n^^h6Hh)3Wog}60)7zHuN-*n%_gHJs^nSD7a2;ipIS`B|Gah@= zWG6x?V>1!5H{yx&a5LIi*}}V%LZ^tyb9$6Sf)MO!W->i1c(ZKpRq&Hqb7kw)GH!I97J6hS4dNr}25F3Bjb& z=8;cITur-n)cO*SdlXonAGxI!$HI3Jsfc(ZJ?%@qGtM5enU2m*wRNx4Bqp6u-7YiT zyqk|pC{=~x3W*z?CfYYKb|&n<y1W4K`jVsps=vCaaz}lT2Cr($yL^ z)BaN3q&oU3T%`sa$%XD|a?a?*sfPZAF$?oJS;Lq)1t5_`J+0Nl zuI#MB5B_$P?D066I;l=lkCXZIkCW$h&2_Ucl=)ZaI(^3z^GrFe9P+kmciHqAzgA`_ zke=ttTlfd`#`8SV)8x)5m`8f5gn4%OD61S-{sA+I%i5Y%P2MZ!d`bJ1Ip415d*)jF z3Nf7;?IvaQn)i228oQo16S%TH&R|<<u@J4=2ji?u;21q hR%On=!zz1VYKB=iw*8u#W9n?y*8SxTZUc6P{6Aemqv!wt literal 0 HcmV?d00001 diff --git a/current/po/sv.po b/current/po/sv.po new file mode 100644 index 00000000..2409210d --- /dev/null +++ b/current/po/sv.po @@ -0,0 +1,2406 @@ +# Swedish messages for Shadow +# Copyright (C) 1999 Free Software Foundation, Inc. +# Kristoffer Brånemyr , 1999. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: shadow 19990709\n" +"POT-Creation-Date: 2000-09-02 20:40+0200\n" +"PO-Revision-Date: 1999-08-16 21:20+0100\n" +"Last-Translator: Kristoffer Brånemyr \n" +"Language-Team: sv \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libmisc/addgrps.c:60 +#, c-format +msgid "Warning: unknown group %s\n" +msgstr "Varning: okänd grupp %s\n" + +#: libmisc/addgrps.c:71 +msgid "Warning: too many groups\n" +msgstr "Varning: för många grupper\n" + +#: libmisc/age.c:104 +msgid "Your password has expired." +msgstr "Ditt lösenord har upphört" + +#: libmisc/age.c:107 +msgid "Your password is inactive." +msgstr "Ditt lösenord är inaktivt" + +#: libmisc/age.c:110 +msgid "Your login has expired." +msgstr "Din användare har upphört." + +#: libmisc/age.c:127 +msgid " Contact the system administrator.\n" +msgstr " Kontakta systemoperatören.\n" + +#: libmisc/age.c:130 +msgid " Choose a new password.\n" +msgstr " Välj ett nytt lösenord.\n" + +#: libmisc/age.c:228 +#, c-format +msgid "Your password will expire in %ld days.\n" +msgstr "Ditt lösenord upphör om %ld dagar.\n" + +#: libmisc/age.c:230 +msgid "Your password will expire tomorrow.\n" +msgstr "Ditt lösenord upphör imorgon.\n" + +#: libmisc/age.c:232 +msgid "Your password will expire today.\n" +msgstr "Ditt lösenord upphör idag.\n" + +#: libmisc/chowntty.c:110 +#, c-format +msgid "Unable to change tty %s" +msgstr "Kunde inte byta tty %s" + +#: libmisc/env.c:160 +msgid "Environment overflow\n" +msgstr "Miljön överflödades\n" + +#: libmisc/env.c:200 +#, c-format +msgid "You may not change $%s\n" +msgstr "Du får inte ändra $%s\n" + +#: libmisc/failure.c:238 +#, c-format +msgid "%d %s since last login. Last was %s on %s.\n" +msgstr "%d %s sedan förra inloggningen. Den sista var %s på %s.\n" + +#: libmisc/failure.c:239 +msgid "failures" +msgstr "felaktiga inloggningar" + +#: libmisc/failure.c:239 +msgid "failure" +msgstr "felaktig inloggning" + +#: libmisc/limits.c:397 +msgid "Too many logins.\n" +msgstr "För många inloggningar.\n" + +#: libmisc/login_desrpc.c:63 +#, c-format +msgid "Password does not decrypt secret key for %s.\n" +msgstr "Lösenordet avkrypterar inte den hemliga nyckeln för %s.\n" + +#: libmisc/login_desrpc.c:69 +#, c-format +msgid "Could not set %s's secret key: is the keyserv daemon running?\n" +msgstr "" +"Kunde inte sätta den hemliga nyckeln för %s: är keyserv demonen igång?\n" + +#: libmisc/mail.c:62 libmisc/mail.c:77 +msgid "You have new mail." +msgstr "Du har ny post." + +#: libmisc/mail.c:73 +msgid "No mail." +msgstr "Ingen post." + +#: libmisc/mail.c:75 +msgid "You have mail." +msgstr "Du har post." + +#: libmisc/obscure.c:281 src/passwd.c:309 +#, c-format +msgid "Bad password: %s. " +msgstr "Felaktigt lösenord: %s. " + +#: libmisc/pam_pass.c:42 +#, c-format +msgid "passwd: pam_start() failed, error %d\n" +msgstr "passwd: pam_start() misslyckades, fel %d\n" + +#: libmisc/pam_pass.c:49 +#, c-format +msgid "passwd: %s\n" +msgstr "passwd: %s\n" + +#: libmisc/setupenv.c:205 +#, c-format +msgid "Unable to cd to \"%s\"\n" +msgstr "Kunde inte byta aktuell katalog till \"%s\"\n" + +#: libmisc/setupenv.c:213 +msgid "No directory, logging in with HOME=/" +msgstr "Ingen hemkatalog, loggar in med HOME=/" + +#: libmisc/shell.c:78 +#, c-format +msgid "Executing shell %s\n" +msgstr "Startar skal %s\n" + +#. +#. * Obviously something is really wrong - I can't figure out +#. * how to execute this stupid shell, so I might as well give +#. * up in disgust ... +#. +#: libmisc/shell.c:122 +#, c-format +msgid "Cannot execute %s" +msgstr "Kan inte starta %s" + +#: libmisc/suauth.c:99 +msgid "Access to su to that account DENIED.\n" +msgstr "Du har inte behörighet att köra su till det kontot.\n" + +#: libmisc/suauth.c:106 +msgid "Password authentication bypassed.\n" +msgstr "Hoppade över lösenordskontroll.\n" + +#: libmisc/suauth.c:113 +msgid "Please enter your OWN password as authentication.\n" +msgstr "Var god skriv in ditt EGET lösenord som äkthetsbevis.\n" + +#: libmisc/sub.c:61 +#, c-format +msgid "Invalid root directory \"%s\"\n" +msgstr "Felaktig rotkatalog \"%s\"\n" + +#: libmisc/sub.c:73 +#, c-format +msgid "Can't change root directory to \"%s\"\n" +msgstr "Kan inte byta rotkatalog till \"%s\"\n" + +#: libmisc/xmalloc.c:28 +#, c-format +msgid "malloc(%d) failed\n" +msgstr "malloc(%d) misslyckades\n" + +#: lib/dialchk.c:71 +msgid "Dialup Password: " +msgstr "Uppringningslösenord: " + +#: lib/getdef.c:253 +msgid "Could not allocate space for config info.\n" +msgstr "Kunde inte allokera rum för konfigureringsinformation.\n" + +#. +#. * Item was never found. +#. +#: lib/getdef.c:307 +#, c-format +msgid "configuration error - unknown item '%s' (notify administrator)\n" +msgstr "konfigurerings fel - okänt object \"%s\" (meddela systemoperatören)\n" + +#: lib/getdef.c:394 +#, c-format +msgid "error - lookup '%s' failed\n" +msgstr "fel - kunde inte hitta \"%s\"\n" + +#: lib/getdef.c:402 +#, c-format +msgid "%s not found\n" +msgstr "%s hittades inte\n" + +#. +#. * get the password from her, and set the salt for +#. * the decryption from the group file. +#. +#: lib/pwauth.c:54 src/newgrp.c:305 +msgid "Password: " +msgstr "Lösenord: " + +#: lib/pwauth.c:56 +#, c-format +msgid "%s's Password: " +msgstr "Lösenord för %s: " + +#: lib/pwauth.c:270 +msgid "(Echo on) " +msgstr "" + +#: lib/strerror.c:20 +#, c-format +msgid "Unknown error %d" +msgstr "Okänt fel %d" + +#: src/chage.c:156 +#, c-format +msgid "" +"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n" +" [ -I inactive ] [ -E expire ] [ -d last_day ] user\n" +msgstr "" +"Användning: %s [ -l ] [ -m min_dagar ] [ -M max_dagar ] [ -W varna ]\n" +" [ -I inaktiv ] [ -E utgång ] [ -d senaste_dag ] användare\n" + +#: src/chage.c:158 +#, c-format +msgid "Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n" +msgstr "" +"Användning: %s [ -l ] [ -m min_dagar ] [ -M max_dagar ] [ -d senaste_dag ] " +"användare\n" + +#: src/chage.c:193 +msgid "" +"Enter the new value, or press return for the default\n" +"\n" +msgstr "" +"Skriv in det nya värdet, eller tryck på return för standardvärdet\n" +"\n" + +#: src/chage.c:196 +msgid "Minimum Password Age" +msgstr "Minsta lösenordsålder" + +#: src/chage.c:201 +msgid "Maximum Password Age" +msgstr "Högsta lösenordsålder" + +#: src/chage.c:207 +msgid "Last Password Change (YYYY-MM-DD)" +msgstr "Senaste lösenordsändring (ÅÅÅÅ-MM-DD)" + +#: src/chage.c:216 +msgid "Password Expiration Warning" +msgstr "Lösenords upphörningsvarning" + +#: src/chage.c:221 +msgid "Password Inactive" +msgstr "Lösenord inaktivt" + +#: src/chage.c:227 +msgid "Account Expiration Date (YYYY-MM-DD)" +msgstr "Kontot upphör (ÅÅÅÅ-MM-DD)" + +#. +#. * Start with the easy numbers - the number of days before the +#. * password can be changed, the number of days after which the +#. * password must be chaged, the number of days before the +#. * password expires that the user is told, and the number of +#. * days after the password expires that the account becomes +#. * unusable. +#. +#: src/chage.c:281 +#, c-format +msgid "Minimum:\t%ld\n" +msgstr "Minst:\t%ld\n" + +#: src/chage.c:282 +#, c-format +msgid "Maximum:\t%ld\n" +msgstr "Högst:\t%ld\n" + +#: src/chage.c:284 +#, c-format +msgid "Warning:\t%ld\n" +msgstr "Varning:\t%ld\n" + +#: src/chage.c:285 +#, c-format +msgid "Inactive:\t%ld\n" +msgstr "Inaktivt:\t%ld\n" + +#. +#. * The "last change" date is either "Never" or the date the +#. * password was last modified. The date is the number of +#. * days since 1/1/1970. +#. +#: src/chage.c:294 +msgid "Last Change:\t\t" +msgstr "Senaste ändring:\t\t" + +#: src/chage.c:296 src/chage.c:310 src/chage.c:327 src/chage.c:340 +msgid "Never\n" +msgstr "Aldrig\n" + +#. +#. * The password expiration date is determined from the last +#. * change date plus the number of days the password is valid +#. * for. +#. +#: src/chage.c:308 +msgid "Password Expires:\t" +msgstr "Lösenordet upphör:\t" + +#. +#. * The account becomes inactive if the password is expired +#. * for more than "inactdays". The expiration date is calculated +#. * and the number of inactive days is added. The resulting date +#. * is when the active will be disabled. +#. +#: src/chage.c:324 +#, fuzzy +msgid "Password Inactive:\t" +msgstr "Lösenord inaktivt" + +#. +#. * The account will expire on the given date regardless of the +#. * password expiring or not. +#. +#: src/chage.c:338 +#, fuzzy +msgid "Account Expires:\t" +msgstr "Lösenordet upphör:\t" + +#: src/chage.c:486 +#, c-format +msgid "%s: do not include \"l\" with other flags\n" +msgstr "%s: inkludera inte \"l\" tillsammands med andra flaggor\n" + +#: src/chage.c:498 src/chage.c:610 src/login.c:529 +#, c-format +msgid "%s: permission denied\n" +msgstr "%s: tillåtelse nekas\n" + +#: src/chage.c:510 src/chpasswd.c:120 +#, c-format +msgid "%s: can't lock password file\n" +msgstr "%s: kan inte låsa lösenordsfilen\n" + +#: src/chage.c:516 src/chpasswd.c:124 +#, c-format +msgid "%s: can't open password file\n" +msgstr "%s: kan inte öppna lösenordsfilen\n" + +#: src/chage.c:523 +#, c-format +msgid "%s: unknown user: %s\n" +msgstr "%s: okänd användare: %s\n" + +#: src/chage.c:542 +#, c-format +msgid "%s: can't lock shadow password file\n" +msgstr "%s: kan inte låsa skugglösenordsfilen\n" + +#: src/chage.c:549 +#, c-format +msgid "%s: can't open shadow password file\n" +msgstr "%s: kan inte öppna skugglösenordsfilen\n" + +#: src/chage.c:631 +#, c-format +msgid "Changing the aging information for %s\n" +msgstr "Ändrar åldringsinformation för %s\n" + +#: src/chage.c:633 +#, c-format +msgid "%s: error changing fields\n" +msgstr "%s: fel uppstod under byte av fält\n" + +#: src/chage.c:660 src/chage.c:723 src/pwunconv.c:183 +#, c-format +msgid "%s: can't update password file\n" +msgstr "%s: kan inte uppdatera lösenordsfilen\n" + +#: src/chage.c:690 src/pwunconv.c:178 +#, c-format +msgid "%s: can't update shadow password file\n" +msgstr "%s: kan inte uppdatera skugglösenordsfilen\n" + +#: src/chage.c:739 src/chage.c:754 src/chfn.c:570 src/chsh.c:409 +#: src/passwd.c:825 src/passwd.c:926 +msgid "Error updating the DBM password entry.\n" +msgstr "Fel under uppdatering av DBM-lösenordsnoteringen.\n" + +#: src/chage.c:771 +#, c-format +msgid "%s: can't rewrite shadow password file\n" +msgstr "%s: kan inte skriva om skugglösenordsfilen\n" + +#: src/chage.c:785 +#, c-format +msgid "%s: can't rewrite password file\n" +msgstr "%s: kan inte skriva om lösenordsfilen\n" + +#: src/chage.c:836 +#, c-format +msgid "%s: no aging information present\n" +msgstr "%s: ingen åldringsinformation finns tillgänglig\n" + +#: src/chfn.c:107 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n" +"\t[ -h home_ph ] [ -o other ] [ user ]\n" +msgstr "" +"%s [ -f hela_namnet ] [ -r rumsnummer ] [ -w arbetstele ]\n" +"\t[ -h hemtele ] [ -o övrigt ] [ användare ]\n" + +#: src/chfn.c:111 +#, c-format +msgid "" +"Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n" +msgstr "" +"Användning: %s [ -f hela_namnet ] [ -r rumsnummer ] [ -w arbetstele ] [ -h " +"hemtele ]\n" + +#: src/chfn.c:163 src/chsh.c:119 +msgid "Enter the new value, or press return for the default\n" +msgstr "Skriv in det nya värdet, eller tryck return för standardvärdet\n" + +#: src/chfn.c:166 +msgid "Full Name" +msgstr "Hela namnet" + +#: src/chfn.c:168 +#, c-format +msgid "\tFull Name: %s\n" +msgstr "\tHela namnet: %s\n" + +#: src/chfn.c:171 +msgid "Room Number" +msgstr "Rumsnummer" + +#: src/chfn.c:173 +#, c-format +msgid "\tRoom Number: %s\n" +msgstr "\tRumsnummer: %s\n" + +#: src/chfn.c:176 +msgid "Work Phone" +msgstr "Arbetstelefonnummer" + +#: src/chfn.c:178 +#, c-format +msgid "\tWork Phone: %s\n" +msgstr "\tArbetstelefonnummer: %s\n" + +#: src/chfn.c:181 +msgid "Home Phone" +msgstr "Hemtelefonnummer" + +#: src/chfn.c:183 +#, c-format +msgid "\tHome Phone: %s\n" +msgstr "\tHemtelefonnummer: %s\n" + +#: src/chfn.c:186 +msgid "Other" +msgstr "Övrigt" + +#: src/chfn.c:298 src/chfn.c:306 src/chfn.c:314 src/chfn.c:322 src/chfn.c:330 +#: src/chfn.c:391 src/passwd.c:1226 +#, c-format +msgid "%s: Permission denied.\n" +msgstr "%s: Tillåtelse nekas.\n" + +#: src/chfn.c:351 src/chsh.c:224 src/passwd.c:1277 +#, c-format +msgid "%s: Unknown user %s\n" +msgstr "%s: Okänd användare %s\n" + +#: src/chfn.c:357 src/chsh.c:232 src/passwd.c:1207 +#, c-format +msgid "%s: Cannot determine your user name.\n" +msgstr "%s: Kan inte avgöra ditt användarnamn.\n" + +#: src/chfn.c:373 src/chsh.c:250 +#, c-format +msgid "%s: cannot change user `%s' on NIS client.\n" +msgstr "%s: kan inte ändra användare \"%s\" på NIS-klienten.\n" + +#: src/chfn.c:378 src/chsh.c:257 +#, c-format +msgid "%s: `%s' is the NIS master for this client.\n" +msgstr "%s: \"%s\" är NIS-mästare för denna klient.\n" + +#: src/chfn.c:453 +#, c-format +msgid "Changing the user information for %s\n" +msgstr "Ändrar användarinformation för %s\n" + +#: src/chfn.c:462 +#, c-format +msgid "%s: invalid name: \"%s\"\n" +msgstr "%s: felaktigt namn: \"%s\"\n" + +#: src/chfn.c:467 +#, c-format +msgid "%s: invalid room number: \"%s\"\n" +msgstr "%s: felaktigt rumsnummer: \"%s\"\n" + +#: src/chfn.c:472 +#, c-format +msgid "%s: invalid work phone: \"%s\"\n" +msgstr "%s: felaktigt arbetstelefonnummer: \"%s\"\n" + +#: src/chfn.c:477 +#, c-format +msgid "%s: invalid home phone: \"%s\"\n" +msgstr "%s: felaktigt hemtelefonnummer: \"%s\"\n" + +#: src/chfn.c:482 +#, c-format +msgid "%s: \"%s\" contains illegal characters\n" +msgstr "%s: \"%s\" innehåller otillåtna tecken\n" + +#: src/chfn.c:494 +#, c-format +msgid "%s: fields too long\n" +msgstr "%s: för långa fält\n" + +#: src/chfn.c:509 src/chsh.c:347 src/gpasswd.c:582 src/passwd.c:1388 +msgid "Cannot change ID to root.\n" +msgstr "Kan inte ändra ID till root.\n" + +#: src/chfn.c:522 src/chsh.c:361 src/passwd.c:735 src/passwd.c:880 +msgid "Cannot lock the password file; try again later.\n" +msgstr "Kan inte låsa lösenordsfilen; försök igen senare.\n" + +#: src/chfn.c:528 src/chsh.c:367 src/passwd.c:740 src/passwd.c:885 +msgid "Cannot open the password file.\n" +msgstr "Kan inte öppna lösenordsfilen.\n" + +#: src/chfn.c:545 src/chsh.c:382 src/passwd.c:746 src/usermod.c:1313 +#, c-format +msgid "%s: %s not found in /etc/passwd\n" +msgstr "%s: %s hittades inte i /etc/passwd\n" + +#: src/chfn.c:562 src/chsh.c:401 src/passwd.c:819 src/passwd.c:920 +#: src/passwd.c:960 +msgid "Error updating the password entry.\n" +msgstr "Fel under uppdatering av lösenordsnoteringen.\n" + +#: src/chfn.c:585 src/chsh.c:424 src/passwd.c:832 src/passwd.c:933 +msgid "Cannot commit password file changes.\n" +msgstr "Kan inte genomföra ändringar i lösenordsfilen.\n" + +#: src/chfn.c:592 src/chsh.c:431 +msgid "Cannot unlock the password file.\n" +msgstr "Kan inte låsa upp lösenordsfilen.\n" + +#: src/chpasswd.c:76 +#, c-format +msgid "usage: %s [-e]\n" +msgstr "Användning: %s [-e]\n" + +#: src/chpasswd.c:132 src/pwconv.c:104 +#, c-format +msgid "%s: can't lock shadow file\n" +msgstr "%s: kan inte låsa skuggfilen\n" + +#: src/chpasswd.c:137 src/gpasswd.c:608 src/pwconv.c:109 src/pwunconv.c:118 +#: src/pwunconv.c:123 +#, c-format +msgid "%s: can't open shadow file\n" +msgstr "%s: kan inte öppna skuggfilen\n" + +#: src/chpasswd.c:159 src/newusers.c:415 +#, c-format +msgid "%s: line %d: line too long\n" +msgstr "%s: rad %d: för lång rad\n" + +#: src/chpasswd.c:179 +#, c-format +msgid "%s: line %d: missing new password\n" +msgstr "%s: rad %d: det nya lösenordet saknas\n" + +#: src/chpasswd.c:195 +#, c-format +msgid "%s: line %d: unknown user %s\n" +msgstr "%s: rad %d: okänd användare %s\n" + +#: src/chpasswd.c:247 +#, c-format +msgid "%s: line %d: cannot update password entry\n" +msgstr "%s: rad %d: kan inte uppdatera lösenordsnoteringen\n" + +#: src/chpasswd.c:263 src/newusers.c:535 +#, c-format +msgid "%s: error detected, changes ignored\n" +msgstr "%s: fel upptäcktes, ändringarna ignorerades\n" + +#: src/chpasswd.c:274 +#, c-format +msgid "%s: error updating shadow file\n" +msgstr "%s: fel under uppdatering av skuggfilen\n" + +#: src/chpasswd.c:282 +#, c-format +msgid "%s: error updating password file\n" +msgstr "%s: fel under uppdatering av lösenordsfilen\n" + +#: src/chsh.c:105 +#, c-format +msgid "Usage: %s [ -s shell ] [ name ]\n" +msgstr "Användning: %s [ -s skal ] [ namn ]\n" + +#: src/chsh.c:120 +msgid "Login Shell" +msgstr "Inloggningsskal" + +#: src/chsh.c:273 src/chsh.c:286 +#, c-format +msgid "You may not change the shell for %s.\n" +msgstr "Du får inte ändra skal åt %s.\n" + +#: src/chsh.c:315 +#, c-format +msgid "Changing the login shell for %s\n" +msgstr "Ändrar inloggningsskal åt %s\n" + +#: src/chsh.c:327 +#, c-format +msgid "%s: Invalid entry: %s\n" +msgstr "%s: Felaktig notering: %s\n" + +#: src/chsh.c:332 +#, c-format +msgid "%s is an invalid shell.\n" +msgstr "%s är ett felaktigt skal.\n" + +#: src/dpasswd.c:69 +#, c-format +msgid "Usage: %s [ -(a|d) ] shell\n" +msgstr "Användning: %s [ -(a|d) ] skal\n" + +#: src/dpasswd.c:134 +msgid "Shell password: " +msgstr "Skallösenord: " + +#: src/dpasswd.c:140 +msgid "re-enter Shell password: " +msgstr "skriv in skallösenordet igen: " + +#: src/dpasswd.c:147 +#, c-format +msgid "%s: Passwords do not match, try again.\n" +msgstr "%s: Lösenorden matchar inte varandra, försök igen.\n" + +#: src/dpasswd.c:167 +#, c-format +msgid "%s: can't create %s" +msgstr "%s: kan inte skapa %s" + +#: src/dpasswd.c:172 +#, c-format +msgid "%s: can't open %s" +msgstr "%s: kan inte öppna %s" + +#: src/dpasswd.c:200 +#, c-format +msgid "%s: Shell %s not found.\n" +msgstr "%s: Hittade inte skalet %s.\n" + +#: src/expiry.c:84 +msgid "Usage: expiry { -f | -c }\n" +msgstr "Användning: expiry { -f | -c }\n" + +#: src/expiry.c:137 +#, c-format +msgid "%s: WARNING! Must be set-UID root!\n" +msgstr "%s: VARNING! Måste vara set-UID root!\n" + +#: src/expiry.c:148 +#, c-format +msgid "%s: unknown user\n" +msgstr "%s: okänd användare\n" + +#: src/faillog.c:79 +#, c-format +msgid "usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n" +msgstr "" +"Användning: %s [-a|-u användare] [-m högst] [-r] [-t dagar] [-l låssek]\n" + +#: src/faillog.c:134 src/lastlog.c:94 +#, c-format +msgid "Unknown User: %s\n" +msgstr "Okänd användare: %s\n" + +#: src/faillog.c:215 +msgid "Username Failures Maximum Latest\n" +msgstr "Användarnamn Felaktiga inloggningar Högsta Senaste\n" + +#: src/faillog.c:232 +#, c-format +msgid " %s on %s" +msgstr " %s på %s" + +#: src/faillog.c:236 +#, c-format +msgid " [%lds left]" +msgstr " [%lds kvar]" + +#: src/faillog.c:239 +#, c-format +msgid " [%lds lock]" +msgstr " [%lds låsning]" + +#: src/gpasswd.c:89 +#, c-format +msgid "usage: %s [-r|-R] group\n" +msgstr "Användning: %s [-r|-R] grupp\n" + +#: src/gpasswd.c:90 +#, c-format +msgid " %s [-a user] group\n" +msgstr " %s [-a användare] grupp\n" + +#: src/gpasswd.c:91 +#, c-format +msgid " %s [-d user] group\n" +msgstr " %s [-d användare] grupp\n" + +#: src/gpasswd.c:93 +#, c-format +msgid " %s [-A user,...] [-M user,...] group\n" +msgstr " %s [-A användare,...] [-M användare,...] grupp\n" + +#: src/gpasswd.c:96 +#, c-format +msgid " %s [-M user,...] group\n" +msgstr " %s [-M användare,...] grupp\n" + +#: src/gpasswd.c:160 src/gpasswd.c:245 +#, c-format +msgid "%s: unknown user %s\n" +msgstr "%s: okänd användare %s\n" + +#: src/gpasswd.c:172 +msgid "Permission denied.\n" +msgstr "Tillåtelse nekas.\n" + +#: src/gpasswd.c:257 +#, c-format +msgid "%s: shadow group passwords required for -A\n" +msgstr "%s: skuggrupplösenord krävs för -A\n" + +#: src/gpasswd.c:308 +msgid "Who are you?\n" +msgstr "Vem är du?\n" + +#: src/gpasswd.c:328 src/newgrp.c:251 +#, c-format +msgid "unknown group: %s\n" +msgstr "okänd grupp: %s\n" + +#: src/gpasswd.c:436 +#, c-format +msgid "Adding user %s to group %s\n" +msgstr "Lägger till användare %s till grupp %s\n" + +#: src/gpasswd.c:453 +#, c-format +msgid "Removing user %s from group %s\n" +msgstr "Tar bort användare %s från grupp %s\n" + +#: src/gpasswd.c:466 +#, c-format +msgid "%s: unknown member %s\n" +msgstr "%s: okänd medlem %s\n" + +#: src/gpasswd.c:513 +#, c-format +msgid "%s: Not a tty\n" +msgstr "%s: Inte en tty\n" + +#. +#. * A new password is to be entered and it must be encrypted, +#. * etc. The password will be prompted for twice, and both +#. * entries must be identical. There is no need to validate +#. * the old password since the invoker is either the group +#. * owner, or root. +#. +#: src/gpasswd.c:535 +#, c-format +msgid "Changing the password for group %s\n" +msgstr "Ändrar lösenordet för grupp %s\n" + +#: src/gpasswd.c:538 +msgid "New Password: " +msgstr "Nytt lösenord: " + +#: src/gpasswd.c:543 src/passwd.c:422 +msgid "Re-enter new password: " +msgstr "Skriv in det nya lösenordet igen: " + +#: src/gpasswd.c:555 +msgid "They don't match; try again" +msgstr "De matchar inte; försök igen" + +#: src/gpasswd.c:559 +#, c-format +msgid "%s: Try again later\n" +msgstr "%s: Försök igen senare\n" + +#: src/gpasswd.c:590 +#, c-format +msgid "%s: can't get lock\n" +msgstr "%s: kan inte låsa\n" + +#: src/gpasswd.c:596 +#, c-format +msgid "%s: can't get shadow lock\n" +msgstr "%s: kan inte låsa skuggfilen\n" + +#: src/gpasswd.c:602 +#, c-format +msgid "%s: can't open file\n" +msgstr "%s: kan inte öppna filen\n" + +#: src/gpasswd.c:614 +#, c-format +msgid "%s: can't update entry\n" +msgstr "%s: kan inte uppdatera noteringen\n" + +#: src/gpasswd.c:620 +#, c-format +msgid "%s: can't update shadow entry\n" +msgstr "%s: kan inte uppdatera noteringen i skuggfilen\n" + +#: src/gpasswd.c:626 +#, c-format +msgid "%s: can't re-write file\n" +msgstr "%s: kan inte skriva om filen\n" + +#: src/gpasswd.c:632 +#, c-format +msgid "%s: can't re-write shadow file\n" +msgstr "%s: kan inte skriva om skuggfilen\n" + +#: src/gpasswd.c:640 +#, c-format +msgid "%s: can't unlock file\n" +msgstr "%s: kan inte låsa upp filen\n" + +#: src/gpasswd.c:645 +#, c-format +msgid "%s: can't update DBM files\n" +msgstr "%s: kan inte uppdatera DBM-filer\n" + +#: src/gpasswd.c:652 +#, c-format +msgid "%s: can't update DBM shadow files\n" +msgstr "%s: kan inte uppdatera DBM-skuggfiler\n" + +#: src/groupadd.c:105 +msgid "usage: groupadd [-g gid [-o]] group\n" +msgstr "Användning: groupadd [-g gid [-o]] grupp\n" + +#: src/groupadd.c:173 src/groupadd.c:196 src/groupmod.c:183 src/groupmod.c:230 +#: src/useradd.c:931 src/usermod.c:539 src/usermod.c:675 +#, c-format +msgid "%s: error adding new group entry\n" +msgstr "%s: gick inte att lägga till en ny gruppnotering\n" + +#: src/groupadd.c:183 src/groupadd.c:206 src/groupmod.c:199 src/useradd.c:942 +#: src/usermod.c:551 src/usermod.c:687 +#, c-format +msgid "%s: cannot add new dbm group entry\n" +msgstr "%s: kan inte lägga till en ny dbm-gruppnotering\n" + +#: src/groupadd.c:258 src/useradd.c:996 +#, c-format +msgid "%s: name %s is not unique\n" +msgstr "%s: namnet %s är inte unikt\n" + +#: src/groupadd.c:273 +#, c-format +msgid "%s: gid %ld is not unique\n" +msgstr "%s: gid %ld är inte unikt\n" + +#: src/groupadd.c:297 +#, c-format +msgid "%s: can't get unique gid\n" +msgstr "%s: kan inte hitta ett unikt gid\n" + +#. +#. * All invalid group names land here. +#. +#: src/groupadd.c:321 src/groupmod.c:341 +#, c-format +msgid "%s: %s is a not a valid group name\n" +msgstr "%s: %s är inte ett giltigt gruppnamn\n" + +#: src/groupadd.c:350 src/groupmod.c:367 +#, c-format +msgid "%s: invalid group %s\n" +msgstr "%s: ogiltig grupp %s\n" + +#: src/groupadd.c:367 src/useradd.c:1272 +#, c-format +msgid "%s: -O requires NAME=VALUE\n" +msgstr "%s: -O kräver NAME=VÄRDE\n" + +#: src/groupadd.c:412 src/groupdel.c:167 src/groupmod.c:403 src/useradd.c:1381 +#: src/userdel.c:303 src/usermod.c:563 +#, c-format +msgid "%s: cannot rewrite group file\n" +msgstr "%s: kan inte skriva om gruppfilen\n" + +#: src/groupadd.c:418 src/groupdel.c:173 src/groupmod.c:409 src/useradd.c:1389 +#: src/userdel.c:309 src/usermod.c:700 +#, c-format +msgid "%s: cannot rewrite shadow group file\n" +msgstr "%s: kan inte skriva om skuggruppfilen\n" + +#: src/groupadd.c:437 src/groupdel.c:192 src/groupmod.c:428 src/userdel.c:389 +#, c-format +msgid "%s: unable to lock group file\n" +msgstr "%s: kan inte låsa gruppfilen\n" + +#: src/groupadd.c:441 src/groupdel.c:196 src/groupmod.c:432 +#, c-format +msgid "%s: unable to open group file\n" +msgstr "%s: kan inte öppna gruppfilen\n" + +#: src/groupadd.c:446 src/groupdel.c:201 src/groupmod.c:437 src/userdel.c:398 +#, c-format +msgid "%s: unable to lock shadow group file\n" +msgstr "%s: kan inte låsa skuggruppfilen\n" + +#: src/groupadd.c:451 src/groupdel.c:206 src/groupmod.c:442 +#, c-format +msgid "%s: unable to open shadow group file\n" +msgstr "%s: kan inte öppna skuggruppfilen\n" + +#: src/groupadd.c:518 +#, c-format +msgid "%s: group %s exists\n" +msgstr "%s: grupp %s existerar\n" + +#: src/groupdel.c:86 +msgid "usage: groupdel group\n" +msgstr "Användning: groupdel grupp\n" + +#: src/groupdel.c:104 src/groupmod.c:187 src/groupmod.c:234 +#, c-format +msgid "%s: error removing group entry\n" +msgstr "%s: fel under borttagning av gruppnotering\n" + +#: src/groupdel.c:116 src/groupmod.c:206 +#, c-format +msgid "%s: error removing group dbm entry\n" +msgstr "%s: fel under borttagning av dbm-gruppnotering\n" + +#: src/groupdel.c:131 +#, c-format +msgid "%s: error removing shadow group entry\n" +msgstr "%s: fel under borttagning av skuggruppnotering\n" + +#: src/groupdel.c:144 src/groupmod.c:252 +#, c-format +msgid "%s: error removing shadow group dbm entry\n" +msgstr "%s: fel under borttagning av dbm-skuggruppnotering\n" + +#. +#. * Can't remove the group. +#. +#: src/groupdel.c:248 +#, c-format +msgid "%s: cannot remove user's primary group.\n" +msgstr "%s: kan inte ta bort användarens primära grupp.\n" + +#: src/groupdel.c:305 src/groupmod.c:501 +#, c-format +msgid "%s: group %s does not exist\n" +msgstr "%s: grupp %s existerar inte\n" + +#: src/groupdel.c:319 src/groupmod.c:517 +#, c-format +msgid "%s: group %s is a NIS group\n" +msgstr "%s: grupp %s är en NIS-grupp\n" + +#: src/groupdel.c:325 src/groupmod.c:523 src/userdel.c:761 src/usermod.c:1016 +#, c-format +msgid "%s: %s is the NIS master\n" +msgstr "%s: %s är NIS-mästeren\n" + +#: src/groupmod.c:105 +msgid "usage: groupmod [-g gid [-o]] [-n name] group\n" +msgstr "Användning: groupmod [-g gid [-o]] [-n namn] grupp\n" + +#: src/groupmod.c:165 +#, c-format +msgid "%s: %s not found in /etc/group\n" +msgstr "%s: %s hittades inte i /etc/group\n" + +#: src/groupmod.c:246 +#, c-format +msgid "%s: cannot add new dbm shadow group entry\n" +msgstr "%s: kunde inte lägga till en ny dbm-skuggruppnotering\n" + +#: src/groupmod.c:299 +#, c-format +msgid "%s: %ld is not a unique gid\n" +msgstr "%s: %ld är inte ett unikt gid\n" + +#: src/groupmod.c:330 +#, c-format +msgid "%s: %s is not a unique name\n" +msgstr "%s: %s är inte ett unikt namn\n" + +#: src/groups.c:62 +#, c-format +msgid "unknown user %s\n" +msgstr "okänd användare %s\n" + +#: src/grpck.c:98 +#, c-format +msgid "Usage: %s [ -r ] [ group [ gshadow ] ]\n" +msgstr "Användning: %s [ -r ] [ grupp [ gshadow ] ]\n" + +#: src/grpck.c:100 +#, c-format +msgid "Usage: %s [ -r ] [ group ]\n" +msgstr "Användning: %s [ -r ] [ grupp ]\n" + +#: src/grpck.c:119 src/pwck.c:119 +msgid "No" +msgstr "Nej" + +#: src/grpck.c:234 src/grpck.c:242 src/pwck.c:216 src/pwck.c:225 +#, c-format +msgid "%s: cannot lock file %s\n" +msgstr "%s: kan inte låsa filen %s\n" + +#: src/grpck.c:257 src/grpck.c:265 src/mkpasswd.c:216 src/pwck.c:241 +#: src/pwck.c:250 +#, c-format +msgid "%s: cannot open file %s\n" +msgstr "%s: kan inte öppna filen %s\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:298 +msgid "invalid group file entry\n" +msgstr "felaktig gruppfilsnotering\n" + +#: src/grpck.c:299 src/grpck.c:362 src/grpck.c:454 src/grpck.c:517 +#: src/grpck.c:534 src/pwck.c:286 src/pwck.c:348 src/pwck.c:455 src/pwck.c:517 +#: src/pwck.c:541 +#, c-format +msgid "delete line `%s'? " +msgstr "ta bort rad \"%s\"? " + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:361 +msgid "duplicate group entry\n" +msgstr "dubblett av gruppnotering\n" + +#: src/grpck.c:378 +#, c-format +msgid "invalid group name `%s'\n" +msgstr "ogiltigt gruppnamn \"%s\"\n" + +#: src/grpck.c:388 +#, c-format +msgid "group %s: bad GID (%d)\n" +msgstr "grupp %s: felaktigt GID (%d)\n" + +#: src/grpck.c:414 +#, c-format +msgid "group %s: no user %s\n" +msgstr "grupp %s: användaren %s finns inte\n" + +#: src/grpck.c:416 src/grpck.c:585 +#, c-format +msgid "delete member `%s'? " +msgstr "ta bort medlem \"%s\"? " + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/grpck.c:453 +msgid "invalid shadow group file entry\n" +msgstr "felaktig skuggruppfilsnotering\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/grpck.c:516 +msgid "duplicate shadow group entry\n" +msgstr "dubblett av skuggruppfilsnotering\n" + +#: src/grpck.c:533 +msgid "no matching group file entry\n" +msgstr "inga matchande gruppfilsnoteringar\n" + +#: src/grpck.c:553 +#, c-format +msgid "shadow group %s: no administrative user %s\n" +msgstr "skuggrupp %s: finns ingen administrativ användare %s\n" + +#: src/grpck.c:555 +#, c-format +msgid "delete administrative member `%s'? " +msgstr "ta bort administrativa medlemmen \"%s\"? " + +#: src/grpck.c:583 +#, c-format +msgid "shadow group %s: no user %s\n" +msgstr "skuggrupp %s: finns ingen användare %s\n" + +#: src/grpck.c:610 src/grpck.c:616 src/pwck.c:572 src/pwck.c:580 +#, c-format +msgid "%s: cannot update file %s\n" +msgstr "%s: kan inte uppdatera filen %s\n" + +#: src/grpck.c:640 src/pwck.c:606 +#, c-format +msgid "%s: the files have been updated; run mkpasswd\n" +msgstr "%s: filerna är uppdaterade; kör mkpasswd\n" + +#: src/grpck.c:641 src/grpck.c:645 src/pwck.c:607 src/pwck.c:611 +#, c-format +msgid "%s: no changes\n" +msgstr "%s: inga ändringar\n" + +#: src/grpck.c:644 src/pwck.c:610 +#, c-format +msgid "%s: the files have been updated\n" +msgstr "%s: filerna är uppdaterade\n" + +#: src/grpconv.c:62 src/grpunconv.c:63 +#, c-format +msgid "%s: can't lock group file\n" +msgstr "%s: kan inte låsa gruppfilen\n" + +#: src/grpconv.c:67 src/grpunconv.c:68 +#, c-format +msgid "%s: can't open group file\n" +msgstr "%s: kan inte öppna gruppfilen\n" + +#: src/grpconv.c:72 src/grpunconv.c:73 +#, c-format +msgid "%s: can't lock shadow group file\n" +msgstr "%s: kan inte låsa skuggruppfilen\n" + +#: src/grpconv.c:77 src/grpunconv.c:78 +#, c-format +msgid "%s: can't open shadow group file\n" +msgstr "%s: kan inte öppna skuggruppfilen\n" + +#. +#. * This shouldn't happen (the entry exists) but... +#. +#: src/grpconv.c:93 +#, c-format +msgid "%s: can't remove shadow group %s\n" +msgstr "%s: kan inte ta bort skuggruppen %s\n" + +#: src/grpconv.c:134 src/pwconv.c:160 +#, c-format +msgid "%s: can't update shadow entry for %s\n" +msgstr "%s: kan inte uppdatera skuggnoteringen för %s\n" + +#: src/grpconv.c:143 src/grpunconv.c:94 +#, c-format +msgid "%s: can't update entry for group %s\n" +msgstr "%s: kan inte uppdatera noteringen för gruppen %s\n" + +#: src/grpconv.c:150 src/grpunconv.c:102 +#, c-format +msgid "%s: can't update shadow group file\n" +msgstr "%s: kan inte uppdatera skuggruppfilen\n" + +#: src/grpconv.c:154 src/grpunconv.c:107 +#, c-format +msgid "%s: can't update group file\n" +msgstr "%s: kan inte uppdatera gruppfilen\n" + +#: src/grpconv.c:169 src/grpunconv.c:128 +#, c-format +msgid "%s: not configured for shadow group support.\n" +msgstr "%s: inte konfigurerad med stöd för skuggrupper.\n" + +#: src/grpunconv.c:112 +#, c-format +msgid "%s: can't delete shadow group file\n" +msgstr "%s: kan inte ta bort skuggruppfilen\n" + +#: src/id.c:56 +msgid "usage: id [ -a ]\n" +msgstr "Användning: id [ -a ]\n" + +#: src/id.c:58 +msgid "usage: id\n" +msgstr "Användning: id\n" + +#: src/id.c:118 +#, c-format +msgid "uid=%d(%s)" +msgstr "uid=%d(%s)" + +#: src/id.c:120 +#, c-format +msgid "uid=%d" +msgstr "uid=%d" + +#: src/id.c:124 +#, c-format +msgid " gid=%d(%s)" +msgstr " gid=%d(%s)" + +#: src/id.c:126 +#, c-format +msgid " gid=%d" +msgstr " gid=%d" + +#: src/id.c:136 +#, c-format +msgid " euid=%d(%s)" +msgstr " euid=%d(%s)" + +#: src/id.c:138 +#, c-format +msgid " euid=%d" +msgstr " euid=%d" + +#: src/id.c:143 +#, c-format +msgid " egid=%d(%s)" +msgstr " egid=%d(%s)" + +#: src/id.c:145 +#, c-format +msgid " egid=%d" +msgstr " egid=%d" + +#. +#. * Start off the group message. It will be of the format +#. * +#. * groups=###(aaa),###(aaa),###(aaa) +#. * +#. * where "###" is a numerical value and "aaa" is the +#. * corresponding name for each respective numerical value. +#. +#: src/id.c:166 +msgid " groups=" +msgstr " grupper=" + +#: src/lastlog.c:167 +msgid "Username Port From Latest\n" +msgstr "Användarnamn Port Från Senaste\n" + +#: src/lastlog.c:169 +msgid "Username Port Latest\n" +msgstr "Användarnamn Port Senaste\n" + +#: src/lastlog.c:183 +msgid "**Never logged in**" +msgstr "**Aldrig inloggad**" + +#: src/login.c:198 +#, c-format +msgid "usage: %s [-p] [name]\n" +msgstr "Användning: %s [-p] [namn]\n" + +#: src/login.c:201 +#, c-format +msgid " %s [-p] [-h host] [-f name]\n" +msgstr " %s [-p] [-h värd] [-f namn]\n" + +#: src/login.c:203 +#, c-format +msgid " %s [-p] -r host\n" +msgstr " %s [-p] -r värd\n" + +#: src/login.c:286 +msgid "Invalid login time\n" +msgstr "Felaktig inloggningstid\n" + +#: src/login.c:341 +msgid "" +"\n" +"System closed for routine maintenance\n" +msgstr "" +"\n" +"Systemet är stängt för rutinunderhåll\n" + +#: src/login.c:351 +msgid "" +"\n" +"[Disconnect bypassed -- root login allowed.]\n" +msgstr "" +"\n" +"[Nerkoppling kringgicks -- root inloggning tillåten.]\n" + +#: src/login.c:390 +#, c-format +msgid "" +"\n" +"Login timed out after %d seconds.\n" +msgstr "" +"\n" +"Inloggningen avbröts efter %d sekunders inaktivitet.\n" + +#: src/login.c:692 +#, c-format +msgid " on `%.100s' from `%.200s'" +msgstr " på \"%.100s\" från \"%.200s\"" + +#: src/login.c:694 +#, c-format +msgid " on `%.100s'" +msgstr " på \"%.100s\"" + +#: src/login.c:834 +#, c-format +msgid "" +"\n" +"%s login: " +msgstr "" +"\n" +"%s användare: " + +#: src/login.c:836 +msgid "login: " +msgstr "användare: " + +#: src/login.c:1026 src/sulogin.c:231 +msgid "Login incorrect" +msgstr "Felaktig inloggning" + +#: src/login.c:1213 +msgid "Warning: login re-enabled after temporary lockout.\n" +msgstr "Varning: inloggning på nytt aktiv efter den temporära utelåsningen.\n" + +#: src/login.c:1223 +#, c-format +msgid "Last login: %s on %s" +msgstr "Senaste inloggning: %s på %s" + +#: src/login.c:1226 +#, c-format +msgid "Last login: %.19s on %s" +msgstr "Senaste inloggning: %.19s på %s" + +#: src/login.c:1231 +#, c-format +msgid " from %.*s" +msgstr " från %.*s" + +#: src/login.c:1303 +msgid "Starting rad_login\n" +msgstr "Startar rad_login\n" + +#: src/mkpasswd.c:49 +#, c-format +msgid "%s: no DBM database on system - no action performed\n" +msgstr "%s: ingen DBM-databas på systemet - ingen åtgärd genomfördes\n" + +#: src/mkpasswd.c:245 src/mkpasswd.c:249 +#, c-format +msgid "%s: cannot overwrite file %s\n" +msgstr "%s: kan inte skriva över filen %s\n" + +#: src/mkpasswd.c:263 +#, c-format +msgid "%s: cannot open DBM files for %s\n" +msgstr "%s: kan inte öppna DBM-filer för %s\n" + +#: src/mkpasswd.c:296 +#, c-format +msgid "%s: the beginning with " +msgstr "%s: början med " + +#: src/mkpasswd.c:321 +#, c-format +msgid "%s: error parsing line \"%s\"\n" +msgstr "%s: fel under analysering av rad \"%s\"\n" + +#: src/mkpasswd.c:326 src/mkpasswd.c:328 src/mkpasswd.c:330 src/mkpasswd.c:332 +msgid "adding record for name " +msgstr "lägger till notering för namn " + +#: src/mkpasswd.c:336 src/mkpasswd.c:341 src/mkpasswd.c:345 src/mkpasswd.c:349 +#, c-format +msgid "%s: error adding record for " +msgstr "%s: fel under tillägg av notering för " + +#: src/mkpasswd.c:367 +#, c-format +msgid "added %d entries, longest was %d\n" +msgstr "lade till %d noteringar, den längsta var %d\n" + +#: src/mkpasswd.c:382 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n" +msgstr "Användning: %s [ -vf ] [ -p|g|sp|sg ] fil\n" + +#: src/mkpasswd.c:384 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g|sp ] file\n" +msgstr "Användning: %s [ -vf ] [ -p|g|sp ] fil\n" + +#: src/mkpasswd.c:387 +#, c-format +msgid "Usage: %s [ -vf ] [ -p|g ] file\n" +msgstr "Användning: %s [ -vf ] [ -p|g ] fil\n" + +#: src/newgrp.c:66 +msgid "usage: newgrp [ - ] [ group ]\n" +msgstr "Användning: newgrp [ - ] [ grupp ]\n" + +#: src/newgrp.c:68 +#, fuzzy +msgid "usage: sg group [[-c] command ]\n" +msgstr "Användning: sg grupp [ kommando ]\n" + +#: src/newgrp.c:125 +#, c-format +msgid "unknown uid: %d\n" +msgstr "okänt uid: %d\n" + +#: src/newgrp.c:201 +#, c-format +msgid "unknown gid: %ld\n" +msgstr "okänt gid: %ld\n" + +#: src/newgrp.c:245 +#, c-format +msgid "unknown gid: %d\n" +msgstr "okänt gid: %d\n" + +#: src/newgrp.c:323 src/newgrp.c:332 +msgid "Sorry.\n" +msgstr "Tyvärr.\n" + +#: src/newgrp.c:364 +msgid "too many groups\n" +msgstr "för många grupper\n" + +#: src/newusers.c:76 +#, c-format +msgid "Usage: %s [ input ]\n" +msgstr "Användning: %s [ indata ]\n" + +#: src/newusers.c:364 +#, c-format +msgid "%s: can't lock /etc/passwd.\n" +msgstr "%s: kan inte låsa /etc/passwd.\n" + +#: src/newusers.c:375 +#, c-format +msgid "%s: can't lock files, try again later\n" +msgstr "%s: kan inte låsa filerna, försök igen senare\n" + +#: src/newusers.c:390 +#, c-format +msgid "%s: can't open files\n" +msgstr "%s: kan inte öppna filerna\n" + +#: src/newusers.c:435 +#, c-format +msgid "%s: line %d: invalid line\n" +msgstr "%s: rad %d: ogiltig rad\n" + +#: src/newusers.c:453 +#, c-format +msgid "%s: line %d: can't create GID\n" +msgstr "%s: rad %d: kan inte skapa GID\n" + +#: src/newusers.c:469 +#, c-format +msgid "%s: line %d: can't create UID\n" +msgstr "%s: rad %d: kan inte skapa UID\n" + +#: src/newusers.c:481 +#, c-format +msgid "%s: line %d: cannot find user %s\n" +msgstr "%s: rad %d: kan inte hitta användaren %s\n" + +#: src/newusers.c:489 +#, c-format +msgid "%s: line %d: can't update password\n" +msgstr "%s: rad %d: kan inte uppdatera lösenordet\n" + +#: src/newusers.c:506 +#, c-format +msgid "%s: line %d: mkdir failed\n" +msgstr "%s: rad %d: mkdir misslyckades\n" + +#: src/newusers.c:510 +#, c-format +msgid "%s: line %d: chown failed\n" +msgstr "%s: rad %d: chown misslyckades\n" + +#: src/newusers.c:519 +#, c-format +msgid "%s: line %d: can't update entry\n" +msgstr "%s: rad %d: kan inte uppdatera notering\n" + +#: src/newusers.c:550 +#, c-format +msgid "%s: error updating files\n" +msgstr "%s: kunde inte uppdatera filerna\n" + +#: src/passwd.c:239 +#, c-format +msgid "usage: %s [ -f | -s ] [ name ]\n" +msgstr "Användning: %s [ -f | -s ] [ namn ]\n" + +#: src/passwd.c:242 +#, c-format +msgid " %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n" +msgstr " %s [ -x högst ] [ -n minst ] [ -w varna ] [ -i inaktiv ] namn\n" + +#: src/passwd.c:245 +#, c-format +msgid " %s { -l | -u | -d | -S | -e } name\n" +msgstr " %s { -l | -u | -d | -S | -e } namn\n" + +#: src/passwd.c:347 +#, c-format +msgid "User %s has a TCFS key, his old password is required.\n" +msgstr "Användare %s har en TCFS-nyckel, hans förra lösenord krävs.\n" + +#: src/passwd.c:348 +msgid "You can use -t option to force the change.\n" +msgstr "Du kan använda flaggan -t för att påtvinga ändringen.\n" + +#: src/passwd.c:354 +msgid "Old password: " +msgstr "Förra lösenordet: " + +#: src/passwd.c:361 +#, c-format +msgid "Incorrect password for `%s'\n" +msgstr "Felaktigt lösenord för \"%s\"\n" + +#: src/passwd.c:374 +#, c-format +msgid "Warning: user %s has a TCFS key.\n" +msgstr "Varning: användare %s har en TCFS-nyckel.\n" + +#: src/passwd.c:392 +#, c-format +msgid "" +"Enter the new password (minimum of %d, maximum of %d characters)\n" +"Please use a combination of upper and lower case letters and numbers.\n" +msgstr "" +"Skriv in det nya lösenordet (minst %d, högst %d tecken)\n" +"Var god använd en kombination av versaler, gemener och siffror.\n" + +#: src/passwd.c:399 +msgid "New password: " +msgstr "Nytt lösenord: " + +#: src/passwd.c:409 +msgid "Try again.\n" +msgstr "Försök igen.\n" + +#: src/passwd.c:418 +msgid "" +"\n" +"Warning: weak password (enter it again to use it anyway).\n" +msgstr "" +"\n" +"Varning: svagt lösenord (skriv in det igen för att använda det ändå).\n" + +#: src/passwd.c:427 +msgid "They don't match; try again.\n" +msgstr "De matchar inte; försök igen.\n" + +#: src/passwd.c:512 src/passwd.c:528 +#, c-format +msgid "The password for %s cannot be changed.\n" +msgstr "Lösenordet för %s kan inte bytas.\n" + +#: src/passwd.c:556 +#, c-format +msgid "Sorry, the password for %s cannot be changed yet.\n" +msgstr "Tyvärr, lösenordet för %s kan inte ändras än.\n" + +#: src/passwd.c:693 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: slut på minne\n" + +#: src/passwd.c:845 +msgid "Cannot lock the TCFS key database; try again later\n" +msgstr "Kan inte låsa TCFS-nyckeldatabasen; försök igen senare\n" + +#: src/passwd.c:851 +msgid "Cannot open the TCFS key database.\n" +msgstr "Kan inte öppna TCFS-nyckeldatabasen.\n" + +#: src/passwd.c:857 +msgid "Error updating the TCFS key database.\n" +msgstr "Fel under uppdatering av TCFS-nyckeldatabasen.\n" + +#: src/passwd.c:862 +msgid "Cannot commit TCFS changes.\n" +msgstr "Kan inte utföra TCFS ändringar.\n" + +#: src/passwd.c:1069 +#, c-format +msgid "%s: Cannot execute %s" +msgstr "%s: Kan inte starta %s" + +#: src/passwd.c:1176 +#, c-format +msgid "%s: repository %s not supported\n" +msgstr "%s: förvaringsplatsen %s stöds ej\n" + +#: src/passwd.c:1263 +#, c-format +msgid "%s: Permission denied\n" +msgstr "%s: Tillåtelse nekas\n" + +#: src/passwd.c:1287 +#, c-format +msgid "You may not change the password for %s.\n" +msgstr "Du får inte ändra lösenordet för %s.\n" + +#: src/passwd.c:1352 +#, c-format +msgid "Changing password for %s\n" +msgstr "Ändrar lösenord för %s\n" + +#: src/passwd.c:1356 +#, c-format +msgid "The password for %s is unchanged.\n" +msgstr "Lösenordet för %s är oförändrat.\n" + +#: src/passwd.c:1412 +msgid "Password changed.\n" +msgstr "Lösenordet ändrat.\n" + +#: src/pwck.c:98 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd [ shadow ] ]\n" +msgstr "Användning: %s [ -qr ] [ passwd [ shadow ] ]\n" + +#: src/pwck.c:100 +#, c-format +msgid "Usage: %s [ -qr ] [ passwd ]\n" +msgstr "Användning: %s [ -qr ] [ passwd ]\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:285 +msgid "invalid password file entry\n" +msgstr "felaktig notering i lösenordsfilen\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:347 +msgid "duplicate password entry\n" +msgstr "dubblett av lösenords notering\n" + +#: src/pwck.c:363 +#, c-format +msgid "invalid user name `%s'\n" +msgstr "ogiltigt användarnamn \"%s\"\n" + +#: src/pwck.c:373 +#, c-format +msgid "user %s: bad UID (%d)\n" +msgstr "användare %s: felaktigt UID (%d)\n" + +#. +#. * No primary group, just give a warning +#. +#: src/pwck.c:388 +#, c-format +msgid "user %s: no group %d\n" +msgstr "användare %s: ingen grupp %d\n" + +#. +#. * Home directory doesn't exist, give a warning +#. +#: src/pwck.c:403 +#, c-format +msgid "user %s: directory %s does not exist\n" +msgstr "användare %s: katalogen %s finns inte\n" + +#. +#. * Login shell doesn't exist, give a warning +#. +#: src/pwck.c:418 +#, c-format +msgid "user %s: program %s does not exist\n" +msgstr "användare %s: programmet %s finns inte\n" + +#. +#. * Tell the user this entire line is bogus and +#. * ask them to delete it. +#. +#: src/pwck.c:454 +msgid "invalid shadow password file entry\n" +msgstr "felaktig notering i skugglösenordsfilen\n" + +#. +#. * Tell the user this entry is a duplicate of +#. * another and ask them to delete it. +#. +#: src/pwck.c:516 +msgid "duplicate shadow password entry\n" +msgstr "dubblett av notering i skugglösenordsfilen\n" + +#. +#. * Tell the user this entry has no matching +#. * /etc/passwd entry and ask them to delete it. +#. +#: src/pwck.c:540 +msgid "no matching password file entry\n" +msgstr "ingen matchande notering i lösenordsfilen\n" + +#: src/pwck.c:557 +#, c-format +msgid "user %s: last password change in the future\n" +msgstr "användare %s: senaste lösenordsändring i framtiden\n" + +#: src/pwconv.c:94 src/pwunconv.c:108 +#, c-format +msgid "%s: can't lock passwd file\n" +msgstr "%s: kan inte låsa lösenordsfilen\n" + +#: src/pwconv.c:99 src/pwunconv.c:113 +#, c-format +msgid "%s: can't open passwd file\n" +msgstr "%s: kan inte öppna lösenordsfilen\n" + +#: src/pwconv.c:126 +#, c-format +msgid "%s: can't remove shadow entry for %s\n" +msgstr "%s: kan inte ta bort notering i skugglösenordsfilen för %s\n" + +#: src/pwconv.c:169 +#, c-format +msgid "%s: can't update passwd entry for %s\n" +msgstr "%s: kan inte uppdatera noteringen i lösenordsfilen för %s\n" + +#: src/pwconv.c:176 +#, c-format +msgid "%s: can't update shadow file\n" +msgstr "%s: kan inte uppdatera skuggfilen\n" + +#: src/pwconv.c:180 +#, c-format +msgid "%s: can't update passwd file\n" +msgstr "%s: kan inte uppdatera lösenordsfilen\n" + +#: src/pwunconv.c:62 +#, c-format +msgid "%s: Shadow passwords are not configured.\n" +msgstr "%s: Shadowlösenord är inte konfigurerade.\n" + +#: src/pwunconv.c:171 +#, c-format +msgid "%s: can't update entry for user %s\n" +msgstr "%s: kan inte uppdatera noteringen för användaren %s\n" + +#: src/pwunconv.c:188 +#, c-format +msgid "%s: can't delete shadow password file\n" +msgstr "%s: kan inte ta bort skugglösenordsfilen\n" + +#: src/su.c:140 +msgid "Sorry." +msgstr "Tyvärr." + +#: src/su.c:222 +#, c-format +msgid "%s: must be run from a terminal\n" +msgstr "%s: måste köras från en terminal\n" + +#: src/su.c:311 +#, c-format +msgid "%s: pam_start: error %d\n" +msgstr "%s: pam_start: fel %d\n" + +#: src/su.c:337 +#, c-format +msgid "Unknown id: %s\n" +msgstr "Okänt id: %s\n" + +#. access denied (-1) or unexpected value +#: src/su.c:372 src/su.c:387 +#, c-format +msgid "You are not authorized to su %s\n" +msgstr "Du har inte tillåtelse att köra su till %s\n" + +#. require own password +#: src/su.c:383 +msgid "(Enter your own password.)" +msgstr "(Skriv in ditt eget lösenord.)" + +#: src/su.c:404 +#, c-format +msgid "%s: permission denied (shell).\n" +msgstr "%s: tillåtelse nekas (skal).\n" + +#: src/su.c:428 +#, c-format +msgid "" +"%s: %s\n" +"(Ignored)\n" +msgstr "" +"%s: %s\n" +"(Ignorerad)\n" + +#: src/su.c:628 +msgid "No shell\n" +msgstr "Inget skal\n" + +#. must be a password file! +#: src/sulogin.c:136 +msgid "No password file\n" +msgstr "Ingen lösenordsfil\n" + +#. +#. * Fail secure +#. +#: src/sulogin.c:178 +msgid "No password entry for 'root'\n" +msgstr "Ingen lösenordsnotering för \"root\"\n" + +#. +#. * Here we prompt for the root password, or if no password is +#. * given we just exit. +#. +#. get a password for root +#: src/sulogin.c:192 +msgid "" +"\n" +"Type control-d to proceed with normal startup,\n" +"(or give root password for system maintenance):" +msgstr "" +"\n" +"Skriv control-d för att fortsätta med den normala uppstarten,\n" +"(eller skriv in lösenordet för root för systemunderhåll):" + +#. make new environment active +#: src/sulogin.c:241 +msgid "Entering System Maintenance Mode\n" +msgstr "Går in i systemunderhållsläge\n" + +#: src/useradd.c:243 +#, c-format +msgid "%s: rebuild the group database\n" +msgstr "%s: bygg om gruppdatabasen\n" + +#: src/useradd.c:250 +#, c-format +msgid "%s: rebuild the shadow group database\n" +msgstr "%s: bygg om skuggruppdatabasen\n" + +#: src/useradd.c:287 src/usermod.c:967 +#, c-format +msgid "%s: invalid numeric argument `%s'\n" +msgstr "%s: ogiltigt numeriskt argument \"%s\"\n" + +#: src/useradd.c:343 +#, c-format +msgid "%s: unknown gid %s\n" +msgstr "%s: okänt gid %s\n" + +#: src/useradd.c:350 src/useradd.c:642 src/useradd.c:1228 src/usermod.c:254 +#: src/usermod.c:1098 +#, c-format +msgid "%s: unknown group %s\n" +msgstr "%s: okänd grupp %s\n" + +#: src/useradd.c:418 +#, c-format +msgid "group=%s,%ld basedir=%s skel=%s\n" +msgstr "grupp=%s,%ld baskatalog=%s skel=%s\n" + +#: src/useradd.c:421 +#, c-format +msgid "shell=%s " +msgstr "skal=%s " + +#: src/useradd.c:423 +#, c-format +msgid "inactive=%ld expire=%s" +msgstr "inaktiv=%ld upphör=%s" + +#: src/useradd.c:427 +#, c-format +msgid "GROUP=%ld\n" +msgstr "GRUPP=%ld\n" + +#: src/useradd.c:428 +#, c-format +msgid "HOME=%s\n" +msgstr "HEM=%s\n" + +#: src/useradd.c:430 +#, c-format +msgid "INACTIVE=%ld\n" +msgstr "INAKTIV=%ld\n" + +#: src/useradd.c:431 +#, c-format +msgid "EXPIRE=%s\n" +msgstr "UPPHÖR=%s\n" + +#: src/useradd.c:433 +#, c-format +msgid "SHELL=%s\n" +msgstr "SKAL=%s\n" + +#: src/useradd.c:434 +#, c-format +msgid "SKEL=%s\n" +msgstr "SKEL=%s\n" + +#: src/useradd.c:470 +#, c-format +msgid "%s: cannot create new defaults file\n" +msgstr "%s: kan inte skapa en ny standardfil\n" + +#: src/useradd.c:564 src/useradd.c:575 +#, c-format +msgid "%s: rename: %s" +msgstr "%s: rename: %s" + +#: src/useradd.c:662 src/usermod.c:274 +#, c-format +msgid "%s: group `%s' is a NIS group.\n" +msgstr "%s: grupp \"%s\" är en NIS-grupp.\n" + +#: src/useradd.c:670 src/usermod.c:282 +#, c-format +msgid "%s: too many groups specified (max %d).\n" +msgstr "%s: för många grupper speciferade (max %d).\n" + +#: src/useradd.c:702 src/usermod.c:314 +#, c-format +msgid "usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n" +msgstr "Användning: %s\t[-u uid [-o]] [-g grupp] [-G grupp,...] \n" + +#: src/useradd.c:705 +msgid "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n" +msgstr "\t\t[-d hem] [-s skal] [-c kommentar] [-m [-k mall]]\n" + +#: src/useradd.c:708 src/usermod.c:320 +msgid "[-f inactive] [-e expire ] " +msgstr "[-f inaktiv] [-e upphör ] " + +#: src/useradd.c:711 +msgid "[-A program] " +msgstr "[-A program] " + +#: src/useradd.c:713 +msgid "[-p passwd] name\n" +msgstr "[-p passwd] namn\n" + +#: src/useradd.c:715 +#, c-format +msgid " %s\t-D [-g group] [-b base] [-s shell]\n" +msgstr " %s\t-D [-g grupp] [-b bas] [-s skal]\n" + +#: src/useradd.c:718 +msgid "\t\t[-f inactive] [-e expire ]\n" +msgstr "\t\t[-f inaktiv] [-e utgång ]\n" + +#: src/useradd.c:815 src/usermod.c:472 +#, c-format +msgid "%s: error locking group file\n" +msgstr "%s: fel under låsning av gruppfilen\n" + +#: src/useradd.c:819 src/usermod.c:477 +#, c-format +msgid "%s: error opening group file\n" +msgstr "%s: fel under öppning av gruppfilen\n" + +#: src/useradd.c:824 src/usermod.c:584 +#, c-format +msgid "%s: error locking shadow group file\n" +msgstr "%s: fel under låsning av skuggruppfilen\n" + +#: src/useradd.c:829 src/usermod.c:590 +#, c-format +msgid "%s: error opening shadow group file\n" +msgstr "%s: fel under öppning av skuggruppfilen\n" + +#: src/useradd.c:1001 +#, c-format +msgid "%s: uid %d is not unique\n" +msgstr "%s: uid %d är inte unikt\n" + +#: src/useradd.c:1031 +#, c-format +msgid "%s: can't get unique uid\n" +msgstr "%s: kan inte hitta ett unikt uid\n" + +#: src/useradd.c:1139 src/useradd.c:1283 src/usermod.c:1046 src/usermod.c:1057 +#: src/usermod.c:1067 src/usermod.c:1113 src/usermod.c:1157 +#, c-format +msgid "%s: invalid field `%s'\n" +msgstr "%s: felaktigt fält \"%s\"\n" + +#: src/useradd.c:1153 +#, c-format +msgid "%s: invalid base directory `%s'\n" +msgstr "%s: felaktig baskatalog \"%s\"\n" + +#: src/useradd.c:1163 +#, c-format +msgid "%s: invalid comment `%s'\n" +msgstr "%s: felaktig kommentar \"%s\"\n" + +#: src/useradd.c:1173 +#, c-format +msgid "%s: invalid home directory `%s'\n" +msgstr "%s: felaktig hemkatalog \"%s\"\n" + +#: src/useradd.c:1191 src/usermod.c:1080 +#, c-format +msgid "%s: invalid date `%s'\n" +msgstr "%s: felaktigt datum \"%s\"\n" + +#: src/useradd.c:1203 +#, c-format +msgid "%s: shadow passwords required for -e\n" +msgstr "%s: skugglösenord krävs för -e\n" + +#: src/useradd.c:1218 +#, c-format +msgid "%s: shadow passwords required for -f\n" +msgstr "%s: skugglösenord krävs för -f\n" + +#: src/useradd.c:1292 +#, c-format +msgid "%s: invalid shell `%s'\n" +msgstr "%s: felaktigt skal \"%s\"\n" + +#: src/useradd.c:1333 +#, c-format +msgid "%s: invalid user name `%s'\n" +msgstr "%s: felaktigt användar namn \"%s\"\n" + +#: src/useradd.c:1369 src/userdel.c:292 src/usermod.c:1225 +#, c-format +msgid "%s: cannot rewrite password file\n" +msgstr "%s: kan inte skriva om lösenordsfilen\n" + +#: src/useradd.c:1374 src/userdel.c:295 src/usermod.c:1230 +#, c-format +msgid "%s: cannot rewrite shadow password file\n" +msgstr "%s: kan inte skriva om skugglösenordsfilen\n" + +#: src/useradd.c:1414 src/userdel.c:359 src/usermod.c:1265 +#, c-format +msgid "%s: unable to lock password file\n" +msgstr "%s: kan inte låsa lösenordsfilen\n" + +#: src/useradd.c:1418 src/userdel.c:363 src/usermod.c:1269 +#, c-format +msgid "%s: unable to open password file\n" +msgstr "%s: kan inte öppna lösenordsfilen\n" + +#: src/useradd.c:1424 src/userdel.c:368 src/usermod.c:1274 +#, c-format +msgid "%s: cannot lock shadow password file\n" +msgstr "%s: kan inte låsa skugglösenordsfilen\n" + +#: src/useradd.c:1430 src/userdel.c:373 src/usermod.c:1279 +#, c-format +msgid "%s: cannot open shadow password file\n" +msgstr "%s: kan inte öppna skugglösenordsfilen\n" + +#: src/useradd.c:1529 src/usermod.c:1366 +#, c-format +msgid "%s: error adding authentication method\n" +msgstr "%s: fel under tillägning av metod för äkthetsbevisning\n" + +#: src/useradd.c:1552 +#, c-format +msgid "%s: error adding new password entry\n" +msgstr "%s: fel under tilläggning av ny lösenordsnotering\n" + +#: src/useradd.c:1567 +#, c-format +msgid "%s: error updating password dbm entry\n" +msgstr "%s: fel under uppdatering av dbm-lösenordsnotering\n" + +#: src/useradd.c:1583 src/usermod.c:1425 +#, c-format +msgid "%s: error adding new shadow password entry\n" +msgstr "%s: fel under tilläggning av ny skugglösenordsnotering\n" + +#: src/useradd.c:1599 src/usermod.c:1440 +#, c-format +msgid "%s: error updating shadow passwd dbm entry\n" +msgstr "%s: fel under uppdatering av dbm-skugglösenordsnotering\n" + +#: src/useradd.c:1631 +#, c-format +msgid "%s: cannot create directory %s\n" +msgstr "%s: kan inte skapa katalog %s\n" + +#: src/useradd.c:1708 src/usermod.c:1203 +#, c-format +msgid "%s: user %s exists\n" +msgstr "%s: användare %s existerar\n" + +#: src/useradd.c:1738 +#, c-format +msgid "%s: warning: CREATE_HOME not supported, please use -m instead.\n" +msgstr "%s: varning: CREATE_HOME stöds inte, använd -m istället.\n" + +#: src/userdel.c:127 +#, c-format +msgid "usage: %s [-r] name\n" +msgstr "Användning: %s [-r] namn\n" + +#: src/userdel.c:178 src/userdel.c:260 +#, c-format +msgid "%s: error updating group entry\n" +msgstr "%s: fel under uppdatering av gruppnotering\n" + +#: src/userdel.c:188 src/userdel.c:269 +#, c-format +msgid "%s: cannot update dbm group entry\n" +msgstr "%s: kan inte uppdatera dbm-gruppnotering\n" + +#: src/userdel.c:215 +#, fuzzy, c-format +msgid "%s: cannot remove dbm group entry\n" +msgstr "%s: kan inte uppdatera dbm-gruppnotering\n" + +#: src/userdel.c:300 +#, c-format +msgid "%s: cannot rewrite TCFS key file\n" +msgstr "%s: kan inte skriva om TCFS-nyckelfilen\n" + +#: src/userdel.c:380 +#, c-format +msgid "%s: cannot lock TCFS key file\n" +msgstr "%s: kan inte låsa TCFS-nyckelfilen\n" + +#: src/userdel.c:384 +#, c-format +msgid "%s: cannot open TCFS key file\n" +msgstr "%s: kan inte öppna TCFS-nyckelfilen\n" + +#: src/userdel.c:393 +#, c-format +msgid "%s: cannot open group file\n" +msgstr "%s: kan inte öppna gruppfilen\n" + +#: src/userdel.c:403 +#, c-format +msgid "%s: cannot open shadow group file\n" +msgstr "%s: kan inte öppna skuggruppfilen\n" + +#: src/userdel.c:434 src/userdel.c:449 +#, c-format +msgid "%s: error deleting authentication\n" +msgstr "%s: fel under borttagning av metod för äkthetsbevisning\n" + +#: src/userdel.c:458 +#, c-format +msgid "%s: error deleting password entry\n" +msgstr "%s: fel under borttagning av lösenordsnotering\n" + +#: src/userdel.c:461 +#, c-format +msgid "%s: error deleting shadow password entry\n" +msgstr "%s: fel under borttagning av skugglösenordsnotering\n" + +#: src/userdel.c:470 +#, c-format +msgid "%s: error deleting TCFS entry\n" +msgstr "%s: fel under borttagning av TCFS-notering\n" + +#: src/userdel.c:483 +#, c-format +msgid "%s: error deleting password dbm entry\n" +msgstr "%s: fel under borttagning av dbm-lösenordsnotering\n" + +#: src/userdel.c:502 +#, c-format +msgid "%s: error deleting shadow passwd dbm entry\n" +msgstr "%s: fel under borttagning av dbm-skugglösenordsnotering\n" + +#: src/userdel.c:543 +#, c-format +msgid "%s: user %s is currently logged in\n" +msgstr "%s: användare %s är inloggad\n" + +#: src/userdel.c:660 +#, c-format +msgid "%s: warning: %s not owned by %s, not removing\n" +msgstr "%s: varning: %s ägs inte av %s, tar inte bort\n" + +#: src/userdel.c:666 +#, c-format +msgid "%s: warning: can't remove " +msgstr "%s: varning: kan inte ta bort " + +#: src/userdel.c:741 src/usermod.c:994 +#, c-format +msgid "%s: user %s does not exist\n" +msgstr "%s: användare %s finns inte\n" + +#: src/userdel.c:755 src/usermod.c:1010 +#, c-format +msgid "%s: user %s is a NIS user\n" +msgstr "%s: användare %s är en NIS-användare\n" + +#: src/userdel.c:792 +#, c-format +msgid "%s: %s not owned by %s, not removing\n" +msgstr "%s: %s ägs inte av %s, tar inte bort\n" + +#: src/userdel.c:815 +#, c-format +msgid "%s: not removing directory %s (would remove home of user %s)\n" +msgstr "%s: tar inte bort katalogen %s (skulle ta bort hemkatalogen för %s)\n" + +#: src/userdel.c:828 +#, c-format +msgid "%s: error removing directory %s\n" +msgstr "%s: fel under borttagning av katalogen %s\n" + +#: src/usermod.c:317 +msgid "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n" +msgstr "\t\t[-d hem [-m]] [-s skal] [-c kommentar] [-l nytt_namn]\n" + +#: src/usermod.c:323 +msgid "[-A {DEFAULT|program},... ] " +msgstr "[-A {DEFAULT|program},... ] " + +#: src/usermod.c:325 +#, fuzzy +msgid "[-p passwd] [-L|-U] name\n" +msgstr "[-p passwd] namn\n" + +#: src/usermod.c:504 +#, c-format +msgid "%s: out of memory in update_group\n" +msgstr "%s: slut på minne i update_group\n" + +#: src/usermod.c:627 +#, c-format +msgid "%s: out of memory in update_gshadow\n" +msgstr "%s: slut på minne i update_gshadow\n" + +#: src/usermod.c:1180 +#, c-format +msgid "%s: no flags given\n" +msgstr "%s: inga flaggor givna\n" + +#: src/usermod.c:1187 +#, c-format +msgid "%s: shadow passwords required for -e and -f\n" +msgstr "%s: skugglösenord krävs för -e och -f\n" + +#: src/usermod.c:1208 +#, c-format +msgid "%s: uid %ld is not unique\n" +msgstr "%s: uid %ld är inte unikt\n" + +#: src/usermod.c:1356 +#, c-format +msgid "%s: error deleting authentication method\n" +msgstr "%s: fel under borttagning av metod för äkthetsbevisning\n" + +#: src/usermod.c:1376 +#, c-format +msgid "%s: error changing authentication method\n" +msgstr "%s: fel under ändring av metod för äkthetsbevisning\n" + +#: src/usermod.c:1393 +#, c-format +msgid "%s: error changing password entry\n" +msgstr "%s: fel under ändring av lösenordsnotering\n" + +#: src/usermod.c:1399 +#, c-format +msgid "%s: error removing password entry\n" +msgstr "%s: fel under borttagning av lösenordsnotering\n" + +#: src/usermod.c:1407 +#, c-format +msgid "%s: error adding password dbm entry\n" +msgstr "%s: fel under tilläggning av dbm-lösenordsnotering\n" + +#: src/usermod.c:1414 +#, c-format +msgid "%s: error removing passwd dbm entry\n" +msgstr "%s: fel under borttagning av dbm-lösenordsnotering\n" + +#: src/usermod.c:1431 +#, c-format +msgid "%s: error removing shadow password entry\n" +msgstr "%s: fel under borttagning av skugglösenordsnotering\n" + +#: src/usermod.c:1446 +#, c-format +msgid "%s: error removing shadow passwd dbm entry\n" +msgstr "%s: fel under borttagning av dbm-skugglösenordsnotering\n" + +#: src/usermod.c:1477 +#, c-format +msgid "%s: directory %s exists\n" +msgstr "%s: katalogen %s existerar\n" + +#: src/usermod.c:1484 +#, c-format +msgid "%s: can't create %s\n" +msgstr "%s: kan inte skapa %s\n" + +#: src/usermod.c:1490 +#, c-format +msgid "%s: can't chown %s\n" +msgstr "%s: kan inte byta ägare på %s\n" + +#: src/usermod.c:1506 +#, c-format +msgid "%s: cannot rename directory %s to %s\n" +msgstr "%s: kan inte byta namn på katalogen %s till %s\n" + +#. better leave it alone +#: src/usermod.c:1603 +#, c-format +msgid "%s: warning: %s not owned by %s\n" +msgstr "%s: varning: %s ägs inte av %s\n" + +#: src/usermod.c:1609 +msgid "failed to change mailbox owner" +msgstr "kunde inte byta ägare av brevlådan" + +#: src/usermod.c:1616 +msgid "failed to rename mailbox" +msgstr "kunde inte byta namn på brevlådan" + +#: src/vipw.c:102 +#, c-format +msgid "" +"\n" +"%s: %s is unchanged\n" +msgstr "" +"\n" +"%s: %s är oförändrad\n" + +#: src/vipw.c:127 +msgid "Couldn't lock file" +msgstr "Kunde inte låsa filen" + +#: src/vipw.c:134 +msgid "Couldn't make backup" +msgstr "Kunde inte göra en backup" + +#: src/vipw.c:187 +#, c-format +msgid "%s: can't restore %s: %s (your changes are in %s)\n" +msgstr "%s: kan inte återställa %s: %s (dina ändringar är i %s)\n" + +#: src/vipw.c:226 +msgid "" +"Usage:\n" +"`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n" +"`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n" +msgstr "" +"Användning:\n" +"\"vipw\" editerar /etc/passwd \"vipw -w\" editerar /etc/shadow\n" +"\"vipg\" editerar /etc/group \"vipg -w\" editerar /etc/gshadow\n" diff --git a/current/redhat/Makefile.am b/current/redhat/Makefile.am new file mode 100644 index 00000000..4e9ac2fa --- /dev/null +++ b/current/redhat/Makefile.am @@ -0,0 +1,8 @@ +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + +EXTRA_DIST = README shadow-utils.spec shadow-utils.spec.in \ + shadow-970616-fix.patch shadow-970616-glibc.patch \ + shadow-970616-rh.patch shadow-970616-utuser.patch \ + shadow-970616.login.defs shadow-970616.useradd \ + shadow-utils-970616.spec diff --git a/current/redhat/Makefile.in b/current/redhat/Makefile.in new file mode 100644 index 00000000..7aa97334 --- /dev/null +++ b/current/redhat/Makefile.in @@ -0,0 +1,214 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# This is a dummy Makefile.am to get automake work flawlessly, +# and also cooperate to make a distribution for `make dist' + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +EXTRA_DIST = README shadow-utils.spec shadow-utils.spec.in shadow-970616-fix.patch shadow-970616-glibc.patch shadow-970616-rh.patch shadow-970616-utuser.patch shadow-970616.login.defs shadow-970616.useradd shadow-utils-970616.spec + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = shadow-utils.spec +DIST_COMMON = README Makefile.am Makefile.in shadow-utils.spec.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps redhat/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +shadow-utils.spec: $(top_builddir)/config.status shadow-utils.spec.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = redhat + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/redhat/README b/current/redhat/README new file mode 100644 index 00000000..96739e7f --- /dev/null +++ b/current/redhat/README @@ -0,0 +1,29 @@ +Included here are the patches from the shadow-utils-970616-11.src.rpm +(RedHat 5.0 updates). I'd like to make it possible to build binary +packages for all Linux distributions "out of the box" from the same +upstream sources. This needs more work for RedHat 5.0, and I only have +RedHat 4.2 (hint hint). If you have any suggestions regarding this +package, please contact me. Perhaps the necessary changes can be +included in the standard sources, so that everything can be build with +one simple command (rpm -ta shadow-xxxxxx.tar.gz). + +One suggestion for the shadow-utils-970616-11 patch: instead of adding +new (sometimes quite distribution-specific) options to useradd (and +symlinking adduser -> useradd), I'd suggest to use a program or script +called "adduser" that implements the distribution-specific UID/GID +allocation etc. and runs useradd to do all the dirty work (modifying +password files etc.). Also, please don't change the default behaviour +of useradd, which is to create the home directory only if the -m option +is specified). I'd like to keep useradd simple, and compatible with +other implementations (the user* and group* commands are quite similar +to commands with the same names found on many commercial UN*X systems). + +I'd suggest to take a look at the adduser-3.x package from the Debian +distribution. It's a perl script, which shouldn't be too hard to modify +to suit the requirements of Red Hat, or any other Linux distribution. +It runs programs from the shadow suite to do the actual password file +modifications, is reasonably user friendly, and configurable. + +Comments? + +--marekm diff --git a/current/redhat/shadow-970616-fix.patch b/current/redhat/shadow-970616-fix.patch new file mode 100644 index 00000000..341f11a4 --- /dev/null +++ b/current/redhat/shadow-970616-fix.patch @@ -0,0 +1,256 @@ +--- shadow-970616/libmisc/Makefile.in.fix Sun Jun 15 20:05:05 1997 ++++ shadow-970616/libmisc/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -99,13 +99,6 @@ + + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status +- + mostlyclean-noinstLIBRARIES: + + clean-noinstLIBRARIES: +--- shadow-970616/man/Makefile.in.fix Sun Jun 15 20:05:05 1997 ++++ shadow-970616/man/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -72,12 +72,6 @@ + TAR = tar + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + install-man: $(MANS) + $(mkinstalldirs) $(mandir)/man8 + $(mkinstalldirs) $(mandir)/man1 +--- shadow-970616/lib/Makefile.in.fix Sun Jun 15 20:05:06 1997 ++++ shadow-970616/lib/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -123,12 +123,6 @@ + default: all + + +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status +- + mostlyclean-noinstLIBRARIES: + + clean-noinstLIBRARIES: +--- shadow-970616/src/useradd.c.fix Tue Dec 30 14:09:29 1997 ++++ shadow-970616/src/useradd.c Tue Dec 30 14:37:22 1997 +@@ -570,8 +570,7 @@ + */ + + static int +-get_groups(list) +- char *list; ++get_groups(char *list) + { + char *cp; + const struct group *grp; +@@ -606,7 +605,7 @@ + * GID values, otherwise the string is looked up as is. + */ + +- grp = getgr_nam_gid(*list); ++ grp = getgr_nam_gid(list); + + /* + * There must be a match, either by GID value or by +@@ -1401,25 +1400,6 @@ + Prog); + fail_exit (1); + } +-#endif +- if (do_grp_update) { +- if (! gr_close ()) { +- fprintf (stderr, "%s: cannot rewrite group file\n", +- Prog); +- fail_exit (1); +- } +- (void) gr_unlock (); +-#ifdef SHADOWGRP +- if (is_shadow_grp && ! sgr_close ()) { +- fprintf (stderr, "%s: cannot rewrite shadow group file\n", +- Prog); +- fail_exit (1); +- } +- if (is_shadow_grp) +- sgr_unlock (); +-#endif +- } +-#ifdef SHADOWPWD + if (is_shadow_pwd) + spw_unlock (); + #endif +@@ -1758,7 +1738,6 @@ + /* + * Write out the new group file entry. + */ +- + if (! gr_update (&grp)) { + fprintf (stderr, "%s: error adding new group entry\n", Prog); + fail_exit (10); +@@ -1801,6 +1780,8 @@ + #endif /* SHADOWGRP */ + SYSLOG((LOG_INFO, "new group: name=%s, gid=%d\n", + user_name, user_gid)); ++ /* we need to remeber we have to close the group file... */ ++ do_grp_update++; + } + + /* +--- shadow-970616/src/Makefile.in.fix Sun Jun 15 20:05:08 1997 ++++ shadow-970616/src/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -251,12 +251,6 @@ + default: all + + +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status +- + mostlyclean-usbinPROGRAMS: + + clean-usbinPROGRAMS: +--- shadow-970616/contrib/Makefile.in.fix Sun Jun 15 20:05:09 1997 ++++ shadow-970616/contrib/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -60,12 +60,6 @@ + TAR = tar + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + tags: TAGS + TAGS: + +--- shadow-970616/debian/Makefile.in.fix Sun Jun 15 20:05:09 1997 ++++ shadow-970616/debian/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -64,12 +64,6 @@ + TAR = tar + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + tags: TAGS + TAGS: + +--- shadow-970616/doc/Makefile.in.fix Sun Jun 15 20:05:09 1997 ++++ shadow-970616/doc/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -61,12 +61,6 @@ + TAR = tar + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + tags: TAGS + TAGS: + +--- shadow-970616/etc/Makefile.in.fix Sun Jun 15 20:05:09 1997 ++++ shadow-970616/etc/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -60,12 +60,6 @@ + TAR = tar + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + tags: TAGS + TAGS: + +--- shadow-970616/old/Makefile.in.fix Sun Jun 15 20:05:10 1997 ++++ shadow-970616/old/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -61,12 +61,6 @@ + TAR = tar + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + tags: TAGS + TAGS: + +--- shadow-970616/shlib/Makefile.in.fix Sun Jun 15 20:05:10 1997 ++++ shadow-970616/shlib/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -60,11 +60,6 @@ + default: all + + +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in +- cd $(top_srcdir) && automake $(subdir)/Makefile +- +-Makefile: $(top_builddir)/config.status Makefile.in +- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + tags: TAGS + TAGS: + +--- shadow-970616/configure.in.fix Sun Jun 15 19:42:47 1997 ++++ shadow-970616/configure.in Tue Dec 30 14:09:29 1997 +@@ -38,7 +38,7 @@ + AC_CHECK_HEADERS(gshadow.h shadow.h lastlog.h) + + AC_EGREP_HEADER(ut_host, utmp.h, AC_DEFINE(UT_HOST)) +-AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_name)) ++AC_EGREP_HEADER(ut_user, utmp.h, AC_DEFINE(UT_USER, ut_user)) + AC_EGREP_HEADER(ll_host, lastlog.h, AC_DEFINE(HAVE_LL_HOST)) + + dnl Checks for typedefs, structures, and compiler characteristics. +--- shadow-970616/Makefile.in.fix Sun Jun 15 20:05:08 1997 ++++ shadow-970616/Makefile.in Tue Dec 30 14:09:29 1997 +@@ -64,28 +64,6 @@ + TAR = tar + default: all + +- +-$(srcdir)/Makefile.in: Makefile.am configure.in +- cd $(srcdir) && automake Makefile +- +-# For an explanation of the following Makefile rules, see node +-# `Automatic Remaking' in GNU Autoconf documentation. +-Makefile: Makefile.in config.status +- CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status +-config.status: configure +- ./config.status --recheck +-$(srcdir)/configure: configure.in $(ACLOCAL) $(CONFIGURE_DEPENDENCIES) +- cd $(srcdir) && autoconf +- +-$(CONFIG_HEADER): stamp-h +-stamp-h: $(CONFIG_HEADER_IN) config.status +- CONFIG_FILES= CONFIG_HEADERS=$(CONFIG_HEADER) ./config.status +- @echo timestamp > stamp-h +-$(srcdir)/$(CONFIG_HEADER_IN): stamp-h.in +-$(srcdir)/stamp-h.in: configure.in $(ACLOCAL) $(ACCONFIG) $(CONFIG_TOP) $(CONFIG_BOT) +- cd $(srcdir) && autoheader +- echo timestamp > $(srcdir)/stamp-h.in +- + # This directory's subdirectories are mostly independent; you can cd + # into them and run `make' without going through this Makefile. + # To change the values of `make' variables: instead of editing Makefiles, diff --git a/current/redhat/shadow-970616-glibc.patch b/current/redhat/shadow-970616-glibc.patch new file mode 100644 index 00000000..ecd7039e --- /dev/null +++ b/current/redhat/shadow-970616-glibc.patch @@ -0,0 +1,11 @@ +--- shadow-970616/libmisc/strtoday.c.ewt Thu Nov 13 19:25:25 1997 ++++ shadow-970616/libmisc/strtoday.c Thu Nov 13 19:27:57 1997 +@@ -28,7 +28,7 @@ + */ + + #if !defined(__GLIBC__) +-#define _XOPEN_SOURCE ++#define _XOPEN_SOURCE 500 + #endif + + #include diff --git a/current/redhat/shadow-970616-rh.patch b/current/redhat/shadow-970616-rh.patch new file mode 100644 index 00000000..3b3e34d3 --- /dev/null +++ b/current/redhat/shadow-970616-rh.patch @@ -0,0 +1,1242 @@ +--- shadow-970616/man/shadowconfig.8.rh Thu May 1 14:18:17 1997 ++++ shadow-970616/man/shadowconfig.8 Fri Dec 12 15:36:29 1997 +@@ -14,7 +14,3 @@ + will print an error message and exit with a nonzero code if it finds + anything awry. If that happens, you should correct the error and run + it again. +-.PP +-Read +-.I /usr/doc/passwd/README.debian.gz +-for a brief introduction to shadow passwords and related features. +--- shadow-970616/man/useradd.8.rh Thu May 1 19:15:12 1997 ++++ shadow-970616/man/useradd.8 Fri Dec 12 15:36:29 1997 +@@ -50,13 +50,15 @@ + .RB [ -G + .IR group [,...]] + .RB [ -m " [" -k +-.IR skeleton_dir ]] ++.IR skeleton_dir ] " |" " " -M ] + .RB [ -s + .IR shell ] + .br + .RB [ -u + .IR uid " [" + .BR -o ]] ++.RB [ -n ] ++.RB [ -r ] + .I login + .TP 8 + .B useradd +@@ -81,6 +83,8 @@ + The new user account will be entered into the system files as needed, + the home directory will be created, and initial files copied, depending + on the command line options. ++The version provided with Red Hat Linux will create a group for each ++user added to the system, unless \fB-n\fR option is given. + The options which apply to the \fBuseradd\fR command are + .IP "\fB-A {\fImethod\fR|\fBDEFAULT\fR},..." + The value of the user's authentication method. +@@ -128,6 +132,21 @@ + option. + The default is to not create the directory and to not copy any + files. ++.IP \fB-M\fR ++The user home directory will not be created, even if the system ++wide settings from \fI/etc/login.defs\fR is to create home dirs. ++.IP \fB-n\fR ++A group having the same name as the user being added to the system ++will be created by default. This option will turn off this Red Hat ++Linux specific behavior. ++.IP \fB-r\fR ++This flag is used to create a system account. That is, an user with an ++UID lower than value of UID_MIN defined in \fI/etc/login.defs\fR. Note ++that \fBuseradd\fR will not create a home directory for such an user, ++regardless of the default setting in \fI/etc/login.defs\fR. ++You have to specify \fB-m\fR option if you want a home directory ++for a system account to be created. ++This is an option added by Red Hat. + .IP "\fB-s \fIshell\fR" + The name of the user's login shell. + The default is to leave this field blank, which causes the system +@@ -168,19 +187,24 @@ + .SH NOTES + The system administrator is responsible for placing the default + user files in the \fI/etc/skel\fR directory. ++.br ++This version of useradd was modified by Red Hat to suit Red Hat ++user/group convention. + .SH CAVEATS + You may not add a user to an NIS group. + This must be performed on the NIS server. + .SH FILES +-/etc/passwd \- user account information ++\fB/etc/passwd\fR \- user account information ++.br ++\fB/etc/shadow\fR \- secure user account information + .br +-/etc/shadow \- secure user account information ++\fB/etc/group\fR \- group information + .br +-/etc/group \- group information ++\fB/etc/default/useradd\fR \- default information + .br +-/etc/default/useradd \- default information ++\fB/etc/login.defs\fR \- system-wide settings + .br +-/etc/skel \- directory containing default files ++\fB/etc/skel\fR \- directory containing default files + .SH SEE ALSO + .BR chfn (1), + .BR chsh (1), +--- shadow-970616/man/groupadd.8.rh Thu May 1 19:15:06 1997 ++++ shadow-970616/man/groupadd.8 Fri Dec 12 15:36:29 1997 +@@ -32,7 +32,7 @@ + groupadd \- Create a new group + .SH SYNOPSIS + .B groupadd +-[\fB-g\fI gid \fR[\fB-o\fR]] ++[\fB-g\fI gid \fR[\fB-o\fR]] [\fB-r\fR] [\fB-f\fR] + .I group + .SH DESCRIPTION + The \fBgroupadd\fR command +@@ -44,9 +44,29 @@ + The numerical value of the group's ID. + This value must be unique, unless the \fB-o\fR option is used. + The value must be non-negative. +-The default is to use the smallest ID value greater than 99 and ++The default is to use the smallest ID value greater than 500 and + greater than every other group. +-Values between 0 and 99 are typically reserved for system accounts. ++Values between 0 and 499 are typically reserved for \fIsystem accounts\fR. ++.IP \fB-r\fR ++This flag instructs \fBgroupadd\fR to add a \fIsystem ++account\fR. First available \fIgid\fR lower than 499 will be ++automatically selected unless \fB-g\fR option is given also on the ++command line. ++.br ++This is an option added by Red Hat Software. ++.IP \fB-f\fR ++This is \fIforce\fR flag. This will stop \fBgroupadd\fR exit with ++error when the group about to be added already exists on the ++system. If that is the case, the group won't be altered (or added ++again, for that matter). ++.br ++This option also modifies the way \fB-g\fR option works. When you ++request a \fIgid\fR that it is not unique and you don't give \fB-o\fR ++option too, the group creation will fall back to the standard behavior ++(adding a group as neither \fB-g\fR or \fB-o\fR options were ++specified). ++.br ++This is an option added by Red Hat Software. + .SH FILES + /etc/group \- group account information + .br +--- shadow-970616/lib/getdef.c.rh Thu May 1 19:14:40 1997 ++++ shadow-970616/lib/getdef.c Fri Dec 12 15:36:29 1997 +@@ -61,6 +61,7 @@ + #ifdef HAVE_LIBCRACK + { "CRACKLIB_DICTPATH", NULL }, + #endif ++ { "CREATE_HOME", NULL }, + { "DEFAULT_HOME", NULL }, + { "DIALUPS_CHECK_ENAB", NULL }, + { "ENVIRON_FILE", NULL }, +@@ -171,7 +172,7 @@ + if ((d = def_find(item)) == NULL || d->value == NULL) + return 0; + +- return (strcmp(d->value, "yes") == 0); ++ return (strcasecmp(d->value, "yes") == 0); + } + + +--- shadow-970616/src/useradd.c.rh Sun Jun 1 01:25:40 1997 ++++ shadow-970616/src/useradd.c Fri Dec 12 15:58:04 1997 +@@ -60,7 +60,7 @@ + #define USER_DEFAULTS_FILE "/etc/default/useradd" + #define NEW_USER_FILE "/etc/default/nuaddXXXXXX" + #endif +- ++ + /* + * Needed for MkLinux DR1/2/2.1 - J. + */ +@@ -71,22 +71,22 @@ + /* + * These defaults are used if there is no defaults file. + */ +-static gid_t def_group = 1; ++static gid_t def_group = 100; + static char *def_gname = "other"; + static char *def_home = "/home"; +-static char *def_shell = ""; ++static char *def_shell = "/dev/null"; + static char *def_template = SKEL_DIR; + #ifdef SHADOWPWD + static long def_inactive = -1; + static char *def_expire = ""; + #endif + +-static char def_file[] = USER_DEFAULTS_FILE; ++static char def_file[] = USER_DEFAULTS_FILE; + + #define VALID(s) (strcspn (s, ":\n") == strlen (s)) + + static char *user_name = ""; +-static char *user_pass = "!"; ++static char *user_pass = "!!"; + static uid_t user_id; + static gid_t user_gid; + static char *user_comment = ""; +@@ -114,10 +114,13 @@ + sflg = 0, /* shell program for new account */ + cflg = 0, /* comment (GECOS) field for new account */ + mflg = 0, /* create user's home directory if it doesn't exist */ +- kflg = 0, /* specify a directory to fill new user directory */ ++ Mflg = 0, /* do NOT create user's home directory no matter what */ ++ kflg = 0, /* specify a directory to fill new user directory */ + fflg = 0, /* days until account with expired password is locked */ + eflg = 0, /* days since 1970-01-01 when account is locked */ +- Dflg = 0; /* set/show new user default values */ ++ Dflg = 0, /* set/show new user default values */ ++ nflg = 0, /* do not add a group for this user */ ++ rflg = 0; /* create a system account */ + + #ifdef AUTH_METHODS + static int Aflg = 0; /* specify authentication method for user */ +@@ -168,6 +171,7 @@ + * exit status values + */ + #define E_SUCCESS 0 /* success */ ++#define E_LOCKING 1 /* locking error */ + #define E_USAGE 2 /* bad command syntax */ + #define E_BAD_ARG 3 /* invalid argument to option */ + #define E_UID_IN_USE 4 /* uid already in use (and no -o) */ +@@ -177,19 +181,19 @@ + #define E_HOMEDIR 12 /* can't create home directory */ + + #ifdef SVR4 +-#define DGROUP "defgroup=" +-#define HOME "defparent=" +-#define SHELL "defshell=" +-#define INACT "definact=" +-#define EXPIRE "defexpire=" +-#define SKEL "defskel=" ++#define DGROUP "defgroup=" ++#define HOME "defparent=" ++#define SHELL "defshell=" ++#define INACT "definact=" ++#define EXPIRE "defexpire=" ++#define SKEL "defskel=" + #else +-#define DGROUP "GROUP=" +-#define HOME "HOME=" +-#define SHELL "SHELL=" +-#define INACT "INACTIVE=" +-#define EXPIRE "EXPIRE=" +-#define SKEL "SKEL=" ++#define DGROUP "GROUP=" ++#define HOME "HOME=" ++#define SHELL "SHELL=" ++#define INACT "INACTIVE=" ++#define EXPIRE "EXPIRE=" ++#define SKEL "SKEL=" + #endif + + /* +@@ -679,7 +683,7 @@ + #ifdef AUTH_METHODS + fprintf(stderr, "[-A program] "); + #endif +- fprintf(stderr, "[-p passwd] name\n"); ++ fprintf(stderr, "[-p passwd] [-n] [-r] name\n"); + + fprintf(stderr, " %s\t-D [-g group] [-b base] [-s shell]" + #ifdef SHADOWPWD +@@ -771,153 +775,129 @@ + static void + grp_update() + { +- const struct group *grp; +- struct group *ngrp; ++ const struct group *grp; ++ struct group *ngrp; + #ifdef SHADOWGRP +- const struct sgrp *sgrp; +- struct sgrp *nsgrp; ++ const struct sgrp *sgrp; ++ struct sgrp *nsgrp; + #endif + +- /* +- * Lock and open the group file. This will load all of the group +- * entries. +- */ ++ /* ++ * Scan through the entire group file looking for the groups that ++ * the user is a member of. ++ */ + +- if (! gr_lock ()) { +- fprintf (stderr, "%s: error locking group file\n", Prog); +- exit (1); +- } +- if (! gr_open (O_RDWR)) { +- fprintf (stderr, "%s: error opening group file\n", Prog); +- exit (1); +- } +-#ifdef SHADOWGRP +- if (is_shadow_grp && ! sgr_lock ()) { +- fprintf (stderr, "%s: error locking shadow group file\n", Prog); +- exit (1); +- } +- if (is_shadow_grp && ! sgr_open (O_RDWR)) { +- fprintf (stderr, "%s: error opening shadow group file\n", Prog); +- exit (1); +- } +-#endif ++ for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) { + + /* +- * Scan through the entire group file looking for the groups that +- * the user is a member of. ++ * See if the user specified this group as one of their ++ * concurrent groups. + */ + +- for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) { ++ if (!is_on_list(user_groups, grp->gr_name)) ++ continue; + +- /* +- * See if the user specified this group as one of their +- * concurrent groups. +- */ +- +- if (!is_on_list(user_groups, grp->gr_name)) +- continue; +- +- /* +- * Make a copy - gr_update() will free() everything +- * from the old entry, and we need it later. +- */ ++ /* ++ * Make a copy - gr_update() will free() everything ++ * from the old entry, and we need it later. ++ */ + +- ngrp = __gr_dup(grp); +- if (!ngrp) { +- exit(13); /* XXX */ +- } ++ ngrp = __gr_dup(grp); ++ if (!ngrp) { ++ exit(13); /* XXX */ ++ } + +- /* +- * Add the username to the list of group members and +- * update the group entry to reflect the change. +- */ ++ /* ++ * Add the username to the list of group members and ++ * update the group entry to reflect the change. ++ */ + +- ngrp->gr_mem = add_list (ngrp->gr_mem, user_name); +- if (! gr_update (ngrp)) { +- fprintf (stderr, "%s: error adding new group entry\n", +- Prog); +- fail_exit (1); +- } ++ ngrp->gr_mem = add_list (ngrp->gr_mem, user_name); ++ if (! gr_update (ngrp)) { ++ fprintf (stderr, "%s: error adding new group entry\n", ++ Prog); ++ fail_exit (1); ++ } + #ifdef NDBM +- /* +- * Update the DBM group file with the new entry as well. +- */ ++ /* ++ * Update the DBM group file with the new entry as well. ++ */ + +- if (! gr_dbm_update (ngrp)) { +- fprintf (stderr, "%s: cannot add new dbm group entry\n", +- Prog); +- fail_exit (1); +- } else +- gr_dbm_added++; +-#endif +- SYSLOG((LOG_INFO, "add `%s' to group `%s'\n", +- user_name, ngrp->gr_name)); +- } ++ if (! gr_dbm_update (ngrp)) { ++ fprintf (stderr, "%s: cannot add new dbm group entry\n", ++ Prog); ++ fail_exit (1); ++ } else ++ gr_dbm_added++; ++#endif ++ SYSLOG((LOG_INFO, "add `%s' to group `%s'\n", ++ user_name, ngrp->gr_name)); ++ } + #ifdef NDBM +- endgrent (); ++ endgrent (); + #endif + + #ifdef SHADOWGRP +- if (!is_shadow_grp) +- return; ++ if (!is_shadow_grp) ++ return; + +- /* +- * Scan through the entire shadow group file looking for the groups +- * that the user is a member of. The administrative list isn't +- * modified. +- */ ++ /* ++ * Scan through the entire shadow group file looking for the groups ++ * that the user is a member of. The administrative list isn't ++ * modified. ++ */ + +- for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) { ++ for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) { + +- /* +- * See if the user specified this group as one of their +- * concurrent groups. +- */ ++ /* ++ * See if the user specified this group as one of their ++ * concurrent groups. ++ */ + +- if (!gr_locate(sgrp->sg_name)) +- continue; ++ if (!gr_locate(sgrp->sg_name)) ++ continue; + +- if (!is_on_list(user_groups, sgrp->sg_name)) +- continue; ++ if (!is_on_list(user_groups, sgrp->sg_name)) ++ continue; + +- /* +- * Make a copy - sgr_update() will free() everything +- * from the old entry, and we need it later. +- */ ++ /* ++ * Make a copy - sgr_update() will free() everything ++ * from the old entry, and we need it later. ++ */ + +- nsgrp = __sgr_dup(sgrp); +- if (!nsgrp) { +- exit(13); /* XXX */ +- } ++ nsgrp = __sgr_dup(sgrp); ++ if (!nsgrp) { ++ exit(13); /* XXX */ ++ } + +- /* +- * Add the username to the list of group members and +- * update the group entry to reflect the change. +- */ ++ /* ++ * Add the username to the list of group members and ++ * update the group entry to reflect the change. ++ */ + +- nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name); +- if (! sgr_update (nsgrp)) { +- fprintf (stderr, "%s: error adding new group entry\n", +- Prog); +- fail_exit (1); +- } ++ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name); ++ if (! sgr_update (nsgrp)) { ++ fprintf (stderr, "%s: error adding new group entry\n", ++ Prog); ++ fail_exit (1); ++ } + #ifdef NDBM +- /* +- * Update the DBM group file with the new entry as well. +- */ ++ /* ++ * Update the DBM group file with the new entry as well. ++ */ + +- if (! sg_dbm_update (nsgrp)) { +- fprintf (stderr, "%s: cannot add new dbm group entry\n", +- Prog); +- fail_exit (1); +- } else +- sg_dbm_added++; ++ if (! sg_dbm_update (nsgrp)) { ++ fprintf (stderr, "%s: cannot add new dbm group entry\n", ++ Prog); ++ fail_exit (1); ++ } else ++ sg_dbm_added++; + #endif /* NDBM */ +- SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n", +- user_name, nsgrp->sg_name)); +- } ++ SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n", ++ user_name, nsgrp->sg_name)); ++ } + #ifdef NDBM +- endsgent (); ++ endsgent (); + #endif /* NDBM */ + #endif /* SHADOWGRP */ + } +@@ -936,8 +916,13 @@ + const struct passwd *pwd; + uid_t uid_min, uid_max; + +- uid_min = getdef_num("UID_MIN", 100); +- uid_max = getdef_num("UID_MAX", 60000); ++ if (!rflg) { ++ uid_min = getdef_num("UID_MIN", 500); ++ uid_max = getdef_num("UID_MAX", 60000); ++ } else { ++ uid_min = 1; ++ uid_max = 499; ++ } + + /* + * Start with some UID value if the user didn't provide us with +@@ -1003,6 +988,88 @@ + } + } + ++/* ++ * find_new_gid - find the next available GID ++ * ++ * find_new_gid() locates the next highest unused GID in the group ++ * file, or checks the given group ID against the existing ones for ++ * uniqueness. ++ */ ++ ++static void ++find_new_gid() ++{ ++ const struct group *grp; ++ gid_t gid_min, gid_max; ++ ++ if (!rflg) { ++ gid_min = getdef_num("GID_MIN", 500); ++ gid_max = getdef_num("GID_MAX", 60000); ++ } else { ++ gid_min = 1; ++ gid_max = 499; ++ } ++ ++ /* ++ * Start with some GID value if the user didn't provide us with ++ * one already. ++ */ ++ ++ user_gid = gid_min; ++ ++ /* ++ * Search the entire group file, either looking for this ++ * GID (if the user specified one with -g) or looking for the ++ * largest unused value. ++ */ ++ ++#ifdef NO_GETGRENT ++ gr_rewind(); ++ while ((grp = gr_next())) ++#else ++ setgrent(); ++ while ((grp = getgrent())) ++#endif ++ { ++ if (strcmp(user_name, grp->gr_name) == 0) { ++ user_gid = grp->gr_gid; ++ return; ++ } ++ if (grp->gr_gid >= user_gid) { ++ if (grp->gr_gid > gid_max) ++ continue; ++ user_gid = grp->gr_gid + 1; ++ } ++ } ++#ifndef NO_GETGRENT /* RH Linux does have this, so ... */ ++ /* A quick test gets here: if the UID is available ++ * as a GID, go ahead and use it */ ++ if (!getgrgid(user_id)) { ++ user_gid = user_id; ++ return; ++ } ++#endif ++ if (user_gid == gid_max + 1) { ++ for (user_gid = gid_min; user_gid < gid_max; user_gid++) { ++#ifdef NO_GETGRENT ++ gr_rewind(); ++ while ((grp = gr_next()) && grp->gr_gid != user_gid) ++ ; ++ if (!grp) ++ break; ++#else ++ if (!getgrgid(user_gid)) ++ break; ++#endif ++ } ++ if (user_gid == gid_max) { ++ fprintf(stderr, "%s: can't get unique gid (run out of GIDs)\n", ++ Prog); ++ fail_exit(4); ++ } ++ } ++} ++ + #ifdef AUTH_METHODS + /* + * convert_auth - convert the argument list to a authentication list +@@ -1099,9 +1166,9 @@ + int arg; + + #ifdef SHADOWPWD +-#define FLAGS "A:Du:og:G:d:s:c:mk:p:f:e:b:" ++#define FLAGS "A:Du:og:G:d:s:c:mMk:p:f:e:b:nr" + #else +-#define FLAGS "A:Du:og:G:d:s:c:mk:p:b:" ++#define FLAGS "A:Du:og:G:d:s:c:mMk:p:b:nr" + #endif + while ((arg = getopt(argc, argv, FLAGS)) != EOF) { + #undef FLAGS +@@ -1251,6 +1318,15 @@ + user_id = get_number(optarg); + uflg++; + break; ++ case 'n': ++ nflg++; ++ break; ++ case 'r': ++ rflg++; ++ break; ++ case 'M': ++ Mflg++; ++ break; + default: + usage (); + } +@@ -1261,9 +1337,12 @@ + * Certain options are only valid in combination with others. + * Check it here so that they can be specified in any order. + */ +- if ((oflg && !uflg) || (kflg && !mflg)) ++ if (kflg && !mflg) + usage(); + ++ if (mflg && Mflg) /* the admin is not decided .. create or not ? */ ++ usage(); ++ + /* + * Either -D or username is required. Defaults can be set with -D + * for the -b, -e, -f, -g, -s options only. +@@ -1312,39 +1391,53 @@ + static void + close_files() + { +- if (! pw_close ()) { +- fprintf (stderr, "%s: cannot rewrite password file\n", Prog); +- fail_exit (1); +- } ++ if (! pw_close ()) { ++ fprintf (stderr, "%s: cannot rewrite password file\n", Prog); ++ fail_exit (1); ++ } + #ifdef SHADOWPWD +- if (is_shadow_pwd && ! spw_close ()) { +- fprintf (stderr, "%s: cannot rewrite shadow password file\n", +- Prog); +- fail_exit (1); ++ if (is_shadow_pwd && ! spw_close ()) { ++ fprintf (stderr, "%s: cannot rewrite shadow password file\n", ++ Prog); ++ fail_exit (1); ++ } ++#endif ++ if (do_grp_update) { ++ if (! gr_close ()) { ++ fprintf (stderr, "%s: cannot rewrite group file\n", ++ Prog); ++ fail_exit (1); + } +-#endif +- if (do_grp_update) { +- if (! gr_close ()) { +- fprintf (stderr, "%s: cannot rewrite group file\n", +- Prog); +- fail_exit (1); +- } +- (void) gr_unlock (); ++ (void) gr_unlock (); + #ifdef SHADOWGRP +- if (is_shadow_grp && ! sgr_close ()) { +- fprintf (stderr, "%s: cannot rewrite shadow group file\n", +- Prog); +- fail_exit (1); +- } +- if (is_shadow_grp) +- sgr_unlock (); +-#endif ++ if (is_shadow_grp && ! sgr_close ()) { ++ fprintf (stderr, "%s: cannot rewrite shadow group file\n", ++ Prog); ++ fail_exit (1); + } ++ if (is_shadow_grp) ++ sgr_unlock (); ++#endif ++ } + #ifdef SHADOWPWD +- if (is_shadow_pwd) +- spw_unlock (); ++ if (is_shadow_pwd) ++ spw_unlock (); + #endif +- (void) pw_unlock (); ++ (void) pw_unlock (); ++ if (! gr_close ()) { ++ fprintf (stderr, "%s: cannot rewrite group file\n", Prog); ++ fail_exit (10); ++ } ++ (void) gr_unlock (); ++#ifdef SHADOWGRP ++ if (is_shadow_grp && ! sgr_close ()) { ++ fprintf (stderr, "%s: cannot rewrite shadow group file\n", ++ Prog); ++ fail_exit (10); ++ } ++ if (is_shadow_grp) ++ sgr_unlock (); ++#endif /* SHADOWGRP */ + } + + /* +@@ -1353,27 +1446,47 @@ + * open_files() opens the two password files. + */ + +-static void +-open_files() ++static void open_files(void) + { +- if (!pw_lock_first()) { +- fprintf (stderr, "%s: unable to lock password file\n", Prog); +- exit (1); +- } +- if (! pw_open (O_RDWR)) { +- fprintf (stderr, "%s: unable to open password file\n", Prog); +- exit (1); +- } ++ if (!pw_lock_first()) { ++ fprintf (stderr, "%s: unable to lock password file\n", Prog); ++ exit (1); ++ } ++ if (! pw_open (O_RDWR)) { ++ fprintf (stderr, "%s: unable to open password file\n", Prog); ++ exit (1); ++ } + #ifdef SHADOWPWD +- if (is_shadow_pwd && ! spw_lock ()) { +- fprintf (stderr, "%s: cannot lock shadow password file\n", Prog); +- exit (1); +- } +- if (is_shadow_pwd && ! spw_open (O_RDWR)) { +- fprintf (stderr, "%s: cannot open shadow password file\n", Prog); +- exit (1); +- } +-#endif ++ if (is_shadow_pwd && ! spw_lock ()) { ++ fprintf (stderr, "%s: cannot lock shadow password file\n", Prog); ++ exit (1); ++ } ++ if (is_shadow_pwd && ! spw_open (O_RDWR)) { ++ fprintf (stderr, "%s: cannot open shadow password file\n", Prog); ++ exit (1); ++ } ++#endif ++ if (! gr_lock ()) { ++ fprintf (stderr, "%s: unable to lock group file\n", Prog); ++ exit (E_LOCKING); ++ } ++ if (! gr_open (O_RDWR)) { ++ fprintf (stderr, "%s: unable to open group file\n", Prog); ++ fail_exit (10); ++ } ++#ifdef SHADOWGRP ++ if (is_shadow_grp && ! sgr_lock ()) { ++ fprintf (stderr, "%s: unable to lock shadow group file\n", ++ Prog); ++ fail_exit (E_LOCKING); ++ } ++ if (is_shadow_grp && ! sgr_open (O_RDWR)) { ++ fprintf (stderr, "%s: unable to open shadow group file\n", ++ Prog); ++ fail_exit (10); ++ } ++#endif /* SHADOWGRP*/ ++ + } + + +@@ -1424,9 +1537,6 @@ + struct spwd spent; + #endif + +- if (! oflg) +- find_new_uid (); +- + #ifdef AUTH_METHODS + if (Aflg) { + convert_auth(user_auth, auth_arg); +@@ -1582,6 +1692,117 @@ + } + } + ++/* a fake something */ ++static char *empty_list = NULL; ++ ++/* ++ * new_grent - initialize the values in a group file entry ++ * ++ * new_grent() takes all of the values that have been entered and ++ * fills in a (struct group) with them. ++ */ ++ ++static void ++new_grent(grent) ++ struct group *grent; ++{ ++ bzero ((char *) grent, sizeof *grent); ++ grent->gr_name = user_name; ++ grent->gr_passwd = "x"; ++ grent->gr_gid = user_gid; ++ grent->gr_mem = &empty_list; ++} ++ ++#ifdef SHADOWGRP ++/* ++ * new_sgent - initialize the values in a shadow group file entry ++ * ++ * new_sgent() takes all of the values that have been entered and ++ * fills in a (struct sgrp) with them. ++ */ ++ ++static void ++new_sgent(sgent) ++ struct sgrp *sgent; ++{ ++ bzero ((char *) sgent, sizeof *sgent); ++ sgent->sg_name = user_name; ++ sgent->sg_passwd = "!"; ++ sgent->sg_adm = &empty_list; ++ sgent->sg_mem = &empty_list; ++} ++#endif /* SHADOWGRP */ ++ ++/* ++ * grp_update - add new group file entries ++ * ++ * grp_update() writes the new records to the group files. ++ */ ++ ++static void grp_add() ++{ ++ struct group grp; ++#ifdef SHADOWGRP ++ struct sgrp sgrp; ++#endif /* SHADOWGRP */ ++ ++ /* ++ * Create the initial entries for this new group. ++ */ ++ ++ new_grent (&grp); ++#ifdef SHADOWGRP ++ new_sgent (&sgrp); ++#endif /* SHADOWGRP */ ++ ++ /* ++ * Write out the new group file entry. ++ */ ++ ++ if (! gr_update (&grp)) { ++ fprintf (stderr, "%s: error adding new group entry\n", Prog); ++ fail_exit (10); ++ } ++#ifdef NDBM ++ ++ /* ++ * Update the DBM group file with the new entry as well. ++ */ ++ ++ if (gr_dbm_present() && ! gr_dbm_update (&grp)) { ++ fprintf (stderr, "%s: cannot add new dbm group entry\n", Prog); ++ fail_exit (10); ++ } ++ endgrent (); ++#endif /* NDBM */ ++ ++#ifdef SHADOWGRP ++ ++ /* ++ * Write out the new shadow group entries as well. ++ */ ++ ++ if (is_shadow_grp && ! sgr_update (&sgrp)) { ++ fprintf (stderr, "%s: error adding new group entry\n", Prog); ++ fail_exit (10); ++ } ++#ifdef NDBM ++ ++ /* ++ * Update the DBM group file with the new entry as well. ++ */ ++ ++ if (is_shadow_grp && sg_dbm_present() && ! sg_dbm_update (&sgrp)) { ++ fprintf (stderr, "%s: cannot add new dbm group entry\n", Prog); ++ fail_exit (10); ++ } ++ endsgent (); ++#endif /* NDBM */ ++#endif /* SHADOWGRP */ ++ SYSLOG((LOG_INFO, "new group: name=%s, gid=%d\n", ++ user_name, user_gid)); ++} ++ + /* + * main - useradd command + */ +@@ -1591,76 +1812,100 @@ + int argc; + char **argv; + { +- /* +- * Get my name so that I can use it to report errors. +- */ ++ /* ++ * Get my name so that I can use it to report errors. ++ */ + +- Prog = Basename(argv[0]); ++ Prog = Basename(argv[0]); + +- openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH); ++ openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH); + + #ifdef SHADOWPWD +- is_shadow_pwd = (access(SHADOW_FILE, 0) == 0); ++ is_shadow_pwd = (access(SHADOW_FILE, 0) == 0); + #endif + #ifdef SHADOWGRP +- is_shadow_grp = (access(SGROUP_FILE, 0) == 0); ++ is_shadow_grp = (access(SGROUP_FILE, 0) == 0); + #endif + +- /* +- * The open routines for the NDBM files don't use read-write +- * as the mode, so we have to clue them in. +- */ ++ /* ++ * The open routines for the NDBM files don't use read-write ++ * as the mode, so we have to clue them in. ++ */ + + #ifdef NDBM +- pw_dbm_mode = O_RDWR; ++ pw_dbm_mode = O_RDWR; + #ifdef SHADOWPWD +- sp_dbm_mode = O_RDWR; ++ sp_dbm_mode = O_RDWR; + #endif +- gr_dbm_mode = O_RDWR; ++ gr_dbm_mode = O_RDWR; + #ifdef SHADOWGRP +- sg_dbm_mode = O_RDWR; ++ sg_dbm_mode = O_RDWR; + #endif + #endif +- get_defaults(); ++ get_defaults(); + +- process_flags(argc, argv); ++ process_flags(argc, argv); + +- /* +- * See if we are messing with the defaults file, or creating +- * a new user. +- */ ++ if (!rflg) /* for system accounts defaults are ignored ++ * == do not create */ ++ if (getdef_bool("CREATE_HOME")) ++ mflg = 1; + +- if (Dflg) { +- if (gflg || bflg || fflg || eflg || sflg) +- exit (set_defaults () ? 1:0); ++ if (Mflg) /* absolutely sure that we do not create home dirs */ ++ mflg = 0; ++ /* ++ * See if we are messing with the defaults file, or creating ++ * a new user. ++ */ + +- show_defaults (); +- exit (0); +- } ++ if (Dflg) { ++ if (gflg || bflg || fflg || eflg || sflg) ++ exit (set_defaults () ? 1:0); + +- /* +- * Start with a quick check to see if the user exists. +- */ ++ show_defaults (); ++ exit (0); ++ } + +- if (getpwnam(user_name)) { +- fprintf(stderr, "%s: user %s exists\n", Prog, user_name); +- exit(E_NAME_IN_USE); +- } ++ /* ++ * Start with a quick check to see if the user exists. ++ */ + +- /* +- * Do the hard stuff - open the files, create the user entries, +- * create the home directory, then close and update the files. +- */ +- +- open_files (); ++ if (getpwnam(user_name)) { ++ if (!oflg) { ++ fprintf(stderr, "%s: user %s exists\n", Prog, user_name); ++ exit(E_NAME_IN_USE); ++ } else { ++ exit (E_SUCCESS); ++ } ++ } + +- usr_update (); ++ /* ++ * Do the hard stuff - open the files, create the user entries, ++ * create the home directory, then close and update the files. ++ */ ++ ++ open_files (); ++ ++ /* first, seek for a valid uid to use for this user. ++ * We do this because later we can use the uid we found as ++ * gid too ... --rh */ ++ if (! uflg) ++ find_new_uid (); ++ ++ /* do we have to add a group for that user ? */ ++ if (! (nflg || gflg)) { ++ find_new_gid(); ++ grp_add(); ++ } ++ ++ usr_update (); ++ ++ if (mflg) { ++ create_home (); ++ copy_tree (def_template, user_home, user_id, user_gid); ++ } ++ close_files (); + +- if (mflg) { +- create_home (); +- copy_tree (def_template, user_home, user_id, user_gid); +- } +- close_files (); +- exit(E_SUCCESS); +- /*NOTREACHED*/ ++ exit(E_SUCCESS); ++ /*NOTREACHED*/ + } +--- shadow-970616/src/groupadd.c.rh Thu May 1 19:07:11 1997 ++++ shadow-970616/src/groupadd.c Fri Dec 12 15:36:29 1997 +@@ -61,6 +61,11 @@ + oflg = 0, /* permit non-unique group ID to be specified with -g */ + gflg = 0; /* ID value for the new group */ + ++/* For adding "system" accounts */ ++static int system_flag = 0; ++static int force_flag = 0; ++#define MIN_GID 10 ++ + #ifdef NDBM + extern int gr_dbm_mode; + extern int sg_dbm_mode; +@@ -75,7 +80,7 @@ + static void + usage() + { +- fprintf (stderr, "usage: groupadd [-g gid [-o]] group\n"); ++ fprintf (stderr, "usage: groupadd [-g gid [-o]] [-r] [-f] group\n"); + exit (2); + } + +@@ -202,8 +207,13 @@ + const struct group *grp; + gid_t gid_min, gid_max; + +- gid_min = getdef_num("GID_MIN", 100); +- gid_max = getdef_num("GID_MAX", 60000); ++ if (!system_flag) { ++ gid_min = getdef_num("GID_MIN", 500); ++ gid_max = getdef_num("GID_MAX", 60000); ++ } else { ++ gid_min = MIN_GID; ++ gid_max = getdef_num("GID_MIN", 499); ++ } + + /* + * Start with some GID value if the user didn't provide us with +@@ -227,16 +237,34 @@ + while ((grp = getgrent())) { + #endif + if (strcmp(group_name, grp->gr_name) == 0) { ++ if (!force_flag) { + fprintf(stderr, "%s: name %s is not unique\n", + Prog, group_name); + fail_exit(9); ++ } else { ++ fail_exit(0); ++ } + } + if (gflg && group_id == grp->gr_gid) { ++ if (!force_flag) { + fprintf(stderr, "%s: gid %ld is not unique\n", + Prog, (long) group_id); + fail_exit(4); ++ } else { ++ /* we invalidate the gflg and search again */ ++ gflg = 0; ++ if (oflg) ++ oflg = 0; ++ /* now, start at the begining... */ ++#ifdef NO_GETGRENT ++ gr_rewind(); ++#else ++ setgrent(); ++#endif ++ continue; ++ } + } +- if (! gflg && grp->gr_gid >= group_id) { ++ if (!gflg && grp->gr_gid >= group_id) { + if (grp->gr_gid > gid_max) + continue; + group_id = grp->gr_gid + 1; +@@ -298,42 +326,49 @@ + process_flags(argc, argv) + int argc; + char **argv; +-{ +- extern int optind; +- extern char *optarg; +- char *end; +- int arg; ++ { ++ extern int optind; ++ extern char *optarg; ++ char *end; ++ int arg; + +- while ((arg = getopt (argc, argv, "og:")) != EOF) { ++ while ((arg = getopt (argc, argv, "og:rf")) != EOF) { + switch (arg) { +- case 'g': +- gflg++; +- if (! isdigit (optarg[0])) +- usage (); +- +- group_id = strtol (optarg, &end, 10); +- if (*end != '\0') { +- fprintf (stderr, "%s: invalid group %s\n", +- Prog, optarg); +- fail_exit (3); +- } +- break; +- case 'o': +- if (! gflg) +- usage (); +- +- oflg++; +- break; +- default: +- usage (); ++ case 'g': ++ gflg++; ++ if (! isdigit (optarg[0])) ++ usage (); ++ ++ group_id = strtol (optarg, &end, 10); ++ if (*end != '\0') { ++ fprintf (stderr, "%s: invalid group %s\n", ++ Prog, optarg); ++ fail_exit (3); ++ } ++ break; ++ case 'o': ++ if (! gflg) ++ usage (); ++ ++ oflg++; ++ break; ++ case 'r': /* "system" group */ ++ system_flag++; ++ break; ++ case 'f': /* "force" - don't exit with error if group already exist */ ++ force_flag++; ++ break; ++ ++ default: ++ usage (); + } +- } +- if (optind != argc - 1) ++ } ++ if (optind != argc - 1) + usage (); + +- group_name = argv[argc - 1]; +- check_new_name (); +-} ++ group_name = argv[argc - 1]; ++ check_new_name (); ++ } + + /* + * close_files - close all of the files that were opened +@@ -448,8 +483,12 @@ + */ + + if (getgrnam(group_name)) { ++ if ( !force_flag) { + fprintf (stderr, "%s: group %s exists\n", Prog, group_name); + exit(9); ++ } else { ++ exit(0); ++ } + } + + /* diff --git a/current/redhat/shadow-970616-utuser.patch b/current/redhat/shadow-970616-utuser.patch new file mode 100644 index 00000000..2c27cb25 --- /dev/null +++ b/current/redhat/shadow-970616-utuser.patch @@ -0,0 +1,12 @@ +--- shadow-970616/configure.in.ewt Thu Nov 13 16:43:25 1997 ++++ shadow-970616/configure.in Thu Nov 13 16:43:34 1997 +@@ -38,7 +38,8 @@ + AC_CHECK_HEADERS(gshadow.h shadow.h lastlog.h) + + AC_EGREP_HEADER(ut_host, utmp.h, AC_DEFINE(UT_HOST)) +-AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_name)) ++AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_user), ++ AC_EGREP_HEADER(ut_name, utmp.h, AC_DEFINE(UT_USER, ut_name))) + AC_EGREP_HEADER(ll_host, lastlog.h, AC_DEFINE(HAVE_LL_HOST)) + + dnl Checks for typedefs, structures, and compiler characteristics. diff --git a/current/redhat/shadow-970616.login.defs b/current/redhat/shadow-970616.login.defs new file mode 100644 index 00000000..6f578df7 --- /dev/null +++ b/current/redhat/shadow-970616.login.defs @@ -0,0 +1,57 @@ +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, MAIL_DIR takes precedence. +# QMAIL_DIR is for Qmail +# +#QMAIL_DIR Maildir +MAIL_DIR /var/spool/mail +#MAIL_FILE .mail + +# 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 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 500 +UID_MAX 60000 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 500 +GID_MAX 60000 + +# +# Require password before chfn/chsh can make any changes. +# +CHFN_AUTH yes + +# +# Don't allow users to change their "real name" using chfn. +# +CHFN_RESTRICT yes + +# +# 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 + +# +# If useradd should create home directories for users by default +# On RH systems, we do. This option is ORed with the -m flag on +# useradd command line. +# +CREATE_HOME yes + diff --git a/current/redhat/shadow-970616.useradd b/current/redhat/shadow-970616.useradd new file mode 100644 index 00000000..ae81dbb3 --- /dev/null +++ b/current/redhat/shadow-970616.useradd @@ -0,0 +1,7 @@ +# useradd defaults file +GROUP=100 +HOME=/home +INACTIVE=-1 +EXPIRE= +SHELL=/bin/bash +SKEL=/etc/skel diff --git a/current/redhat/shadow-utils-970616.spec b/current/redhat/shadow-utils-970616.spec new file mode 100644 index 00000000..4fc4dc1c --- /dev/null +++ b/current/redhat/shadow-utils-970616.spec @@ -0,0 +1,137 @@ +Summary: Shadow password file utilities for Linux +Name: shadow-utils +Version: 970616 +Release: 11 +Source0: ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/beta/shadow-970616.tar.gz +Source1: shadow-970616.login.defs +Source2: shadow-970616.useradd +Patch0: shadow-970616-rh.patch +Patch1: shadow-970616-utuser.patch +Patch2: shadow-970616-glibc.patch +Patch3: shadow-970616-fix.patch +Copyright: BSD +Group: Utilities/System +BuildRoot: /var/tmp/shadow-utils +Obsoletes: adduser + +%changelog +* Tue Dec 30 1997 Cristian Gafton +- updated the spec file +- updated the patch so that new accounts created on shadowed system won't + confuse pam_pwdb anymore ('!!' default password instead on '!') +- fixed a bug that made useradd -G segfault +- the check for the ut_user is now patched into configure + +* Thu Nov 13 1997 Erik Troan +- added patch for XOPEN oddities in glibc headers +- check for ut_user before checking for ut_name -- this works around some + confusion on glibc 2.1 due to the utmpx header not defining the ut_name + compatibility stuff. I used a gross sed hack here because I couldn't make + automake work properly on the sparc (this could be a glibc 2.0.99 problem + though). The utuser patch works fine, but I don't apply it. +- sleep after running autoconf + +* Thu Nov 06 1997 Cristian Gafton +- added forgot lastlog command to the spec file + +* Mon Oct 26 1997 Cristian Gafton +- obsoletes adduser + +* Thu Oct 23 1997 Cristian Gafton +- modified groupadd; updated the patch + +* Fri Sep 12 1997 Cristian Gafton +- updated to 970616 +- changed useradd to meet RH specs +- fixed some bugs + +* Tue Jun 17 1997 Erik Troan +- built against glibc + +%description +This package includes the programs necessary to convert standard +UNIX password files to the shadow password format, as well as +programs for command-line management of the user's accounts. + - 'pwconv' converts everything to the shadow password format. + - 'pwunconv' unconverts from shadow passwords, generating a file + in the current directory called npasswd that is a standard UNIX + password file. + - 'pwck' checks the integrity of the password and shadow files. + - 'lastlog' prints out the last login times of all users. + - 'useradd', 'userdel' and 'usermod' for accounts management. + - 'groupadd', 'groupdel' and 'groupmod' for group management. + +A number of man pages are also included that relate to these utilities, +and shadow passwords in general. + +%prep +# This is just a few of the core utilities from the shadow suite... +# packaged up for use w/PAM +%setup -n shadow-970616 +%patch -p1 -b .rh +#%patch1 -p1 -b .utname +%patch2 -p1 -b .xopen +%patch3 -p1 -b .fix + +%build +autoheader +autoconf +sleep 2 +CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr +make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/usr +make install prefix=/$RPM_BUILD_ROOT/usr +mkdir -p $RPM_BUILD_ROOT/etc/default +install -m 0600 -o root $RPM_SOURCE_DIR/shadow-970616.useradd $RPM_BUILD_ROOT/etc/default/useradd +install -m 0644 -o root $RPM_SOURCE_DIR/shadow-970616.login.defs $RPM_BUILD_ROOT/etc/login.defs +install -m 0500 -o root src/pwconv $RPM_BUILD_ROOT/usr/sbin +install -m 0500 -o root src/pwunconv $RPM_BUILD_ROOT/usr/sbin +ln -s pwconv $RPM_BUILD_ROOT/usr/sbin/pwconv5 +install -m 0644 -o root man/pw*conv.8 $RPM_BUILD_ROOT/usr/man/man8 +ln -s pwconv.8 $RPM_BUILD_ROOT/usr/man/man8/pwconv5.8 +ln -s useradd $RPM_BUILD_ROOT/usr/sbin/adduser +ln -s useradd.8 $RPM_BUILD_ROOT/usr/man/man8/adduser.8 + +%files +%doc doc/ANNOUNCE doc/CHANGES doc/HOWTO +%doc doc/LICENSE doc/README doc/README.linux +%dir /etc/default +/usr/sbin/adduser +/usr/sbin/useradd +/usr/sbin/usermod +/usr/sbin/userdel +/usr/sbin/groupadd +/usr/sbin/groupdel +/usr/sbin/groupmod +/usr/sbin/grpck +/usr/sbin/pwck +/usr/bin/chage +/usr/bin/gpasswd +/usr/sbin/lastlog +# /usr/sbin/vipw +/usr/sbin/chpasswd +/usr/sbin/newusers +/usr/sbin/pw*conv* +/usr/man/man1/chage.1 +/usr/man/man1/gpasswd.1 +/usr/man/man3/shadow.3 +/usr/man/man5/shadow.5 +/usr/man/man8/adduser.8 +/usr/man/man8/chpasswd.8 +/usr/man/man8/group*.8 +/usr/man/man8/user*.8 +/usr/man/man8/pwck.8 +/usr/man/man8/grpck.8 +/usr/man/man8/newusers.8 +# /usr/man/man8/shadowconfig.8 +/usr/man/man8/pw*conv*.8 +# /usr/man/man8/vipw.8 +/usr/man/man8/lastlog.8 +%config /etc/login.defs +%config /etc/default/useradd + +%clean +rm -rf $RPM_BUILD_ROOT diff --git a/current/redhat/shadow-utils.spec.in b/current/redhat/shadow-utils.spec.in new file mode 100644 index 00000000..017100bf --- /dev/null +++ b/current/redhat/shadow-utils.spec.in @@ -0,0 +1,154 @@ +# shadow-utils.spec generated automatically from shadow-utils.spec.in +# $Id: shadow-utils.spec.in,v 1.3 2000/09/02 18:40:43 marekm Exp $ + +# FIXME - this is out of date, please update for current Red Hat + +Summary: Shadow password file utilities for Linux +Name: shadow-utils +Version: @VERSION@ +Release: 1 +Copyright: Free +Group: Utilities/System +Source: ftp://ftp.ists.pwr.wroc.pl/pub/linux/shadow/shadow-@VERSION@.tar.gz +BuildRoot: /var/tmp/shadow-utils +Packager: Timo Karjalainen +# Obsoletes: adduser + +%description +This package includes the programs necessary to convert traditional +V7 UNIX password files to the SVR4 shadow password format and additional +tools to work with shadow passwords. + - 'pwconv' converts everything to the shadow password format. + - 'pwunconv' converts back to non-shadow passwords. + - 'pwck' checks the integrity of the password and shadow files. + - 'lastlog' prints out the last login times of all users. + - 'useradd', 'userdel', 'usermod' to manage user accounts. + - 'groupadd', 'groupdel', 'groupmod' to manage groups. + +A number of man pages are also included that relate to these utilities, +and shadow passwords in general. + +%changelog + +* Sun Dec 14 1997 Marek Michalkiewicz + +- Lots of changes, see doc/CHANGES for more details + +* Sun Jun 08 1997 Timo Karjalainen + +- Initial release + +%prep +# This is just a few of the core utilities from the shadow suite... +# packaged up for use w/PAM +%setup -n shadow-@VERSION@ + +%build +# shared lib support is untested, so... +CFLAGS="$RPM_OPT_FLAGS" ./configure --disable-shared --prefix=/usr --exec-prefix=/usr +make + +%install +if [ -d $RPM_BUILD_ROOT ] ; then + rm -rf $RPM_BUILD_ROOT +fi +mkdir -p $RPM_BUILD_ROOT/usr +# neato trick, heh ? :-) +./configure --prefix=$RPM_BUILD_ROOT/usr +make install +mkdir -p $RPM_BUILD_ROOT/etc/default + +# FIXME +#install -m 0600 -o root $RPM_SOURCE_DIR/shadow-970616.useradd $RPM_BUILD_ROOT/etc/default/useradd +#install -m 0644 -o root $RPM_SOURCE_DIR/shadow-970616.login.defs $RPM_BUILD_ROOT/etc/login.defs +#ln -s useradd $RPM_BUILD_ROOT/usr/sbin/adduser +#ln -s useradd.8 $RPM_BUILD_ROOT/usr/man/man8/adduser.8 + +#make prefix=$RPM_BUILD_ROOT/usr exec_prefix=$RPM_BUILD_ROOT/usr install +#touch $RPM_BUILD_ROOT/etc/{login.defs,default/useradd} +#chmod 640 $RPM_BUILD_ROOT/etc/{login.defs,default/useradd} +#chown root $RPM_BUILD_ROOT/etc/{login.defs,default/useradd} +#chgrp root $RPM_BUILD_ROOT/etc/{login.defs,default/useradd} + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%doc doc/ANNOUNCE doc/CHANGES doc/HOWTO +%doc doc/LICENSE doc/README doc/README.linux +%dir /etc/default +%config /etc/default/useradd +# %config /etc/limits +# %config /etc/login.access +%config /etc/login.defs +# %config /etc/limits +# %config /etc/porttime +# %config /etc/securetty +# %config /etc/shells +# %config /etc/suauth +# /bin/login +# /bin/su +/usr/bin/chage +# /usr/bin/chfn +# /usr/bin/chsh +# /usr/bin/expiry +# /usr/bin/faillog +/usr/bin/gpasswd +/usr/bin/lastlog +# /usr/bin/newgrp +# /usr/bin/passwd +# /usr/bin/sg +/usr/man/man1/chage.1 +# /usr/man/man1/chfn.1 +# /usr/man/man1/chsh.1 +/usr/man/man1/gpasswd.1 +# /usr/man/man1/login.1 +# /usr/man/man1/passwd.1 +# /usr/man/man1/sg.1 +# /usr/man/man1/su.1 +/usr/man/man3/shadow.3 +# /usr/man/man5/faillog.5 +# /usr/man/man5/limits.5 +# /usr/man/man5/login.access.5 +# /usr/man/man5/login.defs.5 +# /usr/man/man5/passwd.5 +# /usr/man/man5/porttime.5 +/usr/man/man5/shadow.5 +# /usr/man/man5/suauth.5 +# /usr/man/man8/adduser.8 +/usr/man/man8/chpasswd.8 +# /usr/man/man8/faillog.8 +/usr/man/man8/groupadd.8 +/usr/man/man8/groupdel.8 +/usr/man/man8/groupmod.8 +/usr/man/man8/grpck.8 +/usr/man/man8/lastlog.8 +# /usr/man/man8/logoutd.8 +/usr/man/man8/newusers.8 +/usr/man/man8/pwck.8 +/usr/man/man8/pwconv.8 +# /usr/man/man8/shadowconfig.8 +/usr/man/man8/useradd.8 +/usr/man/man8/userdel.8 +/usr/man/man8/usermod.8 +# /usr/man/man8/vigr.8 +# /usr/man/man8/vipw.8 +# /usr/sbin/adduser +/usr/sbin/chpasswd +/usr/sbin/groupadd +/usr/sbin/groupdel +/usr/sbin/groupmod +/usr/sbin/grpck +/usr/sbin/grpconv +/usr/sbin/grpunconv +# /usr/sbin/logoutd +/usr/sbin/newusers +/usr/sbin/pwck +/usr/sbin/pwconv +/usr/sbin/pwunconv +# /usr/sbin/shadowconfig +/usr/sbin/useradd +/usr/sbin/userdel +/usr/sbin/usermod +# /usr/sbin/vigr +# /usr/sbin/vipw diff --git a/current/src/Makefile.am b/current/src/Makefile.am new file mode 100644 index 00000000..db8203fd --- /dev/null +++ b/current/src/Makefile.am @@ -0,0 +1,90 @@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +# Watch out; note the difference between prefix & exec_prefix. +# Normally configure sets exec_prefix to root when prefix is /usr. + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +ubindir = ${prefix}/bin +usbindir = ${prefix}/sbin +localedir = $(datadir)/locale + +noinst_HEADERS = patchlevel.h + +DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@ + +# XXX why are login and su in /bin anyway (other than for +# historical reasons)? +# +# if the system is screwed so badly that it can't mount /usr, +# you can (hopefully) boot single user, and then you're root +# so you don't need these programs for recovery. +# +# also /lib/libshadow.so.x.xx (if any) could be moved to /usr/lib +# and installation would be much simpler (just two directories, +# $prefix/bin and $prefix/sbin, no install-data hacks...) + +bin_PROGRAMS = login \ + su +ubin_PROGRAMS = faillog lastlog \ + chage chfn chsh expiry gpasswd newgrp passwd +usbin_PROGRAMS = chpasswd dpasswd groupadd groupdel groupmod \ + logoutd mkpasswd newusers \ + useradd userdel usermod grpck pwck vipw \ + grpconv grpunconv pwconv pwunconv + +EXTRA_DIST = shadowconfig.sh + +# id and groups are from gnu, sulogin from sysvinit, +# also suid programs are installed by hand. +# XXX installation by hand breaks libtool shared lib support +# (the wrapper scripts get installed instead of binaries), +# so we now chmod the programs by hand after normal installation. + +suidbins = su +suidubins = chage chfn chsh expiry gpasswd newgrp passwd + +install-exec-hook: + for i in $(suidbins); do \ + chmod 4755 $(DESTDIR)$(bindir)/$$i; \ + done + +install-data-hook: + for i in $(suidubins); do \ + chmod 4755 $(DESTDIR)$(ubindir)/$$i; \ + done + rm -f $(DESTDIR)$(ubindir)/sg + ln -s newgrp $(DESTDIR)$(ubindir)/sg + +noinst_PROGRAMS = groups id sulogin + +#install-exec-local: +# $(mkinstalldirs) $(bindir) +# for i in $(suidbins); do \ +# $(INSTALL) -m 4755 $$i $(bindir); \ +# done +# $(mkinstalldirs) $(ubindir) +# for i in $(suidubins); do \ +# $(INSTALL) -m 4755 $$i $(ubindir); \ +# done +# rm -f $(bindir)/sg +# ln -s $(ubindir)/newgrp $(bindir)/sg +# +#noinst_PROGRAMS = id groups \ +# su \ +# chage chfn chsh expiry gpasswd newgrp passwd \ +# sulogin + +shlibs = ../lib/libshadow.la +# With glibc2, almost all programs need libcrypt for some reason, +# even those that don't actually use crypt(). +LDADD = ${shlibs} ../libmisc/libmisc.a ../lib/libshadow.a @INTLLIBS@ @LIBCRYPT@ @LIBTCFS@ @LIBSKEY@ @LIBMD@ +INCLUDES = -I${top_srcdir}/lib -I$(top_srcdir)/libmisc + +chfn_LDADD = ${LDADD} @LIBPAM@ +chsh_LDADD = ${LDADD} @LIBPAM@ +login_LDADD = ${LDADD} @LIBPAM@ +passwd_LDADD = ${LDADD} @LIBCRACK@ @LIBPAM@ +su_LDADD = ${LDADD} @LIBPAM@ + diff --git a/current/src/Makefile.in b/current/src/Makefile.in new file mode 100644 index 00000000..773a3b3c --- /dev/null +++ b/current/src/Makefile.in @@ -0,0 +1,895 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPP = @CPP@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBCRACK = @LIBCRACK@ +LIBCRYPT = @LIBCRYPT@ +LIBMD = @LIBMD@ +LIBPAM = @LIBPAM@ +LIBSKEY = @LIBSKEY@ +LIBTCFS = @LIBTCFS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +U = @U@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +YACC = @YACC@ +l = @l@ + +AUTOMAKE_OPTIONS = 1.0 foreign + +# Watch out; note the difference between prefix & exec_prefix. +# Normally configure sets exec_prefix to root when prefix is /usr. + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +ubindir = ${prefix}/bin +usbindir = ${prefix}/sbin +localedir = $(datadir)/locale + +noinst_HEADERS = patchlevel.h + +DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@ + +# XXX why are login and su in /bin anyway (other than for +# historical reasons)? +# +# if the system is screwed so badly that it can't mount /usr, +# you can (hopefully) boot single user, and then you're root +# so you don't need these programs for recovery. +# +# also /lib/libshadow.so.x.xx (if any) could be moved to /usr/lib +# and installation would be much simpler (just two directories, +# $prefix/bin and $prefix/sbin, no install-data hacks...) + +bin_PROGRAMS = login su + +ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd + +usbin_PROGRAMS = chpasswd dpasswd groupadd groupdel groupmod logoutd mkpasswd newusers useradd userdel usermod grpck pwck vipw grpconv grpunconv pwconv pwunconv + + +EXTRA_DIST = shadowconfig.sh + +# id and groups are from gnu, sulogin from sysvinit, +# also suid programs are installed by hand. +# XXX installation by hand breaks libtool shared lib support +# (the wrapper scripts get installed instead of binaries), +# so we now chmod the programs by hand after normal installation. + +suidbins = su +suidubins = chage chfn chsh expiry gpasswd newgrp passwd + +noinst_PROGRAMS = groups id sulogin + +#install-exec-local: +# $(mkinstalldirs) $(bindir) +# for i in $(suidbins); do \ +# $(INSTALL) -m 4755 $$i $(bindir); \ +# done +# $(mkinstalldirs) $(ubindir) +# for i in $(suidubins); do \ +# $(INSTALL) -m 4755 $$i $(ubindir); \ +# done +# rm -f $(bindir)/sg +# ln -s $(ubindir)/newgrp $(bindir)/sg +# +#noinst_PROGRAMS = id groups \ +# su \ +# chage chfn chsh expiry gpasswd newgrp passwd \ +# sulogin + +shlibs = ../lib/libshadow.la +# With glibc2, almost all programs need libcrypt for some reason, +# even those that don't actually use crypt(). +LDADD = ${shlibs} ../libmisc/libmisc.a ../lib/libshadow.a @INTLLIBS@ @LIBCRYPT@ @LIBTCFS@ @LIBSKEY@ @LIBMD@ +INCLUDES = -I${top_srcdir}/lib -I$(top_srcdir)/libmisc + +chfn_LDADD = ${LDADD} @LIBPAM@ +chsh_LDADD = ${LDADD} @LIBPAM@ +login_LDADD = ${LDADD} @LIBPAM@ +passwd_LDADD = ${LDADD} @LIBCRACK@ @LIBPAM@ +su_LDADD = ${LDADD} @LIBPAM@ +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(ubin_PROGRAMS) \ +$(usbin_PROGRAMS) + +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +login_SOURCES = login.c +login_OBJECTS = login.o +login_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +login_LDFLAGS = +su_SOURCES = su.c +su_OBJECTS = su.o +su_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +su_LDFLAGS = +groups_SOURCES = groups.c +groups_OBJECTS = groups.o +groups_LDADD = $(LDADD) +groups_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +groups_LDFLAGS = +id_SOURCES = id.c +id_OBJECTS = id.o +id_LDADD = $(LDADD) +id_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +id_LDFLAGS = +sulogin_SOURCES = sulogin.c +sulogin_OBJECTS = sulogin.o +sulogin_LDADD = $(LDADD) +sulogin_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +sulogin_LDFLAGS = +faillog_SOURCES = faillog.c +faillog_OBJECTS = faillog.o +faillog_LDADD = $(LDADD) +faillog_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +faillog_LDFLAGS = +lastlog_SOURCES = lastlog.c +lastlog_OBJECTS = lastlog.o +lastlog_LDADD = $(LDADD) +lastlog_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +lastlog_LDFLAGS = +chage_SOURCES = chage.c +chage_OBJECTS = chage.o +chage_LDADD = $(LDADD) +chage_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +chage_LDFLAGS = +chfn_SOURCES = chfn.c +chfn_OBJECTS = chfn.o +chfn_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +chfn_LDFLAGS = +chsh_SOURCES = chsh.c +chsh_OBJECTS = chsh.o +chsh_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +chsh_LDFLAGS = +expiry_SOURCES = expiry.c +expiry_OBJECTS = expiry.o +expiry_LDADD = $(LDADD) +expiry_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +expiry_LDFLAGS = +gpasswd_SOURCES = gpasswd.c +gpasswd_OBJECTS = gpasswd.o +gpasswd_LDADD = $(LDADD) +gpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +gpasswd_LDFLAGS = +newgrp_SOURCES = newgrp.c +newgrp_OBJECTS = newgrp.o +newgrp_LDADD = $(LDADD) +newgrp_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +newgrp_LDFLAGS = +passwd_SOURCES = passwd.c +passwd_OBJECTS = passwd.o +passwd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +passwd_LDFLAGS = +chpasswd_SOURCES = chpasswd.c +chpasswd_OBJECTS = chpasswd.o +chpasswd_LDADD = $(LDADD) +chpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +chpasswd_LDFLAGS = +dpasswd_SOURCES = dpasswd.c +dpasswd_OBJECTS = dpasswd.o +dpasswd_LDADD = $(LDADD) +dpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +dpasswd_LDFLAGS = +groupadd_SOURCES = groupadd.c +groupadd_OBJECTS = groupadd.o +groupadd_LDADD = $(LDADD) +groupadd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +groupadd_LDFLAGS = +groupdel_SOURCES = groupdel.c +groupdel_OBJECTS = groupdel.o +groupdel_LDADD = $(LDADD) +groupdel_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +groupdel_LDFLAGS = +groupmod_SOURCES = groupmod.c +groupmod_OBJECTS = groupmod.o +groupmod_LDADD = $(LDADD) +groupmod_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +groupmod_LDFLAGS = +logoutd_SOURCES = logoutd.c +logoutd_OBJECTS = logoutd.o +logoutd_LDADD = $(LDADD) +logoutd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +logoutd_LDFLAGS = +mkpasswd_SOURCES = mkpasswd.c +mkpasswd_OBJECTS = mkpasswd.o +mkpasswd_LDADD = $(LDADD) +mkpasswd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +mkpasswd_LDFLAGS = +newusers_SOURCES = newusers.c +newusers_OBJECTS = newusers.o +newusers_LDADD = $(LDADD) +newusers_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +newusers_LDFLAGS = +useradd_SOURCES = useradd.c +useradd_OBJECTS = useradd.o +useradd_LDADD = $(LDADD) +useradd_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +useradd_LDFLAGS = +userdel_SOURCES = userdel.c +userdel_OBJECTS = userdel.o +userdel_LDADD = $(LDADD) +userdel_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +userdel_LDFLAGS = +usermod_SOURCES = usermod.c +usermod_OBJECTS = usermod.o +usermod_LDADD = $(LDADD) +usermod_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +usermod_LDFLAGS = +grpck_SOURCES = grpck.c +grpck_OBJECTS = grpck.o +grpck_LDADD = $(LDADD) +grpck_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +grpck_LDFLAGS = +pwck_SOURCES = pwck.c +pwck_OBJECTS = pwck.o +pwck_LDADD = $(LDADD) +pwck_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +pwck_LDFLAGS = +vipw_SOURCES = vipw.c +vipw_OBJECTS = vipw.o +vipw_LDADD = $(LDADD) +vipw_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +vipw_LDFLAGS = +grpconv_SOURCES = grpconv.c +grpconv_OBJECTS = grpconv.o +grpconv_LDADD = $(LDADD) +grpconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +grpconv_LDFLAGS = +grpunconv_SOURCES = grpunconv.c +grpunconv_OBJECTS = grpunconv.o +grpunconv_LDADD = $(LDADD) +grpunconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +grpunconv_LDFLAGS = +pwconv_SOURCES = pwconv.c +pwconv_OBJECTS = pwconv.o +pwconv_LDADD = $(LDADD) +pwconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +pwconv_LDFLAGS = +pwunconv_SOURCES = pwunconv.c +pwunconv_OBJECTS = pwunconv.o +pwunconv_LDADD = $(LDADD) +pwunconv_DEPENDENCIES = ../lib/libshadow.la ../libmisc/libmisc.a \ +../lib/libshadow.a +pwunconv_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = login.c su.c groups.c id.c sulogin.c faillog.c lastlog.c chage.c chfn.c chsh.c expiry.c gpasswd.c newgrp.c passwd.c chpasswd.c dpasswd.c groupadd.c groupdel.c groupmod.c logoutd.c mkpasswd.c newusers.c useradd.c userdel.c usermod.c grpck.c pwck.c vipw.c grpconv.c grpunconv.c pwconv.c pwunconv.c +OBJECTS = login.o su.o groups.o id.o sulogin.o faillog.o lastlog.o chage.o chfn.o chsh.o expiry.o gpasswd.o newgrp.o passwd.o chpasswd.o dpasswd.o groupadd.o groupdel.o groupmod.o logoutd.o mkpasswd.o newusers.o useradd.o userdel.o usermod.o grpck.o pwck.o vipw.o grpconv.o grpunconv.o pwconv.o pwunconv.o + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +mostlyclean-ubinPROGRAMS: + +clean-ubinPROGRAMS: + -test -z "$(ubin_PROGRAMS)" || rm -f $(ubin_PROGRAMS) + +distclean-ubinPROGRAMS: + +maintainer-clean-ubinPROGRAMS: + +install-ubinPROGRAMS: $(ubin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(ubindir) + @list='$(ubin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(ubindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(ubindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-ubinPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(ubin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(ubindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +mostlyclean-usbinPROGRAMS: + +clean-usbinPROGRAMS: + -test -z "$(usbin_PROGRAMS)" || rm -f $(usbin_PROGRAMS) + +distclean-usbinPROGRAMS: + +maintainer-clean-usbinPROGRAMS: + +install-usbinPROGRAMS: $(usbin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(usbindir) + @list='$(usbin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(usbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(usbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-usbinPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(usbin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(usbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +login: $(login_OBJECTS) $(login_DEPENDENCIES) + @rm -f login + $(LINK) $(login_LDFLAGS) $(login_OBJECTS) $(login_LDADD) $(LIBS) + +su: $(su_OBJECTS) $(su_DEPENDENCIES) + @rm -f su + $(LINK) $(su_LDFLAGS) $(su_OBJECTS) $(su_LDADD) $(LIBS) + +groups: $(groups_OBJECTS) $(groups_DEPENDENCIES) + @rm -f groups + $(LINK) $(groups_LDFLAGS) $(groups_OBJECTS) $(groups_LDADD) $(LIBS) + +id: $(id_OBJECTS) $(id_DEPENDENCIES) + @rm -f id + $(LINK) $(id_LDFLAGS) $(id_OBJECTS) $(id_LDADD) $(LIBS) + +sulogin: $(sulogin_OBJECTS) $(sulogin_DEPENDENCIES) + @rm -f sulogin + $(LINK) $(sulogin_LDFLAGS) $(sulogin_OBJECTS) $(sulogin_LDADD) $(LIBS) + +faillog: $(faillog_OBJECTS) $(faillog_DEPENDENCIES) + @rm -f faillog + $(LINK) $(faillog_LDFLAGS) $(faillog_OBJECTS) $(faillog_LDADD) $(LIBS) + +lastlog: $(lastlog_OBJECTS) $(lastlog_DEPENDENCIES) + @rm -f lastlog + $(LINK) $(lastlog_LDFLAGS) $(lastlog_OBJECTS) $(lastlog_LDADD) $(LIBS) + +chage: $(chage_OBJECTS) $(chage_DEPENDENCIES) + @rm -f chage + $(LINK) $(chage_LDFLAGS) $(chage_OBJECTS) $(chage_LDADD) $(LIBS) + +chfn: $(chfn_OBJECTS) $(chfn_DEPENDENCIES) + @rm -f chfn + $(LINK) $(chfn_LDFLAGS) $(chfn_OBJECTS) $(chfn_LDADD) $(LIBS) + +chsh: $(chsh_OBJECTS) $(chsh_DEPENDENCIES) + @rm -f chsh + $(LINK) $(chsh_LDFLAGS) $(chsh_OBJECTS) $(chsh_LDADD) $(LIBS) + +expiry: $(expiry_OBJECTS) $(expiry_DEPENDENCIES) + @rm -f expiry + $(LINK) $(expiry_LDFLAGS) $(expiry_OBJECTS) $(expiry_LDADD) $(LIBS) + +gpasswd: $(gpasswd_OBJECTS) $(gpasswd_DEPENDENCIES) + @rm -f gpasswd + $(LINK) $(gpasswd_LDFLAGS) $(gpasswd_OBJECTS) $(gpasswd_LDADD) $(LIBS) + +newgrp: $(newgrp_OBJECTS) $(newgrp_DEPENDENCIES) + @rm -f newgrp + $(LINK) $(newgrp_LDFLAGS) $(newgrp_OBJECTS) $(newgrp_LDADD) $(LIBS) + +passwd: $(passwd_OBJECTS) $(passwd_DEPENDENCIES) + @rm -f passwd + $(LINK) $(passwd_LDFLAGS) $(passwd_OBJECTS) $(passwd_LDADD) $(LIBS) + +chpasswd: $(chpasswd_OBJECTS) $(chpasswd_DEPENDENCIES) + @rm -f chpasswd + $(LINK) $(chpasswd_LDFLAGS) $(chpasswd_OBJECTS) $(chpasswd_LDADD) $(LIBS) + +dpasswd: $(dpasswd_OBJECTS) $(dpasswd_DEPENDENCIES) + @rm -f dpasswd + $(LINK) $(dpasswd_LDFLAGS) $(dpasswd_OBJECTS) $(dpasswd_LDADD) $(LIBS) + +groupadd: $(groupadd_OBJECTS) $(groupadd_DEPENDENCIES) + @rm -f groupadd + $(LINK) $(groupadd_LDFLAGS) $(groupadd_OBJECTS) $(groupadd_LDADD) $(LIBS) + +groupdel: $(groupdel_OBJECTS) $(groupdel_DEPENDENCIES) + @rm -f groupdel + $(LINK) $(groupdel_LDFLAGS) $(groupdel_OBJECTS) $(groupdel_LDADD) $(LIBS) + +groupmod: $(groupmod_OBJECTS) $(groupmod_DEPENDENCIES) + @rm -f groupmod + $(LINK) $(groupmod_LDFLAGS) $(groupmod_OBJECTS) $(groupmod_LDADD) $(LIBS) + +logoutd: $(logoutd_OBJECTS) $(logoutd_DEPENDENCIES) + @rm -f logoutd + $(LINK) $(logoutd_LDFLAGS) $(logoutd_OBJECTS) $(logoutd_LDADD) $(LIBS) + +mkpasswd: $(mkpasswd_OBJECTS) $(mkpasswd_DEPENDENCIES) + @rm -f mkpasswd + $(LINK) $(mkpasswd_LDFLAGS) $(mkpasswd_OBJECTS) $(mkpasswd_LDADD) $(LIBS) + +newusers: $(newusers_OBJECTS) $(newusers_DEPENDENCIES) + @rm -f newusers + $(LINK) $(newusers_LDFLAGS) $(newusers_OBJECTS) $(newusers_LDADD) $(LIBS) + +useradd: $(useradd_OBJECTS) $(useradd_DEPENDENCIES) + @rm -f useradd + $(LINK) $(useradd_LDFLAGS) $(useradd_OBJECTS) $(useradd_LDADD) $(LIBS) + +userdel: $(userdel_OBJECTS) $(userdel_DEPENDENCIES) + @rm -f userdel + $(LINK) $(userdel_LDFLAGS) $(userdel_OBJECTS) $(userdel_LDADD) $(LIBS) + +usermod: $(usermod_OBJECTS) $(usermod_DEPENDENCIES) + @rm -f usermod + $(LINK) $(usermod_LDFLAGS) $(usermod_OBJECTS) $(usermod_LDADD) $(LIBS) + +grpck: $(grpck_OBJECTS) $(grpck_DEPENDENCIES) + @rm -f grpck + $(LINK) $(grpck_LDFLAGS) $(grpck_OBJECTS) $(grpck_LDADD) $(LIBS) + +pwck: $(pwck_OBJECTS) $(pwck_DEPENDENCIES) + @rm -f pwck + $(LINK) $(pwck_LDFLAGS) $(pwck_OBJECTS) $(pwck_LDADD) $(LIBS) + +vipw: $(vipw_OBJECTS) $(vipw_DEPENDENCIES) + @rm -f vipw + $(LINK) $(vipw_LDFLAGS) $(vipw_OBJECTS) $(vipw_LDADD) $(LIBS) + +grpconv: $(grpconv_OBJECTS) $(grpconv_DEPENDENCIES) + @rm -f grpconv + $(LINK) $(grpconv_LDFLAGS) $(grpconv_OBJECTS) $(grpconv_LDADD) $(LIBS) + +grpunconv: $(grpunconv_OBJECTS) $(grpunconv_DEPENDENCIES) + @rm -f grpunconv + $(LINK) $(grpunconv_LDFLAGS) $(grpunconv_OBJECTS) $(grpunconv_LDADD) $(LIBS) + +pwconv: $(pwconv_OBJECTS) $(pwconv_DEPENDENCIES) + @rm -f pwconv + $(LINK) $(pwconv_LDFLAGS) $(pwconv_OBJECTS) $(pwconv_LDADD) $(LIBS) + +pwunconv: $(pwunconv_OBJECTS) $(pwunconv_DEPENDENCIES) + @rm -f pwunconv + $(LINK) $(pwunconv_LDFLAGS) $(pwunconv_OBJECTS) $(pwunconv_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +chage.o: chage.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \ + ../lib/shadowio.h +chfn.o: chfn.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \ + ../lib/getdef.h ../lib/pwauth.h +chpasswd.o: chpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \ + ../lib/shadowio.h +chsh.o: chsh.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \ + ../lib/getdef.h ../lib/pwauth.h +dpasswd.o: dpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/dialup.h +expiry.o: expiry.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +faillog.o: faillog.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/faillog.h +gpasswd.o: gpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/groupio.h \ + ../lib/sgroupio.h +groupadd.o: groupadd.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/prototypes.h ../libmisc/chkname.h \ + ../lib/getdef.h ../lib/groupio.h ../lib/sgroupio.h +groupdel.o: groupdel.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/groupio.h \ + ../lib/sgroupio.h +groupmod.o: groupmod.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \ + ../lib/groupio.h ../lib/sgroupio.h +groups.o: groups.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +grpck.o: grpck.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \ + ../lib/commonio.h ../lib/groupio.h ../lib/sgroupio.h +grpconv.o: grpconv.c ../config.h ../lib/prototypes.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/groupio.h ../lib/sgroupio.h \ + ../lib/rcsid.h +grpunconv.o: grpunconv.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/groupio.h \ + ../lib/sgroupio.h +id.o: id.c ../config.h ../lib/rcsid.h ../lib/defines.h ../lib/gshadow_.h +lastlog.o: lastlog.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +login.o: login.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/faillog.h \ + ../libmisc/failure.h ../lib/pwauth.h ../lib/getdef.h \ + ../lib/dialchk.h +logoutd.o: logoutd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +mkpasswd.o: mkpasswd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h +newgrp.o: newgrp.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h +newusers.o: newusers.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h \ + ../lib/pwio.h ../lib/groupio.h ../lib/shadowio.h +passwd.o: passwd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwauth.h \ + ../lib/shadowio.h ../lib/pwio.h ../lib/getdef.h +pwck.o: pwck.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \ + ../lib/commonio.h ../lib/pwio.h ../lib/shadowio.h +pwconv.o: pwconv.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwio.h \ + ../lib/shadowio.h ../lib/getdef.h +pwunconv.o: pwunconv.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/prototypes.h ../lib/pwio.h \ + ../lib/shadowio.h +sulogin.o: sulogin.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h \ + ../lib/pwauth.h +su.o: su.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/pwauth.h \ + ../lib/getdef.h +useradd.o: useradd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \ + ../lib/pwauth.h ../lib/faillog.h ../lib/groupio.h \ + ../lib/sgroupio.h ../lib/pwio.h ../lib/shadowio.h \ + ../lib/getdef.h +userdel.o: userdel.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h \ + ../lib/pwauth.h ../lib/groupio.h ../lib/pwio.h \ + ../lib/shadowio.h ../lib/sgroupio.h +usermod.o: usermod.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \ + ../lib/defines.h ../lib/gshadow_.h ../libmisc/chkname.h \ + ../lib/faillog.h ../lib/pwauth.h ../lib/getdef.h \ + ../lib/groupio.h ../lib/sgroupio.h ../lib/pwio.h \ + ../lib/shadowio.h +vipw.o: vipw.c ../config.h ../lib/rcsid.h ../lib/defines.h \ + ../lib/gshadow_.h ../lib/prototypes.h ../lib/pwio.h \ + ../lib/shadowio.h ../lib/groupio.h ../lib/sgroupio.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-exec: install-exec-am + +install-data-am: install-ubinPROGRAMS install-usbinPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS uninstall-ubinPROGRAMS \ + uninstall-usbinPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(ubindir) \ + $(DESTDIR)$(usbindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \ + mostlyclean-ubinPROGRAMS mostlyclean-usbinPROGRAMS \ + mostlyclean-compile mostlyclean-libtool \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-ubinPROGRAMS \ + clean-usbinPROGRAMS clean-compile clean-libtool \ + clean-tags clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \ + distclean-ubinPROGRAMS distclean-usbinPROGRAMS \ + distclean-compile distclean-libtool distclean-tags \ + distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-noinstPROGRAMS \ + maintainer-clean-ubinPROGRAMS \ + maintainer-clean-usbinPROGRAMS maintainer-clean-compile \ + maintainer-clean-libtool maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-ubinPROGRAMS distclean-ubinPROGRAMS clean-ubinPROGRAMS \ +maintainer-clean-ubinPROGRAMS uninstall-ubinPROGRAMS \ +install-ubinPROGRAMS mostlyclean-usbinPROGRAMS distclean-usbinPROGRAMS \ +clean-usbinPROGRAMS maintainer-clean-usbinPROGRAMS \ +uninstall-usbinPROGRAMS install-usbinPROGRAMS mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +install-exec-hook: + for i in $(suidbins); do \ + chmod 4755 $(DESTDIR)$(bindir)/$$i; \ + done + +install-data-hook: + for i in $(suidubins); do \ + chmod 4755 $(DESTDIR)$(ubindir)/$$i; \ + done + rm -f $(DESTDIR)$(ubindir)/sg + ln -s newgrp $(DESTDIR)$(ubindir)/sg + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/current/src/chage.c b/current/src/chage.c new file mode 100644 index 00000000..fd1e5d64 --- /dev/null +++ b/current/src/chage.c @@ -0,0 +1,841 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: chage.c,v 1.18 2000/09/02 18:40:43 marekm Exp $") + +#include +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +#include + +/* + * chage depends on some form of aging being present. It makes no sense + * to have a program that has no input. + */ + +#ifdef SHADOWPWD +#ifndef AGING +#define AGING +#endif /* AGING */ +#else /* !SHADOWPWD */ +#if !defined(ATT_AGE) && defined(AGING) +#undef AGING +#endif /* !ATT_AGE && AGING */ +#endif /* SHADOWPWD */ + +static char *Prog; +static int amroot; + +#ifdef AGING /*{*/ + +/* + * Global variables + */ + +static long mindays; +static long maxdays; +static long lastday; +#ifdef SHADOWPWD +static long warndays; +static long inactdays; +static long expdays; +#endif + +/* + * External identifiers + */ + +extern long a64l(); +extern char *l64a(); + +#include "pwio.h" + +#ifdef SHADOWPWD +#include "shadowio.h" +#endif + +extern int optind; +extern char *optarg; +#ifdef NDBM +extern int pw_dbm_mode; +#ifdef SHADOWPWD +extern int sp_dbm_mode; +#endif +#endif + +/* + * #defines for messages. This facilitates foreign language conversion + * since all messages are defined right here. + */ + +/* + * xgettext doesn't like #defines, so now we only leave untranslated + * messages here. -MM + */ + +#define AGE_CHANGED "changed password expiry for %s\n" +#define LOCK_FAIL "failed locking %s\n" +#define OPEN_FAIL "failed opening %s\n" +#define WRITE_FAIL "failed updating %s\n" +#define CLOSE_FAIL "failed rewriting %s\n" + +#define EPOCH "1969-12-31" + +#ifdef SHADOWPWD +#define DBMERROR2 "error updating DBM shadow entry.\n" +#else +#define DBMERROR2 "error updating DBM passwd entry.\n" +#endif + +/* local function prototypes */ +static void usage(void); +static void date_to_str(char *, size_t, time_t); +static int new_fields(void); +static void print_date(time_t); +static void list_fields(void); +static void cleanup(int); + + +/* + * isnum - determine whether or not a string is a number + */ +int +isnum(const char *s) +{ + while (*s) { + if (!isdigit(*s)) + return 0; + s++; + } + return 1; +} + +/* + * usage - print command line syntax and exit + */ + +static void +usage(void) +{ +#ifdef SHADOWPWD + fprintf(stderr, _("Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -W warn ]\n [ -I inactive ] [ -E expire ] [ -d last_day ] user\n"), Prog); +#else + fprintf(stderr, _("Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -d last_day ] user\n"), Prog); +#endif + exit(1); +} + +static void +date_to_str(char *buf, size_t maxsize, time_t date) +{ + struct tm *tp; + + tp = gmtime(&date); +#ifdef HAVE_STRFTIME + strftime(buf, maxsize, "%Y-%m-%d", tp); +#else + snprintf(buf, maxsize, "%04d-%02d-%02d", + tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday); +#endif /* HAVE_STRFTIME */ +} + +/* + * new_fields - change the user's password aging information interactively. + * + * prompt the user for all of the password age values. set the fields + * from the user's response, or leave alone if nothing was entered. the + * value (-1) is used to indicate the field should be removed if possible. + * any other negative value is an error. very large positive values will + * be handled elsewhere. + */ + +static int +new_fields(void) +{ + char buf[200]; + char *cp; + + printf(_("Enter the new value, or press return for the default\n\n")); + + snprintf(buf, sizeof buf, "%ld", mindays); + change_field(buf, sizeof buf, _("Minimum Password Age")); + if (((mindays = strtol (buf, &cp, 10)) == 0 && *cp) || mindays < -1) + return 0; + + snprintf(buf, sizeof buf, "%ld", maxdays); + change_field(buf, sizeof buf, _("Maximum Password Age")); + if (((maxdays = strtol (buf, &cp, 10)) == 0 && *cp) || maxdays < -1) + return 0; + + date_to_str(buf, sizeof buf, lastday * SCALE); + + change_field(buf, sizeof buf, _("Last Password Change (YYYY-MM-DD)")); + + if (strcmp (buf, EPOCH) == 0) + lastday = -1; + else if ((lastday = strtoday (buf)) == -1) + return 0; + +#ifdef SHADOWPWD + snprintf(buf, sizeof buf, "%ld", warndays); + change_field (buf, sizeof buf, _("Password Expiration Warning")); + if (((warndays = strtol (buf, &cp, 10)) == 0 && *cp) || warndays < -1) + return 0; + + snprintf(buf, sizeof buf, "%ld", inactdays); + change_field(buf, sizeof buf, _("Password Inactive")); + if (((inactdays = strtol (buf, &cp, 10)) == 0 && *cp) || inactdays < -1) + return 0; + + date_to_str(buf, sizeof buf, expdays * SCALE); + + change_field(buf, sizeof buf, _("Account Expiration Date (YYYY-MM-DD)")); + + if (strcmp (buf, EPOCH) == 0) + expdays = -1; + else if ((expdays = strtoday (buf)) == -1) + return 0; +#endif /* SHADOWPWD */ + + return 1; +} + +static void +print_date(time_t date) +{ +#ifdef HAVE_STRFTIME + struct tm *tp; + char buf[80]; + + tp = gmtime(&date); + strftime(buf, sizeof buf, "%b %d, %Y", tp); + puts(buf); +#else + struct tm *tp; + char *cp; + + tp = gmtime(&date); + cp = asctime(tp); + printf("%6.6s, %4.4s\n", cp + 4, cp + 20); +#endif +} + +/* + * list_fields - display the current values of the expiration fields + * + * display the password age information from the password fields. date + * values will be displayed as a calendar date, or the word "Never" if + * the date is 1/1/70, which is day number 0. + */ + +static void +list_fields(void) +{ + long changed = 0; + long expires; + + /* + * Start with the easy numbers - the number of days before the + * password can be changed, the number of days after which the + * password must be chaged, the number of days before the + * password expires that the user is told, and the number of + * days after the password expires that the account becomes + * unusable. + */ + + printf(_("Minimum:\t%ld\n"), mindays); + printf(_("Maximum:\t%ld\n"), maxdays); +#ifdef SHADOWPWD + printf(_("Warning:\t%ld\n"), warndays); + printf(_("Inactive:\t%ld\n"), inactdays); +#endif + + /* + * The "last change" date is either "Never" or the date the + * password was last modified. The date is the number of + * days since 1/1/1970. + */ + + printf(_("Last Change:\t\t")); + if (lastday <= 0) { + printf(_("Never\n")); + } else { + changed = lastday * SCALE; + print_date(changed); + } + + /* + * The password expiration date is determined from the last + * change date plus the number of days the password is valid + * for. + */ + + printf(_("Password Expires:\t")); + if (lastday <= 0 || maxdays >= 10000*(DAY/SCALE) || maxdays <= 0) { + printf (_("Never\n")); + } else { + expires = changed + maxdays * SCALE; + print_date(expires); + } + +#ifdef SHADOWPWD + /* + * The account becomes inactive if the password is expired + * for more than "inactdays". The expiration date is calculated + * and the number of inactive days is added. The resulting date + * is when the active will be disabled. + */ + + printf(_("Password Inactive:\t")); + if (lastday <= 0 || inactdays <= 0 || + maxdays >= 10000*(DAY/SCALE) || maxdays <= 0) { + printf (_("Never\n")); + } else { + expires = changed + (maxdays + inactdays) * SCALE; + print_date(expires); + } + + /* + * The account will expire on the given date regardless of the + * password expiring or not. + */ + + printf(_("Account Expires:\t")); + if (expdays <= 0) { + printf (_("Never\n")); + } else { + expires = expdays * SCALE; + print_date(expires); + } +#endif +} + +/* + * chage - change a user's password aging information + * + * This command controls the password aging information. + * + * The valid options are + * + * -m minimum number of days before password change (*) + * -M maximim number of days before password change (*) + * -d last password change date (*) + * -l password aging information + * -W expiration warning days (*) + * -I password inactive after expiration (*) + * -E account expiration date (*) + * + * (*) requires root permission to execute. + * + * All of the time fields are entered in the internal format + * which is either seconds or days. + * + * The options -W, -I and -E all depend on the SHADOWPWD + * macro being defined. + */ + +int +main(int argc, char **argv) +{ + int flag; + int lflg = 0; + int mflg = 0; + int Mflg = 0; + int dflg = 0; +#ifdef SHADOWPWD + int Wflg = 0; + int Iflg = 0; + int Eflg = 0; + const struct spwd *sp; + struct spwd spwd; +#else + char new_age[5]; +#endif + uid_t ruid; + const struct passwd *pw; + struct passwd pwent; + char name[BUFSIZ]; + + sanitize_env(); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + ruid = getuid(); + amroot = (ruid == 0); + + /* + * Get the program name so that error messages can use it. + */ + + Prog = Basename(argv[0]); + + OPENLOG("chage"); +#ifdef NDBM +#ifdef SHADOWPWD + sp_dbm_mode = O_RDWR; +#endif + pw_dbm_mode = O_RDWR; +#endif + + /* + * Parse the flags. The difference between password file + * formats includes the number of fields, and whether the + * dates are entered as days or weeks. Shadow password + * file info =must= be entered in days, while regular + * password file info =must= be entered in weeks. + */ + +#ifdef SHADOWPWD +#define FLAGS "lm:M:W:I:E:d:" +#else +#define FLAGS "lm:M:d:" +#endif + while ((flag = getopt(argc, argv, FLAGS)) != EOF) { +#undef FLAGS + switch (flag) { + case 'l': + lflg++; + break; + case 'm': + mflg++; + mindays = strtol (optarg, 0, 10); + break; + case 'M': + Mflg++; + maxdays = strtol (optarg, 0, 10); + break; + case 'd': + dflg++; + if (!isnum(optarg)) + lastday = strtoday (optarg); + else + lastday = strtol (optarg, 0, 10); + break; +#ifdef SHADOWPWD + case 'W': + Wflg++; + warndays = strtol (optarg, 0, 10); + break; + case 'I': + Iflg++; + inactdays = strtol (optarg, 0, 10); + break; + case 'E': + Eflg++; + if (!isnum(optarg)) + expdays = strtoday (optarg); + else + expdays = strtol (optarg, 0, 10); + break; +#endif + default: + usage (); + } + } + + /* + * Make certain the flags do not conflict and that there is + * a user name on the command line. + */ + + if (argc != optind + 1) + usage (); + +#ifdef SHADOWPWD + if (lflg && (mflg || Mflg || dflg || Wflg || Iflg || Eflg)) +#else + if (lflg && (mflg || Mflg || dflg)) +#endif + { + fprintf (stderr, _("%s: do not include \"l\" with other flags\n"), Prog); + closelog(); + usage (); + } + + /* + * An unprivileged user can ask for their own aging information, + * but only root can change it, or list another user's aging + * information. + */ + + if (!amroot && !lflg) { + fprintf (stderr, _("%s: permission denied\n"), Prog); + closelog(); + exit (1); + } + + /* + * Lock and open the password file. This loads all of the + * password file entries into memory. Then we get a pointer + * to the password file entry for the requested user. + */ + /* We don't lock the password file if we are not root */ + if (amroot && !pw_lock()) { + fprintf(stderr, _("%s: can't lock password file\n"), Prog); + SYSLOG((LOG_ERR, LOCK_FAIL, PASSWD_FILE)); + closelog(); + exit(1); + } + if (!pw_open((!amroot || lflg) ? O_RDONLY:O_RDWR)) { + fprintf(stderr, _("%s: can't open password file\n"), Prog); + cleanup(1); + SYSLOG((LOG_ERR, OPEN_FAIL, PASSWD_FILE)); + closelog(); + exit(1); + } + if (!(pw = pw_locate(argv[optind]))) { + fprintf(stderr, _("%s: unknown user: %s\n"), Prog, argv[optind]); + cleanup(1); + closelog(); + exit(1); + } + + pwent = *pw; + STRFCPY(name, pwent.pw_name); + +#ifdef SHADOWPWD + /* + * For shadow password files we have to lock the file and + * read in the entries as was done for the password file. + * The user entries does not have to exist in this case; + * a new entry will be created for this user if one does + * not exist already. + */ + /* We don't lock the shadow file if we are not root */ + if (amroot && !spw_lock()) { + fprintf(stderr, _("%s: can't lock shadow password file\n"), Prog); + cleanup(1); + SYSLOG((LOG_ERR, LOCK_FAIL, SHADOW_FILE)); + closelog(); + exit(1); + } + if (!spw_open((!amroot || lflg) ? O_RDONLY : O_RDWR)) { + fprintf(stderr, _("%s: can't open shadow password file\n"), Prog); + cleanup(2); + SYSLOG((LOG_ERR, OPEN_FAIL, SHADOW_FILE)); + closelog(); + exit(1); + } + + sp = spw_locate(argv[optind]); + + /* + * Set the fields that aren't being set from the command line + * from the password file. + */ + + if (sp) { + spwd = *sp; + + if (! Mflg) + maxdays = spwd.sp_max; + if (! mflg) + mindays = spwd.sp_min; + if (! dflg) + lastday = spwd.sp_lstchg; + if (! Wflg) + warndays = spwd.sp_warn; + if (! Iflg) + inactdays = spwd.sp_inact; + if (! Eflg) + expdays = spwd.sp_expire; + } +#ifdef ATT_AGE + else +#endif /* ATT_AGE */ +#endif /* SHADOWPWD */ +#ifdef ATT_AGE + { + if (pwent.pw_age && strlen (pwent.pw_age) >= 2) { + if (! Mflg) + maxdays = c64i (pwent.pw_age[0]) * (WEEK/SCALE); + if (! mflg) + mindays = c64i (pwent.pw_age[1]) * (WEEK/SCALE); + if (! dflg && strlen (pwent.pw_age) == 4) + lastday = a64l (pwent.pw_age+2) * (WEEK/SCALE); + } else { + mindays = 0; + maxdays = 10000L * (DAY/SCALE); + lastday = -1; + } +#ifdef SHADOWPWD + warndays = inactdays = expdays = -1; +#endif /* SHADOWPWD */ + } +#endif /* ATT_AGE */ + + /* + * Print out the expiration fields if the user has + * requested the list option. + */ + + if (lflg) { + if (!amroot && (ruid != pwent.pw_uid)) { + fprintf(stderr, _("%s: permission denied\n"), Prog); + closelog(); + exit(1); + } + list_fields(); + cleanup(2); + closelog(); + exit(0); + } + + /* + * If none of the fields were changed from the command line, + * let the user interactively change them. + */ + +#ifdef SHADOWPWD + if (! mflg && ! Mflg && ! dflg && ! Wflg && ! Iflg && ! Eflg) +#else + if (! mflg && ! Mflg && ! dflg) +#endif + { + printf(_("Changing the aging information for %s\n"), name); + if (!new_fields()) { + fprintf(stderr, _("%s: error changing fields\n"), Prog); + cleanup(2); + closelog(); + exit(1); + } + } + +#ifdef SHADOWPWD + /* + * There was no shadow entry. The new entry will have the + * encrypted password transferred from the normal password + * file along with the aging information. + */ + + if (sp == 0) { + sp = &spwd; + memzero(&spwd, sizeof spwd); + + spwd.sp_namp = xstrdup (pwent.pw_name); + spwd.sp_pwdp = xstrdup (pwent.pw_passwd); + spwd.sp_flag = -1; + + pwent.pw_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */ +#ifdef ATT_AGE + pwent.pw_age = ""; +#endif + if (!pw_update(&pwent)) { + fprintf(stderr, _("%s: can't update password file\n"), Prog); + cleanup(2); + SYSLOG((LOG_ERR, WRITE_FAIL, PASSWD_FILE)); + closelog(); + exit(1); + } +#ifdef NDBM + (void) pw_dbm_update (&pwent); + endpwent (); +#endif + } +#endif /* SHADOWPWD */ + +#ifdef SHADOWPWD + + /* + * Copy the fields back to the shadow file entry and + * write the modified entry back to the shadow file. + * Closing the shadow and password files will commit + * any changes that have been made. + */ + + spwd.sp_max = maxdays; + spwd.sp_min = mindays; + spwd.sp_lstchg = lastday; + spwd.sp_warn = warndays; + spwd.sp_inact = inactdays; + spwd.sp_expire = expdays; + + if (!spw_update(&spwd)) { + fprintf(stderr, _("%s: can't update shadow password file\n"), Prog); + cleanup(2); + SYSLOG((LOG_ERR, WRITE_FAIL, SHADOW_FILE)); + closelog(); + exit(1); + } +#else /* !SHADOWPWD */ + + /* + * fill in the new_age string with the new values + */ + + if (maxdays > (63 * 7) && mindays == 0) { + new_age[0] = '\0'; + } else { + if (maxdays > (63 * 7)) + maxdays = 63 * 7; + + if (mindays > (63 * 7)) + mindays = 63 * 7; + + new_age[0] = i64c (maxdays / 7); + new_age[1] = i64c ((mindays + 6) / 7); + + if (lastday == 0) + new_age[2] = '\0'; + else + strcpy (new_age + 2, l64a (lastday / 7)); + + } + pwent.pw_age = new_age; + + if (!pw_update(&pwent)) { + fprintf(stderr, _("%s: can't update password file\n"), Prog); + cleanup(2); + SYSLOG((LOG_ERR, WRITE_FAIL, PASSWD_FILE)); + closelog(); + exit(1); + } +#endif /* SHADOWPWD */ + +#ifdef NDBM +#ifdef SHADOWPWD + + /* + * See if the shadow DBM file exists and try to update it. + */ + + if (sp_dbm_present() && !sp_dbm_update(&spwd)) { + fprintf(stderr, _("Error updating the DBM password entry.\n")); + cleanup(2); + SYSLOG((LOG_ERR, DBMERROR2)); + closelog(); + exit(1); + } + endspent(); + +#else /* !SHADOWPWD */ + + /* + * See if the password DBM file exists and try to update it. + */ + + if (pw_dbm_present() && !pw_dbm_update(&pwent)) { + fprintf(stderr, _("Error updating the DBM password entry.\n")); + cleanup(2); + SYSLOG((LOG_ERR, DBMERROR2)); + closelog(); + exit(1); + } + endpwent (); +#endif /* SHADOWPWD */ +#endif /* NDBM */ + +#ifdef SHADOWPWD + /* + * Now close the shadow password file, which will cause all + * of the entries to be re-written. + */ + + if (!spw_close()) { + fprintf(stderr, _("%s: can't rewrite shadow password file\n"), Prog); + cleanup(2); + SYSLOG((LOG_ERR, CLOSE_FAIL, SHADOW_FILE)); + closelog(); + exit(1); + } +#endif /* SHADOWPWD */ + + /* + * Close the password file. If any entries were modified, the + * file will be re-written. + */ + + if (!pw_close()) { + fprintf(stderr, _("%s: can't rewrite password file\n"), Prog); + cleanup(2); + SYSLOG((LOG_ERR, CLOSE_FAIL, PASSWD_FILE)); + closelog(); + exit(1); + } + cleanup(2); + SYSLOG((LOG_INFO, AGE_CHANGED, name)); + closelog(); + exit(0); + /*NOTREACHED*/ +} + +/* + * cleanup - unlock any locked password files + */ + +static void +cleanup(int state) +{ + switch (state) { + case 2: +#ifdef SHADOWPWD + if (amroot) + spw_unlock(); +#endif + case 1: + if (amroot) + pw_unlock(); + case 0: + break; + } +} + +#else /*} !AGING {*/ + +/* + * chage - but there is no age info! + */ + +int +main(int argc, char **argv) +{ + char *Prog; + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + fprintf (stderr, _("%s: no aging information present\n"), Prog); + exit(1); +} + +#endif /*} AGING */ + diff --git a/current/src/chfn.c b/current/src/chfn.c new file mode 100644 index 00000000..413ff33f --- /dev/null +++ b/current/src/chfn.c @@ -0,0 +1,600 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: chfn.c,v 1.17 2000/09/02 18:40:43 marekm Exp $") + +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +#include +#include "pwio.h" +#include "getdef.h" +#include "pwauth.h" + +#ifdef HAVE_SHADOW_H +#include +#endif + +#ifdef USE_PAM +#include "pam_defs.h" +#endif + +/* + * Global variables. + */ + +static char *Prog; +static char fullnm[BUFSIZ]; +static char roomno[BUFSIZ]; +static char workph[BUFSIZ]; +static char homeph[BUFSIZ]; +static char slop[BUFSIZ]; +static int amroot; + +/* + * External identifiers + */ + +extern int optind; +extern char *optarg; +#ifdef NDBM +extern int pw_dbm_mode; +#endif + +/* + * #defines for messages. This facilitates foreign language conversion + * since all messages are defined right here. + */ + +#define WRONGPWD2 "incorrect password for `%s'" +#define PWDBUSY2 "can't lock /etc/passwd\n" +#define OPNERROR2 "can't open /etc/passwd\n" +#define UPDERROR2 "error updating passwd entry\n" +#define DBMERROR2 "error updating DBM passwd entry.\n" +#define NOTROOT2 "can't setuid(0).\n" +#define CLSERROR2 "can't rewrite /etc/passwd.\n" +#define UNLKERROR2 "can't unlock /etc/passwd.\n" +#define CHGGECOS "changed user `%s' information.\n" + +/* local function prototypes */ +static void usage(void); +static int may_change_field(int); +static void new_fields(void); +static char *copy_field(char *, char *, char *); + +/* + * usage - print command line syntax and exit + */ + +static void +usage(void) +{ + if (amroot) + fprintf(stderr, + _("Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ]\n\t[ -h home_ph ] [ -o other ] [ user ]\n"), + Prog); + else + fprintf(stderr, + _("Usage: %s [ -f full_name ] [ -r room_no ] [ -w work_ph ] [ -h home_ph ]\n"), + Prog); + exit(1); +} + + +static int +may_change_field(int field) +{ + const char *cp; + + /* + * CHFN_RESTRICT can now specify exactly which fields may be + * changed by regular users, by using any combination of the + * following letters: + * f - full name + * r - room number + * w - work phone + * h - home phone + * + * This makes it possible to disallow changing the room number + * information, for example - this feature was suggested by + * Maciej 'Tycoon' Majchrowski. + * + * For backward compatibility, "yes" is equivalent to "rwh", + * "no" is equivalent to "frwh". Only root can change anything + * if the string is empty or not defined at all. + */ + if (amroot) + return 1; + cp = getdef_str("CHFN_RESTRICT"); + if (!cp) + cp = ""; + else if (strcmp(cp, "yes") == 0) + cp = "rwh"; + else if (strcmp(cp, "no") == 0) + cp = "frwh"; + if (strchr(cp, field)) + return 1; + return 0; +} + +/* + * new_fields - change the user's GECOS information interactively + * + * prompt the user for each of the four fields and fill in the fields + * from the user's response, or leave alone if nothing was entered. + */ + +static void +new_fields(void) +{ + printf(_("Enter the new value, or press return for the default\n")); + + if (may_change_field('f')) + change_field(fullnm, sizeof fullnm, _("Full Name")); + else + printf(_("\tFull Name: %s\n"), fullnm); + + if (may_change_field('r')) + change_field(roomno, sizeof roomno, _("Room Number")); + else + printf(_("\tRoom Number: %s\n"), roomno); + + if (may_change_field('w')) + change_field(workph, sizeof workph, _("Work Phone")); + else + printf(_("\tWork Phone: %s\n"), workph); + + if (may_change_field('h')) + change_field(homeph, sizeof homeph, _("Home Phone")); + else + printf(_("\tHome Phone: %s\n"), homeph); + + if (amroot) + change_field(slop, sizeof slop, _("Other")); +} + +/* + * copy_field - get the next field from the gecos field + * + * copy_field copies the next field from the gecos field, returning a + * pointer to the field which follows, or NULL if there are no more + * fields. + * + * in - the current GECOS field + * out - where to copy the field to + * extra - fields with '=' get copied here + */ + +static char * +copy_field(char *in, char *out, char *extra) +{ + char *cp = NULL; + + while (in) { + if ((cp = strchr (in, ','))) + *cp++ = '\0'; + + if (! strchr (in, '=')) + break; + + if (extra) { + if (extra[0]) + strcat (extra, ","); + + strcat (extra, in); + } + in = cp; + } + if (in && out) + strcpy (out, in); + + return cp; +} + + +/* + * chfn - change a user's password file information + * + * This command controls the GECOS field information in the + * password file entry. + * + * The valid options are + * + * -f full name + * -r room number + * -w work phone number + * -h home phone number + * -o other information (*) + * + * (*) requires root permission to execute. + */ + +int +main(int argc, char **argv) +{ + char *cp; /* temporary character pointer */ + const struct passwd *pw; /* password file entry */ + struct passwd pwent; /* modified password file entry */ + char old_gecos[BUFSIZ]; /* buffer for old GECOS fields */ + char new_gecos[BUFSIZ]; /* buffer for new GECOS fields */ + int flag; /* flag currently being processed */ + int fflg = 0; /* -f - set full name */ + int rflg = 0; /* -r - set room number */ + int wflg = 0; /* -w - set work phone number */ + int hflg = 0; /* -h - set home phone number */ + int oflg = 0; /* -o - set other information */ + char *user; + + sanitize_env(); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* + * This command behaves different for root and non-root + * users. + */ + + amroot = (getuid () == 0); +#ifdef NDBM + pw_dbm_mode = O_RDWR; +#endif + + /* + * Get the program name. The program name is used as a + * prefix to most error messages. + */ + + Prog = Basename(argv[0]); + + OPENLOG("chfn"); + + /* + * The remaining arguments will be processed one by one and + * executed by this command. The name is the last argument + * if it does not begin with a "-", otherwise the name is + * determined from the environment and must agree with the + * real UID. Also, the UID will be checked for any commands + * which are restricted to root only. + */ + + while ((flag = getopt (argc, argv, "f:r:w:h:o:")) != EOF) { + switch (flag) { + case 'f': + if (!may_change_field('f')) { + fprintf(stderr, _("%s: Permission denied.\n"), Prog); + exit(1); + } + fflg++; + STRFCPY(fullnm, optarg); + break; + case 'r': + if (!may_change_field('r')) { + fprintf(stderr, _("%s: Permission denied.\n"), Prog); + exit(1); + } + rflg++; + STRFCPY(roomno, optarg); + break; + case 'w': + if (!may_change_field('w')) { + fprintf(stderr, _("%s: Permission denied.\n"), Prog); + exit(1); + } + wflg++; + STRFCPY(workph, optarg); + break; + case 'h': + if (!may_change_field('h')) { + fprintf(stderr, _("%s: Permission denied.\n"), Prog); + exit(1); + } + hflg++; + STRFCPY(homeph, optarg); + break; + case 'o': + if (!amroot) { + fprintf(stderr, _("%s: Permission denied.\n"), Prog); + exit(1); + } + oflg++; + STRFCPY(slop, optarg); + break; + default: + usage(); + } + } + + /* + * Get the name of the user to check. It is either + * the command line name, or the name getlogin() + * returns. + */ + + if (optind < argc) { + user = argv[optind]; + pw = getpwnam(user); + if (!pw) { + fprintf(stderr, _("%s: Unknown user %s\n"), Prog, user); + exit(1); + } + } else { + pw = get_my_pwent(); + if (!pw) { + fprintf(stderr, _("%s: Cannot determine your user name.\n"), Prog); + exit(1); + } + user = xstrdup(pw->pw_name); + } + +#ifdef USE_NIS + /* + * Now we make sure this is a LOCAL password entry for + * this user ... + */ + + if (__ispwNIS ()) { + char *nis_domain; + char *nis_master; + + fprintf (stderr, _("%s: cannot change user `%s' on NIS client.\n"), Prog, user); + + if (! yp_get_default_domain (&nis_domain) && + ! yp_master (nis_domain, "passwd.byname", + &nis_master)) { + fprintf (stderr, _("%s: `%s' is the NIS master for this client.\n"), Prog, nis_master); + } + exit (1); + } +#endif + + /* + * Non-privileged users are only allowed to change the + * gecos field if the UID of the user matches the current + * real UID. + */ + + if (!amroot && pw->pw_uid != getuid()) { + fprintf (stderr, _("%s: Permission denied.\n"), Prog); + closelog(); + exit(1); + } + + /* + * Non-privileged users are optionally authenticated + * (must enter the password of the user whose information + * is being changed) before any changes can be made. + * Idea from util-linux chfn/chsh. --marekm + */ + + if (!amroot && getdef_bool("CHFN_AUTH")) + passwd_check(pw->pw_name, pw->pw_passwd, "chfn"); + + /* + * Now get the full name. It is the first comma separated field + * in the GECOS field. + */ + + STRFCPY(old_gecos, pw->pw_gecos); + cp = copy_field (old_gecos, fflg ? (char *) 0:fullnm, slop); + + /* + * Now get the room number. It is the next comma separated field, + * if there is indeed one. + */ + + if (cp) + cp = copy_field (cp, rflg ? (char *) 0:roomno, slop); + + /* + * Now get the work phone number. It is the third field. + */ + + if (cp) + cp = copy_field (cp, wflg ? (char *) 0:workph, slop); + + /* + * Now get the home phone number. It is the fourth field. + */ + + if (cp) + cp = copy_field (cp, hflg ? (char *) 0:homeph, slop); + + /* + * Anything left over is "slop". + */ + + if (cp && !oflg) { + if (slop[0]) + strcat (slop, ","); + + strcat (slop, cp); + } + + /* + * If none of the fields were changed from the command line, + * let the user interactively change them. + */ + + if (!fflg && !rflg && !wflg && !hflg && !oflg) { + printf(_("Changing the user information for %s\n"), user); + new_fields(); + } + + /* + * Check all of the fields for valid information + */ + + if (valid_field(fullnm, ":,=")) { + fprintf(stderr, _("%s: invalid name: \"%s\"\n"), Prog, fullnm); + closelog(); + exit(1); + } + if (valid_field(roomno, ":,=")) { + fprintf(stderr, _("%s: invalid room number: \"%s\"\n"), Prog, roomno); + closelog(); + exit(1); + } + if (valid_field(workph, ":,=")) { + fprintf(stderr, _("%s: invalid work phone: \"%s\"\n"), Prog, workph); + closelog(); + exit(1); + } + if (valid_field (homeph, ":,=")) { + fprintf(stderr, _("%s: invalid home phone: \"%s\"\n"), Prog, homeph); + closelog(); + exit(1); + } + if (valid_field(slop, ":")) { + fprintf(stderr, _("%s: \"%s\" contains illegal characters\n"), Prog, slop); + closelog(); + exit(1); + } + + /* + * Build the new GECOS field by plastering all the pieces together, + * if they will fit ... + */ + + if (strlen(fullnm) + strlen(roomno) + strlen(workph) + + strlen(homeph) + strlen(slop) > (unsigned int) 80) { + fprintf(stderr, _("%s: fields too long\n"), Prog); + closelog(); + exit(1); + } + snprintf(new_gecos, sizeof new_gecos, "%s,%s,%s,%s%s%s", + fullnm, roomno, workph, homeph, slop[0] ? "," : "", slop); + + /* + * Before going any further, raise the ulimit to prevent + * colliding into a lowered ulimit, and set the real UID + * to root to protect against unexpected signals. Any + * keyboard signals are set to be ignored. + */ + + if (setuid(0)) { + fprintf(stderr, _("Cannot change ID to root.\n")); + SYSLOG((LOG_ERR, NOTROOT2)); + closelog(); + exit(1); + } + pwd_init(); + + /* + * The passwd entry is now ready to be committed back to + * the password file. Get a lock on the file and open it. + */ + + if (!pw_lock()) { + fprintf(stderr, _("Cannot lock the password file; try again later.\n")); + SYSLOG((LOG_WARN, PWDBUSY2)); + closelog(); + exit(1); + } + if (!pw_open(O_RDWR)) { + fprintf(stderr, _("Cannot open the password file.\n")); + pw_unlock(); + SYSLOG((LOG_ERR, OPNERROR2)); + closelog(); + exit(1); + } + + /* + * Get the entry to update using pw_locate() - we want the real + * one from /etc/passwd, not the one from getpwnam() which could + * contain the shadow password if (despite the warnings) someone + * enables AUTOSHADOW (or SHADOW_COMPAT in libc). --marekm + */ + pw = pw_locate(user); + if (!pw) { + pw_unlock(); + fprintf(stderr, + _("%s: %s not found in /etc/passwd\n"), Prog, user); + exit(1); + } + + /* + * Make a copy of the entry, then change the gecos field. The other + * fields remain unchanged. + */ + pwent = *pw; + pwent.pw_gecos = new_gecos; + + /* + * Update the passwd file entry. If there is a DBM file, + * update that entry as well. + */ + + if (!pw_update(&pwent)) { + fprintf(stderr, _("Error updating the password entry.\n")); + pw_unlock(); + SYSLOG((LOG_ERR, UPDERROR2)); + closelog(); + exit(1); + } +#ifdef NDBM + if (pw_dbm_present() && !pw_dbm_update(&pwent)) { + fprintf(stderr, _("Error updating the DBM password entry.\n")); + pw_unlock (); + SYSLOG((LOG_ERR, DBMERROR2)); + closelog(); + exit(1); + } + endpwent(); +#endif + + /* + * Changes have all been made, so commit them and unlock the + * file. + */ + + if (!pw_close()) { + fprintf(stderr, _("Cannot commit password file changes.\n")); + pw_unlock(); + SYSLOG((LOG_ERR, CLSERROR2)); + closelog(); + exit(1); + } + if (!pw_unlock()) { + fprintf(stderr, _("Cannot unlock the password file.\n")); + SYSLOG((LOG_ERR, UNLKERROR2)); + closelog(); + exit(1); + } + SYSLOG((LOG_INFO, CHGGECOS, user)); + closelog(); + exit (0); +} diff --git a/current/src/chpasswd.c b/current/src/chpasswd.c new file mode 100644 index 00000000..dc46498f --- /dev/null +++ b/current/src/chpasswd.c @@ -0,0 +1,288 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + * + * chpasswd - update passwords in batch + * + * chpasswd reads standard input for a list of colon separated + * user names and new passwords. the appropriate password + * files are updated to reflect the changes. because the + * changes are made in a batch fashion, the user must run + * the mkpasswd command after this command terminates since + * no password updates occur until the very end. + * + * 1997/07/29: Modified to take "-e" argument which specifies that + * the passwords have already been encrypted. + * -- Jay Soffian + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: chpasswd.c,v 1.10 2000/08/26 18:27:18 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include +#include +#include "pwio.h" +#ifdef SHADOWPWD +#include "shadowio.h" +#endif + +static char *Prog; +static int eflg = 0; +#ifdef SHADOWPWD +static int is_shadow_pwd; +#endif + +extern char *l64a(); + +/* local function prototypes */ +static void usage(void); + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("usage: %s [-e]\n"), Prog); + exit(1); +} + +int +main(int argc, char **argv) +{ + char buf[BUFSIZ]; + char *name; + char *newpwd; + char *cp; +#ifdef SHADOWPWD + const struct spwd *sp; + struct spwd newsp; +#endif + const struct passwd *pw; + struct passwd newpw; +#ifdef ATT_AGE + char newage[5]; +#endif + int errors = 0; + int line = 0; + long now = time ((long *) 0) / (24L*3600L); + int ok; + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* XXX - use getopt() */ + if (!(argc == 1 || (argc == 2 && !strcmp(argv[1], "-e")))) + usage(); + if (argc == 2) + eflg = 1; + + /* + * Lock the password file and open it for reading. This will + * bring all of the entries into memory where they may be + * updated. + */ + + if (!pw_lock()) { + fprintf(stderr, _("%s: can't lock password file\n"), Prog); + exit(1); + } + if (! pw_open (O_RDWR)) { + fprintf(stderr, _("%s: can't open password file\n"), Prog); + pw_unlock(); + exit(1); + } +#ifdef SHADOWPWD + is_shadow_pwd = spw_file_present(); + if (is_shadow_pwd) { + if (!spw_lock()) { + fprintf(stderr, _("%s: can't lock shadow file\n"), Prog); + pw_unlock(); + exit(1); + } + if (!spw_open(O_RDWR)) { + fprintf(stderr, _("%s: can't open shadow file\n"), Prog); + pw_unlock(); + spw_unlock(); + exit(1); + } + } +#endif + + /* + * Read each line, separating the user name from the password. + * The password entry for each user will be looked up in the + * appropriate file (shadow or passwd) and the password changed. + * For shadow files the last change date is set directly, for + * passwd files the last change date is set in the age only if + * aging information is present. + */ + + while (fgets (buf, sizeof buf, stdin) != (char *) 0) { + line++; + if ((cp = strrchr (buf, '\n'))) { + *cp = '\0'; + } else { + fprintf(stderr, _("%s: line %d: line too long\n"), + Prog, line); + errors++; + continue; + } + + /* + * The username is the first field. It is separated + * from the password with a ":" character which is + * replaced with a NUL to give the new password. The + * new password will then be encrypted in the normal + * fashion with a new salt generated, unless the '-e' + * is given, in which case it is assumed to already be + * encrypted. + */ + + name = buf; + if ((cp = strchr (name, ':'))) { + *cp++ = '\0'; + } else { + fprintf(stderr, _("%s: line %d: missing new password\n"), + Prog, line); + errors++; + continue; + } + newpwd = cp; + if (!eflg) + cp = pw_encrypt(newpwd, crypt_make_salt()); + + /* + * Get the password file entry for this user. The user + * must already exist. + */ + + pw = pw_locate(name); + if (!pw) { + fprintf (stderr, _("%s: line %d: unknown user %s\n"), + Prog, line, name); + errors++; + continue; + } + +#ifdef SHADOWPWD + if (is_shadow_pwd) + sp = spw_locate(name); + else + sp = NULL; +#endif + + /* + * The freshly encrypted new password is merged into + * the user's password file entry and the last password + * change date is set to the current date. + */ + +#ifdef SHADOWPWD + if (sp) { + newsp = *sp; + newsp.sp_pwdp = cp; + newsp.sp_lstchg = now; + } else +#endif + { + newpw = *pw; + newpw.pw_passwd = cp; +#ifdef ATT_AGE + if (newpw.pw_age[0]) { + strcpy(newage, newpw.pw_age); + strcpy(newage + 2, l64a(now / 7)); + newpw.pw_age = newage; + } +#endif + } + + /* + * The updated password file entry is then put back + * and will be written to the password file later, after + * all the other entries have been updated as well. + */ + +#ifdef SHADOWPWD + if (sp) + ok = spw_update(&newsp); + else +#endif + ok = pw_update(&newpw); + + if (!ok) { + fprintf(stderr, _("%s: line %d: cannot update password entry\n"), + Prog, line); + errors++; + continue; + } + } + + /* + * Any detected errors will cause the entire set of changes + * to be aborted. Unlocking the password file will cause + * all of the changes to be ignored. Otherwise the file is + * closed, causing the changes to be written out all at + * once, and then unlocked afterwards. + */ + + if (errors) { + fprintf(stderr, _("%s: error detected, changes ignored\n"), Prog); +#ifdef SHADOWPWD + if (is_shadow_pwd) + spw_unlock(); +#endif + pw_unlock(); + exit(1); + } +#ifdef SHADOWPWD + if (is_shadow_pwd) { + if (!spw_close()) { + fprintf(stderr, _("%s: error updating shadow file\n"), Prog); + pw_unlock(); + exit(1); + } + spw_unlock(); + } +#endif + if (!pw_close()) { + fprintf(stderr, _("%s: error updating password file\n"), Prog); + exit(1); + } + pw_unlock(); + + return (0); +} diff --git a/current/src/chsh.c b/current/src/chsh.c new file mode 100644 index 00000000..fa4a7273 --- /dev/null +++ b/current/src/chsh.c @@ -0,0 +1,437 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: chsh.c,v 1.17 2000/09/02 18:40:43 marekm Exp $") + +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +#include +#include "pwio.h" +#include "getdef.h" +#include "pwauth.h" + +#ifdef HAVE_SHADOW_H +#include +#endif + +#ifdef USE_PAM +#include "pam_defs.h" +#endif + +#ifndef SHELLS_FILE +#define SHELLS_FILE "/etc/shells" +#endif + +/* + * Global variables. + */ + +static char *Prog; /* Program name */ +static int amroot; /* Real UID is root */ +static char loginsh[BUFSIZ]; /* Name of new login shell */ + +/* + * External identifiers + */ + +extern int optind; +extern char *optarg; +#ifdef NDBM +extern int pw_dbm_mode; +#endif + +/* + * #defines for messages. This facilitates foreign language conversion + * since all messages are defined right here. + */ + +#define WRONGPWD2 "incorrect password for `%s'" +#define NOPERM2 "can't change shell for `%s'\n" +#define PWDBUSY2 "can't lock /etc/passwd\n" +#define OPNERROR2 "can't open /etc/passwd\n" +#define UPDERROR2 "error updating passwd entry\n" +#define DBMERROR2 "error updating DBM passwd entry.\n" +#define NOTROOT2 "can't setuid(0).\n" +#define CLSERROR2 "can't rewrite /etc/passwd.\n" +#define UNLKERROR2 "can't unlock /etc/passwd.\n" +#define CHGSHELL "changed user `%s' shell to `%s'\n" + +/* local function prototypes */ +static void usage(void); +static void new_fields(void); +static int restricted_shell(const char *); + +/* + * usage - print command line syntax and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("Usage: %s [ -s shell ] [ name ]\n"), Prog); + exit(1); +} + +/* + * new_fields - change the user's login shell information interactively + * + * prompt the user for the login shell and change it according to the + * response, or leave it alone if nothing was entered. + */ + +static void +new_fields(void) +{ + printf(_("Enter the new value, or press return for the default\n")); + change_field(loginsh, sizeof loginsh, _("Login Shell")); +} + +/* + * restricted_shell - return true if the named shell begins with 'r' or 'R' + * + * If the first letter of the filename is 'r' or 'R', the shell is + * considered to be restricted. + */ + +static int +restricted_shell(const char *sh) +{ +#if 0 + char *cp = Basename((char *) sh); + return *cp == 'r' || *cp == 'R'; +#else + /* + * Shells not listed in /etc/shells are considered to be + * restricted. Changed this to avoid confusion with "rc" + * (the plan9 shell - not restricted despite the name + * starting with 'r'). --marekm + */ + return !check_shell(sh); +#endif +} + + +/* + * chsh - this command controls changes to the user's shell + * + * The only supported option is -s which permits the + * the login shell to be set from the command line. + */ + +int +main(int argc, char **argv) +{ + char *user; /* User name */ + int flag; /* Current command line flag */ + int sflg = 0; /* -s - set shell from command line */ + const struct passwd *pw; /* Password entry from /etc/passwd */ + struct passwd pwent; /* New password entry */ + + sanitize_env(); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* + * This command behaves different for root and non-root + * users. + */ + + amroot = getuid () == 0; +#ifdef NDBM + pw_dbm_mode = O_RDWR; +#endif + + /* + * Get the program name. The program name is used as a + * prefix to most error messages. + */ + + Prog = Basename(argv[0]); + + OPENLOG("chsh"); + + /* + * There is only one option, but use getopt() anyway to + * keep things consistent. + */ + + while ((flag = getopt (argc, argv, "s:")) != EOF) { + switch (flag) { + case 's': + sflg++; + STRFCPY(loginsh, optarg); + break; + default: + usage (); + } + } + + /* + * There should be only one remaining argument at most + * and it should be the user's name. + */ + + if (argc > optind + 1) + usage (); + + /* + * Get the name of the user to check. It is either + * the command line name, or the name getlogin() + * returns. + */ + + if (optind < argc) { + user = argv[optind]; + pw = getpwnam(user); + if (!pw) { + fprintf(stderr, + _("%s: Unknown user %s\n"), + Prog, user); + exit(1); + } + } else { + pw = get_my_pwent(); + if (!pw) { + fprintf(stderr, + _("%s: Cannot determine your user name.\n"), + Prog); + exit(1); + } + user = xstrdup(pw->pw_name); + } + +#ifdef USE_NIS + /* + * Now we make sure this is a LOCAL password entry for + * this user ... + */ + + if (__ispwNIS ()) { + char *nis_domain; + char *nis_master; + + fprintf(stderr, + _("%s: cannot change user `%s' on NIS client.\n"), + Prog, user); + + if (! yp_get_default_domain (&nis_domain) && + ! yp_master (nis_domain, "passwd.byname", + &nis_master)) { + fprintf(stderr, + _("%s: `%s' is the NIS master for this client.\n"), + Prog, nis_master); + } + exit (1); + } +#endif + + /* + * Non-privileged users are only allowed to change the + * shell if the UID of the user matches the current + * real UID. + */ + + if (! amroot && pw->pw_uid != getuid()) { + SYSLOG((LOG_WARN, NOPERM2, user)); + closelog(); + fprintf(stderr, _("You may not change the shell for %s.\n"), + user); + exit(1); + } + + /* + * Non-privileged users are only allowed to change the + * shell if it is not a restricted one. + */ + + if (! amroot && restricted_shell(pw->pw_shell)) { + SYSLOG((LOG_WARN, NOPERM2, user)); + closelog(); + fprintf(stderr, _("You may not change the shell for %s.\n"), + user); + exit(1); + } + + /* + * Non-privileged users are optionally authenticated + * (must enter the password of the user whose information + * is being changed) before any changes can be made. + * Idea from util-linux chfn/chsh. --marekm + */ + + if (!amroot && getdef_bool("CHFN_AUTH")) + passwd_check(pw->pw_name, pw->pw_passwd, "chsh"); + + /* + * Now get the login shell. Either get it from the password + * file, or use the value from the command line. + */ + + if (! sflg) + STRFCPY(loginsh, pw->pw_shell); + + /* + * If the login shell was not set on the command line, + * let the user interactively change it. + */ + + if (! sflg) { + printf(_("Changing the login shell for %s\n"), user); + new_fields(); + } + + /* + * Check all of the fields for valid information. The shell + * field may not contain any illegal characters. Non-privileged + * users are restricted to using the shells in /etc/shells. + * The shell must be executable by the user. + */ + + if (valid_field (loginsh, ":,=")) { + fprintf(stderr, _("%s: Invalid entry: %s\n"), Prog, loginsh); + closelog(); + exit(1); + } + if (!amroot && (!check_shell(loginsh) || access(loginsh, X_OK) != 0)) { + fprintf(stderr, _("%s is an invalid shell.\n"), loginsh); + closelog(); + exit(1); + } + + /* + * Before going any further, raise the ulimit to prevent + * colliding into a lowered ulimit, and set the real UID + * to root to protect against unexpected signals. Any + * keyboard signals are set to be ignored. + */ + + if (setuid(0)) { + SYSLOG((LOG_ERR, NOTROOT2)); + closelog(); + fprintf (stderr, _("Cannot change ID to root.\n")); + exit(1); + } + pwd_init(); + + /* + * The passwd entry is now ready to be committed back to + * the password file. Get a lock on the file and open it. + */ + + if (!pw_lock()) { + SYSLOG((LOG_WARN, PWDBUSY2)); + closelog(); + fprintf(stderr, + _("Cannot lock the password file; try again later.\n")); + exit(1); + } + if (! pw_open (O_RDWR)) { + SYSLOG((LOG_ERR, OPNERROR2)); + closelog(); + fprintf(stderr, _("Cannot open the password file.\n")); + pw_unlock(); + exit(1); + } + + /* + * Get the entry to update using pw_locate() - we want the real + * one from /etc/passwd, not the one from getpwnam() which could + * contain the shadow password if (despite the warnings) someone + * enables AUTOSHADOW (or SHADOW_COMPAT in libc). --marekm + */ + pw = pw_locate(user); + if (!pw) { + pw_unlock(); + fprintf(stderr, + _("%s: %s not found in /etc/passwd\n"), Prog, user); + exit(1); + } + + /* + * Make a copy of the entry, then change the shell field. The other + * fields remain unchanged. + */ + pwent = *pw; + pwent.pw_shell = loginsh; + + /* + * Update the passwd file entry. If there is a DBM file, + * update that entry as well. + */ + + if (!pw_update(&pwent)) { + SYSLOG((LOG_ERR, UPDERROR2)); + closelog(); + fprintf(stderr, _("Error updating the password entry.\n")); + pw_unlock(); + exit(1); + } +#ifdef NDBM + if (pw_dbm_present() && ! pw_dbm_update (&pwent)) { + SYSLOG((LOG_ERR, DBMERROR2)); + closelog(); + fprintf (stderr, _("Error updating the DBM password entry.\n")); + pw_unlock(); + exit(1); + } + endpwent(); +#endif + + /* + * Changes have all been made, so commit them and unlock the + * file. + */ + + if (!pw_close()) { + SYSLOG((LOG_ERR, CLSERROR2)); + closelog(); + fprintf(stderr, _("Cannot commit password file changes.\n")); + pw_unlock(); + exit(1); + } + if (!pw_unlock()) { + SYSLOG((LOG_ERR, UNLKERROR2)); + closelog(); + fprintf(stderr, _("Cannot unlock the password file.\n")); + exit(1); + } + SYSLOG((LOG_INFO, CHGSHELL, user, loginsh)); + closelog(); + exit (0); +} diff --git a/current/src/dpasswd.c b/current/src/dpasswd.c new file mode 100644 index 00000000..6de5ea20 --- /dev/null +++ b/current/src/dpasswd.c @@ -0,0 +1,259 @@ +/* + * Copyright 1990 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: dpasswd.c,v 1.12 2000/09/02 18:40:43 marekm Exp $") + +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" +#include "dialup.h" + +#define DTMP "/etc/d_passwd.tmp" + +/* + * Prompts and messages go here. + */ + +#define DIALCHG "changed password for %s\n" +#define DIALADD "added password for %s\n" +#define DIALREM "removed password for %s\n" + +static int aflg = 0; +static int dflg = 0; +static char *Prog; + +extern int optind; +extern char *optarg; + +extern char *getpass(); + +/* local function prototypes */ +static void usage(void); + +static void +usage(void) +{ + fprintf(stderr, _("Usage: %s [ -(a|d) ] shell\n"), Prog); + exit(1); +} + +int +main(int argc, char **argv) +{ + struct dialup *dial; + struct dialup dent; + struct stat sb; + FILE *fp; + char *sh = 0; + char *cp; + char pass[BUFSIZ]; + int fd; + int found = 0; + int opt; + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + + while ((opt = getopt (argc, argv, "a:d:")) != EOF) { + switch (opt) { + case 'a': + aflg++; + sh = optarg; + break; + case 'd': + dflg++; + sh = optarg; + break; + default: + usage (); + } + } + if (! aflg && ! dflg) + aflg++; + + if (! sh) { + if (optind >= argc) + usage (); + else + sh = argv[optind]; + } + if (aflg + dflg != 1) + usage (); + + /* + * Add a new shell to the password file, or update an existing + * entry. Begin by getting an encrypted password for this + * shell. + */ + + if (aflg) { + int tries = 3; + + dent.du_shell = sh; + dent.du_passwd = ""; /* XXX warning: const */ + +again: + if (! (cp = getpass(_("Shell password: ")))) + exit (1); + + STRFCPY(pass, cp); + strzero(cp); + + if (! (cp = getpass(_("re-enter Shell password: ")))) + exit (1); + + if (strcmp (pass, cp)) { + strzero(pass); + strzero(cp); + fprintf(stderr, + _("%s: Passwords do not match, try again.\n"), + Prog); + + if (--tries) + goto again; + + exit(1); + } + strzero(cp); + dent.du_passwd = pw_encrypt(pass, crypt_make_salt()); + strzero(pass); + } + + /* + * Create the temporary file for the updated dialup password + * information to be placed into. Turn it into a (FILE *) + * for use by putduent(). + */ + + if ((fd = open (DTMP, O_CREAT|O_EXCL|O_RDWR, 0600)) < 0) { + snprintf(pass, sizeof pass, _("%s: can't create %s"), Prog, DTMP); + perror (pass); + exit (1); + } + if (! (fp = fdopen (fd, "r+"))) { + snprintf(pass, sizeof pass, _("%s: can't open %s"), Prog, DTMP); + perror (pass); + unlink (DTMP); + exit (1); + } + + /* + * Scan the dialup password file for the named entry, + * copying out other entries along the way. Copying + * stops when a match is found or the file runs out. + */ + + while ((dial = getduent ())) { + if (strcmp (dial->du_shell, sh) == 0) { + found = 1; + break; + } + if (putduent (dial, fp)) + goto failure; + } + + /* + * To delete the entry, just don't copy it. To update + * the entry, output the modified version - works with + * new entries as well. + */ + + if (dflg && ! found) { + fprintf(stderr, _("%s: Shell %s not found.\n"), Prog, sh); + goto failure; + } + if (aflg) + if (putduent (&dent, fp)) + goto failure; + + /* + * Now copy out the remaining entries. Flush and close the + * new file before doing anything nasty to the existing + * file. + */ + + + while ((dial = getduent ())) + if (putduent (dial, fp)) + goto failure; + + if (fflush (fp)) + goto failure; + + fclose (fp); + + /* + * If the original file did not exist, we must create a new + * file with owner "root" and mode 400. Otherwise we copy + * the modes from the existing file to the new file. + * + * After this is done the new file will replace the old file. + */ + + pwd_init(); + + if (! stat (DIALPWD, &sb)) { + chown (DTMP, sb.st_uid, sb.st_gid); + chmod (DTMP, sb.st_mode); + unlink (DIALPWD); + } else { + chown (DTMP, 0, 0); + chmod (DTMP, 0400); + } + if (! link (DTMP, DIALPWD)) + unlink (DTMP); + + if (aflg && ! found) + SYSLOG((LOG_INFO, DIALADD, sh)); + else if (aflg && found) + SYSLOG((LOG_INFO, DIALCHG, sh)); + else if (dflg) + SYSLOG((LOG_INFO, DIALREM, sh)); + + closelog(); + sync (); + exit (0); + +failure: + unlink (DTMP); + closelog(); + exit (1); +} diff --git a/current/src/expiry.c b/current/src/expiry.c new file mode 100644 index 00000000..b8d09b50 --- /dev/null +++ b/current/src/expiry.c @@ -0,0 +1,210 @@ +/* + * Copyright 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: expiry.c,v 1.9 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" +#include "defines.h" +#include + +#ifndef AGING +#if defined(HAVE_USERSEC_H) || defined(SHADOWPWD) +#define AGING 1 +#endif +#endif + + +#if !defined(SHADOWPWD) && !defined(AGING) /*{*/ + +/* + * Not much to do here ... + */ + +int +main(int argc, char **argv) +{ + exit (0); +} + +#else /*} AGING || SHADOWPWD {*/ + +/* local function prototypes */ +static RETSIGTYPE catch(int); +static void usage(void); + +/* + * catch - signal catcher + */ + +static RETSIGTYPE +catch(int sig) +{ + exit (10); +} + +/* + * usage - print syntax message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("Usage: expiry { -f | -c }\n")); + exit(10); +} + +/* + * expiry - check and enforce password expiration policy + * + * expiry checks (-c) the current password expiraction and + * forces (-f) changes when required. It is callable as a + * normal user command. + */ + +int +main(int argc, char **argv) +{ + struct passwd *pwd; +#ifdef SHADOWPWD + struct spwd *spwd; +#endif + char *Prog = argv[0]; + + sanitize_env(); + + /* + * Start by disabling all of the keyboard signals. + */ + + signal (SIGHUP, catch); + signal (SIGINT, catch); + signal (SIGQUIT, catch); +#ifdef SIGTSTP + signal (SIGTSTP, catch); +#endif + + /* + * expiry takes one of two arguments. The default action + * is to give the usage message. + */ + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (argc != 2 || (strcmp (argv[1], "-f") && strcmp (argv[1], "-c"))) + usage (); + +#if 0 /* could be setgid shadow with /etc/shadow mode 0640 */ + /* + * Make sure I am root. Can't open /etc/shadow without root + * authority. + */ + + if (geteuid () != 0) { + fprintf(stderr, _("%s: WARNING! Must be set-UID root!\n"), + argv[0]); + exit(10); + } +#endif + + /* + * Get user entries for /etc/passwd and /etc/shadow + */ + + if (!(pwd = get_my_pwent())) { + fprintf(stderr, _("%s: unknown user\n"), Prog); + exit(10); + } +#ifdef SHADOWPWD + spwd = getspnam(pwd->pw_name); +#endif + + /* + * If checking accounts, use agecheck() function. + */ + + if (strcmp (argv[1], "-c") == 0) { + + /* + * Print out number of days until expiration. + */ + +#ifdef SHADOWPWD + agecheck (pwd, spwd); +#else + agecheck (pwd); +#endif + + /* + * Exit with status indicating state of account -- + */ + +#ifdef SHADOWPWD + exit (isexpired (pwd, spwd)); +#else + exit (isexpired (pwd)); +#endif + } + + /* + * If forcing password change, use expire() function. + */ + + if (strcmp (argv[1], "-f") == 0) { + + /* + * Just call expire(). It will force the change + * or give a message indicating what to do. And + * it doesn't return at all unless the account + * is unexpired. + */ + +#ifdef SHADOWPWD + expire (pwd, spwd); +#else + expire (pwd); +#endif + exit (0); + } + + /* + * Can't get here ... + */ + + usage (); + exit (1); +} +#endif /*}*/ diff --git a/current/src/faillog.c b/current/src/faillog.c new file mode 100644 index 00000000..beb418ba --- /dev/null +++ b/current/src/faillog.c @@ -0,0 +1,379 @@ +/* + * Copyright 1989 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: faillog.c,v 1.10 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" +#include "faillog.h" + +static char *Prog; /* program name */ +static FILE *fail; /* failure file stream */ +static uid_t user; /* one single user, specified on command line */ +static int days; /* number of days to consider for print command */ +static time_t seconds; /* that number of days in seconds */ + +static int + aflg = 0, /* set if all users are to be printed always */ + uflg = 0, /* set if user is a valid user id */ + tflg = 0; /* print is restricted to most recent days */ + +static struct stat statbuf; /* fstat buffer for file size */ + +#if !defined(UNISTD_H) && !defined(STDLIB_H) +extern char *optarg; +#endif + +#define NOW (time((time_t *) 0)) + +/* local function prototypes */ +static void usage(void); +static void print(void); +static void print_one(const struct faillog *, uid_t); +static void reset(void); +static int reset_one(uid_t); +static void setmax(int); +static void setmax_one(uid_t, int); +static void set_locktime(long); +static void set_locktime_one(uid_t, long); + + +static void +usage(void) +{ + fprintf(stderr, + _("usage: %s [-a|-u user] [-m max] [-r] [-t days] [-l locksecs]\n"), + Prog); + exit(1); +} + +int +main(int argc, char **argv) +{ + int c, anyflag = 0; + struct passwd *pwent; + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* try to open for read/write, if that fails - read only */ + + fail = fopen(FAILLOG_FILE, "r+"); + if (!fail) + fail = fopen(FAILLOG_FILE, "r"); + if (!fail) { + perror(FAILLOG_FILE); + exit(1); + } + while ((c = getopt(argc, argv, "al:m:pru:t:")) != EOF) { + switch (c) { + case 'a': + aflg++; + if (uflg) + usage(); + break; + case 'l': + set_locktime((long) atoi(optarg)); + anyflag++; + break; + case 'm': + setmax(atoi(optarg)); + anyflag++; + break; + case 'p': + print(); + anyflag++; + break; + case 'r': + reset(); + anyflag++; + break; + case 'u': + if (aflg) + usage(); + + pwent = getpwnam(optarg); + if (!pwent) { + fprintf(stderr, _("Unknown User: %s\n"), optarg); + exit(1); + } + uflg++; + user = pwent->pw_uid; + break; + case 't': + days = atoi(optarg); + seconds = days * DAY; + tflg++; + break; + default: + usage(); + } + } + /* no flags implies -a -p (= print information for all users) */ + if (!(anyflag || aflg || tflg || uflg)) + aflg++; + /* (-a or -t days or -u user) and no other flags implies -p + (= print information for selected users) */ + if (!anyflag && (aflg || tflg || uflg)) + print(); + fclose(fail); + return 0; + /*NOTREACHED*/ +} + +static void +print(void) +{ + uid_t uid; + off_t offset; + struct faillog faillog; + + if (uflg) { + offset = user * sizeof faillog; + if (fstat(fileno(fail), &statbuf)) { + perror(FAILLOG_FILE); + return; + } + if (offset >= statbuf.st_size) + return; + + fseek(fail, (off_t) user * sizeof faillog, SEEK_SET); + if (fread((char *) &faillog, sizeof faillog, 1, fail) == 1) + print_one(&faillog, user); + else + perror(FAILLOG_FILE); + } else { + for (uid = 0; + fread((char *) &faillog, sizeof faillog, 1, fail) == 1; + uid++) { + + if (aflg == 0 && faillog.fail_cnt == 0) + continue; + + if (aflg == 0 && tflg && + NOW - faillog.fail_time > seconds) + continue; + + if (aflg && faillog.fail_time == 0) + continue; + + print_one(&faillog, uid); + } + } +} + +static void +print_one(const struct faillog *fl, uid_t uid) +{ + static int once; + char *cp; + struct tm *tm; + time_t now; + struct passwd *pwent; +#ifdef HAVE_STRFTIME + char ptime[80]; +#endif + + if (!once) { + printf(_("Username Failures Maximum Latest\n")); + once++; + } + pwent = getpwuid(uid); + time(&now); + tm = localtime(&fl->fail_time); +#ifdef HAVE_STRFTIME + strftime(ptime, sizeof(ptime), "%a %b %e %H:%M:%S %z %Y",tm); + cp = ptime; +#else + cp = asctime(tm); + cp[24] = '\0'; +#endif + if (pwent) { + printf("%-12s %4d %4d", + pwent->pw_name, fl->fail_cnt, fl->fail_max); + if (fl->fail_time) { + printf(_(" %s on %s"), cp, fl->fail_line); + if (fl->fail_locktime) { + if (fl->fail_time + fl->fail_locktime > now + && fl->fail_cnt) + printf(_(" [%lds left]"), + fl->fail_time + fl->fail_locktime - now); + else + printf(_(" [%lds lock]"), fl->fail_locktime); + } + } + putchar('\n'); + } +} + +static void +reset(void) +{ + uid_t uid; + + if (uflg) + reset_one(user); + else + for (uid = 0; reset_one(uid); uid++) + ; +} + +static int +reset_one(uid_t uid) +{ + off_t offset; + struct faillog faillog; + + offset = uid * sizeof faillog; + if (fstat(fileno(fail), &statbuf)) { + perror(FAILLOG_FILE); + return 0; + } + if (offset >= statbuf.st_size) + return 0; + + if (fseek(fail, offset, SEEK_SET) != 0) { + perror(FAILLOG_FILE); + return 0; + } + if (fread((char *) &faillog, sizeof faillog, 1, fail) != 1) { + if (!feof(fail)) + perror(FAILLOG_FILE); + + return 0; + } + if (faillog.fail_cnt == 0) + return 1; /* don't fill in no holes ... */ + + faillog.fail_cnt = 0; + + if (fseek(fail, offset, SEEK_SET) == 0 + && fwrite((char *) &faillog, sizeof faillog, 1, fail) == 1) { + fflush(fail); + return 1; + } else { + perror(FAILLOG_FILE); + } + return 0; +} + +static void +setmax(int max) +{ + struct passwd *pwent; + + if (uflg) { + setmax_one(user, max); + } else { + setpwent(); + while ((pwent = getpwent())) + setmax_one(pwent->pw_uid, max); + } +} + +static void +setmax_one(uid_t uid, int max) +{ + off_t offset; + struct faillog faillog; + + offset = uid * sizeof faillog; + + if (fseek(fail, offset, SEEK_SET) != 0) { + perror(FAILLOG_FILE); + return; + } + if (fread((char *) &faillog, sizeof faillog, 1, fail) != 1) { + if (!feof(fail)) + perror(FAILLOG_FILE); + memzero(&faillog, sizeof faillog); + } + faillog.fail_max = max; + + if (fseek(fail, offset, SEEK_SET) == 0 + && fwrite((char *) &faillog, sizeof faillog, 1, fail) == 1) + fflush(fail); + else + perror(FAILLOG_FILE); +} + +/* + * XXX - this needs to be written properly some day, right now it is + * a quick cut-and-paste hack from the above two functions. --marekm + */ +static void +set_locktime(long locktime) +{ + struct passwd *pwent; + + if (uflg) { + set_locktime_one(user, locktime); + } else { + setpwent(); + while ((pwent = getpwent())) + set_locktime_one(pwent->pw_uid, locktime); + } +} + +static void +set_locktime_one(uid_t uid, long locktime) +{ + off_t offset; + struct faillog faillog; + + offset = uid * sizeof faillog; + + if (fseek(fail, offset, SEEK_SET) != 0) { + perror(FAILLOG_FILE); + return; + } + if (fread((char *) &faillog, sizeof faillog, 1, fail) != 1) { + if (!feof(fail)) + perror(FAILLOG_FILE); + memzero(&faillog, sizeof faillog); + } + faillog.fail_locktime = locktime; + + if (fseek(fail, offset, SEEK_SET) == 0 + && fwrite((char *) &faillog, sizeof faillog, 1, fail) == 1) + fflush(fail); + else + perror(FAILLOG_FILE); +} diff --git a/current/src/gpasswd.c b/current/src/gpasswd.c new file mode 100644 index 00000000..d1bb023c --- /dev/null +++ b/current/src/gpasswd.c @@ -0,0 +1,661 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: gpasswd.c,v 1.17 2000/09/02 18:40:43 marekm Exp $") + +#include +#include +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" + +#include "groupio.h" +#ifdef SHADOWGRP +#include "sgroupio.h" +#endif + +static char *Prog; +#ifdef SHADOWGRP +static int is_shadowgrp; +#endif + +static int + aflg = 0, + Aflg = 0, + dflg = 0, + Mflg = 0, + rflg = 0, + Rflg = 0; + +#ifndef RETRIES +#define RETRIES 3 +#endif + +extern int optind; +extern char *optarg; +#ifdef NDBM +#ifdef SHADOWGRP +extern int sg_dbm_mode; +#endif +extern int gr_dbm_mode; +#endif + +/* local function prototypes */ +static void usage(void); +static RETSIGTYPE die(int); +static int check_list(const char *); + +/* + * usage - display usage message + */ + +static void +usage(void) +{ + fprintf(stderr, _("usage: %s [-r|-R] group\n"), Prog); + fprintf(stderr, _(" %s [-a user] group\n"), Prog); + fprintf(stderr, _(" %s [-d user] group\n"), Prog); +#ifdef SHADOWGRP + fprintf(stderr, _(" %s [-A user,...] [-M user,...] group\n"), + Prog); +#else + fprintf(stderr, _(" %s [-M user,...] group\n"), Prog); +#endif + exit (1); +} + +/* + * die - set or reset termio modes. + * + * die() is called before processing begins. signal() is then + * called with die() as the signal handler. If signal later + * calls die() with a signal number, the terminal modes are + * then reset. + */ + +static RETSIGTYPE +die(int killed) +{ + static TERMIO sgtty; + + if (killed) + STTY(0, &sgtty); + else + GTTY(0, &sgtty); + + if (killed) { + putchar ('\n'); + fflush (stdout); + exit (killed); + } +} + +/* + * check_list - check a comma-separated list of user names for validity + * + * check_list scans a comma-separated list of user names and checks + * that each listed name exists. + */ + +static int +check_list(const char *users) +{ + const char *start, *end; + char username[32]; + int errors = 0; + int len; + + for (start = users; start && *start; start = end) { + if ((end = strchr (start, ','))) { + len = end - start; + end++; + } else { + len = strlen(start); + } + + if (len > sizeof(username) - 1) + len = sizeof(username) - 1; + strncpy(username, start, len); + username[len] = '\0'; + + /* + * This user must exist. + */ + + if (!getpwnam(username)) { + fprintf(stderr, _("%s: unknown user %s\n"), + Prog, username); + errors++; + } + } + return errors; +} + + +static void +failure(void) +{ + fprintf(stderr, _("Permission denied.\n")); + exit(1); + /*NOTREACHED*/ +} + + +/* + * gpasswd - administer the /etc/group file + * + * -a user add user to the named group + * -d user remove user from the named group + * -r remove password from the named group + * -R restrict access to the named group + * -A user,... make list of users the administrative users + * -M user,... make list of users the group members + */ + +int +main(int argc, char **argv) +{ + int flag; + char *cp; + int amroot; + int retries; + struct group *gr = NULL; + struct group grent; + static char pass[BUFSIZ]; +#ifdef SHADOWGRP + struct sgrp *sg = NULL; + struct sgrp sgent; + char *admins = NULL; +#endif + struct passwd *pw = NULL; + char *myname; + char *user = NULL; + char *group = NULL; + char *members = NULL; + + sanitize_env(); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* + * Make a note of whether or not this command was invoked + * by root. This will be used to bypass certain checks + * later on. Also, set the real user ID to match the + * effective user ID. This will prevent the invoker from + * issuing signals which would interfer with this command. + */ + + amroot = getuid () == 0; +#ifdef NDBM +#ifdef SHADOWGRP + sg_dbm_mode = O_RDWR; +#endif + gr_dbm_mode = O_RDWR; +#endif + + Prog = Basename(argv[0]); + + OPENLOG("gpasswd"); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + +#ifdef SHADOWGRP + is_shadowgrp = sgr_file_present(); +#endif + while ((flag = getopt (argc, argv, "a:d:grRA:M:")) != EOF) { + switch (flag) { + case 'a': /* add a user */ + user = optarg; + if (!getpwnam(user)) { + fprintf(stderr, _("%s: unknown user %s\n"), + Prog, user); + exit(1); + } + aflg++; + break; +#ifdef SHADOWGRP + case 'A': + if (!amroot) + failure(); + if (!is_shadowgrp) { + fprintf(stderr, + _("%s: shadow group passwords required for -A\n"), + Prog); + exit(2); + } + admins = optarg; + if (check_list(admins)) + exit(1); + Aflg++; + break; +#endif + case 'd': /* delete a user */ + dflg++; + user = optarg; + break; + case 'g': /* no-op from normal password */ + break; + case 'M': + if (!amroot) + failure(); + members = optarg; + if (check_list(members)) + exit(1); + Mflg++; + break; + case 'r': /* remove group password */ + rflg++; + break; + case 'R': /* restrict group password */ + Rflg++; + break; + default: + usage(); + } + } + + /* + * Make sure exclusive flags are exclusive + */ + + if (aflg + dflg + rflg + Rflg + (Aflg || Mflg) > 1) + usage (); + + /* + * Determine the name of the user that invoked this command. + * This is really hit or miss because there are so many ways + * that command can be executed and so many ways to trip up + * the routines that report the user name. + */ + + pw = get_my_pwent(); + if (!pw) { + fprintf(stderr, _("Who are you?\n")); + exit(1); + } + myname = xstrdup(pw->pw_name); + + /* + * Get the name of the group that is being affected. The group + * entry will be completely replicated so it may be modified + * later on. + */ + + /* + * XXX - should get the entry using gr_locate() and modify + * that, getgrnam() could give us a NIS group. --marekm + */ + + if (! (group = argv[optind])) + usage (); + + if (! (gr = getgrnam (group))) { + fprintf (stderr, _("unknown group: %s\n"), group); + exit (1); + } + grent = *gr; + grent.gr_name = xstrdup(gr->gr_name); + grent.gr_passwd = xstrdup(gr->gr_passwd); + + grent.gr_mem = dup_list(gr->gr_mem); +#ifdef SHADOWGRP + if ((sg = getsgnam (group))) { + sgent = *sg; + sgent.sg_name = xstrdup(sg->sg_name); + sgent.sg_passwd = xstrdup(sg->sg_passwd); + + sgent.sg_mem = dup_list(sg->sg_mem); + sgent.sg_adm = dup_list(sg->sg_adm); + } else { + sgent.sg_name = xstrdup(group); + sgent.sg_passwd = grent.gr_passwd; + grent.gr_passwd = "!"; /* XXX warning: const */ + + sgent.sg_mem = dup_list(grent.gr_mem); + + sgent.sg_adm = (char **) xmalloc(sizeof(char *) * 2); +#ifdef FIRST_MEMBER_IS_ADMIN + if (sgent.sg_mem[0]) { + sgent.sg_adm[0] = xstrdup(sgent.sg_mem[0]); + sgent.sg_adm[1] = 0; + } else +#endif + sgent.sg_adm[0] = 0; + + sg = &sgent; + } + + /* + * The policy here for changing a group is that 1) you must be + * root or 2). you must be listed as an administrative member. + * Administrative members can do anything to a group that the + * root user can. + */ + + if (!amroot && !is_on_list(sgent.sg_adm, myname)) + failure(); +#else /* ! SHADOWGRP */ + +#ifdef FIRST_MEMBER_IS_ADMIN + /* + * The policy here for changing a group is that 1) you must bes + * root or 2) you must be the first listed member of the group. + * The first listed member of a group can do anything to that + * group that the root user can. The rationale for this hack is + * that the FIRST user is probably the most important user in + * this entire group. + */ + + if (! amroot) { + if (grent.gr_mem[0] == (char *) 0) + failure(); + + if (strcmp(grent.gr_mem[0], myname) != 0) + failure(); + } +#else + /* + * This feature enabled by default could be a security problem + * when installed on existing systems where the first group + * member might be just a normal user... --marekm + */ + + if (!amroot) + failure(); +#endif + +#endif /* SHADOWGRP */ + + /* + * Removing a password is straight forward. Just set the + * password field to a "". + */ + + if (rflg) { + grent.gr_passwd = ""; /* XXX warning: const */ +#ifdef SHADOWGRP + sgent.sg_passwd = ""; /* XXX warning: const */ +#endif + SYSLOG((LOG_INFO, "remove password from group %s by %s\n", group, myname)); + goto output; + } else if (Rflg) { + /* + * Same thing for restricting the group. Set the password + * field to "!". + */ + + grent.gr_passwd = "!"; /* XXX warning: const */ +#ifdef SHADOWGRP + sgent.sg_passwd = "!"; /* XXX warning: const */ +#endif + SYSLOG((LOG_INFO, "restrict access to group %s by %s\n", group, myname)); + goto output; + } + + /* + * Adding a member to a member list is pretty straightforward + * as well. Call the appropriate routine and split. + */ + + if (aflg) { + printf(_("Adding user %s to group %s\n"), user, group); + grent.gr_mem = add_list (grent.gr_mem, user); +#ifdef SHADOWGRP + sgent.sg_mem = add_list (sgent.sg_mem, user); +#endif + SYSLOG((LOG_INFO, "add member %s to group %s by %s\n", user, group, myname)); + goto output; + } + + /* + * Removing a member from the member list is the same deal + * as adding one, except the routine is different. + */ + + if (dflg) { + int removed = 0; + + printf(_("Removing user %s from group %s\n"), user, group); + + if (is_on_list(grent.gr_mem, user)) { + removed = 1; + grent.gr_mem = del_list (grent.gr_mem, user); + } +#ifdef SHADOWGRP + if (is_on_list(sgent.sg_mem, user)) { + removed = 1; + sgent.sg_mem = del_list (sgent.sg_mem, user); + } +#endif + if (! removed) { + fprintf(stderr, _("%s: unknown member %s\n"), + Prog, user); + exit (1); + } + SYSLOG((LOG_INFO, "remove member %s from group %s by %s\n", + user, group, myname)); + goto output; + } + +#ifdef SHADOWGRP + /* + * Replacing the entire list of administators is simple. Check the + * list to make sure everyone is a real user. Then slap the new + * list in place. + */ + + if (Aflg) { + SYSLOG((LOG_INFO, "set administrators of %s to %s\n", + group, admins)); + sgent.sg_adm = comma_to_list(admins); + if (!Mflg) + goto output; + } +#endif + + /* + * Replacing the entire list of members is simple. Check the list + * to make sure everyone is a real user. Then slap the new list + * in place. + */ + + if (Mflg) { + SYSLOG((LOG_INFO,"set members of %s to %s\n",group,members)); +#ifdef SHADOWGRP + sgent.sg_mem = comma_to_list(members); +#endif + grent.gr_mem = comma_to_list(members); + goto output; + } + + /* + * If the password is being changed, the input and output must + * both be a tty. The typical keyboard signals are caught + * so the termio modes can be restored. + */ + + if (! isatty (0) || ! isatty (1)) { + fprintf(stderr, _("%s: Not a tty\n"), Prog); + exit (1); + } + + die (0); /* save tty modes */ + + signal (SIGHUP, die); + signal (SIGINT, die); + signal (SIGQUIT, die); + signal (SIGTERM, die); +#ifdef SIGTSTP + signal (SIGTSTP, die); +#endif + + /* + * A new password is to be entered and it must be encrypted, + * etc. The password will be prompted for twice, and both + * entries must be identical. There is no need to validate + * the old password since the invoker is either the group + * owner, or root. + */ + + printf(_("Changing the password for group %s\n"), group); + + for (retries = 0; retries < RETRIES; retries++) { + if (! (cp = getpass(_("New Password: ")))) + exit (1); + + STRFCPY(pass, cp); + strzero(cp); + if (! (cp = getpass (_("Re-enter new password: ")))) + exit (1); + + if (strcmp(pass, cp) == 0) { + strzero(cp); + break; + } + + strzero(cp); + memzero(pass, sizeof pass); + + if (retries + 1 < RETRIES) + puts(_("They don't match; try again")); + } + + if (retries == RETRIES) { + fprintf(stderr, _("%s: Try again later\n"), Prog); + exit(1); + } + + cp = pw_encrypt(pass, crypt_make_salt()); + memzero(pass, sizeof pass); +#ifdef SHADOWGRP + if (is_shadowgrp) + sgent.sg_passwd = cp; + else +#endif + grent.gr_passwd = cp; + SYSLOG((LOG_INFO, "change the password for group %s by %s\n", group, myname)); + + /* + * This is the common arrival point to output the new group + * file. The freshly crafted entry is in allocated space. + * The group file will be locked and opened for writing. The + * new entry will be output, etc. + */ + +output: + if (setuid(0)) { + fprintf(stderr, _("Cannot change ID to root.\n")); + SYSLOG((LOG_ERR, "can't setuid(0)")); + closelog(); + exit(1); + } + pwd_init(); + + if (! gr_lock ()) { + fprintf(stderr, _("%s: can't get lock\n"), Prog); + SYSLOG((LOG_WARN, "failed to get lock for /etc/group\n")); + exit (1); + } +#ifdef SHADOWGRP + if (is_shadowgrp && ! sgr_lock ()) { + fprintf(stderr, _("%s: can't get shadow lock\n"), Prog); + SYSLOG((LOG_WARN, "failed to get lock for /etc/gshadow\n")); + exit (1); + } +#endif + if (! gr_open (O_RDWR)) { + fprintf(stderr, _("%s: can't open file\n"), Prog); + SYSLOG((LOG_WARN, "cannot open /etc/group\n")); + exit (1); + } +#ifdef SHADOWGRP + if (is_shadowgrp && ! sgr_open (O_RDWR)) { + fprintf(stderr, _("%s: can't open shadow file\n"), Prog); + SYSLOG((LOG_WARN, "cannot open /etc/gshadow\n")); + exit (1); + } +#endif + if (! gr_update (&grent)) { + fprintf(stderr, _("%s: can't update entry\n"), Prog); + SYSLOG((LOG_WARN, "cannot update /etc/group\n")); + exit (1); + } +#ifdef SHADOWGRP + if (is_shadowgrp && ! sgr_update (&sgent)) { + fprintf(stderr, _("%s: can't update shadow entry\n"), Prog); + SYSLOG((LOG_WARN, "cannot update /etc/gshadow\n")); + exit (1); + } +#endif + if (! gr_close ()) { + fprintf(stderr, _("%s: can't re-write file\n"), Prog); + SYSLOG((LOG_WARN, "cannot re-write /etc/group\n")); + exit (1); + } +#ifdef SHADOWGRP + if (is_shadowgrp && ! sgr_close ()) { + fprintf(stderr, _("%s: can't re-write shadow file\n"), Prog); + SYSLOG((LOG_WARN, "cannot re-write /etc/gshadow\n")); + exit (1); + } + if (is_shadowgrp) + sgr_unlock (); +#endif + if (! gr_unlock ()) { + fprintf(stderr, _("%s: can't unlock file\n"), Prog); + exit (1); + } +#ifdef NDBM + if (gr_dbm_present() && ! gr_dbm_update (&grent)) { + fprintf(stderr, _("%s: can't update DBM files\n"), Prog); + SYSLOG((LOG_WARN, "cannot update /etc/group DBM files\n")); + exit (1); + } + endgrent (); +#ifdef SHADOWGRP + if (is_shadowgrp && sg_dbm_present() && ! sg_dbm_update (&sgent)) { + fprintf(stderr, _("%s: can't update DBM shadow files\n"), Prog); + SYSLOG((LOG_WARN, "cannot update /etc/gshadow DBM files\n")); + exit (1); + } + endsgent (); +#endif +#endif + exit (0); + /*NOTREACHED*/ +} diff --git a/current/src/groupadd.c b/current/src/groupadd.c new file mode 100644 index 00000000..cdf92334 --- /dev/null +++ b/current/src/groupadd.c @@ -0,0 +1,537 @@ +/* + * Copyright 1991 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: groupadd.c,v 1.16 2000/09/02 18:40:43 marekm Exp $") + +#include +#include +#include +#include +#include + +#include "defines.h" +#include "prototypes.h" +#include "chkname.h" + +#include "getdef.h" + +#include "groupio.h" + +#ifdef SHADOWGRP +#include "sgroupio.h" + +static int is_shadow_grp; +#endif + +/* + * exit status values + */ + +#define E_SUCCESS 0 /* success */ +#define E_USAGE 2 /* invalid command syntax */ +#define E_BAD_ARG 3 /* invalid argument to option */ +#define E_GID_IN_USE 4 /* gid not unique (when -o not used) */ +#define E_NAME_IN_USE 9 /* group name nut unique */ +#define E_GRP_UPDATE 10 /* can't update group file */ + +static char *group_name; +static gid_t group_id; +static char *empty_list = NULL; + +static char *Prog; + +static int oflg = 0; /* permit non-unique group ID to be specified with -g */ +static int gflg = 0; /* ID value for the new group */ +static int fflg = 0; /* if group already exists, do nothing and exit(0) */ + +#ifdef NDBM +extern int gr_dbm_mode; +extern int sg_dbm_mode; +#endif + +extern int optind; +extern char *optarg; + +/* local function prototypes */ +static void usage(void); +static void new_grent(struct group *); +#ifdef SHADOWGRP +static void new_sgent(struct sgrp *); +#endif +static void grp_update(void); +static void find_new_gid(void); +static void check_new_name(void); +static void process_flags(int, char **); +static void close_files(void); +static void open_files(void); +static void fail_exit(int); + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("usage: groupadd [-g gid [-o]] group\n")); + exit(E_USAGE); +} + +/* + * new_grent - initialize the values in a group file entry + * + * new_grent() takes all of the values that have been entered and + * fills in a (struct group) with them. + */ + +static void +new_grent(struct group *grent) +{ + memzero(grent, sizeof *grent); + grent->gr_name = group_name; + grent->gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */ + grent->gr_gid = group_id; + grent->gr_mem = &empty_list; +} + +#ifdef SHADOWGRP +/* + * new_sgent - initialize the values in a shadow group file entry + * + * new_sgent() takes all of the values that have been entered and + * fills in a (struct sgrp) with them. + */ + +static void +new_sgent(struct sgrp *sgent) +{ + memzero(sgent, sizeof *sgent); + sgent->sg_name = group_name; + sgent->sg_passwd = "!"; /* XXX warning: const */ + sgent->sg_adm = &empty_list; + sgent->sg_mem = &empty_list; +} +#endif /* SHADOWGRP */ + +/* + * grp_update - add new group file entries + * + * grp_update() writes the new records to the group files. + */ + +static void +grp_update(void) +{ + struct group grp; +#ifdef SHADOWGRP + struct sgrp sgrp; +#endif /* SHADOWGRP */ + + /* + * Create the initial entries for this new group. + */ + + new_grent (&grp); +#ifdef SHADOWGRP + new_sgent (&sgrp); +#endif /* SHADOWGRP */ + + /* + * Write out the new group file entry. + */ + + if (! gr_update (&grp)) { + fprintf(stderr, _("%s: error adding new group entry\n"), Prog); + fail_exit(E_GRP_UPDATE); + } +#ifdef NDBM + + /* + * Update the DBM group file with the new entry as well. + */ + + if (gr_dbm_present() && ! gr_dbm_update (&grp)) { + fprintf(stderr, _("%s: cannot add new dbm group entry\n"), Prog); + fail_exit(E_GRP_UPDATE); + } + endgrent (); +#endif /* NDBM */ + +#ifdef SHADOWGRP + + /* + * Write out the new shadow group entries as well. + */ + + if (is_shadow_grp && ! sgr_update (&sgrp)) { + fprintf(stderr, _("%s: error adding new group entry\n"), Prog); + fail_exit(E_GRP_UPDATE); + } +#ifdef NDBM + + /* + * Update the DBM group file with the new entry as well. + */ + + if (is_shadow_grp && sg_dbm_present() && ! sg_dbm_update (&sgrp)) { + fprintf(stderr, _("%s: cannot add new dbm group entry\n"), Prog); + fail_exit(E_GRP_UPDATE); + } + endsgent (); +#endif /* NDBM */ +#endif /* SHADOWGRP */ + SYSLOG((LOG_INFO, "new group: name=%s, gid=%d\n", + group_name, group_id)); +} + +/* + * find_new_gid - find the next available GID + * + * find_new_gid() locates the next highest unused GID in the group + * file, or checks the given group ID against the existing ones for + * uniqueness. + */ + +static void +find_new_gid(void) +{ + const struct group *grp; + gid_t gid_min, gid_max; + + gid_min = getdef_num("GID_MIN", 100); + gid_max = getdef_num("GID_MAX", 60000); + + /* + * Start with some GID value if the user didn't provide us with + * one already. + */ + + if (! gflg) + group_id = gid_min; + + /* + * Search the entire group file, either looking for this + * GID (if the user specified one with -g) or looking for the + * largest unused value. + */ + +#ifdef NO_GETGRENT + gr_rewind(); + while ((grp = gr_next())) { +#else + setgrent(); + while ((grp = getgrent())) { +#endif + if (strcmp(group_name, grp->gr_name) == 0) { + if (fflg) { + fail_exit(E_SUCCESS); + } + fprintf(stderr, _("%s: name %s is not unique\n"), + Prog, group_name); + fail_exit(E_NAME_IN_USE); + } + if (gflg && group_id == grp->gr_gid) { + if (fflg) { + /* turn off -g and search again */ + gflg = 0; +#ifdef NO_GETGRENT + gr_rewind(); +#else + setgrent(); +#endif + continue; + } + fprintf(stderr, _("%s: gid %ld is not unique\n"), + Prog, (long) group_id); + fail_exit(E_GID_IN_USE); + } + if (! gflg && grp->gr_gid >= group_id) { + if (grp->gr_gid > gid_max) + continue; + group_id = grp->gr_gid + 1; + } + } + if (!gflg && group_id == gid_max + 1) { + for (group_id = gid_min; group_id < gid_max; group_id++) { +#ifdef NO_GETGRENT + gr_rewind(); + while ((grp = gr_next()) && grp->gr_gid != group_id) + ; + if (!grp) + break; +#else + if (!getgrgid(group_id)) + break; +#endif + } + if (group_id == gid_max) { + fprintf(stderr, _("%s: can't get unique gid\n"), + Prog); + fail_exit(E_GID_IN_USE); + } + } +} + +/* + * check_new_name - check the new name for validity + * + * check_new_name() insures that the new name doesn't contain + * any illegal characters. + */ + +static void +check_new_name(void) +{ + if (check_group_name(group_name)) + return; + + /* + * All invalid group names land here. + */ + + fprintf(stderr, _("%s: %s is a not a valid group name\n"), + Prog, group_name); + + exit(E_BAD_ARG); +} + +/* + * process_flags - perform command line argument setting + * + * process_flags() interprets the command line arguments and sets + * the values that the user will be created with accordingly. The + * values are checked for sanity. + */ + +static void +process_flags(int argc, char **argv) +{ + char *cp; + int arg; + + while ((arg = getopt(argc, argv, "og:O:f")) != EOF) { + switch (arg) { + case 'g': + gflg++; + if (! isdigit (optarg[0])) + usage (); + + group_id = strtol(optarg, &cp, 10); + if (*cp != '\0') { + fprintf(stderr, _("%s: invalid group %s\n"), + Prog, optarg); + fail_exit(E_BAD_ARG); + } + break; + case 'o': + oflg++; + break; + case 'O': + /* + * override login.defs defaults (-O name=value) + * example: -O GID_MIN=100 -O GID_MAX=499 + * note: -O GID_MIN=10,GID_MAX=499 doesn't work yet + */ + cp = strchr(optarg, '='); + if (!cp) { + fprintf(stderr, + _("%s: -O requires NAME=VALUE\n"), + Prog); + exit(E_BAD_ARG); + } + /* terminate name, point to value */ + *cp++ = '\0'; + if (putdef_str(optarg, cp) < 0) + exit(E_BAD_ARG); + break; + case 'f': + /* + * "force" - do nothing, just exit(0), if the + * specified group already exists. With -g, if + * specified gid already exists, choose another + * (unique) gid (turn off -g). Based on the + * RedHat's patch from shadow-utils-970616-9. + */ + fflg++; + break; + default: + usage(); + } + } + + if (oflg && !gflg) + usage(); + + if (optind != argc - 1) + usage(); + + group_name = argv[argc - 1]; + check_new_name(); +} + +/* + * close_files - close all of the files that were opened + * + * close_files() closes all of the files that were opened for this + * new group. This causes any modified entries to be written out. + */ + +static void +close_files(void) +{ + if (!gr_close()) { + fprintf(stderr, _("%s: cannot rewrite group file\n"), Prog); + fail_exit(E_GRP_UPDATE); + } + gr_unlock(); +#ifdef SHADOWGRP + if (is_shadow_grp && !sgr_close()) { + fprintf(stderr, _("%s: cannot rewrite shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } + if (is_shadow_grp) + sgr_unlock (); +#endif /* SHADOWGRP */ +} + +/* + * open_files - lock and open the group files + * + * open_files() opens the two group files. + */ + +static void +open_files(void) +{ + if (! gr_lock ()) { + fprintf(stderr, _("%s: unable to lock group file\n"), Prog); + exit(E_GRP_UPDATE); + } + if (! gr_open (O_RDWR)) { + fprintf(stderr, _("%s: unable to open group file\n"), Prog); + fail_exit(E_GRP_UPDATE); + } +#ifdef SHADOWGRP + if (is_shadow_grp && ! sgr_lock ()) { + fprintf(stderr, _("%s: unable to lock shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } + if (is_shadow_grp && ! sgr_open (O_RDWR)) { + fprintf(stderr, _("%s: unable to open shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } +#endif /* SHADOWGRP */ +} + +/* + * fail_exit - exit with an error code after unlocking files + */ + +static void +fail_exit(int code) +{ + (void) gr_unlock (); +#ifdef SHADOWGRP + if (is_shadow_grp) + sgr_unlock (); +#endif + exit (code); +} + +/* + * main - groupadd command + */ + +int +main(int argc, char **argv) +{ + + /* + * Get my name so that I can use it to report errors. + */ + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + +#ifdef SHADOWGRP + is_shadow_grp = sgr_file_present(); +#endif + + /* + * The open routines for the DBM files don't use read-write + * as the mode, so we have to clue them in. + */ + +#ifdef NDBM + gr_dbm_mode = O_RDWR; +#ifdef SHADOWGRP + sg_dbm_mode = O_RDWR; +#endif /* SHADOWGRP */ +#endif /* NDBM */ + process_flags(argc, argv); + + /* + * Start with a quick check to see if the group exists. + */ + + if (getgrnam(group_name)) { + if (fflg) { + exit(E_SUCCESS); + } + fprintf(stderr, _("%s: group %s exists\n"), Prog, group_name); + exit(E_NAME_IN_USE); + } + + /* + * Do the hard stuff - open the files, create the group entries, + * then close and update the files. + */ + + open_files(); + + if (!gflg || !oflg) + find_new_gid(); + + grp_update(); + + close_files(); + exit(E_SUCCESS); + /*NOTREACHED*/ +} diff --git a/current/src/groupdel.c b/current/src/groupdel.c new file mode 100644 index 00000000..7ddc3922 --- /dev/null +++ b/current/src/groupdel.c @@ -0,0 +1,351 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: groupdel.c,v 1.12 2000/09/02 18:40:43 marekm Exp $") + +#include +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" + +static char *group_name; +static char *Prog; +static int errors; + +#ifdef NDBM +extern int gr_dbm_mode; +extern int sg_dbm_mode; +#endif + +#include "groupio.h" + +#ifdef SHADOWGRP +#include "sgroupio.h" + +static int is_shadow_grp; +#endif + +/* + * exit status values + */ + +#define E_SUCCESS 0 /* success */ +#define E_USAGE 2 /* invalid command syntax */ +#define E_NOTFOUND 6 /* specified group doesn't exist */ +#define E_GROUP_BUSY 8 /* can't remove user's primary group */ +#define E_GRP_UPDATE 10 /* can't update group file */ + +/* local function prototypes */ +static void usage(void); +static void grp_update(void); +static void close_files(void); +static void open_files(void); +static void group_busy(gid_t); + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("usage: groupdel group\n")); + exit(E_USAGE); +} + +/* + * grp_update - update group file entries + * + * grp_update() writes the new records to the group files. + */ + +static void +grp_update(void) +{ +#ifdef NDBM + struct group *ogrp; +#endif + + if (!gr_remove(group_name)) { + fprintf(stderr, _("%s: error removing group entry\n"), Prog); + errors++; + } +#ifdef NDBM + + /* + * Update the DBM group file + */ + + if (gr_dbm_present()) { + if ((ogrp = getgrnam (group_name)) && + ! gr_dbm_remove (ogrp)) { + fprintf(stderr, _("%s: error removing group dbm entry\n"), + Prog); + errors++; + } + } + endgrent (); +#endif /* NDBM */ + +#ifdef SHADOWGRP + + /* + * Delete the shadow group entries as well. + */ + + if (is_shadow_grp && ! sgr_remove (group_name)) { + fprintf(stderr, _("%s: error removing shadow group entry\n"), + Prog); + errors++; + } +#ifdef NDBM + + /* + * Update the DBM shadow group file + */ + + if (is_shadow_grp && sg_dbm_present()) { + if (! sg_dbm_remove (group_name)) { + fprintf(stderr, + _("%s: error removing shadow group dbm entry\n"), + Prog); + errors++; + } + } + endsgent (); +#endif /* NDBM */ +#endif /* SHADOWGRP */ + SYSLOG((LOG_INFO, "remove group `%s'\n", group_name)); + return; +} + +/* + * close_files - close all of the files that were opened + * + * close_files() closes all of the files that were opened for this + * new group. This causes any modified entries to be written out. + */ + +static void +close_files(void) +{ + if (!gr_close()) { + fprintf(stderr, _("%s: cannot rewrite group file\n"), Prog); + errors++; + } + gr_unlock(); +#ifdef SHADOWGRP + if (is_shadow_grp && !sgr_close()) { + fprintf(stderr, _("%s: cannot rewrite shadow group file\n"), + Prog); + errors++; + } + if (is_shadow_grp) + sgr_unlock(); +#endif /* SHADOWGRP */ +} + +/* + * open_files - lock and open the group files + * + * open_files() opens the two group files. + */ + +static void +open_files(void) +{ + if (!gr_lock()) { + fprintf(stderr, _("%s: unable to lock group file\n"), Prog); + exit(E_GRP_UPDATE); + } + if (!gr_open(O_RDWR)) { + fprintf(stderr, _("%s: unable to open group file\n"), Prog); + exit(E_GRP_UPDATE); + } +#ifdef SHADOWGRP + if (is_shadow_grp && !sgr_lock()) { + fprintf(stderr, _("%s: unable to lock shadow group file\n"), + Prog); + exit(E_GRP_UPDATE); + } + if (is_shadow_grp && !sgr_open(O_RDWR)) { + fprintf(stderr, _("%s: unable to open shadow group file\n"), + Prog); + exit(E_GRP_UPDATE); + } +#endif /* SHADOWGRP */ +} + +/* + * group_busy - check if this is any user's primary group + * + * group_busy verifies that this group is not the primary group + * for any user. You must remove all users before you remove + * the group. + */ + +static void +group_busy(gid_t gid) +{ + struct passwd *pwd; + + /* + * Nice slow linear search. + */ + + setpwent (); + + while ((pwd = getpwent ()) && pwd->pw_gid != gid) + ; + + endpwent (); + + /* + * If pwd isn't NULL, it stopped becaues the gid's matched. + */ + + if (pwd == (struct passwd *) 0) + return; + + /* + * Can't remove the group. + */ + + fprintf(stderr, _("%s: cannot remove user's primary group.\n"), Prog); + exit(E_GROUP_BUSY); +} + +/* + * main - groupdel command + * + * The syntax of the groupdel command is + * + * groupdel group + * + * The named group will be deleted. + */ + +int +main(int argc, char **argv) +{ + struct group *grp; + + /* + * Get my name so that I can use it to report errors. + */ + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (argc != 2) + usage (); + + group_name = argv[1]; + + OPENLOG(Prog); + +#ifdef SHADOWGRP + is_shadow_grp = sgr_file_present(); +#endif + + /* + * The open routines for the DBM files don't use read-write + * as the mode, so we have to clue them in. + */ + +#ifdef NDBM + gr_dbm_mode = O_RDWR; +#ifdef SHADOWGRP + sg_dbm_mode = O_RDWR; +#endif /* SHADOWGRP */ +#endif /* NDBM */ + + /* + * Start with a quick check to see if the group exists. + */ + + if (! (grp = getgrnam(group_name))) { + fprintf(stderr, _("%s: group %s does not exist\n"), + Prog, group_name); + exit(E_NOTFOUND); + } +#ifdef USE_NIS + + /* + * Make sure this isn't a NIS group + */ + + if (__isgrNIS ()) { + char *nis_domain; + char *nis_master; + + fprintf(stderr, _("%s: group %s is a NIS group\n"), + Prog, group_name); + + if (! yp_get_default_domain (&nis_domain) && + ! yp_master (nis_domain, "group.byname", + &nis_master)) { + fprintf (stderr, _("%s: %s is the NIS master\n"), + Prog, nis_master); + } + exit(E_NOTFOUND); + } +#endif + + /* + * Now check to insure that this isn't the primary group of + * anyone. + */ + + group_busy (grp->gr_gid); + + /* + * Do the hard stuff - open the files, delete the group entries, + * then close and update the files. + */ + + open_files (); + + grp_update (); + + close_files (); + exit(errors == 0 ? E_SUCCESS : E_GRP_UPDATE); + /*NOTREACHED*/ +} diff --git a/current/src/groupmod.c b/current/src/groupmod.c new file mode 100644 index 00000000..6fc9bbd9 --- /dev/null +++ b/current/src/groupmod.c @@ -0,0 +1,548 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: groupmod.c,v 1.14 2000/09/02 18:40:44 marekm Exp $") + +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "chkname.h" +#include "defines.h" + +#include "groupio.h" + +#ifdef SHADOWGRP +#include "sgroupio.h" + +static int is_shadow_grp; +#endif + +/* + * exit status values + */ + +#define E_SUCCESS 0 /* success */ +#define E_USAGE 2 /* invalid command syntax */ +#define E_BAD_ARG 3 /* invalid argument to option */ +#define E_GID_IN_USE 4 /* gid already in use (and no -o) */ +#define E_NOTFOUND 6 /* specified group doesn't exist */ +#define E_NAME_IN_USE 9 /* group name already in use */ +#define E_GRP_UPDATE 10 /* can't update group file */ + +static char *group_name; +static char *group_newname; +static gid_t group_id; +static gid_t group_newid; + +static char *Prog; + +static int + oflg = 0, /* permit non-unique group ID to be specified with -g */ + gflg = 0, /* new ID value for the group */ + nflg = 0; /* a new name has been specified for the group */ + +#ifdef NDBM +extern int gr_dbm_mode; +extern int sg_dbm_mode; +#endif + +extern int optind; +extern char *optarg; + +/* local function prototypes */ +static void usage(void); +static void new_grent(struct group *); +#ifdef SHADOWGRP +static void new_sgent(struct sgrp *); +#endif +static void grp_update(void); +static void check_new_gid(void); +static void check_new_name(void); +static void process_flags(int, char **); +static void close_files(void); +static void open_files(void); + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("usage: groupmod [-g gid [-o]] [-n name] group\n")); + exit(E_USAGE); +} + +/* + * new_grent - updates the values in a group file entry + * + * new_grent() takes all of the values that have been entered and + * fills in a (struct group) with them. + */ + +static void +new_grent(struct group *grent) +{ + if (nflg) + grent->gr_name = xstrdup (group_newname); + + if (gflg) + grent->gr_gid = group_newid; +} + +#ifdef SHADOWGRP +/* + * new_sgent - updates the values in a shadow group file entry + * + * new_sgent() takes all of the values that have been entered and + * fills in a (struct sgrp) with them. + */ + +static void +new_sgent(struct sgrp *sgent) +{ + if (nflg) + sgent->sg_name = xstrdup (group_newname); +} +#endif /* SHADOWGRP */ + +/* + * grp_update - update group file entries + * + * grp_update() writes the new records to the group files. + */ + +static void +grp_update(void) +{ + struct group grp; + const struct group *ogrp; +#ifdef SHADOWGRP + struct sgrp sgrp; + const struct sgrp *osgrp = NULL; +#endif /* SHADOWGRP */ + + /* + * Get the current settings for this group. + */ + + ogrp = gr_locate(group_name); + if (!ogrp) { + fprintf(stderr, + _("%s: %s not found in /etc/group\n"), + Prog, group_name); + exit(E_GRP_UPDATE); + } + grp = *ogrp; + new_grent (&grp); +#ifdef SHADOWGRP + if (is_shadow_grp && (osgrp = sgr_locate(group_name))) { + sgrp = *osgrp; + new_sgent (&sgrp); + } +#endif /* SHADOWGRP */ + + /* + * Write out the new group file entry. + */ + + if (!gr_update(&grp)) { + fprintf(stderr, _("%s: error adding new group entry\n"), Prog); + exit(E_GRP_UPDATE); + } + if (nflg && !gr_remove(group_name)) { + fprintf(stderr, _("%s: error removing group entry\n"), Prog); + exit(E_GRP_UPDATE); + } +#ifdef NDBM + + /* + * Update the DBM group file with the new entry as well. + */ + + if (gr_dbm_present()) { + if (!gr_dbm_update(&grp)) { + fprintf(stderr, + _("%s: cannot add new dbm group entry\n"), + Prog); + exit(E_GRP_UPDATE); + } + if (nflg && (ogrp = getgrnam(group_name)) && + !gr_dbm_remove(ogrp)) { + fprintf(stderr, + _("%s: error removing group dbm entry\n"), + Prog); + exit(E_GRP_UPDATE); + } + endgrent (); + } +#endif /* NDBM */ + +#ifdef SHADOWGRP + + /* + * Make sure there was a shadow entry to begin with. Skip + * down to "out" if there wasn't. Can't just return because + * there might be some syslogging to do. + */ + + if (! osgrp) + goto out; + + /* + * Write out the new shadow group entries as well. + */ + + if (!sgr_update(&sgrp)) { + fprintf(stderr, _("%s: error adding new group entry\n"), Prog); + exit(E_GRP_UPDATE); + } + if (nflg && !sgr_remove(group_name)) { + fprintf(stderr, _("%s: error removing group entry\n"), Prog); + exit(E_GRP_UPDATE); + } +#ifdef NDBM + + /* + * Update the DBM shadow group file with the new entry as well. + */ + + if (sg_dbm_present()) { + if (!sg_dbm_update(&sgrp)) { + fprintf(stderr, + _("%s: cannot add new dbm shadow group entry\n"), + Prog); + exit(E_GRP_UPDATE); + } + if (nflg && ! sg_dbm_remove (group_name)) { + fprintf (stderr, + _("%s: error removing shadow group dbm entry\n"), + Prog); + exit(E_GRP_UPDATE); + } + endsgent (); + } +#endif /* NDBM */ +out: +#endif /* SHADOWGRP */ + + if (nflg) + SYSLOG((LOG_INFO, "change group `%s' to `%s'\n", + group_name, group_newname)); + + if (gflg) + SYSLOG((LOG_INFO, "change gid for `%s' to %d\n", + nflg ? group_newname:group_name, group_newid)); +} + +/* + * check_new_gid - check the new GID value for uniqueness + * + * check_new_gid() insures that the new GID value is unique. + */ + +static void +check_new_gid(void) +{ + /* + * First, the easy stuff. If the ID can be duplicated, or if + * the ID didn't really change, just return. If the ID didn't + * change, turn off those flags. No sense doing needless work. + */ + + if (group_id == group_newid) { + gflg = 0; + return; + } + + if (oflg || ! getgrgid (group_newid)) + return; + + /* + * Tell the user what they did wrong. + */ + + fprintf(stderr, + _("%s: %ld is not a unique gid\n"), + Prog, (long) group_newid); + exit(E_GID_IN_USE); +} + +/* + * check_new_name - check the new name for uniqueness + * + * check_new_name() insures that the new name does not exist + * already. You can't have the same name twice, period. + */ + +static void +check_new_name(void) +{ + /* + * Make sure they are actually changing the name. + */ + + if (strcmp(group_name, group_newname) == 0) { + nflg = 0; + return; + } + + if (check_group_name(group_newname)) { + + /* + * If the entry is found, too bad. + */ + + if (getgrnam(group_newname)) { + fprintf(stderr, _("%s: %s is not a unique name\n"), + Prog, group_newname); + exit(E_NAME_IN_USE); + } + return; + } + + /* + * All invalid group names land here. + */ + + fprintf(stderr, _("%s: %s is a not a valid group name\n"), + Prog, group_newname); + exit(E_BAD_ARG); +} + +/* + * process_flags - perform command line argument setting + * + * process_flags() interprets the command line arguments and sets + * the values that the user will be created with accordingly. The + * values are checked for sanity. + */ + +static void +process_flags(int argc, char **argv) +{ + char *end; + int arg; + + while ((arg = getopt (argc, argv, "og:n:")) != EOF) { + switch (arg) { + case 'g': + gflg++; + group_newid = strtol(optarg, &end, 10); + if (*end != '\0') { + fprintf(stderr, + _("%s: invalid group %s\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + break; + case 'n': + nflg++; + group_newname = optarg; + break; + case 'o': + oflg++; + break; + default: + usage (); + } + } + if (oflg && !gflg) + usage(); + + if (optind != argc - 1) + usage(); + + group_name = argv[argc - 1]; +} + +/* + * close_files - close all of the files that were opened + * + * close_files() closes all of the files that were opened for this + * new group. This causes any modified entries to be written out. + */ + +static void +close_files(void) +{ + if (!gr_close()) { + fprintf(stderr, _("%s: cannot rewrite group file\n"), Prog); + exit(E_GRP_UPDATE); + } + gr_unlock(); +#ifdef SHADOWGRP + if (is_shadow_grp && !sgr_close()) { + fprintf(stderr, _("%s: cannot rewrite shadow group file\n"), + Prog); + exit(E_GRP_UPDATE); + } + if (is_shadow_grp) + sgr_unlock (); +#endif /* SHADOWGRP */ +} + +/* + * open_files - lock and open the group files + * + * open_files() opens the two group files. + */ + +static void +open_files(void) +{ + if (!gr_lock()) { + fprintf(stderr, _("%s: unable to lock group file\n"), Prog); + exit(E_GRP_UPDATE); + } + if (!gr_open(O_RDWR)) { + fprintf(stderr, _("%s: unable to open group file\n"), Prog); + exit(E_GRP_UPDATE); + } +#ifdef SHADOWGRP + if (is_shadow_grp && !sgr_lock()) { + fprintf(stderr, _("%s: unable to lock shadow group file\n"), + Prog); + exit(E_GRP_UPDATE); + } + if (is_shadow_grp && !sgr_open(O_RDWR)) { + fprintf(stderr, _("%s: unable to open shadow group file\n"), + Prog); + exit(E_GRP_UPDATE); + } +#endif /* SHADOWGRP */ +} + +/* + * main - groupmod command + * + * The syntax of the groupmod command is + * + * groupmod [ -g gid [ -o ]] [ -n name ] group + * + * The flags are + * -g - specify a new group ID value + * -o - permit the group ID value to be non-unique + * -n - specify a new group name + */ + +int +main(int argc, char **argv) +{ + struct group *grp; + + /* + * Get my name so that I can use it to report errors. + */ + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + +#ifdef SHADOWGRP + is_shadow_grp = sgr_file_present(); +#endif + + /* + * The open routines for the DBM files don't use read-write + * as the mode, so we have to clue them in. + */ + +#ifdef NDBM + gr_dbm_mode = O_RDWR; +#ifdef SHADOWGRP + sg_dbm_mode = O_RDWR; +#endif /* SHADOWGRP */ +#endif /* NDBM */ + process_flags (argc, argv); + + /* + * Start with a quick check to see if the group exists. + */ + + if (!(grp = getgrnam(group_name))) { + fprintf(stderr, _("%s: group %s does not exist\n"), + Prog, group_name); + exit(E_NOTFOUND); + } else + group_id = grp->gr_gid; + +#ifdef USE_NIS + + /* + * Now make sure it isn't an NIS group. + */ + + if (__isgrNIS ()) { + char *nis_domain; + char *nis_master; + + fprintf(stderr, _("%s: group %s is a NIS group\n"), + Prog, group_name); + + if (! yp_get_default_domain (&nis_domain) && + ! yp_master (nis_domain, "group.byname", + &nis_master)) { + fprintf(stderr, _("%s: %s is the NIS master\n"), + Prog, nis_master); + } + exit(E_NOTFOUND); + } +#endif + + if (gflg) + check_new_gid (); + + if (nflg) + check_new_name (); + + /* + * Do the hard stuff - open the files, create the group entries, + * then close and update the files. + */ + + open_files (); + + grp_update (); + + close_files (); + exit(E_SUCCESS); + /*NOTREACHED*/ +} diff --git a/current/src/groups.c b/current/src/groups.c new file mode 100644 index 00000000..875272c8 --- /dev/null +++ b/current/src/groups.c @@ -0,0 +1,183 @@ +/* + * Copyright 1991 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: groups.c,v 1.6 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +/* local function prototypes */ +static void print_groups(const char *); + +/* + * print_groups - print the groups which the named user is a member of + * + * print_groups() scans the groups file for the list of groups + * which the user is listed as being a member of. + */ + +static void +print_groups(const char *member) +{ + int groups = 0; + struct group *grp; + struct passwd *pwd; + int flag = 0; + + setgrent (); + + if ((pwd = getpwnam(member)) == 0) { + fprintf(stderr, _("unknown user %s\n"), member); + exit(1); + } + while ((grp = getgrent ())) { + if (is_on_list(grp->gr_mem, member)) { + if (groups++) + putchar (' '); + + printf ("%s", grp->gr_name); + if (grp->gr_gid == pwd->pw_gid) + flag = 1; + } + } + if (! flag && (grp = getgrgid (pwd->pw_gid))) { + if (groups++) + putchar (' '); + + printf ("%s", grp->gr_name); + } + if (groups) + putchar ('\n'); +} + +/* + * groups - print out the groups a process is a member of + */ + +int +main(int argc, char **argv) +{ +#ifdef HAVE_GETGROUPS + int ngroups; + GETGROUPS_T groups[NGROUPS_MAX]; + int pri_grp; + int i; + struct group *gr; +#else + char *logname; + char *getlogin(); +#endif + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (argc == 1) { + + /* + * Called with no arguments - give the group set + * for the current user. + */ + +#ifdef HAVE_GETGROUPS + /* + * This system supports concurrent group sets, so + * I can ask the system to tell me which groups are + * currently set for this process. + */ + + ngroups = getgroups(NGROUPS_MAX, groups); + if (ngroups < 0) { + perror("getgroups"); + exit(1); + } + + /* + * The groupset includes the primary group as well. + */ + + pri_grp = getegid (); + for (i = 0;i < ngroups;i++) + if (pri_grp == (int) groups[i]) + break; + + if (i != ngroups) + pri_grp = -1; + + /* + * Print out the name of every group in the current + * group set. Unknown groups are printed as their + * decimal group ID values. + */ + + if (pri_grp != -1) { + if ((gr = getgrgid (pri_grp))) + printf ("%s", gr->gr_name); + else + printf ("%d", pri_grp); + } + + for (i = 0;i < ngroups;i++) { + if (i || pri_grp != -1) + putchar (' '); + + if ((gr = getgrgid (groups[i]))) + printf ("%s", gr->gr_name); + else + printf ("%ld", (long) groups[i]); + } + putchar ('\n'); +#else + /* + * This system does not have the getgroups() system + * call, so I must check the groups file directly. + */ + + if ((logname = getlogin ())) + print_groups (logname); + else + exit (1); +#endif + } else { + + /* + * The invoker wanted to know about some other + * user. Use that name to look up the groups instead. + */ + + print_groups (argv[1]); + } + exit (0); +} diff --git a/current/src/grpck.c b/current/src/grpck.c new file mode 100644 index 00000000..50fc2eab --- /dev/null +++ b/current/src/grpck.c @@ -0,0 +1,649 @@ +/* + * Copyright 1992 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: grpck.c,v 1.14 2000/09/02 18:40:44 marekm Exp $") + +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" +#include "chkname.h" +#include + +#include "commonio.h" + +#include "groupio.h" +extern void __gr_del_entry(const struct commonio_entry *); +extern struct commonio_entry *__gr_get_head(void); + +#ifdef SHADOWGRP +#include "sgroupio.h" +extern void __sgr_del_entry(const struct commonio_entry *); +extern struct commonio_entry *__sgr_get_head(void); +#endif + +/* + * Exit codes + */ + +#define E_OKAY 0 +#define E_USAGE 1 +#define E_BAD_ENTRY 2 +#define E_CANT_OPEN 3 +#define E_CANT_LOCK 4 +#define E_CANT_UPDATE 5 + +/* + * Global variables + */ + +extern int optind; +extern char *optarg; + +/* + * Local variables + */ + +static char *Prog; +static const char *grp_file = GROUP_FILE; +#ifdef SHADOWGRP +static const char *sgr_file = SGROUP_FILE; +#endif +static int read_only = 0; + +/* local function prototypes */ +static void usage(void); +static int yes_or_no(void); +static void delete_member(char **, const char *); + +/* + * usage - print syntax message and exit + */ + +static void +usage(void) +{ +#ifdef SHADOWGRP + fprintf(stderr, _("Usage: %s [ -r ] [ group [ gshadow ] ]\n"), Prog); +#else + fprintf(stderr, _("Usage: %s [ -r ] [ group ]\n"), Prog); +#endif + exit(E_USAGE); +} + +/* + * yes_or_no - get answer to question from the user + */ + +static int +yes_or_no(void) +{ + char buf[80]; + + /* + * In read-only mode all questions are answered "no". + */ + + if (read_only) { + puts(_("No")); + return 0; + } + + /* + * Get a line and see what the first character is. + */ + + if (fgets(buf, sizeof buf, stdin)) + return buf[0] == 'y' || buf[0] == 'Y'; + + return 0; +} + +/* + * delete_member - delete an entry in a list of members + */ + +static void +delete_member(char **list, const char *member) +{ + int i; + + for (i = 0; list[i]; i++) + if (list[i] == member) + break; + + if (list[i]) + for (; list[i]; i++) + list[i] = list[i + 1]; +} + +/* + * grpck - verify group file integrity + */ + +int +main(int argc, char **argv) +{ + int arg; + int errors = 0; + int deleted = 0; + int i; + struct commonio_entry *gre, *tgre; + struct group *grp; +#ifdef SHADOWGRP + struct commonio_entry *sge, *tsge; + struct sgrp *sgr; + int is_shadow = 0; +#endif + + /* + * Get my name so that I can use it to report errors. + */ + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + + /* + * Parse the command line arguments + */ + + while ((arg = getopt(argc, argv, "qr")) != EOF) { + switch (arg) { + case 'q': + /* quiet - ignored for now */ + break; + case 'r': + read_only = 1; + break; + default: + usage(); + } + } + + /* + * Make certain we have the right number of arguments + */ + +#ifdef SHADOWGRP + if (optind != argc && optind + 1 != argc && optind + 2 != argc) +#else + if (optind != argc && optind + 1 != argc) +#endif + usage(); + + /* + * If there are two left over filenames, use those as the + * group and group password filenames. + */ + + if (optind != argc) { + grp_file = argv[optind]; + gr_name(grp_file); + } +#ifdef SHADOWGRP + if (optind + 2 == argc) { + sgr_file = argv[optind + 1]; + sgr_name(sgr_file); + is_shadow = 1; + } else if (optind == argc) + is_shadow = sgr_file_present(); +#endif + + /* + * Lock the files if we aren't in "read-only" mode + */ + + if (!read_only) { + if (!gr_lock()) { + fprintf(stderr, _("%s: cannot lock file %s\n"), Prog, grp_file); + if (optind == argc) + SYSLOG((LOG_WARN,"cannot lock %s\n",grp_file)); + closelog(); + exit(E_CANT_LOCK); + } +#ifdef SHADOWGRP + if (is_shadow && !sgr_lock()) { + fprintf(stderr, _("%s: cannot lock file %s\n"), Prog, sgr_file); + if (optind == argc) + SYSLOG((LOG_WARN,"cannot lock %s\n",sgr_file)); + closelog(); + exit(E_CANT_LOCK); + } +#endif + } + + /* + * Open the files. Use O_RDONLY if we are in read_only mode, + * O_RDWR otherwise. + */ + + if (!gr_open(read_only ? O_RDONLY : O_RDWR)) { + fprintf(stderr, _("%s: cannot open file %s\n"), Prog, grp_file); + if (optind == argc) + SYSLOG((LOG_WARN, "cannot open %s\n", grp_file)); + closelog(); + exit(E_CANT_OPEN); + } +#ifdef SHADOWGRP + if (is_shadow && !sgr_open(read_only ? O_RDONLY : O_RDWR)) { + fprintf(stderr, _("%s: cannot open file %s\n"), Prog, sgr_file); + if (optind == argc) + SYSLOG((LOG_WARN, "cannot open %s\n", sgr_file)); + closelog(); + exit(E_CANT_OPEN); + } +#endif + + /* + * Loop through the entire group file. + */ + + for (gre = __gr_get_head(); gre; gre = gre->next) { + /* + * Skip all NIS entries. + */ + + if (gre->line[0] == '+' || gre->line[0] == '-') + continue; + + /* + * Start with the entries that are completely corrupt. + * They have no (struct group) entry because they couldn't + * be parsed properly. + */ + + if (!gre->eptr) { + + /* + * Tell the user this entire line is bogus and + * ask them to delete it. + */ + + printf(_("invalid group file entry\n")); + printf(_("delete line `%s'? "), gre->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (!yes_or_no()) + continue; + + /* + * All group file deletions wind up here. This + * code removes the current entry from the linked + * list. When done, it skips back to the top of + * the loop to try out the next list element. + */ + +delete_gr: + SYSLOG((LOG_INFO, "delete group line `%s'\n", + gre->line)); + deleted++; + + __gr_del_entry(gre); + continue; + } + + /* + * Group structure is good, start using it. + */ + + grp = gre->eptr; + + /* + * Make sure this entry has a unique name. + */ + + for (tgre = __gr_get_head(); tgre; tgre = tgre->next) { + + const struct group *ent = tgre->eptr; + + /* + * Don't check this entry + */ + + if (tgre == gre) + continue; + + /* + * Don't check invalid entries. + */ + + if (!ent) + continue; + + if (strcmp(grp->gr_name, ent->gr_name) != 0) + continue; + + /* + * Tell the user this entry is a duplicate of + * another and ask them to delete it. + */ + + puts(_("duplicate group entry\n")); + printf(_("delete line `%s'? "), gre->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (yes_or_no()) + goto delete_gr; + } + + /* + * Check for invalid group names. --marekm + */ + if (!check_group_name(grp->gr_name)) { + errors++; + printf(_("invalid group name `%s'\n"), grp->gr_name); + } + + /* + * Check for a Slackware bug. Make sure GID is not -1 + * (it has special meaning for some syscalls). --marekm + */ + + if (grp->gr_gid == (gid_t) -1) { + errors++; + printf(_("group %s: bad GID (%d)\n"), + grp->gr_name, (int) grp->gr_gid); + } + + /* + * Workaround for a NYS libc 5.3.12 bug on RedHat 4.2 - + * groups with no members are returned as groups with + * one member "", causing grpck to fail. --marekm + */ + + if (grp->gr_mem[0] && !grp->gr_mem[1] && *(grp->gr_mem[0]) == '\0') + grp->gr_mem[0] = (char *) 0; + + /* + * Make sure each member exists + */ + + for (i = 0; grp->gr_mem[i]; i++) { + if (getpwnam(grp->gr_mem[i])) + continue; + /* + * Can't find this user. Remove them + * from the list. + */ + + errors++; + printf(_("group %s: no user %s\n"), + grp->gr_name, grp->gr_mem[i]); + printf(_("delete member `%s'? "), grp->gr_mem[i]); + + if (!yes_or_no()) + continue; + + SYSLOG((LOG_INFO, "delete member `%s' group `%s'\n", + grp->gr_mem[i], grp->gr_name)); + deleted++; + delete_member(grp->gr_mem, grp->gr_mem[i]); + gre->changed = 1; + __gr_set_changed(); + } + } + +#ifdef SHADOWGRP + if (!is_shadow) + goto shadow_done; + + /* + * Loop through the entire shadow group file. + */ + + for (sge = __sgr_get_head(); sge; sge = sge->next) { + + /* + * Start with the entries that are completely corrupt. + * They have no (struct sgrp) entry because they couldn't + * be parsed properly. + */ + + if (!sge->eptr) { + + /* + * Tell the user this entire line is bogus and + * ask them to delete it. + */ + + printf(_("invalid shadow group file entry\n")); + printf(_("delete line `%s'? "), sge->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (!yes_or_no()) + continue; + + /* + * All shadow group file deletions wind up here. + * This code removes the current entry from the + * linked list. When done, it skips back to the + * top of the loop to try out the next list element. + */ + +delete_sg: + SYSLOG((LOG_INFO, "delete shadow line `%s'\n", + sge->line)); + deleted++; + + __sgr_del_entry(sge); + continue; + } + + /* + * Shadow group structure is good, start using it. + */ + + sgr = sge->eptr; + + /* + * Make sure this entry has a unique name. + */ + + for (tsge = __sgr_get_head(); tsge; tsge = tsge->next) { + + const struct sgrp *ent = tsge->eptr; + + /* + * Don't check this entry + */ + + if (tsge == sge) + continue; + + /* + * Don't check invalid entries. + */ + + if (!ent) + continue; + + if (strcmp(sgr->sg_name, ent->sg_name) != 0) + continue; + + /* + * Tell the user this entry is a duplicate of + * another and ask them to delete it. + */ + + puts(_("duplicate shadow group entry\n")); + printf(_("delete line `%s'? "), sge->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (yes_or_no()) + goto delete_sg; + } + + /* + * Make sure this entry exists in the /etc/group file. + */ + + if (!gr_locate(sgr->sg_name)) { + puts(_("no matching group file entry\n")); + printf(_("delete line `%s'? "), sge->line); + errors++; + if (yes_or_no()) + goto delete_sg; + } + + /* + * Make sure each administrator exists + */ + + for (i = 0; sgr->sg_adm[i]; i++) { + if (getpwnam(sgr->sg_adm[i])) + continue; + /* + * Can't find this user. Remove them + * from the list. + */ + + errors++; + printf(_("shadow group %s: no administrative user %s\n"), + sgr->sg_name, sgr->sg_adm[i]); + printf(_("delete administrative member `%s'? "), sgr->sg_adm[i]); + + if (!yes_or_no()) + continue; + + SYSLOG((LOG_INFO, + "delete admin `%s' from shadow group `%s'\n", + sgr->sg_adm[i], sgr->sg_name)); + deleted++; + delete_member(sgr->sg_adm, sgr->sg_adm[i]); + sge->changed = 1; + __sgr_set_changed(); + } + + /* + * Make sure each member exists + */ + + for (i = 0; sgr->sg_mem[i]; i++) { + if (getpwnam(sgr->sg_mem[i])) + continue; + + /* + * Can't find this user. Remove them + * from the list. + */ + + errors++; + printf(_("shadow group %s: no user %s\n"), + sgr->sg_name, sgr->sg_mem[i]); + printf(_("delete member `%s'? "), sgr->sg_mem[i]); + + if (!yes_or_no()) + continue; + + SYSLOG((LOG_INFO, + "delete member `%s' from shadow group `%s'\n", + sgr->sg_mem[i], sgr->sg_name)); + deleted++; + delete_member(sgr->sg_mem, sgr->sg_mem[i]); + sge->changed = 1; + __sgr_set_changed(); + } + } + +shadow_done: +#endif /* SHADOWGRP */ + + /* + * All done. If there were no deletions we can just abandon any + * changes to the files. + */ + + if (deleted) { + if (!gr_close()) { + fprintf(stderr, _("%s: cannot update file %s\n"), + Prog, grp_file); + exit(E_CANT_UPDATE); + } +#ifdef SHADOWGRP + if (is_shadow && !sgr_close()) { + fprintf(stderr, _("%s: cannot update file %s\n"), + Prog, sgr_file); + exit(E_CANT_UPDATE); + } +#endif + } + + /* + * Don't be anti-social - unlock the files when you're done. + */ + +#ifdef SHADOWGRP + if (is_shadow) + sgr_unlock(); +#endif + (void) gr_unlock(); + + /* + * Tell the user what we did and exit. + */ + + if (errors) +#ifdef NDBM + printf(deleted ? + _("%s: the files have been updated; run mkpasswd\n") : + _("%s: no changes\n"), Prog); +#else + printf(deleted ? + _("%s: the files have been updated\n") : + _("%s: no changes\n"), Prog); +#endif + + exit(errors ? E_BAD_ENTRY : E_OKAY); +} diff --git a/current/src/grpconv.c b/current/src/grpconv.c new file mode 100644 index 00000000..8e641fd3 --- /dev/null +++ b/current/src/grpconv.c @@ -0,0 +1,173 @@ +/* + * grpconv - create or update /etc/gshadow with information from + * /etc/group. + * + * Copyright (C) 1996, Marek Michalkiewicz + * + * This program may be freely used and distributed. If you improve + * it, please send me your changes. Thanks! + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "prototypes.h" + +#ifdef SHADOWGRP + +#include "groupio.h" +#include "sgroupio.h" + +#include "rcsid.h" +RCSID(PKG_VER "$Id: grpconv.c,v 1.11 2000/08/26 18:27:18 marekm Exp $") + +static int group_locked = 0; +static int gshadow_locked = 0; + +/* local function prototypes */ +static void fail_exit(int); + +static void +fail_exit(int status) +{ + if (group_locked) + gr_unlock(); + if (gshadow_locked) + sgr_unlock(); + exit(status); +} + +int +main(int argc, char **argv) +{ + const struct group *gr; + struct group grent; + const struct sgrp *sg; + struct sgrp sgent; + char *Prog = argv[0]; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (!gr_lock()) { + fprintf(stderr, _("%s: can't lock group file\n"), Prog); + fail_exit(5); + } + group_locked++; + if (!gr_open(O_RDWR)) { + fprintf(stderr, _("%s: can't open group file\n"), Prog); + fail_exit(1); + } + + if (!sgr_lock()) { + fprintf(stderr, _("%s: can't lock shadow group file\n"), Prog); + fail_exit(5); + } + gshadow_locked++; + if (!sgr_open(O_CREAT | O_RDWR)) { + fprintf(stderr, _("%s: can't open shadow group file\n"), Prog); + fail_exit(1); + } + + /* + * Remove /etc/gshadow entries for groups not in /etc/group. + */ + sgr_rewind(); + while ((sg = sgr_next())) { + if (gr_locate(sg->sg_name)) + continue; + + if (!sgr_remove(sg->sg_name)) { + /* + * This shouldn't happen (the entry exists) but... + */ + fprintf(stderr, _("%s: can't remove shadow group %s\n"), + Prog, sg->sg_name); + fail_exit(3); + } + } + + /* + * Update shadow group passwords if non-shadow password is not "x". + * Add any missing shadow group entries. + */ + gr_rewind(); + while ((gr = gr_next())) { + sg = sgr_locate(gr->gr_name); + if (sg) { +#if 0 /* because of sg_mem, but see below */ + if (strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) == 0) + continue; +#endif + /* update existing shadow group entry */ + sgent = *sg; + if (strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) != 0) + sgent.sg_passwd = gr->gr_passwd; + } else { + static char *empty = 0; + + /* add new shadow group entry */ + memset(&sgent, 0, sizeof sgent); + sgent.sg_name = gr->gr_name; + sgent.sg_passwd = gr->gr_passwd; + sgent.sg_adm = ∅ + } + /* + * XXX - sg_mem is redundant, it is currently always a copy + * of gr_mem. Very few programs actually use sg_mem, and + * all of them are in the shadow suite... Maybe this field + * could be used for something else? Any suggestions? + */ + sgent.sg_mem = gr->gr_mem; + + if (!sgr_update(&sgent)) { + fprintf(stderr, + _("%s: can't update shadow entry for %s\n"), + Prog, sgent.sg_name); + fail_exit(3); + } + /* remove password from /etc/group */ + grent = *gr; + grent.gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */ + if (!gr_update(&grent)) { + fprintf(stderr, + _("%s: can't update entry for group %s\n"), + Prog, grent.gr_name); + fail_exit(3); + } + } + + if (!sgr_close()) { + fprintf(stderr, _("%s: can't update shadow group file\n"), Prog); + fail_exit(3); + } + if (!gr_close()) { + fprintf(stderr, _("%s: can't update group file\n"), Prog); + fail_exit(3); + } + sgr_unlock(); + gr_unlock(); + return 0; +} +#else /* !SHADOWGRP */ +int +main(int argc, char **argv) +{ + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + fprintf(stderr, _("%s: not configured for shadow group support.\n"), + argv[0]); + exit(1); +} +#endif /* !SHADOWGRP */ diff --git a/current/src/grpunconv.c b/current/src/grpunconv.c new file mode 100644 index 00000000..59cb4994 --- /dev/null +++ b/current/src/grpunconv.c @@ -0,0 +1,131 @@ +/* + * grpunconv - update /etc/group with information from /etc/gshadow. + * + * Copyright (C) 1996, Michael Meskes + * using sources from Marek Michalkiewicz + * + * This program may be freely used and distributed. If you improve + * it, please send me your changes. Thanks! + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: grpunconv.c,v 1.10 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include +#include +#include +#include + +#include +#include "prototypes.h" + +#ifdef SHADOWGRP + +#include "groupio.h" +#include "sgroupio.h" + +static int group_locked = 0; +static int gshadow_locked = 0; + +/* local function prototypes */ +static void fail_exit(int); + +static void +fail_exit(int status) +{ + if (group_locked) + gr_unlock(); + if (gshadow_locked) + sgr_unlock(); + exit(status); +} + +int +main(int argc, char **argv) +{ + const struct group *gr; + struct group grent; + const struct sgrp *sg; + char *Prog = argv[0]; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (!sgr_file_present()) + exit(0); /* no /etc/gshadow, nothing to do */ + + if (!gr_lock()) { + fprintf(stderr, _("%s: can't lock group file\n"), Prog); + fail_exit(5); + } + group_locked++; + if (!gr_open(O_RDWR)) { + fprintf(stderr, _("%s: can't open group file\n"), Prog); + fail_exit(1); + } + + if (!sgr_lock()) { + fprintf(stderr, _("%s: can't lock shadow group file\n"), Prog); + fail_exit(5); + } + gshadow_locked++; + if (!sgr_open(O_RDWR)) { + fprintf(stderr, _("%s: can't open shadow group file\n"), Prog); + fail_exit(1); + } + + /* + * Update group passwords if non-shadow password is "x". + */ + gr_rewind(); + while ((gr = gr_next())) { + sg = sgr_locate(gr->gr_name); + if (sg && strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) == 0) { + /* add password to /etc/group */ + grent = *gr; + grent.gr_passwd = sg->sg_passwd; + if (!gr_update(&grent)) { + fprintf(stderr, + _("%s: can't update entry for group %s\n"), + Prog, grent.gr_name); + fail_exit(3); + } + } + } + + if (!sgr_close()) { + fprintf(stderr, _("%s: can't update shadow group file\n"), Prog); + fail_exit(3); + } + + if (!gr_close()) { + fprintf(stderr, _("%s: can't update group file\n"), Prog); + fail_exit(3); + } + + if (unlink(SGROUP_FILE) != 0) { + fprintf(stderr, _("%s: can't delete shadow group file\n"), Prog); + fail_exit(3); + } + + sgr_unlock(); + gr_unlock(); + return 0; +} +#else /* !SHADOWGRP */ +int +main(int argc, char **argv) +{ + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + fprintf(stderr, _("%s: not configured for shadow group support.\n"), argv[0]); + exit(1); +} +#endif /* !SHADOWGRP */ diff --git a/current/src/id.c b/current/src/id.c new file mode 100644 index 00000000..28839a02 --- /dev/null +++ b/current/src/id.c @@ -0,0 +1,187 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +/* + * id - print current process user identification information + * + * Print the current process identifiers. This includes the + * UID, GID, effective-UID and effective-GID. Optionally print + * the concurrent group set if the current system supports it. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: id.c,v 1.6 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include +#include +#include "defines.h" + +/* local function prototypes */ +static void usage(void); + +static void +usage(void) +{ +#ifdef HAVE_GETGROUPS + fprintf(stderr, _("usage: id [ -a ]\n")); +#else + fprintf(stderr, _("usage: id\n")); +#endif + exit(1); +} + +/*ARGSUSED*/ +int +main(int argc, char **argv) +{ + uid_t ruid, euid; + gid_t rgid, egid; + int i; +/* + * This block of declarations is particularly strained because of several + * different ways of doing concurrent groups. Old BSD systems used int + * for gid's, but short for the type passed to getgroups(). Newer systems + * use gid_t for everything. Some systems have a small and fixed NGROUPS, + * usually about 16 or 32. Others use bigger values. + */ +#ifdef HAVE_GETGROUPS + GETGROUPS_T groups[NGROUPS_MAX]; + int ngroups; + int aflg = 0; +#endif + struct passwd *pw; + struct group *gr; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + +#ifdef HAVE_GETGROUPS + /* + * See if the -a flag has been given to print out the + * concurrent group set. + */ + + if (argc > 1) { + if (argc > 2 || strcmp (argv[1], "-a")) + usage(); + else + aflg = 1; + } +#else + if (argc > 1) + usage(); +#endif + + ruid = getuid(); + euid = geteuid(); + rgid = getgid(); + egid = getegid(); + + /* + * Print out the real user ID and group ID. If the user or + * group does not exist, just give the numerical value. + */ + + pw = getpwuid(ruid); + if (pw) + printf(_("uid=%d(%s)"), (int) ruid, pw->pw_name); + else + printf(_("uid=%d"), (int) ruid); + + gr = getgrgid(rgid); + if (gr) + printf(_(" gid=%d(%s)"), (int) rgid, gr->gr_name); + else + printf(_(" gid=%d"), (int) rgid); + + /* + * Print out the effective user ID and group ID if they are + * different from the real values. + */ + + if (ruid != euid) { + pw = getpwuid(euid); + if (pw) + printf(_(" euid=%d(%s)"), (int) euid, pw->pw_name); + else + printf(_(" euid=%d"), (int) euid); + } + if (rgid != egid) { + gr = getgrgid(egid); + if (gr) + printf(_(" egid=%d(%s)"), (int) egid, gr->gr_name); + else + printf(_(" egid=%d"), (int) egid); + } + +#ifdef HAVE_GETGROUPS + /* + * Print out the concurrent group set if the user has requested + * it. The group numbers will be printed followed by their + * names. + */ + + if (aflg && (ngroups = getgroups (NGROUPS_MAX, groups)) != -1) { + + /* + * Start off the group message. It will be of the format + * + * groups=###(aaa),###(aaa),###(aaa) + * + * where "###" is a numerical value and "aaa" is the + * corresponding name for each respective numerical value. + */ + + printf(_(" groups=")); + for (i = 0; i < ngroups; i++) { + if (i) + putchar(','); + + gr = getgrgid(groups[i]); + if (gr) + printf("%d(%s)", (int) groups[i], gr->gr_name); + else + printf("%d", (int) groups[i]); + } + } +#endif + + /* + * Finish off the line. + */ + + putchar('\n'); + exit(0); + /*NOTREACHED*/ +} diff --git a/current/src/lastlog.c b/current/src/lastlog.c new file mode 100644 index 00000000..a7957ac7 --- /dev/null +++ b/current/src/lastlog.c @@ -0,0 +1,192 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: lastlog.c,v 1.6 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" +#if HAVE_LASTLOG_H +#include +#else +#include "lastlog_.h" +#endif + +/* + * Needed for MkLinux DR1/2/2.1 - J. + */ +#ifndef LASTLOG_FILE +#define LASTLOG_FILE "/var/log/lastlog" +#endif + +static FILE *lastlogfile; /* lastlog file stream */ +static off_t user; /* one single user, specified on command line */ +static int days; /* number of days to consider for print command */ +static time_t seconds; /* that number of days in seconds */ + +static int uflg = 0; /* set if user is a valid user id */ +static int tflg = 0; /* print is restricted to most recent days */ +static struct lastlog lastlog; /* scratch structure to play with ... */ +static struct stat statbuf; /* fstat buffer for file size */ +static struct passwd *pwent; + +extern char *optarg; + +#define NOW (time ((time_t *) 0)) + +/* local function prototypes */ +static void print(void); +static void print_one(const struct passwd *); + +int +main(int argc, char **argv) +{ + int c; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if ((lastlogfile = fopen (LASTLOG_FILE,"r")) == (FILE *) 0) { + perror (LASTLOG_FILE); + exit (1); + } + while ((c = getopt (argc, argv, "u:t:")) != EOF) { + switch (c) { + case 'u': + pwent = getpwnam (optarg); + if (!pwent) { + fprintf(stderr, + _("Unknown User: %s\n"), + optarg); + exit (1); + } + uflg++; + user = pwent->pw_uid; + break; + case 't': + days = atoi (optarg); + seconds = days * DAY; + tflg++; + break; + } + } + print (); + fclose (lastlogfile); + exit (0); + /*NOTREACHED*/ +} + +static void +print(void) +{ + off_t offset; + + if (uflg) { + offset = (unsigned long) user * sizeof lastlog; + if (fstat (fileno (lastlogfile), &statbuf)) { + perror(LASTLOG_FILE); + return; + } + if (offset >= statbuf.st_size) + return; + + fseek (lastlogfile, offset, SEEK_SET); + if (fread ((char *) &lastlog, sizeof lastlog, 1, + lastlogfile) == 1) + print_one (pwent); + else + perror (LASTLOG_FILE); + } else { + setpwent (); + while ((pwent = getpwent ())) { + user = pwent->pw_uid; + offset = (unsigned long) user * sizeof lastlog; + fseek (lastlogfile, offset, SEEK_SET); + if (fread ((char *) &lastlog, sizeof lastlog, 1, + lastlogfile) != 1) + continue; + + if (tflg && NOW - lastlog.ll_time > seconds) + continue; + + print_one (pwent); + } + } +} + +static void +print_one(const struct passwd *pw) +{ + static int once; + char *cp; + struct tm *tm; +#ifdef HAVE_STRFTIME + char ptime[80]; +#endif + + if (! pw) + return; + + if (! once) { +#ifdef HAVE_LL_HOST + printf(_("Username Port From Latest\n")); +#else + printf(_("Username Port Latest\n")); +#endif + once++; + } + tm = localtime (&lastlog.ll_time); +#ifdef HAVE_STRFTIME + strftime(ptime, sizeof(ptime), "%a %b %e %H:%M:%S %z %Y", tm); + cp = ptime; +#else + cp = asctime (tm); + cp[24] = '\0'; +#endif + + if(lastlog.ll_time == (time_t) 0) + cp = _("**Never logged in**\0"); + +#ifdef HAVE_LL_HOST + printf ("%-16s %-8.8s %-16.16s %s\n", pw->pw_name, + lastlog.ll_line, lastlog.ll_host, cp); +#else + printf ("%-16s\t%-8.8s %s\n", pw->pw_name, + lastlog.ll_line, cp); +#endif +} diff --git a/current/src/login.c b/current/src/login.c new file mode 100644 index 00000000..fa5b9170 --- /dev/null +++ b/current/src/login.c @@ -0,0 +1,1314 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: login.c,v 1.18 2000/09/02 18:40:44 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include +#include +#include +#include +#include +#if HAVE_UTMPX_H +#include +#else +#include +#endif +#include + +#if HAVE_LASTLOG_H +#include +#else +#include "lastlog_.h" +#endif + +#include "faillog.h" +#include "failure.h" +#include "pwauth.h" +#include "getdef.h" +#include "dialchk.h" + +#ifdef SVR4_SI86_EUA +#include +#include +#endif + +#ifdef RADIUS +/* + * Support for RADIUS authentication based on a hacked util-linux login + * source sent to me by Jon Lewis. Not tested. You need to link login + * with the radauth.c file (not included here - it doesn't have a clear + * copyright statement, and I don't want to have problems with Debian + * putting the whole package in non-free because of this). --marekm + */ +#include "radlogin.h" +#endif + +#ifdef UT_ADDR +#include +#endif + +#ifdef USE_PAM +#include "pam_defs.h" + +static const struct pam_conv conv = { + misc_conv, + NULL +}; + +static pam_handle_t *pamh = NULL; + +#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \ + fprintf(stderr,"\n%s\n",PAM_STRERROR(pamh, retcode)); \ + syslog(LOG_ERR,"%s",PAM_STRERROR(pamh, retcode)); \ + pam_end(pamh, retcode); exit(1); \ + } +#define PAM_END { retcode = pam_close_session(pamh,0); \ + pam_end(pamh,retcode); } + +#endif /* USE_PAM */ + +/* + * Needed for MkLinux DR1/2/2.1 - J. + */ +#ifndef LASTLOG_FILE +#define LASTLOG_FILE "/var/log/lastlog" +#endif + +const char *hostname = ""; + +struct passwd pwent; +#if HAVE_UTMPX_H +struct utmpx utxent, failent; +struct utmp utent; +#else +struct utmp utent, failent; +#endif +struct lastlog lastlog; +static int pflg = 0; +static int fflg = 0; +#ifdef RLOGIN +static int rflg = 0; +#else +#define rflg 0 +#endif +static int hflg = 0; +static int preauth_flag = 0; + +/* + * Global variables. + */ + +static char *Prog; +static int amroot; +static int timeout; + +/* + * External identifiers. + */ + +extern char **newenvp; +extern size_t newenvc; + +extern void dolastlog(struct lastlog *, const struct passwd *, const char *, const char *); + +extern int optind; +extern char *optarg; +extern char **environ; + +extern int login_access(const char *, const char *); +extern void login_fbtab(const char *, uid_t, gid_t); + +#ifndef ALARM +#define ALARM 60 +#endif + +#ifndef RETRIES +#define RETRIES 3 +#endif + +static struct faillog faillog; + +#define NO_SHADOW "no shadow password for `%s'%s\n" +#define BAD_PASSWD "invalid password for `%s'%s\n" +#define BAD_DIALUP "invalid dialup password for `%s' on `%s'\n" +#define BAD_TIME "invalid login time for `%s'%s\n" +#define BAD_ROOT_LOGIN "ILLEGAL ROOT LOGIN%s\n" +#define ROOT_LOGIN "ROOT LOGIN%s\n" +#define FAILURE_CNT "exceeded failure limit for `%s'%s\n" +#define REG_LOGIN "`%s' logged in%s\n" +#define LOGIN_REFUSED "LOGIN `%s' REFUSED%s\n" +#define REENABLED2 \ + "login `%s' re-enabled after temporary lockout (%d failures).\n" +#define MANY_FAILS "REPEATED login failures%s\n" + +/* local function prototypes */ +static void usage(void); +static void setup_tty(void); +static void bad_time_notify(void); +static void check_flags(int, char * const *); +#ifndef USE_PAM +static void check_nologin(void); +#endif +static void init_env(void); +static RETSIGTYPE alarm_handler(int); + +/* + * usage - print login command usage and exit + * + * login [ name ] + * login -r hostname (for rlogind) + * login -h hostname (for telnetd, etc.) + * login -f name (for pre-authenticated login: datakit, xterm, etc.) + */ + +static void +usage(void) +{ + fprintf(stderr, _("usage: %s [-p] [name]\n"), Prog); + if (!amroot) + exit(1); + fprintf(stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog); +#ifdef RLOGIN + fprintf(stderr, _(" %s [-p] -r host\n"), Prog); +#endif + exit(1); +} + + +static void +setup_tty(void) +{ + TERMIO termio; + + GTTY(0, &termio); /* get terminal characteristics */ + + /* + * Add your favorite terminal modes here ... + */ + + termio.c_lflag |= ISIG|ICANON|ECHO|ECHOE; + termio.c_iflag |= ICRNL; + +#if defined(ECHOKE) && defined(ECHOCTL) + termio.c_lflag |= ECHOKE|ECHOCTL; +#endif +#if defined(ECHOPRT) && defined(NOFLSH) && defined(TOSTOP) + termio.c_lflag &= ~(ECHOPRT|NOFLSH|TOSTOP); +#endif +#ifdef ONLCR + termio.c_oflag |= ONLCR; +#endif + +#ifdef SUN4 + + /* + * Terminal setup for SunOS 4.1 courtesy of Steve Allen + * at UCO/Lick. + */ + + termio.c_cc[VEOF] = '\04'; + termio.c_cflag &= ~CSIZE; + termio.c_cflag |= (PARENB|CS7); + termio.c_lflag |= (ISIG|ICANON|ECHO|IEXTEN); + termio.c_iflag |= (BRKINT|IGNPAR|ISTRIP|IMAXBEL|ICRNL|IXON); + termio.c_iflag &= ~IXANY; + termio.c_oflag |= (XTABS|OPOST|ONLCR); +#endif +#if 0 + termio.c_cc[VERASE] = getdef_num("ERASECHAR", '\b'); + termio.c_cc[VKILL] = getdef_num("KILLCHAR", '\025'); +#else + /* leave these values unchanged if not specified in login.defs */ + termio.c_cc[VERASE] = getdef_num("ERASECHAR", termio.c_cc[VERASE]); + termio.c_cc[VKILL] = getdef_num("KILLCHAR", termio.c_cc[VKILL]); +#endif + + /* + * ttymon invocation prefers this, but these settings won't come into + * effect after the first username login + */ + + STTY(0, &termio); +} + + +/* + * Tell the user that this is not the right time to login at this tty + */ +static void +bad_time_notify(void) +{ +#ifdef HUP_MESG_FILE + FILE *mfp; + + if ((mfp = fopen(HUP_MESG_FILE, "r")) != NULL) { + int c; + + while ((c = fgetc(mfp)) != EOF) { + if (c == '\n') + putchar('\r'); + putchar(c); + } + fclose(mfp); + } else +#endif + printf(_("Invalid login time\n")); + fflush(stdout); +} + + +static void +check_flags(int argc, char * const *argv) +{ + int arg; + + /* + * Check the flags for proper form. Every argument starting with + * "-" must be exactly two characters long. This closes all the + * clever rlogin, telnet, and getty holes. + */ + for (arg = 1; arg < argc; arg++) { + if (argv[arg][0] == '-' && strlen(argv[arg]) > 2) + usage(); + } +} + +#ifndef USE_PAM +static void +check_nologin(void) +{ + char *fname; + + /* + * Check to see if system is turned off for non-root users. + * This would be useful to prevent users from logging in + * during system maintenance. We make sure the message comes + * out for root so she knows to remove the file if she's + * forgotten about it ... + */ + + fname = getdef_str("NOLOGINS_FILE"); + if (fname != NULL && access(fname, F_OK) == 0) { + FILE *nlfp; + int c; + + /* + * Cat the file if it can be opened, otherwise just + * print a default message + */ + + if ((nlfp = fopen (fname, "r"))) { + while ((c = getc (nlfp)) != EOF) { + if (c == '\n') + putchar ('\r'); + + putchar (c); + } + fflush (stdout); + fclose (nlfp); + } else + printf(_("\nSystem closed for routine maintenance\n")); + /* + * Non-root users must exit. Root gets the message, but + * gets to login. + */ + + if (pwent.pw_uid != 0) { + closelog(); + exit(0); + } + printf(_("\n[Disconnect bypassed -- root login allowed.]\n")); + } +} +#endif /* !USE_PAM */ + +static void +init_env(void) +{ + char *cp, *tmp; + + if ((tmp = getenv("LANG"))) { + addenv("LANG", tmp); + } + + /* + * Add the timezone environmental variable so that time functions + * work correctly. + */ + + if ((tmp = getenv("TZ"))) { + addenv("TZ", tmp); + } else if ((cp = getdef_str("ENV_TZ"))) + addenv(*cp == '/' ? tz(cp) : cp, NULL); + + /* + * Add the clock frequency so that profiling commands work + * correctly. + */ + + if ((tmp = getenv("HZ"))) { + addenv("HZ", tmp); + } else if ((cp = getdef_str("ENV_HZ"))) + addenv(cp, NULL); +} + + +static RETSIGTYPE +alarm_handler(int sig) +{ + fprintf(stderr, _("\nLogin timed out after %d seconds.\n"), timeout); + exit(0); +} + + +/* + * login - create a new login session for a user + * + * login is typically called by getty as the second step of a + * new user session. getty is responsible for setting the line + * characteristics to a reasonable set of values and getting + * the name of the user to be logged in. login may also be + * called to create a new user session on a pty for a variety + * of reasons, such as X servers or network logins. + * + * the flags which login supports are + * + * -p - preserve the environment + * -r - perform autologin protocol for rlogin + * -f - do not perform authentication, user is preauthenticated + * -h - the name of the remote host + */ + +int +main(int argc, char **argv) +{ + char username[32]; + char tty[BUFSIZ]; +#ifdef RLOGIN + char term[128] = ""; +#endif +#ifdef HAVE_STRFTIME + char ptime[80]; +#endif + int reason = PW_LOGIN; + int delay; + int retries; + int failed; + int flag; + int subroot = 0; + int is_console; + const char *cp; + char *tmp; + char fromhost[512]; + struct passwd *pwd; + char **envp = environ; + static char temp_pw[2]; + static char temp_shell[] = "/bin/sh"; +#ifdef USE_PAM + int retcode; + pid_t child; + char *pam_user; +#endif /* USE_PAM */ +#ifdef SHADOWPWD + struct spwd *spwd=NULL; +#endif +#ifdef RADIUS + RAD_USER_DATA rad_user_data; + int is_rad_login; +#endif +#if defined(RADIUS) || defined(DES_RPC) || defined(KERBEROS) + /* from pwauth.c */ + extern char *clear_pass; + extern int wipe_clear_pass; + + /* + * We may need the password later, don't want pw_auth() to wipe it + * (we do it ourselves when it is no longer needed). --marekm + */ + wipe_clear_pass = 0; +#endif + + /* + * Some quick initialization. + */ + + sanitize_env(); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + initenv(); + + username[0] = '\0'; + amroot = (getuid() == 0); + Prog = Basename(argv[0]); + + check_flags(argc, argv); + + while ((flag = getopt(argc, argv, "d:f:h:pr:")) != EOF) { + switch (flag) { + case 'p': + pflg++; + break; + case 'f': + /* + * username must be a separate token + * (-f root, *not* -froot). --marekm + */ + if (optarg != argv[optind - 1]) + usage(); + fflg++; + STRFCPY(username, optarg); + break; +#ifdef RLOGIN + case 'r': + rflg++; + hostname = optarg; + reason = PW_RLOGIN; + break; +#endif + case 'h': + hflg++; + hostname = optarg; + reason = PW_TELNET; + break; + case 'd': + /* "-d device" ignored for compatibility */ + break; + default: + usage(); + } + } + +#ifdef RLOGIN + /* + * Neither -h nor -f should be combined with -r. + */ + + if (rflg && (hflg || fflg)) + usage(); +#endif + + /* + * Allow authentication bypass only if real UID is zero. + */ + + if ((rflg || fflg || hflg) && !amroot) { + fprintf(stderr, _("%s: permission denied\n"), Prog); + exit(1); + } + + if (!isatty(0) || !isatty(1) || !isatty(2)) + exit(1); /* must be a terminal */ + +#if 0 + /* + * Get the utmp file entry and get the tty name from it. The + * current process ID must match the process ID in the utmp + * file if there are no additional flags on the command line. + */ + checkutmp(!rflg && !fflg && !hflg); +#else + /* + * Be picky if run by normal users (possible if installed setuid + * root), but not if run by root. This way it still allows logins + * even if your getty is broken, or if something corrupts utmp, + * but users must "exec login" which will use the existing utmp + * entry (will not overwrite remote hostname). --marekm + */ + checkutmp(!amroot); +#endif + STRFCPY(tty, utent.ut_line); + is_console = console(tty); + + if (rflg || hflg) { +#ifdef UT_ADDR + struct hostent *he; + + /* + * Fill in the ut_addr field (remote login IP address). + * XXX - login from util-linux does it, but this is not + * the right place to do it. The program that starts + * login (telnetd, rlogind) knows the IP address, so it + * should create the utmp entry and fill in ut_addr. + * gethostbyname() is not 100% reliable (the remote host + * may be unknown, etc.). --marekm + */ + if ((he = gethostbyname(hostname))) { + utent.ut_addr = *((int32_t *)(he->h_addr_list[0])); +#endif +#ifdef UT_HOST + strncpy(utent.ut_host, hostname, sizeof(utent.ut_host)); +#endif +#if HAVE_UTMPX_H + strncpy(utxent.ut_host, hostname, sizeof(utxent.ut_host)); +#endif + /* + * Add remote hostname to the environment. I think + * (not sure) I saw it once on Irix. --marekm + */ + addenv("REMOTEHOST", hostname); + } +#ifdef __linux__ +/* workaround for init/getty leaving junk in ut_host at least in some + version of RedHat. --marekm */ + else if (amroot) + memzero(utent.ut_host, sizeof utent.ut_host); +#endif + if (hflg && fflg) { + reason = PW_RLOGIN; + preauth_flag++; + } +#ifdef RLOGIN + if (rflg && do_rlogin(hostname, username, sizeof username, term, sizeof term)) + preauth_flag++; +#endif + + OPENLOG("login"); + + setup_tty(); + + umask(getdef_num("UMASK", 077)); + + { + /* + * Use the ULIMIT in the login.defs file, and if + * there isn't one, use the default value. The + * user may have one for themselves, but otherwise, + * just take what you get. + */ + + long limit = getdef_long("ULIMIT", -1L); + + if (limit != -1) + set_filesize_limit(limit); + } + + /* + * The entire environment will be preserved if the -p flag + * is used. + */ + + if (pflg) + while (*envp) /* add inherited environment, */ + addenv(*envp++, NULL); /* some variables change later */ + +#ifdef RLOGIN + if (term[0] != '\0') + addenv("TERM", term); + else +#endif + /* preserve TERM from getty */ + if (!pflg && (tmp = getenv("TERM"))) + addenv("TERM", tmp); + + init_env(); + + if (optind < argc) { /* get the user name */ + if (rflg || fflg) + usage(); + +#ifdef SVR4 + /* + * The "-h" option can't be used with a command-line username, + * because telnetd invokes us as: login -h host TERM=... + */ + + if (! hflg) +#endif + { + STRFCPY(username, argv[optind]); + strzero(argv[optind]); + ++optind; + } + } +#ifdef SVR4 + /* + * check whether ttymon has done the prompt for us already + */ + + { + char *ttymon_prompt; + + if ((ttymon_prompt = getenv("TTYPROMPT")) != NULL && + (*ttymon_prompt != 0)) { + /* read name, without prompt */ + login_prompt((char *)0, username, sizeof username); + } + } +#endif /* SVR4 */ + if (optind < argc) /* now set command line variables */ + set_env(argc - optind, &argv[optind]); + + if (rflg || hflg) + cp = hostname; + else +#ifdef UT_HOST + if (utent.ut_host[0]) + cp = utent.ut_host; + else +#endif +#if HAVE_UTMPX_H + if (utxent.ut_host[0]) + cp = utxent.ut_host; + else +#endif + cp = ""; + + if (*cp) + snprintf(fromhost, sizeof fromhost, + _(" on `%.100s' from `%.200s'"), tty, cp); + else + snprintf(fromhost, sizeof fromhost, _(" on `%.100s'"), tty); + +top: + /* only allow ALARM sec. for login */ + signal(SIGALRM, alarm_handler); + timeout = getdef_num("LOGIN_TIMEOUT", ALARM); + if (timeout > 0) + alarm(timeout); + + environ = newenvp; /* make new environment active */ + delay = getdef_num("FAIL_DELAY", 1); + retries = getdef_num("LOGIN_RETRIES", RETRIES); + +#ifdef USE_PAM + retcode = pam_start("login", username, &conv, &pamh); + if(retcode != PAM_SUCCESS) { + fprintf(stderr,"login: PAM Failure, aborting: %s\n", + PAM_STRERROR(pamh, retcode)); + syslog(LOG_ERR,"Couldn't initialize PAM: %s", + PAM_STRERROR(pamh, retcode)); + exit(99); + } + /* hostname & tty are either set to NULL or their correct values, + depending on how much we know. We also set PAM's fail delay + to ours. */ + retcode = pam_set_item(pamh, PAM_RHOST, hostname); + PAM_FAIL_CHECK; + retcode = pam_set_item(pamh, PAM_TTY, tty); + PAM_FAIL_CHECK; +#ifdef HAVE_PAM_FAIL_DELAY + retcode = pam_fail_delay(pamh, 1000000*delay); + PAM_FAIL_CHECK; +#endif + /* if fflg == 1, then the user has already been authenticated */ + if (!fflg || (getuid() != 0)) { + int failcount; + char hostn[256]; + char login_prompt[256]; /* That's one hell of a prompt :) */ + + /* Make the login prompt look like we want it */ + if (!gethostname(hostn, sizeof(hostn))) + snprintf(login_prompt, sizeof(login_prompt), + "%s login: ", hostn); + else + snprintf(login_prompt, sizeof(login_prompt), + "login: "); + + retcode = pam_set_item(pamh, PAM_USER_PROMPT, login_prompt); + PAM_FAIL_CHECK; + + /* if we didn't get a user on the command line, + set it to NULL */ + pam_get_item(pamh, PAM_USER, (const void **) &pam_user); + if (pam_user[0] == '\0') + pam_set_item(pamh, PAM_USER, NULL); + + /* there may be better ways to deal with some of these + conditions, but at least this way I don't think we'll + be giving away information... */ + /* Perhaps someday we can trust that all PAM modules will + pay attention to failure count and get rid of + MAX_LOGIN_TRIES? */ + + retcode = pam_authenticate(pamh, 0); + while ((failcount++ < retries) && + ((retcode == PAM_AUTH_ERR) || + (retcode == PAM_USER_UNKNOWN) || + (retcode == PAM_CRED_INSUFFICIENT) || + (retcode == PAM_AUTHINFO_UNAVAIL))) { + pam_get_item(pamh, PAM_USER, (const void **) &pam_user); + syslog(LOG_NOTICE,"FAILED LOGIN %d FROM %s FOR %s, %s", + failcount, hostname, pam_user, + PAM_STRERROR(pamh, retcode)); +#ifdef HAVE_PAM_FAIL_DELAY + pam_fail_delay(pamh, 1000000*delay); +#endif + fprintf(stderr, "Login incorrect\n\n"); + pam_set_item(pamh, PAM_USER, NULL); + retcode = pam_authenticate(pamh, 0); + } + + if (retcode != PAM_SUCCESS) { + pam_get_item(pamh, PAM_USER, (const void **) &pam_user); + + if (retcode == PAM_MAXTRIES) + syslog(LOG_NOTICE, + "TOO MANY LOGIN TRIES (%d) FROM %s FOR %s, %s", + failcount, hostname, pam_user, + PAM_STRERROR(pamh, retcode)); + else + syslog(LOG_NOTICE, + "FAILED LOGIN SESSION FROM %s FOR %s, %s", + hostname, pam_user, + PAM_STRERROR(pamh, retcode)); + + fprintf(stderr, "\nLogin incorrect\n"); + pam_end(pamh, retcode); + exit(0); + } + + retcode = pam_acct_mgmt(pamh, 0); + + if(retcode == PAM_NEW_AUTHTOK_REQD) { + retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + } + + PAM_FAIL_CHECK; + } + + /* Grab the user information out of the password file for future usage + First get the username that we are actually using, though. + */ + retcode = pam_get_item(pamh, PAM_USER, (const void **) &pam_user); + setpwent(); + pwd = getpwnam(pam_user); + + if (!pwd || setup_groups(pwd)) + exit(1); + + retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED); + PAM_FAIL_CHECK; + + retcode = pam_open_session(pamh, 0); + PAM_FAIL_CHECK; + + +#else /* ! USE_PAM */ + while (1) { /* repeatedly get login/password pairs */ + failed = 0; /* haven't failed authentication yet */ +#ifdef RADIUS + is_rad_login = 0; +#endif + if (! username[0]) { /* need to get a login id */ + if (subroot) { + closelog (); + exit (1); + } + preauth_flag = 0; +#ifndef LOGIN_PROMPT +#ifdef __linux__ /* hostname login: - like in util-linux login */ + login_prompt(_("\n%s login: "), username, sizeof username); +#else + login_prompt(_("login: "), username, sizeof username); +#endif +#else + login_prompt(LOGIN_PROMPT, username, sizeof username); +#endif + continue; + } +#endif /* ! USE_PAM */ + +#ifdef USE_PAM + if (!(pwd = getpwnam(pam_user))) { + pwent.pw_name = pam_user; +#else + if (!(pwd = getpwnam(username))) { + pwent.pw_name = username; +#endif + strcpy(temp_pw, "!"); + pwent.pw_passwd = temp_pw; + pwent.pw_shell = temp_shell; + + preauth_flag = 0; + failed = 1; + } else { + pwent = *pwd; + } +#ifndef USE_PAM +#ifdef SHADOWPWD + spwd = NULL; + if (pwd && strcmp(pwd->pw_passwd, SHADOW_PASSWD_STRING) == 0) { + spwd = getspnam(username); + if (spwd) + pwent.pw_passwd = spwd->sp_pwdp; + else + SYSLOG((LOG_WARN, NO_SHADOW, username, fromhost)); + } +#endif /* SHADOWPWD */ + + /* + * If the encrypted password begins with a "!", the account + * is locked and the user cannot login, even if they have + * been "pre-authenticated." + */ + if (pwent.pw_passwd[0] == '!' || pwent.pw_passwd[0] == '*') + failed = 1; + + /* + * The -r and -f flags provide a name which has already + * been authenticated by some server. + */ + if (preauth_flag) + goto auth_ok; + + /* + * No password prompt if logging in from listed ttys + * (local console). Passwords don't help much if you + * have physical access to the hardware anyway... + * Suggested by Pavel Machek . + * NOTE: password still required for root logins! + */ + if (pwd && (pwent.pw_uid != 0) + && is_listed("NO_PASSWORD_CONSOLE", tty, 0)) { + temp_pw[0] = '\0'; + pwent.pw_passwd = temp_pw; + } + + if (pw_auth(pwent.pw_passwd, username, reason, (char *) 0) == 0) + goto auth_ok; + +#ifdef RADIUS + /* + * If normal passwd authentication didn't work, try radius. + */ + + if (failed) { + pwd = rad_authenticate(&rad_user_data, username, + clear_pass ? clear_pass : ""); + if (pwd) { + is_rad_login = 1; + pwent = *pwd; + failed = 0; + goto auth_ok; + } + } +#endif /* RADIUS */ + + /* + * Don't log unknown usernames - I mistyped the password for + * username at least once... Should probably use LOG_AUTHPRIV + * for those who really want to log them. --marekm + */ + SYSLOG((LOG_WARN, BAD_PASSWD, + (pwd || getdef_bool("LOG_UNKFAIL_ENAB")) ? + username : "UNKNOWN", fromhost)); + failed = 1; + +auth_ok: + /* + * This is the point where all authenticated users + * wind up. If you reach this far, your password has + * been authenticated and so on. + */ + +#if defined(RADIUS) && !(defined(DES_RPC) || defined(KERBEROS)) + if (clear_pass) { + strzero(clear_pass); + clear_pass = NULL; + } +#endif + + if (getdef_bool("DIALUPS_CHECK_ENAB")) { + alarm (30); + + if (! dialcheck (tty, pwent.pw_shell[0] ? + pwent.pw_shell:"/bin/sh")) { + SYSLOG((LOG_WARN, BAD_DIALUP, username, tty)); + failed = 1; + } + } + + if (! failed && pwent.pw_name && pwent.pw_uid == 0 && + ! is_console) { + SYSLOG((LOG_CRIT, BAD_ROOT_LOGIN, fromhost)); + failed = 1; + } +#ifdef LOGIN_ACCESS + if (!failed && !login_access(username, *hostname ? hostname : tty)) { + SYSLOG((LOG_WARN, LOGIN_REFUSED, username, fromhost)); + failed = 1; + } +#endif + if (pwd && getdef_bool("FAILLOG_ENAB") && + ! failcheck (pwent.pw_uid, &faillog, failed)) { + SYSLOG((LOG_CRIT, FAILURE_CNT, username, fromhost)); + failed = 1; + } + if (! failed) + break; + + /* don't log non-existent users */ + if (pwd && getdef_bool("FAILLOG_ENAB")) + failure (pwent.pw_uid, tty, &faillog); + if (getdef_str("FTMP_FILE") != NULL) { + const char *failent_user; + +#if HAVE_UTMPX_H + failent = utxent; + gettimeofday(&(failent.ut_tv), NULL); +#else + failent = utent; + time(&failent.ut_time); +#endif + if (pwd) { + failent_user = pwent.pw_name; + } else { + if (getdef_bool("LOG_UNKFAIL_ENAB")) + failent_user = username; + else + failent_user = "UNKNOWN"; + } + strncpy(failent.ut_user, failent_user, sizeof(failent.ut_user)); +#ifdef USER_PROCESS + failent.ut_type = USER_PROCESS; +#endif + failtmp(&failent); + } + memzero(username, sizeof username); + + if (--retries <= 0) + SYSLOG((LOG_CRIT, MANY_FAILS, fromhost)); +#if 1 + /* + * If this was a passwordless account and we get here, + * login was denied (securetty, faillog, etc.). There + * was no password prompt, so do it now (will always + * fail - the bad guys won't see that the passwordless + * account exists at all). --marekm + */ + + if (pwent.pw_passwd[0] == '\0') + pw_auth("!", username, reason, (char *) 0); +#endif + /* + * Wait a while (a la SVR4 /usr/bin/login) before attempting + * to login the user again. If the earlier alarm occurs + * before the sleep() below completes, login will exit. + */ + + if (delay > 0) + sleep(delay); + + puts(_("Login incorrect")); + + /* allow only one attempt with -r or -f */ + if (rflg || fflg || retries <= 0) { + closelog(); + exit(1); + } + } /* while (1) */ +#endif /* ! USE_PAM */ + (void) alarm (0); /* turn off alarm clock */ +#ifndef USE_PAM /* PAM does this */ + /* + * porttime checks moved here, after the user has been + * authenticated. now prints a message, as suggested + * by Ivan Nejgebauer . --marekm + */ + if (getdef_bool("PORTTIME_CHECKS_ENAB") && + !isttytime(pwent.pw_name, tty, time ((time_t *) 0))) { + SYSLOG((LOG_WARN, BAD_TIME, username, fromhost)); + closelog(); + bad_time_notify(); + exit(1); + } + + check_nologin(); +#endif + + if (getenv("IFS")) /* don't export user IFS ... */ + addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */ + +#ifdef USE_PAM + setutmp(pam_user, tty, hostname); /* make entry in utmp & wtmp files */ +#else + setutmp(username, tty, hostname); /* make entry in utmp & wtmp files */ +#endif + if (pwent.pw_shell[0] == '*') { /* subsystem root */ + subsystem (&pwent); /* figure out what to execute */ + subroot++; /* say i was here again */ + endpwent (); /* close all of the file which were */ + endgrent (); /* open in the original rooted file */ +#ifdef SHADOWPWD + endspent (); /* system. they will be re-opened */ +#endif +#ifdef SHADOWGRP + endsgent (); /* in the new rooted file system */ +#endif + goto top; /* go do all this all over again */ + } +#ifndef USE_PAM /* pam_lastlog handles this */ + if (getdef_bool("LASTLOG_ENAB")) /* give last login and log this one */ + dolastlog(&lastlog, &pwent, utent.ut_line, hostname); +#endif + +#ifdef SVR4_SI86_EUA + sysi86(SI86LIMUSER, EUA_ADD_USER); /* how do we test for fail? */ +#endif + +#ifndef USE_PAM /* PAM handles this as well */ +#ifdef AGING + /* + * Have to do this while we still have root privileges, otherwise + * we don't have access to /etc/shadow. expire() closes password + * files, and changes to the user in the child before executing + * the passwd program. --marekm + */ +#ifdef SHADOWPWD + if (spwd) { /* check for age of password */ + if (expire (&pwent, spwd)) { + pwd = getpwnam(username); + spwd = getspnam(username); + if (pwd) + pwent = *pwd; + } + } +#else +#ifdef ATT_AGE + if (pwent.pw_age && pwent.pw_age[0]) { + if (expire (&pwent)) { + pwd = getpwnam(username); + if (pwd) + pwent = *pwd; + } + } +#endif /* ATT_AGE */ +#endif /* SHADOWPWD */ +#endif /* AGING */ + +#ifdef RADIUS + if (is_rad_login) { + char whofilename[128]; + FILE *whofile; + + snprintf(whofilename, sizeof whofilename, "/var/log/radacct/%.20s", tty); + whofile = fopen(whofilename, "w"); + if (whofile) { + fprintf(whofile, "%s\n", username); + fclose(whofile); + } + } +#endif + setup_limits(&pwent); /* nice, ulimit etc. */ +#endif /* ! USE_PAM */ + chown_tty(tty, &pwent); + +#ifdef LOGIN_FBTAB + /* + * XXX - not supported yet. Change permissions and ownerships of + * devices like floppy/audio/mouse etc. for console logins, based + * on /etc/fbtab or /etc/logindevperm configuration files (Suns do + * this with their framebuffer devices). Problems: + * + * - most systems (except BSD) don't have that nice revoke() system + * call to ensure the previous user didn't leave a process holding + * one of these devices open or mmap'ed. Any volunteers to do it + * in Linux? + * + * - what to do with different users logged in on different virtual + * consoles? Maybe permissions should be changed only on user's + * request, by running a separate (setuid root) program? + * + * - init/telnetd/rlogind/whatever should restore permissions after + * the user logs out. + * + * Try the new CONSOLE_GROUPS feature instead. It adds specified + * groups (like "floppy") to the group set if the user is logged in + * on the console. This still has the first problem (users leaving + * processes with these devices open), but doesn't need to change + * any permissions, just make them 0660 root:floppy etc. --marekm + * + * Warning: users can still gain permanent access to these groups + * unless any user-writable filesystems are mounted with the "nosuid" + * option. Alternatively, the kernel could be modified to prevent + * ordinary users from setting the setgid bit on executables. + */ + login_fbtab(tty, pwent.pw_uid, pwent.pw_gid); +#endif + + /* We call set_groups() above because this clobbers pam_groups.so */ +#ifndef USE_PAM + if (setup_uid_gid(&pwent, is_console)) +#else + if (change_uid(&pwent)) +#endif + exit(1); + +#ifdef KERBEROS + if (clear_pass) + login_kerberos(username, clear_pass); +#endif +#ifdef DES_RPC + if (clear_pass) + login_desrpc(clear_pass); +#endif +#if defined(DES_RPC) || defined(KERBEROS) + if (clear_pass) + strzero(clear_pass); +#endif + + setup_env(&pwent); /* set env vars, cd to the home dir */ + +#ifdef USE_PAM + { + int i; + const char * const * env; + + env = (const char * const *) pam_getenvlist(pamh); + while (env && *env) { + addenv(*env, NULL); + env++; + } + } +#endif + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (!hushed(&pwent)) { + addenv("HUSHLOGIN=FALSE", NULL); + /* pam_unix, pam_mail and pam_lastlog should take care of this */ +#ifndef USE_PAM + motd(); /* print the message of the day */ + if (getdef_bool("FAILLOG_ENAB") && faillog.fail_cnt != 0) { + failprint(&faillog); + /* Reset the lockout times if logged in */ + if (faillog.fail_max && + faillog.fail_cnt >= faillog.fail_max) { + puts(_("Warning: login re-enabled after temporary lockout.\n")); + SYSLOG((LOG_WARN, REENABLED2, username, + (int) faillog.fail_cnt)); + } + } + if (getdef_bool("LASTLOG_ENAB") && lastlog.ll_time != 0) { +#ifdef HAVE_STRFTIME + strftime(ptime, sizeof(ptime), + "%a %b %e %H:%M:%S %z %Y", + localtime(&lastlog.ll_time)); + printf(_("Last login: %s on %s"), + ptime, lastlog.ll_line); +#else + printf(_("Last login: %.19s on %s"), + ctime(&lastlog.ll_time), lastlog.ll_line); +#endif +#ifdef HAVE_LL_HOST /* SVR4 || __linux__ || SUN4 */ + if (lastlog.ll_host[0]) + printf(_(" from %.*s"), + (int) sizeof lastlog.ll_host, + lastlog.ll_host); +#endif + printf(".\n"); + } +#ifdef AGING +#ifdef SHADOWPWD + agecheck(&pwent, spwd); +#else + agecheck(&pwent); +#endif +#endif /* AGING */ + mailcheck(); /* report on the status of mail */ +#endif /* !USE_PAM */ + } else + addenv("HUSHLOGIN=TRUE", NULL); + + if (getdef_str("TTYTYPE_FILE") != NULL && getenv("TERM") == NULL) + ttytype (tty); + + signal(SIGQUIT, SIG_DFL); /* default quit signal */ + signal(SIGTERM, SIG_DFL); /* default terminate signal */ + signal(SIGALRM, SIG_DFL); /* default alarm signal */ + signal(SIGHUP, SIG_DFL); /* added this. --marekm */ + +#ifdef USE_PAM + /* We must fork before setuid() because we need to call + * pam_close_session() as root. + */ + /* Note: not true in other (non-Linux) PAM implementations, where + the parent process of login (init, telnetd, ...) is responsible + for calling pam_close_session(). This avoids an extra process + for each login. Maybe we should do this on Linux too? -MM */ + /* We let the admin configure whether they need to keep login + around to close sessions */ + if (getdef_bool("CLOSE_SESSIONS")) { + signal(SIGINT, SIG_IGN); + child = fork(); + if (child < 0) { + /* error in fork() */ + fprintf(stderr, "login: failure forking: %s", + strerror(errno)); + PAM_END; + exit(0); + } else if (child) { + /* parent - wait for child to finish, + then cleanup session */ + wait(NULL); + PAM_END; + exit(0); + } + /* child */ + } +#endif + signal(SIGINT, SIG_DFL); /* default interrupt signal */ + + endpwent(); /* stop access to password file */ + endgrent(); /* stop access to group file */ +#ifdef SHADOWPWD + endspent(); /* stop access to shadow passwd file */ +#endif +#ifdef SHADOWGRP + endsgent(); /* stop access to shadow group file */ +#endif + if (pwent.pw_uid == 0) + SYSLOG((LOG_NOTICE, ROOT_LOGIN, fromhost)); + else if (getdef_bool("LOG_OK_LOGINS")) + SYSLOG((LOG_INFO, REG_LOGIN, username, fromhost)); + closelog(); +#ifdef RADIUS + if (is_rad_login) { + printf(_("Starting rad_login\n")); + rad_login(&rad_user_data); + exit(0); + } +#endif + if ((tmp = getdef_str("FAKE_SHELL")) != NULL) { + shell(tmp, pwent.pw_shell); /* fake shell */ + } + shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */ + /*NOTREACHED*/ + return 0; +} diff --git a/current/src/logoutd.c b/current/src/logoutd.c new file mode 100644 index 00000000..7d5ee566 --- /dev/null +++ b/current/src/logoutd.c @@ -0,0 +1,308 @@ +/* + * Copyright 1991 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: logoutd.c,v 1.16 2000/09/02 18:40:44 marekm Exp $") + +#include +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "defines.h" + +#ifdef SVR4 +#include +#endif + +#ifdef SVR4 +#define signal sigset +#endif + +static char *Prog; + +#ifndef DEFAULT_HUP_MESG +#define DEFAULT_HUP_MESG "login time exceeded\r\n" +#endif + +#ifndef HUP_MESG_FILE +#define HUP_MESG_FILE "/etc/logoutd.mesg" +#endif + +/* local function prototypes */ +static int check_login(const struct utmp *); + + +/* + * check_login - check if user (struct utmp) allowed to stay logged in + */ +static int +check_login(const struct utmp *ut) +{ + char user[sizeof(ut->ut_user) + 1]; + time_t now; + + /* + * ut_user may not have the terminating NUL. + */ + strncpy(user, ut->ut_user, sizeof(ut->ut_user)); + user[sizeof(ut->ut_user)] = '\0'; + + time(&now); + + /* + * Check if they are allowed to be logged in right now. + */ + if (!isttytime(user, ut->ut_line, now)) + return 0; +#if 0 + /* + * Check for how long they are allowed to stay logged in. + * XXX - not implemented yet. Need to add a new field to + * /etc/porttime (login time limit in minutes, or no limit, + * based on username, tty, and time of login). + */ + if (now - ut->ut_time > get_time_limit(user, ut->ut_line, ut->ut_time)) + return 0; +#endif + return 1; +} + + +static void +send_mesg_to_tty(int tty_fd) +{ + TERMIO oldt, newt; + FILE *mesg_file, *tty_file; + int c, is_tty; + + tty_file = fdopen(tty_fd, "w"); + if (!tty_file) + return; + + is_tty = (GTTY(tty_fd, &oldt) == 0); + if (is_tty) { + /* Suggested by Ivan Nejgebauar : + set OPOST before writing the message. */ + newt = oldt; + newt.c_oflag |= OPOST; + STTY(tty_fd, &newt); + } + + mesg_file = fopen(HUP_MESG_FILE, "r"); + if (mesg_file) { + while ((c = getc(mesg_file)) != EOF) { + if (c == '\n') + putc('\r', tty_file); + putc(c, tty_file); + } + fclose(mesg_file); + } else { + fputs(DEFAULT_HUP_MESG, tty_file); + } + fflush(tty_file); + fclose(tty_file); + + if (is_tty) { + STTY(tty_fd, &oldt); + } +} + + +/* + * logoutd - logout daemon to enforce /etc/porttime file policy + * + * logoutd is started at system boot time and enforces the login + * time and port restrictions specified in /etc/porttime. The + * utmp file is periodically scanned and offending users are logged + * off from the system. + */ + +int +main(int argc, char **argv) +{ + int i; + int status; + pid_t pid; + struct utmp *ut; + char user[sizeof(ut->ut_user) + 1]; /* terminating NUL */ + char tty_name[sizeof(ut->ut_line) + 6]; /* /dev/ + NUL */ + int tty_fd; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + +#ifndef DEBUG + for (i = 0;close (i) == 0;i++) + ; + +#ifdef HAVE_SETPGRP +#ifdef SETPGRP_VOID + setpgrp(); /* USG */ +#else + setpgrp(getpid(), getpid()); +#endif +#else /* !HAVE_SETPGRP */ + setpgid(getpid(), getpid()); /* BSD || SUN || SUN4 */ +#endif /* !HAVE_SETPGRP */ + + /* + * Put this process in the background. + */ + + pid = fork(); + if (pid > 0) { + /* parent */ + exit(0); + } else if (pid < 0) { + /* error */ + perror("fork"); + exit(1); + } +#endif /* !DEBUG */ + + /* + * Start syslogging everything + */ + + Prog = Basename(argv[0]); + + OPENLOG(Prog); + + /* + * Scan the UTMP file once per minute looking for users that + * are not supposed to still be logged in. + */ + + while (1) { + + /* + * Attempt to re-open the utmp file. The file is only + * open while it is being used. + */ + + setutent(); + + /* + * Read all of the entries in the utmp file. The entries + * for login sessions will be checked to see if the user + * is permitted to be signed on at this time. + */ + + while ((ut = getutent())) { +#ifdef USER_PROCESS + if (ut->ut_type != USER_PROCESS) + continue; +#endif + if (ut->ut_user[0] == '\0') + continue; + if (check_login(ut)) + continue; + + /* + * Put the rest of this in a child process. This + * keeps the scan from waiting on other ports to die. + */ + + pid = fork(); + if (pid > 0) { + /* parent */ + continue; + } else if (pid < 0) { + /* failed - give up until the next scan */ + break; + } + /* child */ + + if (strncmp(ut->ut_line, "/dev/", 5) != 0) + strcpy(tty_name, "/dev/"); + else + tty_name[0] = '\0'; + + strcat(tty_name, ut->ut_line); +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + tty_fd = open(tty_name, O_WRONLY|O_NDELAY|O_NOCTTY); + if (tty_fd != -1) { + send_mesg_to_tty(tty_fd); + close(tty_fd); + sleep(10); + } +#ifdef USER_PROCESS /* USG_UTMP */ + if (ut->ut_pid > 1) { + kill(- ut->ut_pid, SIGHUP); + sleep(10); + kill(- ut->ut_pid, SIGKILL); + } +#else /* BSD || SUN || SUN4 */ + /* + * vhangup() the line to kill try and kill + * whatever is out there using it. + */ + + if ((tty_fd = open (tty_name, O_RDONLY|O_NDELAY)) == -1) + continue; + + vhangup (tty_fd); + close (tty_fd); +#endif /* BSD || SUN || SUN4 */ + + strncpy(user, ut->ut_line, sizeof(user) - 1); + user[sizeof(user) - 1] = '\0'; + + SYSLOG((LOG_NOTICE, "logged off user `%s' on `%s'\n", + user, tty_name)); + + /* + * This child has done all it can, drop dead. + */ + + exit (0); + } + + endutent(); + +#ifndef DEBUG + sleep(60); +#endif + /* + * Reap any dead babies ... + */ + + while (wait (&status) != -1) + ; + } + return 1; /* not reached */ +} diff --git a/current/src/mkpasswd.c b/current/src/mkpasswd.c new file mode 100644 index 00000000..e35da31f --- /dev/null +++ b/current/src/mkpasswd.c @@ -0,0 +1,394 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: mkpasswd.c,v 1.7 2000/08/26 18:27:18 marekm Exp $") + +#include +#include "prototypes.h" +#include "defines.h" +#include + +#if !defined(NDBM) /*{*/ +int +main(int argc, char **argv) +{ + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + fprintf(stderr, + _("%s: no DBM database on system - no action performed\n"), + argv[0]); + return 0; +} + +#else /*} defined(NDBM) {*/ + +#include +#include + +#include +#include + +extern DBM *pw_dbm; +extern DBM *gr_dbm; +#ifdef SHADOWPWD +extern DBM *sp_dbm; +#endif +#ifdef SHADOWGRP +extern DBM *sg_dbm; +#endif +char *fgetsx(); + +#ifdef SHADOWPWD +#ifdef SHADOWGRP +#define USAGE _("Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n") +#else /* !SHADOWGRP */ +#define USAGE _("Usage: %s [ -vf ] [ -p|g|sp ] file\n") +#endif /* SHADOWGRP */ +#else /* !SHADOWPWD */ +#define USAGE _("Usage: %s [ -vf ] [ -p|g ] file\n") +#endif /* SHADOWPWD */ + +char *Progname; +int vflg = 0; +int fflg = 0; +int gflg = 0; +int sflg = 0; /* -s flag -- leave in, makes code nicer */ +int pflg = 0; + +extern struct passwd *sgetpwent(); +extern int pw_dbm_update(); + +extern struct group *sgetgrent(); +extern int gr_dbm_update(); + +#ifdef SHADOWPWD +extern struct spwd *sgetspent(); +extern int sp_dbm_update(); +#endif + +#ifdef SHADOWGRP +extern struct sgrp *sgetsgent(); +extern int sg_dbm_update(); +#endif + +/* local function prototypes */ +static void usage(void); + +/* + * mkpasswd - create DBM files for /etc/passwd-like input file + * + * mkpasswd takes an an argument the name of a file in /etc/passwd format + * and creates a DBM file keyed by user ID and name. The output files have + * the same name as the input file, with .dir and .pag appended. + * + * this command will also create look-aside files for + * /etc/group, /etc/shadow, and /etc/gshadow. + */ + +int +main(int argc, char **argv) +{ + extern int optind; + extern char *optarg; + FILE *fp; /* File pointer for input file */ + char *file; /* Name of input file */ + char *dir; /* Name of .dir file */ + char *pag; /* Name of .pag file */ + char *cp; /* Temporary character pointer */ + int flag; /* Flag for command line option */ + int cnt = 0; /* Number of entries in database */ + int longest = 0; /* Longest entry in database */ + int len; /* Length of input line */ + int errors = 0; /* Count of errors processing file */ + char buf[BUFSIZ*8]; /* Input line from file */ + struct passwd *passwd=NULL; /* Pointer to password file entry */ + + struct group *group=NULL; /* Pointer to group file entry */ +#ifdef SHADOWPWD + struct spwd *shadow=NULL; /* Pointer to shadow passwd entry */ +#endif +#ifdef SHADOWGRP + struct sgrp *gshadow=NULL; /* Pointer to shadow group entry */ +#endif + DBM *dbm; /* Pointer to new NDBM files */ + DBM *dbm_open(); /* Function to open NDBM files */ + + /* + * Figure out what my name is. I will use this later ... + */ + + Progname = Basename(argv[0]); + + /* + * Figure out what the flags might be ... + */ + + while ((flag = getopt (argc, argv, "fvpgs")) != EOF) { + switch (flag) { + case 'v': + vflg++; + break; + case 'f': + fflg++; + break; + case 'g': + gflg++; +#ifndef SHADOWGRP + if (sflg) + usage (); +#endif + if (pflg) + usage (); + + break; +#if defined(SHADOWPWD) || defined(SHADOWGRP) + case 's': + sflg++; +#ifndef SHADOWGRP + if (gflg) + usage (); +#endif + break; +#endif + case 'p': + pflg++; + if (gflg) + usage (); + + break; + default: + usage(); + } + } + + /* + * Backwards compatibility fix for -p flag ... + */ + +#ifdef SHADOWPWD + if (! sflg && ! gflg) +#else + if (! gflg) +#endif + pflg++; + + /* + * The last and only remaining argument must be the file name + */ + + if (argc - 1 != optind) + usage (); + + file = argv[optind]; + + if (! (fp = fopen (file, "r"))) { + fprintf (stderr, _("%s: cannot open file %s\n"), Progname, file); + exit (1); + } + + /* + * Make the filenames for the two DBM files. + */ + + dir = xmalloc (strlen (file) + 5); /* space for .dir file */ + strcat (strcpy (dir, file), ".dir"); + + pag = xmalloc (strlen (file) + 5); /* space for .pag file */ + strcat (strcpy (pag, file), ".pag"); + + /* + * Remove existing files if requested. + */ + + if (fflg) { + (void) unlink (dir); + (void) unlink (pag); + } + + /* + * Create the two DBM files - it is an error for these files + * to have existed already. + */ + + if (access(dir, F_OK) == 0) { + fprintf (stderr, _("%s: cannot overwrite file %s\n"), Progname, dir); + exit (1); + } + if (access(pag, F_OK) == 0) { + fprintf (stderr, _("%s: cannot overwrite file %s\n"), Progname, pag); + exit (1); + } + + if (sflg) + umask(077); + else + umask(022); + + /* + * Now the DBM database gets initialized + */ + + if (! (dbm = dbm_open (file, O_RDWR|O_CREAT, 0644))) { + fprintf (stderr, _("%s: cannot open DBM files for %s\n"), Progname, file); + exit (1); + } + if (gflg) { +#ifdef SHADOWGRP + if (sflg) + sg_dbm = dbm; + else +#endif + gr_dbm = dbm; + } else { +#ifdef SHADOWPWD + if (sflg) + sp_dbm = dbm; + else +#endif + pw_dbm = dbm; + } + + /* + * Read every line in the password file and convert it into a + * data structure to be put in the DBM database files. + */ + + while (fgetsx (buf, BUFSIZ, fp) != NULL) { + + /* + * Get the next line and strip off the trailing newline + * character. + */ + + buf[sizeof buf - 1] = '\0'; + if (! (cp = strchr (buf, '\n'))) { + fprintf (stderr, _("%s: the beginning with "%.16s ..." is too long\n"), Progname, buf); + exit (1); + } + *cp = '\0'; + len = strlen (buf); + +#ifdef USE_NIS + /* + * Parse the password file line into a (struct passwd). + * Erroneous lines cause error messages, but that's + * all. YP lines are ignored completely. + */ + + if (buf[0] == '-' || buf[0] == '+') + continue; +#endif + if (! (((! sflg && pflg) && (passwd = sgetpwent (buf))) +#ifdef SHADOWPWD + || ((sflg && pflg) && (shadow = sgetspent (buf))) +#endif + || ((! sflg && gflg) && (group = sgetgrent (buf))) +#ifdef SHADOWGRP + || ((sflg && gflg) && (gshadow = sgetsgent (buf))) +#endif + )) { + fprintf (stderr, _("%s: error parsing line \"%s\"\n"), Progname, buf); + errors++; + continue; + } + if (vflg) { + if (!sflg && pflg) printf (_("adding record for name "%s"\n"), passwd->pw_name); +#ifdef SHADOWPWD + if (sflg && pflg) printf (_("adding record for name "%s"\n"), shadow->sp_namp); +#endif + if (!sflg && gflg) printf (_("adding record for name "%s"\n"), group->gr_name); +#ifdef SHADOWGRP + if (sflg && gflg) printf (_("adding record for name "%s"\n"), gshadow->sg_name); +#endif + } + if (! sflg && pflg && ! pw_dbm_update (passwd)) + fprintf (stderr, _("%s: error adding record for "%s"\n"), + Progname, passwd->pw_name); + +#ifdef SHADOWPWD + if (sflg && pflg && ! sp_dbm_update (shadow)) + fprintf (stderr, _("%s: error adding record for "%s"\n"), + Progname, shadow->sp_namp); +#endif + if (! sflg && gflg && ! gr_dbm_update (group)) + fprintf (stderr, _("%s: error adding record for "%s"\n"), + Progname, group->gr_name); +#ifdef SHADOWGRP + if (sflg && gflg && ! sg_dbm_update (gshadow)) + fprintf (stderr, _("%s: error adding record for "%s"\n"), + Progname, gshadow->sg_name); +#endif /* SHADOWGRP */ + + /* + * Update the longest record and record count + */ + + if (len > longest) + longest = len; + cnt++; + } + + /* + * Tell the user how things went ... + */ + + if (vflg) + printf (_("added %d entries, longest was %d\n"), cnt, longest); + + exit (errors); + /*NOTREACHED*/ +} + +/* + * usage - print error message and exit + */ + +static void +usage(void) +{ +#ifdef SHADOWPWD +#ifdef SHADOWGRP + fprintf (stderr, _("Usage: %s [ -vf ] [ -p|g|sp|sg ] file\n"), Progname); +#else /* !SHADOWGRP */ + fprintf (stderr, _("Usage: %s [ -vf ] [ -p|g|sp ] file\n"), Progname); +#endif /* SHADOWGRP */ +#else /* !SHADOWPWD */ + fprintf (stderr, _("Usage: %s [ -vf ] [ -p|g ] file\n"), Progname); +#endif /* SHADOWPWD */ + + + exit (1); + /*NOTREACHED*/ +} +#endif /*} defined(NDBM) */ diff --git a/current/src/newgrp.c b/current/src/newgrp.c new file mode 100644 index 00000000..9eb2c5bf --- /dev/null +++ b/current/src/newgrp.c @@ -0,0 +1,499 @@ +/* + * Copyright 1990 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: newgrp.c,v 1.16 2000/09/02 18:40:44 marekm Exp $") + +#include +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" + +#include "getdef.h" + +extern char **environ; + +#ifdef HAVE_SETGROUPS +static int ngroups; +static GETGROUPS_T *grouplist; +#endif + +static char *Prog; +static int is_newgrp; + +/* local function prototypes */ +static void usage(void); + +/* + * usage - print command usage message + */ + +static void +usage(void) +{ + if (is_newgrp) + fprintf (stderr, _("usage: newgrp [ - ] [ group ]\n")); + else + fprintf (stderr, _("usage: sg group [[-c] command ]\n")); +} + +/* + * newgrp - change the invokers current real and effective group id + */ + +int +main(int argc, char **argv) +{ + int initflag = 0; + int needspasswd = 0; + int i; + int their_grp = 0; + int cflag = 0; + gid_t gid; + char *cp; + const char *cpasswd, *name, *prog; + char *group = NULL; + char *command=NULL; + char **envp = environ; + struct passwd *pwd; + struct group *grp; +#ifdef SHADOWPWD + struct spwd *spwd; +#endif +#ifdef SHADOWGRP + struct sgrp *sgrp; +#endif + +#if ENABLE_NLS + /* XXX - remove when gettext is safe to use in setuid programs */ + sanitize_env(); +#endif + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* + * save my name for error messages and save my real gid incase + * of errors. if there is an error i have to exec a new login + * shell for the user since her old shell won't have fork'd to + * create the process. skip over the program name to the next + * command line argument. + */ + + Prog = Basename(argv[0]); + is_newgrp = (strcmp(Prog, "newgrp") == 0); + OPENLOG(is_newgrp ? "newgrp" : "sg"); + gid = getgid(); + argc--; argv++; + + initenv(); + + pwd = get_my_pwent(); + if (!pwd) { + fprintf (stderr, _("unknown uid: %d\n"), (int) getuid()); + SYSLOG((LOG_WARN, "unknown uid %d\n", (int) getuid())); + closelog(); + exit(1); + } + name = pwd->pw_name; + + /* + * Parse the command line. There are two accepted flags. The + * first is "-", which for newgrp means to re-create the entire + * environment as though a login had been performed, and "-c", + * which for sg causes a command string to be executed. + * + * The next argument, if present, must be the new group name. + * Any remaining remaining arguments will be used to execute a + * command as the named group. If the group name isn't present, + * I just use the login group ID of the current user. + * + * The valid syntax are + * newgrp [ - ] [ groupid ] + * newgrp [ -l ] [ groupid ] + * sg [ - ] + * sg [ - ] groupid [ command ] + */ + + if (argc > 0 && (!strcmp(argv[0], "-") || !strcmp(argv[0], "-l"))) { + argc--; argv++; + initflag = 1; + } + if (!is_newgrp) { + /* + * Do the command line for everything that is + * not "newgrp". + */ + + if (argc > 0 && argv[0][0] != '-') { + group = argv[0]; + argc--; argv++; + } else { + usage (); + closelog(); + exit (1); + } + if (argc > 0) { + + /* skip -c if specified so both forms work: + "sg group -c command" (as in the man page) or + "sg group command" (as in the usage message). */ + + if (argc > 1 && strcmp(argv[0], "-c") == 0) + command = argv[1]; + else + command = argv[0]; + cflag++; + } + } else { + + /* + * Do the command line for "newgrp". It's just + * making sure there aren't any flags and getting + * the new group name. + */ + + if (argc > 0 && argv[0][0] == '-') { + usage (); + goto failure; + } else if (argv[0] != (char *) 0) { + group = argv[0]; + } else { + + /* + * get the group file entry for her login group id. + * the entry must exist, simply to be annoying. + */ + + if (! (grp = getgrgid (pwd->pw_gid))) { + fprintf(stderr, _("unknown gid: %ld\n"), + (long) pwd->pw_gid); + SYSLOG((LOG_CRIT, "unknown gid: %ld\n", + (long) pwd->pw_gid)); + goto failure; + } + } + } + +#ifdef HAVE_SETGROUPS + /* + * get the current users groupset. the new group will be + * added to the concurrent groupset if there is room, otherwise + * you get a nasty message but at least your real and effective + * group id's are set. + */ + + /* don't use getgroups(0, 0) - it doesn't work on some systems */ + i = 16; + for (;;) { + grouplist = (GETGROUPS_T *) xmalloc(i * sizeof(GETGROUPS_T)); + ngroups = getgroups(i, grouplist); + if (i > ngroups && !(ngroups == -1 && errno == EINVAL)) + break; + /* not enough room, so try allocating a larger buffer */ + free(grouplist); + i *= 2; + } + if (ngroups < 0) { + perror("getgroups"); + exit(1); + } +#endif /* HAVE_SETGROUPS */ + + /* + * now we put her in the new group. the password file entry for + * her current user id has been gotten. if there was no optional + * group argument she will have her real and effective group id + * set to the value from her password file entry. otherwise + * we validate her access to the specified group. + */ + + if (group == (char *) 0) { + if (! (grp = getgrgid (pwd->pw_gid))) { + fprintf (stderr, _("unknown gid: %d\n"), pwd->pw_gid); + goto failure; + } + group = grp->gr_name; + their_grp = 1; + } else if (! (grp = getgrnam (group))) { + fprintf (stderr, _("unknown group: %s\n"), group); + goto failure; + } +#ifdef SHADOWGRP + if ((sgrp = getsgnam (group))) { + grp->gr_passwd = sgrp->sg_passwd; + grp->gr_mem = sgrp->sg_mem; + } +#endif + + /* + * see if she is a member of this group. + * if she isn't a member, she needs to provide the + * group password. if there is no group password, she + * will be denied access anyway. + * + * we also check if this is the users default group, eg. + * they aren't a member, but this is the group listed as + * the one they belong to in their pwd entry. + */ + + if (!is_on_list(grp->gr_mem, name) && !their_grp) + needspasswd = 1; + + /* + * if she does not have either a shadowed password, + * or a regular password, and the group has a password, + * she needs to give the group password. + */ + +#ifdef SHADOWPWD + if ((spwd = getspnam (name))) + pwd->pw_passwd = spwd->sp_pwdp; +#endif + + if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0]) + needspasswd = 1; + + /* + * now i see about letting her into the group she requested. + * if she is the root user, i'll let her in without having to + * prompt for the password. otherwise i ask for a password + * if she flunked one of the tests above. note that she + * won't have to provide the password to her login group even + * if she isn't listed as a member. + */ + + if (getuid () != 0 && needspasswd) { + + /* + * get the password from her, and set the salt for + * the decryption from the group file. + */ + + if (! (cp = getpass (_("Password: ")))) + goto failure; + + /* + * encrypt the key she gave us using the salt from + * the password in the group file. the result of + * this encryption must match the previously + * encrypted value in the file. + */ + + cpasswd = pw_encrypt (cp, grp->gr_passwd); + strzero(cp); + + if (grp->gr_passwd[0] == '\0') { + /* + * there is no password, print out "Sorry" and give up + */ + sleep(1); + fputs (_("Sorry.\n"), stderr); + goto failure; + } + + if (strcmp (cpasswd, grp->gr_passwd) != 0) { + SYSLOG((LOG_INFO, + "Invalid password for group `%s' from `%s'\n", + group, name)); + sleep(1); + fputs (_("Sorry.\n"), stderr); + goto failure; + } + } + + /* + * all successful validations pass through this point. the + * group id will be set, and the group added to the concurrent + * groupset. + */ + +#ifdef USE_SYSLOG + if (getdef_bool ("SYSLOG_SG_ENAB")) + SYSLOG((LOG_INFO, "user `%s' switched to group `%s'\n", + name, group)); +#endif + gid = grp->gr_gid; + +#ifdef HAVE_SETGROUPS + /* + * i am going to try to add her new group id to her concurrent + * group set. if the group id is already present i'll just + * skip this part. if the group doesn't fit, i'll complain + * loudly and skip this part ... + */ + + for (i = 0;i < ngroups;i++) { + if (gid == grouplist[i]) + break; + } + if (i == ngroups) { + if (ngroups >= NGROUPS_MAX) { + fprintf (stderr, _("too many groups\n")); + } else { + grouplist[ngroups++] = gid; + if (setgroups(ngroups, grouplist)) { + perror("setgroups"); + } + } + } +#endif + +okay: + /* + * i set her group id either to the value she requested, or + * to the original value if the newgrp failed. + */ + + if (setgid(gid)) + perror("setgid"); + + if (setuid(getuid())) { + perror("setuid"); + exit(1); + } + + /* + * see if the "-c" flag was used. if it was, i just create a + * shell command for her using the argument that followed the + * "-c" flag. + */ + + if (cflag) { + closelog(); + execl("/bin/sh", "sh", "-c", command, (char *) 0); + if (errno == ENOENT) { + perror("/bin/sh"); + exit(127); + } else { + perror("/bin/sh"); + exit(126); + } + } + + /* + * i have to get the pathname of her login shell. as a favor, + * i'll try her environment for a $SHELL value first, and + * then try the password file entry. obviously this shouldn't + * be in the restricted command directory since it could be + * used to leave the restricted environment. + */ + + if (! initflag && (cp = getenv ("SHELL"))) + prog = cp; + else if (pwd->pw_shell && pwd->pw_shell[0]) + prog = pwd->pw_shell; + else + prog = "/bin/sh"; + + /* + * now i try to find the basename of the login shell. this + * will become argv[0] of the spawned command. + */ + + cp = Basename((char *) prog); + +#ifdef SHADOWPWD + endspent (); +#endif +#ifdef SHADOWGRP + endsgent (); +#endif + endpwent (); + endgrent (); + + /* + * switch back to her home directory if i am doing login + * initialization. + */ + + if (initflag) { + if (chdir (pwd->pw_dir)) + perror("chdir"); + + while (*envp) { + if (strncmp (*envp, "PATH=", 5) == 0 || + strncmp (*envp, "HOME=", 5) == 0 || + strncmp (*envp, "SHELL=", 6) == 0 || + strncmp (*envp, "TERM=", 5) == 0) + addenv(*envp, NULL); + + envp++; + } + } else { + while (*envp) + addenv(*envp++, NULL); + } + + /* sanitize_env() removes $HOME from the environment (maybe it + shouldn't - please tell me if you are sure that $HOME can't + cause security problems) - add it from user's passwd entry. + */ + addenv("HOME", pwd->pw_dir); + + /* + * exec the login shell and go away. we are trying to get + * back to the previous environment which should be the + * user's login shell. + */ + + shell(prog, initflag ? (char *)0 : cp); + /*NOTREACHED*/ + +failure: + /* + * this is where all failures land. the group id will not + * have been set, so the setgid() below will set me to the + * original group id i had when i was invoked. + */ + + /* + * only newgrp needs to re-exec the user's shell. that is + * because the shell doesn't recognize "sg", so it doesn't + * "exec" this command. + */ + + if (!is_newgrp) { + closelog(); + exit (1); + } + + /* + * The GID is still set to the old value, so now I can + * give the user back her shell. + */ + + goto okay; +} diff --git a/current/src/newusers.c b/current/src/newusers.c new file mode 100644 index 00000000..fd313c4b --- /dev/null +++ b/current/src/newusers.c @@ -0,0 +1,568 @@ +/* + * Copyright 1990 - 1993, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + * + * newusers - create users from a batch file + * + * newusers creates a collection of entries in /etc/passwd + * and related files by reading a passwd-format file and + * adding entries in the related directories. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: newusers.c,v 1.11 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include "prototypes.h" +#include "defines.h" +#include +#include +#include +#include + +static char *Prog; + +#include "getdef.h" +#include "pwio.h" +#include "groupio.h" + +#ifdef SHADOWPWD +#include "shadowio.h" + +static int is_shadow; +#endif + +/* local function prototypes */ +static void usage(void); +static int add_group(const char *, const char *, gid_t *); +static int add_user(const char *, const char *, uid_t *, gid_t); +static void update_passwd(struct passwd *, const char *); +static int add_passwd(struct passwd *, const char *); + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("Usage: %s [ input ]\n"), Prog); + exit(1); +} + +/* + * add_group - create a new group or add a user to an existing group + */ + +static int +add_group(const char *name, const char *gid, gid_t *ngid) +{ + const struct passwd *pwd; + const struct group *grp; + struct group grent; + char *members[2]; + int i; + + /* + * Start by seeing if the named group already exists. This + * will be very easy to deal with if it does. + */ + + if ((grp = gr_locate (gid))) { +add_member: + grent = *grp; + *ngid = grent.gr_gid; + for (i = 0;grent.gr_mem[i] != (char *) 0;i++) + if (strcmp (grent.gr_mem[i], name) == 0) + return 0; + + grent.gr_mem = (char **) xmalloc (sizeof (char *) * (i + 2)); + memcpy (grent.gr_mem, grp->gr_mem, sizeof (char *) * (i + 2)); + grent.gr_mem[i] = xstrdup (name); + grent.gr_mem[i + 1] = (char *) 0; + + return ! gr_update (&grent); + } + + /* + * The group did not exist, so I try to figure out what the + * GID is going to be. The gid parameter is probably "", meaning + * I figure out the GID from the password file. I want the UID + * and GID to match, unless the GID is already used. + */ + + if (gid[0] == '\0') { + i = 100; + for (pw_rewind ();(pwd = pw_next ());) { + if (pwd->pw_uid >= i) + i = pwd->pw_uid + 1; + } + for (gr_rewind ();(grp = gr_next ());) { + if (grp->gr_gid == i) { + i = -1; + break; + } + } + } else if (gid[0] >= '0' && gid[0] <= '9') { + + /* + * The GID is a number, which means either this is a brand new + * group, or an existing group. For existing groups I just add + * myself as a member, just like I did earlier. + */ + + i = atoi (gid); + for (gr_rewind ();(grp = gr_next ());) + if (grp->gr_gid == i) + goto add_member; + } else + + /* + * The last alternative is that the GID is a name which is not + * already the name of an existing group, and I need to figure + * out what group ID that group name is going to have. + */ + + i = -1; + + /* + * If I don't have a group ID by now, I'll go get the + * next one. + */ + + if (i == -1) { + for (i = 100, gr_rewind ();(grp = gr_next ());) + if (grp->gr_gid >= i) + i = grp->gr_gid + 1; + } + + /* + * Now I have all of the fields required to create the new + * group. + */ + + if (gid[0] && (gid[0] <= '0' || gid[0] >= '9')) + grent.gr_name = xstrdup(gid); + else + grent.gr_name = xstrdup(name); + + grent.gr_passwd = "x"; /* XXX warning: const */ + grent.gr_gid = i; + members[0] = xstrdup(name); + members[1] = (char *) 0; + grent.gr_mem = members; + + *ngid = grent.gr_gid; + return ! gr_update (&grent); +} + +/* + * add_user - create a new user ID + */ + +static int +add_user(const char *name, const char *uid, uid_t *nuid, gid_t gid) +{ + const struct passwd *pwd; + struct passwd pwent; + uid_t i; + + /* + * The first guess for the UID is either the numerical UID + * that the caller provided, or the next available UID. + */ + + if (uid[0] >= '0' && uid[0] <= '9') { + i = atoi (uid); + } else if (uid[0] && (pwd = pw_locate (uid))) { + i = pwd->pw_uid; + } else { + i = 100; + for (pw_rewind ();(pwd = pw_next ());) + if (pwd->pw_uid >= i) + i = pwd->pw_uid + 1; + } + + /* + * I don't want to fill in the entire password structure + * members JUST YET, since there is still more data to be + * added. So, I fill in the parts that I have. + */ + + pwent.pw_name = xstrdup(name); + pwent.pw_passwd = "x"; /* XXX warning: const */ +#ifdef ATT_AGE + pwent.pw_age = ""; +#endif +#ifdef ATT_COMMENT + pwent.pw_comment = ""; +#endif +#ifdef BSD_QUOTA + pwent.pw_quota = 0; +#endif + pwent.pw_uid = i; + pwent.pw_gid = gid; + pwent.pw_gecos = ""; /* XXX warning: const */ + pwent.pw_dir = ""; /* XXX warning: const */ + pwent.pw_shell = ""; /* XXX warning: const */ + + *nuid = i; + return ! pw_update (&pwent); +} + +static void +update_passwd(struct passwd *pwd, const char *passwd) +{ + pwd->pw_passwd = pw_encrypt(passwd, crypt_make_salt()); +#ifdef ATT_AGE + if (strlen(pwd->pw_age) == 4) { + static char newage[5]; + extern char *l64a(); + + strcpy(newage, pwd->pw_age); + strcpy(newage + 2, l64a(time((time_t *) 0) / WEEK)); + pwd->pw_age = newage; + } +#endif +} + +/* + * add_passwd - add or update the encrypted password + */ + +static int +add_passwd(struct passwd *pwd, const char *passwd) +{ +#ifdef SHADOWPWD + const struct spwd *sp; + struct spwd spent; +#endif + + /* + * In the case of regular password files, this is real + * easy - pwd points to the entry in the password file. + * Shadow files are harder since there are zillions of + * things to do ... + */ + + if (!is_shadow) { + update_passwd(pwd, passwd); + return 0; + } + +#ifdef SHADOWPWD + /* + * Do the first and easiest shadow file case. The user + * already exists in the shadow password file. + */ + + if ((sp = spw_locate (pwd->pw_name))) { + spent = *sp; + spent.sp_pwdp = pw_encrypt(passwd, crypt_make_salt()); + return ! spw_update (&spent); + } + + /* + * Pick the next easiest case - the user has an encrypted + * password which isn't equal to "x". The password was set + * to "x" earlier when the entry was created, so this user + * would have to have had the password set someplace else. + */ + + if (strcmp (pwd->pw_passwd, "x") != 0) { + update_passwd(pwd, passwd); + return 0; + } + + /* + * Now the really hard case - I need to create an entirely + * new shadow password file entry. + */ + + spent.sp_namp = pwd->pw_name; + spent.sp_pwdp = pw_encrypt(passwd, crypt_make_salt()); + spent.sp_lstchg = time((time_t *) 0) / SCALE; + spent.sp_min = getdef_num("PASS_MIN_DAYS", 0); + /* 10000 is infinity this week */ + spent.sp_max = getdef_num("PASS_MAX_DAYS", 10000); + spent.sp_warn = getdef_num("PASS_WARN_AGE", -1); + spent.sp_inact = -1; + spent.sp_expire = -1; + spent.sp_flag = -1; + + return ! spw_update (&spent); +#endif +} + +int +main(int argc, char **argv) +{ + char buf[BUFSIZ]; + char *fields[8]; + int nfields; + char *cp; + const struct passwd *pw; + struct passwd newpw; + int errors = 0; + int line = 0; + uid_t uid; + gid_t gid; + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (argc > 1 && argv[1][0] == '-') + usage (); + + if (argc == 2) { + if (! freopen (argv[1], "r", stdin)) { + snprintf(buf, sizeof buf, "%s: %s", Prog, argv[1]); + perror (buf); + exit (1); + } + } + + /* + * Lock the password files and open them for update. This will + * bring all of the entries into memory where they may be + * searched for an modified, or new entries added. The password + * file is the key - if it gets locked, assume the others can + * be locked right away. + */ + + if (!pw_lock()) { + fprintf (stderr, _("%s: can't lock /etc/passwd.\n"), Prog); + exit (1); + } +#ifdef SHADOWPWD + is_shadow = spw_file_present(); + + if ((is_shadow && !spw_lock()) || !gr_lock()) +#else + if (!gr_lock()) +#endif + { + fprintf (stderr, _("%s: can't lock files, try again later\n"), + Prog); + (void) pw_unlock (); +#ifdef SHADOWPWD + if (is_shadow) + spw_unlock(); +#endif + exit (1); + } +#ifdef SHADOWPWD + if (!pw_open(O_RDWR) || (is_shadow && !spw_open(O_RDWR)) || !gr_open(O_RDWR)) +#else + if (!pw_open(O_RDWR) || !gr_open(O_RDWR)) +#endif + { + fprintf (stderr, _("%s: can't open files\n"), Prog); + (void) pw_unlock (); +#ifdef SHADOWPWD + if (is_shadow) + spw_unlock(); +#endif + (void) gr_unlock (); + exit (1); + } + + /* + * Read each line. The line has the same format as a password + * file entry, except that certain fields are not contrained to + * be numerical values. If a group ID is entered which does + * not already exist, an attempt is made to allocate the same + * group ID as the numerical user ID. Should that fail, the + * next available group ID over 100 is allocated. The pw_gid + * field will be updated with that value. + */ + + while (fgets (buf, sizeof buf, stdin) != (char *) 0) { + line++; + if ((cp = strrchr (buf, '\n'))) { + *cp = '\0'; + } else { + fprintf (stderr, _("%s: line %d: line too long\n"), + Prog, line); + errors++; + continue; + } + + /* + * Break the string into fields and screw around with + * them. There MUST be 7 colon separated fields, + * although the values aren't that particular. + */ + + for (cp = buf, nfields = 0;nfields < 7;nfields++) { + fields[nfields] = cp; + if ((cp = strchr (cp, ':'))) + *cp++ = '\0'; + else + break; + } + if (nfields != 6) { + fprintf (stderr, _("%s: line %d: invalid line\n"), + Prog, line); + continue; + } + + /* + * Now the fields are processed one by one. The first + * field to be processed is the group name. A new + * group will be created if the group name is non-numeric + * and does not already exist. The named user will be + * the only member. If there is no named group to be a + * member of, the UID will be figured out and that value + * will be a candidate for a new group, if that group ID + * exists, a whole new group ID will be made up. + */ + + if (! (pw = pw_locate (fields[0])) && + add_group (fields[0], fields[3], &gid)) { + fprintf (stderr, _("%s: line %d: can't create GID\n"), + Prog, line); + errors++; + continue; + } + + /* + * Now we work on the user ID. It has to be specified + * either as a numerical value, or left blank. If it + * is a numerical value, that value will be used, otherwise + * the next available user ID is computed and used. After + * this there will at least be a (struct passwd) for the + * user. + */ + + if (! pw && add_user (fields[0], fields[2], &uid, gid)) { + fprintf (stderr, _("%s: line %d: can't create UID\n"), + Prog, line); + errors++; + continue; + } + + /* + * The password, gecos field, directory, and shell fields + * all come next. + */ + + if (! (pw = pw_locate (fields[0]))) { + fprintf (stderr, _("%s: line %d: cannot find user %s\n"), + Prog, line, fields[0]); + errors++; + continue; + } + newpw = *pw; + + if (add_passwd (&newpw, fields[1])) { + fprintf (stderr, _("%s: line %d: can't update password\n"), + Prog, line); + errors++; + continue; + } + if (fields[4][0]) + newpw.pw_gecos = fields[4]; + + if (fields[5][0]) + newpw.pw_dir = fields[5]; + + if (fields[6][0]) + newpw.pw_shell = fields[6]; + + if (newpw.pw_dir[0] && access(newpw.pw_dir, F_OK)) { + if (mkdir (newpw.pw_dir, + 0777 & ~getdef_num("UMASK", 077))) + fprintf (stderr, _("%s: line %d: mkdir failed\n"), + Prog, line); + else if (chown (newpw.pw_dir, + newpw.pw_uid, newpw.pw_gid)) + fprintf (stderr, _("%s: line %d: chown failed\n"), + Prog, line); + } + + /* + * Update the password entry with the new changes made. + */ + + if (! pw_update (&newpw)) { + fprintf (stderr, _("%s: line %d: can't update entry\n"), + Prog, line); + errors++; + continue; + } + } + + /* + * Any detected errors will cause the entire set of changes + * to be aborted. Unlocking the password file will cause + * all of the changes to be ignored. Otherwise the file is + * closed, causing the changes to be written out all at + * once, and then unlocked afterwards. + */ + + if (errors) { + fprintf (stderr, _("%s: error detected, changes ignored\n"), Prog); + (void) gr_unlock (); +#ifdef SHADOWPWD + if (is_shadow) + spw_unlock(); +#endif + (void) pw_unlock (); + exit (1); + } +#ifdef SHADOWPWD + if (!pw_close() || (is_shadow && !spw_close()) || !gr_close()) +#else + if (!pw_close() || ! gr_close()) +#endif + { + fprintf (stderr, _("%s: error updating files\n"), Prog); + (void) gr_unlock (); +#ifdef SHADOWPWD + if (is_shadow) + spw_unlock(); +#endif + (void) pw_unlock (); + exit (1); + } + (void) gr_unlock (); +#ifdef SHADOWPWD + if (is_shadow) + spw_unlock(); +#endif + (void) pw_unlock (); + + exit (0); + /*NOTREACHED*/ +} diff --git a/current/src/passwd.c b/current/src/passwd.c new file mode 100644 index 00000000..b43eb78b --- /dev/null +++ b/current/src/passwd.c @@ -0,0 +1,1415 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: passwd.c,v 1.20 2000/09/02 18:40:44 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_USERSEC_H +#include +#include +#include +#endif + +#ifndef GPASSWD_PROGRAM +#define GPASSWD_PROGRAM "gpasswd" +#endif + +#ifndef CHFN_PROGRAM +#define CHFN_PROGRAM "chfn" +#endif + +#ifndef CHSH_PROGRAM +#define CHSH_PROGRAM "chsh" +#endif + +#include +#ifndef HAVE_USERSEC_H +#ifdef SHADOWPWD +#ifndef AGING +#define AGING 0 +#endif /* !AGING */ +#endif /* SHADOWPWD */ +#endif /* !HAVE_USERSEC_H */ +#include "pwauth.h" + +#ifdef HAVE_TCFS +#include +#include "tcfsio.h" +#endif + +#ifdef SHADOWPWD +#include "shadowio.h" +#endif +#include "pwio.h" +#include "getdef.h" + +/* + * exit status values + */ + +#define E_SUCCESS 0 /* success */ +#define E_NOPERM 1 /* permission denied */ +#define E_USAGE 2 /* invalid combination of options */ +#define E_FAILURE 3 /* unexpected failure, nothing done */ +#define E_MISSING 4 /* unexpected failure, passwd file missing */ +#define E_PWDBUSY 5 /* passwd file busy, try again later */ +#define E_BAD_ARG 6 /* invalid argument to option */ + +/* + * Global variables + */ + +#ifdef HAVE_USERSEC_H +int minage = 0; /* Minimum age in weeks */ +int maxage = 10000; /* Maximum age in weeks */ +#endif + +static char *name; /* The name of user whose password is being changed */ +static char *myname; /* The current user's name */ +static char *Prog; /* Program name */ +static int amroot; /* The real UID was 0 */ + +static int + lflg = 0, /* -l - lock account */ + uflg = 0, /* -u - unlock account */ + dflg = 0, /* -d - delete password */ +#ifdef AGING + xflg = 0, /* -x - set maximum days */ + nflg = 0, /* -n - set minimum days */ + eflg = 0, /* -e - force password change */ + kflg = 0, /* -k - change only if expired */ +#endif +#ifdef SHADOWPWD + wflg = 0, /* -w - set warning days */ + iflg = 0, /* -i - set inactive days */ +#endif + qflg = 0, /* -q - quiet mode */ + aflg = 0, /* -a - show status for all users */ + Sflg = 0; /* -S - show password status */ + +/* + * set to 1 if there are any flags which require root privileges, + * and require username to be specified + */ +static int anyflag = 0; + +#ifdef AGING +static long age_min = 0; /* Minimum days before change */ +static long age_max = 0; /* Maximum days until change */ +#ifdef SHADOWPWD +static long warn = 0; /* Warning days before change */ +static long inact = 0; /* Days without change before locked */ +#endif +#endif + +static int do_update_age = 0; + +#ifndef USE_PAM +static char crypt_passwd[128]; /* The "old-style" password, if present */ +static int do_update_pwd = 0; +#endif + +#ifdef HAVE_TCFS +static struct tcfspwd *tcfspword; +static int tcfs_force = 0; +#endif + +/* + * External identifiers + */ + +#ifdef ATT_AGE +extern char *l64a(); +#endif + +extern int optind; /* Index into argv[] for current option */ +extern char *optarg; /* Pointer to current option value */ + +#ifndef HAVE_USERSEC_H +#ifdef NDBM +extern int sp_dbm_mode; +extern int pw_dbm_mode; +#endif +#endif + + +#define WRONGPWD2 "incorrect password for `%s'" +#define CANTCHANGE2 "password locked for `%s'" + +#define TOOSOON2 "now < minimum age for `%s'" + +#define EXECFAILED2 "cannot execute %s" +#define NOPERM2 "can't change pwd for `%s'" + +#define PWDBUSY2 "can't lock password file" +#define OPNERROR2 "can't open password file" +#define UPDERROR2 "error updating password entry" +#define CLSERROR2 "can't rewrite password file" +#define DBMERROR2 "error updaring dbm password entry" + +#ifdef HAVE_TCFS +#define TCFSPWDBUSY2 "can't lock TCFS key database" +#define TCFSOPNERROR2 "can't open TCFS key database" +#define TCFSUPDERROR2 "error updating TCFS key database" +#define TCFSCLSERROR2 "can't rewrite TCFS key database" +#endif + +#define NOTROOT2 "can't setuid(0)" +#define CHGPASSWD "password for `%s' changed by `%s'" +#define NOCHGPASSWD "did not change password for `%s'" + +/* local function prototypes */ +static void usage(int); +#ifndef USE_PAM +#ifdef AUTH_METHODS +static char *get_password(const char *); +static int uses_default_method(const char *); +#endif /* AUTH_METHODS */ +static int reuse(const char *, const struct passwd *); +static int new_password(const struct passwd *); +#ifdef SHADOWPWD +static void check_password(const struct passwd *, const struct spwd *); +#else /* !SHADOWPWD */ +static void check_password(const struct passwd *); +#endif /* !SHADOWPWD */ +static char *insert_crypt_passwd(const char *, const char *); +#endif /* !USE_PAM */ +static char *date_to_str(time_t); +static const char *pw_status(const char *); +static void print_status(const struct passwd *); +static void fail_exit(int); +static void oom(void); +static char *update_crypt_pw(char *); +static void update_noshadow(void); +#ifdef SHADOWPWD +static void update_shadow(void); +#endif +#ifdef HAVE_TCFS +static void update_tcfs(void); +#endif +#ifdef HAVE_USERSEC_H +static void update_userpw(char *); +#endif +static long getnumber(const char *); + +/* + * usage - print command usage and exit + */ + +static void +usage(int status) +{ + fprintf(stderr, _("usage: %s [ -f | -s ] [ name ]\n"), Prog); + if (amroot) { + fprintf(stderr, + _(" %s [ -x max ] [ -n min ] [ -w warn ] [ -i inact ] name\n"), + Prog); + fprintf(stderr, + _(" %s { -l | -u | -d | -S | -e } name\n"), + Prog); + } + exit(status); +} + +#ifndef USE_PAM +#ifdef AUTH_METHODS +/* + * get_password - locate encrypted password in authentication list + */ + +static char * +get_password(const char *list) +{ + char *cp, *end; + static char buf[257]; + + STRFCPY(buf, list); + for (cp = buf;cp;cp = end) { + if ((end = strchr (cp, ';'))) + *end++ = 0; + + if (cp[0] == '@') + continue; + + return cp; + } + return (char *) 0; +} + +/* + * uses_default_method - determine if "old-style" password present + * + * uses_default_method determines if a "old-style" password is present + * in the authentication string, and if one is present it extracts it. + */ + +static int +uses_default_method(const char *methods) +{ + char *cp; + + if ((cp = get_password (methods))) { + STRFCPY(crypt_passwd, cp); + return 1; + } + return 0; +} +#endif /* AUTH_METHODS */ + +static int +reuse(const char *pass, const struct passwd *pw) +{ +#ifdef HAVE_LIBCRACK_HIST + const char *reason; +#ifdef HAVE_LIBCRACK_PW + const char *FascistHistoryPw(const char *,const struct passwd *); + reason = FascistHistory(pass, pw); +#else + const char *FascistHistory(const char *, int); + reason = FascistHistory(pass, pw->pw_uid); +#endif + if (reason) { + printf(_("Bad password: %s. "), reason); + return 1; + } +#endif + return 0; +} + +/* + * new_password - validate old password and replace with new + * (both old and new in global "char crypt_passwd[128]") + */ + +/*ARGSUSED*/ +static int +new_password(const struct passwd *pw) +{ + char *clear; /* Pointer to clear text */ + char *cipher; /* Pointer to cipher text */ + char *cp; /* Pointer to getpass() response */ + char orig[200]; /* Original password */ + char pass[200]; /* New password */ + int i; /* Counter for retries */ + int warned; + int pass_max_len; +#ifdef HAVE_LIBCRACK_HIST + int HistUpdate(const char *, const char *); +#endif + + /* + * Authenticate the user. The user will be prompted for their + * own password. + */ + +#ifdef HAVE_TCFS + tcfs_force = tcfs_force && amroot; + + if ((tcfs_locate(name) && !tcfs_force) || (!amroot && crypt_passwd[0])) { + if (amroot) { + printf(_("User %s has a TCFS key, his old password is required.\n"), name); + printf(_("You can use -t option to force the change.\n")); + } +#else + if (! amroot && crypt_passwd[0]) { +#endif + + if (!(clear = getpass(_("Old password: ")))) + return -1; + + cipher = pw_encrypt(clear, crypt_passwd); + if (strcmp(cipher, crypt_passwd) != 0) { + SYSLOG((LOG_WARN, WRONGPWD2, pw->pw_name)); + sleep(1); + fprintf(stderr, _("Incorrect password for `%s'\n"), + pw->pw_name); + return -1; + } + STRFCPY(orig, clear); +#ifdef HAVE_TCFS + STRFCPY(tcfspword->tcfsorig, clear); +#endif + strzero(clear); + strzero(cipher); + } else { +#ifdef HAVE_TCFS + if (tcfs_locate(name)) + printf(_("Warning: user %s has a TCFS key.\n"), name); +#endif + orig[0] = '\0'; + } + + /* + * Get the new password. The user is prompted for the new password + * and has five tries to get it right. The password will be tested + * for strength, unless it is the root user. This provides an escape + * for initial login passwords. + */ + + if (getdef_bool("MD5_CRYPT_ENAB")) + pass_max_len = 127; + else + pass_max_len = getdef_num("PASS_MAX_LEN", 8); + + if (!qflg) + printf(_("\ +Enter the new password (minimum of %d, maximum of %d characters)\n\ +Please use a combination of upper and lower case letters and numbers.\n"), + getdef_num("PASS_MIN_LEN", 5), pass_max_len); + + warned = 0; + for (i = getdef_num("PASS_CHANGE_TRIES", 5); i > 0; i--) { + if (!(cp = getpass(_("New password: ")))) { + memzero(orig, sizeof orig); + return -1; + } + if (warned && strcmp(pass, cp) != 0) + warned = 0; + STRFCPY(pass, cp); + strzero(cp); + + if (!amroot && (!obscure(orig, pass, pw) || reuse(pass, pw))) { + printf(_("Try again.\n")); + continue; + } + /* + * If enabled, warn about weak passwords even if you are root + * (enter this password again to use it anyway). --marekm + */ + if (amroot && !warned && getdef_bool("PASS_ALWAYS_WARN") + && (!obscure(orig, pass, pw) || reuse(pass, pw))) { + printf(_("\nWarning: weak password (enter it again to use it anyway).\n")); + warned++; + continue; + } + if (!(cp = getpass(_("Re-enter new password: ")))) { + memzero(orig, sizeof orig); + return -1; + } + if (strcmp (cp, pass)) + fprintf(stderr, _("They don't match; try again.\n")); + else { + strzero(cp); + break; + } + } + memzero(orig, sizeof orig); + + if (i == 0) { + memzero(pass, sizeof pass); + return -1; + } + +#ifdef HAVE_TCFS + STRFCPY(tcfspword->tcfspass, pass); +#endif + + /* + * Encrypt the password, then wipe the cleartext password. + */ + + cp = pw_encrypt(pass, crypt_make_salt()); + memzero(pass, sizeof pass); + +#ifdef HAVE_LIBCRACK_HIST + HistUpdate(pw->pw_name, crypt_passwd); +#endif + STRFCPY(crypt_passwd, cp); + return 0; +} + +/* + * check_password - test a password to see if it can be changed + * + * check_password() sees if the invoker has permission to change the + * password for the given user. + */ + +#ifdef SHADOWPWD +static void +check_password(const struct passwd *pw, const struct spwd *sp) +{ +#else +static void +check_password(const struct passwd *pw) +{ +#endif + time_t now, last, ok; + int exp_status; +#ifdef HAVE_USERSEC_H + struct userpw *pu; +#endif + +#ifdef SHADOWPWD + exp_status = isexpired(pw, sp); +#else + exp_status = isexpired(pw); +#endif + + /* + * If not expired and the "change only if expired" option + * (idea from PAM) was specified, do nothing... --marekm + */ + if (kflg && exp_status == 0) + exit(E_SUCCESS); + + /* + * Root can change any password any time. + */ + + if (amroot) + return; + + time(&now); + +#ifdef SHADOWPWD + /* + * Expired accounts cannot be changed ever. Passwords + * which are locked may not be changed. Passwords where + * min > max may not be changed. Passwords which have + * been inactive too long cannot be changed. + */ + + if (sp->sp_pwdp[0] == '!' || exp_status > 1 || + (sp->sp_max >= 0 && sp->sp_min > sp->sp_max)) { + fprintf(stderr, _("The password for %s cannot be changed.\n"), + sp->sp_namp); + SYSLOG((LOG_WARN, CANTCHANGE2, sp->sp_namp)); + closelog(); + exit(E_NOPERM); + } + + /* + * Passwords may only be changed after sp_min time is up. + */ + + last = sp->sp_lstchg * SCALE; + ok = last + (sp->sp_min > 0 ? sp->sp_min * SCALE : 0); + +#else /* !SHADOWPWD */ + if (pw->pw_passwd[0] == '!' || exp_status > 1) { + fprintf(stderr, _("The password for %s cannot be changed.\n"), + pw->pw_name); + SYSLOG((LOG_WARN, CANTCHANGE2, pw->pw_name)); + closelog(); + exit(E_NOPERM); + } +#ifdef ATT_AGE + /* + * Can always be changed if there is no age info + */ + + if (! pw->pw_age[0]) + return; + + last = a64l (pw->pw_age + 2) * WEEK; + ok = last + c64i (pw->pw_age[1]) * WEEK; +#else /* !ATT_AGE */ +#ifdef HAVE_USERSEC_H + pu = getuserpw(pw->pw_name); + last = pu ? pu->upw_lastupdate : 0L; + ok = last + (minage > 0 ? minage * WEEK : 0); +#else + last = 0; + ok = 0; +#endif +#endif /* !ATT_AGE */ +#endif /* !SHADOWPWD */ + if (now < ok) { + fprintf(stderr, _("Sorry, the password for %s cannot be changed yet.\n"), pw->pw_name); + SYSLOG((LOG_WARN, TOOSOON2, pw->pw_name)); + closelog(); + exit(E_NOPERM); + } +} + +/* + * insert_crypt_passwd - add an "old-style" password to authentication string + * result now malloced to avoid overflow, just in case. --marekm + */ +static char * +insert_crypt_passwd(const char *string, const char *passwd) +{ +#ifdef AUTH_METHODS + if (string && *string) { + char *cp, *result; + + result = xmalloc(strlen(string) + strlen(passwd) + 1); + cp = result; + while (*string) { + if (string[0] == ';') { + *cp++ = *string++; + } else if (string[0] == '@') { + while (*string && *string != ';') + *cp++ = *string++; + } else { + while (*passwd) + *cp++ = *passwd++; + + while (*string && *string != ';') + string++; + } + } + *cp = '\0'; + return result; + } +#endif + return xstrdup(passwd); +} +#endif /* !USE_PAM */ + +static char * +date_to_str(time_t t) +{ + static char buf[80]; + struct tm *tm; + + tm = gmtime(&t); +#ifdef HAVE_STRFTIME + strftime(buf, sizeof buf, "%m/%d/%Y", tm); +#else + snprintf(buf, sizeof buf, "%02d/%02d/%04d", + tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900); +#endif + return buf; +} + +static const char * +pw_status(const char *pass) +{ + if (*pass == '*' || *pass == '!') + return "L"; + if (*pass == '\0') + return "NP"; + return "P"; +} + +/* + * print_status - print current password status + */ + +static void +print_status(const struct passwd *pw) +{ +#ifdef SHADOWPWD + struct spwd *sp; +#endif +#ifdef HAVE_USERSEC_H + struct userpw *pu; +#endif + +#ifdef SHADOWPWD + sp = getspnam(pw->pw_name); + if (sp) { + printf("%s %s %s %ld %ld %ld %ld\n", + pw->pw_name, + pw_status(sp->sp_pwdp), + date_to_str(sp->sp_lstchg * SCALE), + (sp->sp_min * SCALE) / DAY, + (sp->sp_max * SCALE) / DAY, + (sp->sp_warn * SCALE) / DAY, + (sp->sp_inact * SCALE) / DAY); + } else +#endif + { +#ifdef HAVE_USERSEC_H + pu = getuserpw(name); + printf("%s %s %s %d %d\n", + pw->pw_name, + pw_status(pw->pw_passwd), + date_to_str(pu ? pu->upw_lastupdate : 0L), + minage > 0 ? minage * 7 : 0, + maxage > 0 ? maxage * 7 : 10000); +#else /* !HAVE_USERSEC_H */ +#ifdef ATT_AGE + printf("%s %s %s %d %d\n", + pw->pw_name, + pw_status(pw->pw_passwd), + date_to_str(strlen(pw->pw_age) > 2 ? + a64l(pw->pw_age + 2) * WEEK : 0L), + pw->pw_age[0] ? c64i(pw->pw_age[1]) * 7 : 0, + pw->pw_age[0] ? c64i(pw->pw_age[0]) * 7 : 10000); +#else + printf("%s %s\n", pw->pw_name, pw_status(pw->pw_passwd)); +#endif +#endif /* !HAVE_USERSEC_H */ + } +} + + +static void +fail_exit(int status) +{ + pw_unlock(); +#ifdef SHADOWPWD + spw_unlock(); +#endif +#ifdef HAVE_TCFS + tcfs_unlock(); +#endif + exit(status); +} + +static void +oom(void) +{ + fprintf(stderr, _("%s: out of memory\n"), Prog); + fail_exit(E_FAILURE); +} + +static char * +update_crypt_pw(char *cp) +{ +#ifndef USE_PAM + if (do_update_pwd) + cp = insert_crypt_passwd(cp, crypt_passwd); +#endif + + if (dflg) + cp = ""; /* XXX warning: const */ + + if (uflg && *cp == '!') + cp++; + + if (lflg && *cp != '!') { + char *newpw = xmalloc(strlen(cp) + 2); + + strcpy(newpw, "!"); + strcat(newpw, cp); + cp = newpw; + } + return cp; +} + + +static void +update_noshadow(void) +{ + const struct passwd *pw; + struct passwd *npw; +#ifdef ATT_AGE + char age[5]; + long week = time((time_t *) 0) / WEEK; + char *cp; +#endif + + if (!pw_lock()) { + fprintf(stderr, + _("Cannot lock the password file; try again later.\n")); + SYSLOG((LOG_WARN, PWDBUSY2)); + exit(E_PWDBUSY); + } + if (!pw_open(O_RDWR)) { + fprintf(stderr, _("Cannot open the password file.\n")); + SYSLOG((LOG_ERR, OPNERROR2)); + fail_exit(E_MISSING); + } + pw = pw_locate(name); + if (!pw) { + fprintf(stderr, _("%s: %s not found in /etc/passwd\n"), + Prog, name); + fail_exit(E_NOPERM); + } + npw = __pw_dup(pw); + if (!npw) + oom(); + npw->pw_passwd = update_crypt_pw(npw->pw_passwd); +#ifdef ATT_AGE + memzero(age, sizeof(age)); + STRFCPY(age, npw->pw_age); + + /* + * Just changing the password - update the last change date + * if there is one, otherwise the age just disappears. + */ + if (do_update_age) { + if (strlen(age) > 2) { + cp = l64a(week); + age[2] = cp[0]; + age[3] = cp[1]; + } else { + age[0] = '\0'; + } + } + + if (xflg) { + if (age_max > 0) + age[0] = i64c((age_max + 6) / 7); + else + age[0] = '.'; + + if (age[1] == '\0') + age[1] = '.'; + } + if (nflg) { + if (age[0] == '\0') + age[0] = 'z'; + + if (age_min > 0) + age[1] = i64c((age_min + 6) / 7); + else + age[1] = '.'; + } + /* + * The last change date is added by -n or -x if it's + * not already there. + */ + if ((nflg || xflg) && strlen(age) <= 2) { + cp = l64a(week); + age[2] = cp[0]; + age[3] = cp[1]; + } + + /* + * Force password change - if last change date is + * present, it will be set to (today - max - 1 week). + * Otherwise, just set min = max = 0 (will disappear + * when password is changed). + */ + if (eflg) { + if (strlen(age) > 2) { + cp = l64a(week - c64i(age[0]) - 1); + age[2] = cp[0]; + age[3] = cp[1]; + } else { + strcpy(age, ".."); + } + } + + npw->pw_age = age; +#endif + if (!pw_update(npw)) { + fprintf(stderr, _("Error updating the password entry.\n")); + SYSLOG((LOG_ERR, UPDERROR2)); + fail_exit(E_FAILURE); + } +#ifdef NDBM + if (pw_dbm_present() && !pw_dbm_update(npw)) { + fprintf(stderr, _("Error updating the DBM password entry.\n")); + SYSLOG((LOG_ERR, DBMERROR2)); + fail_exit(E_FAILURE); + } + endpwent(); +#endif + if (!pw_close()) { + fprintf(stderr, _("Cannot commit password file changes.\n")); + SYSLOG((LOG_ERR, CLSERROR2)); + fail_exit(E_FAILURE); + } + pw_unlock(); +} + +#ifdef HAVE_TCFS +static void +update_tcfs(void) +{ + if (!tcfs_force) { + if (!tcfs_lock()) { + fprintf(stderr, _("Cannot lock the TCFS key database; try again later\n")); + SYSLOG((LOG_WARN, TCFSPWDBUSY2)); + exit(E_PWDBUSY); + } + if (!tcfs_open(O_RDWR)) { + fprintf(stderr, + _("Cannot open the TCFS key database.\n")); + SYSLOG((LOG_WARN, TCFSOPNERROR2)); + fail_exit(E_MISSING); + } + if (!tcfs_update(name, tcfspword)) { + fprintf(stderr, + _("Error updating the TCFS key database.\n")); + SYSLOG((LOG_ERR, TCFSUPDERROR2)); + fail_exit(E_FAILURE); + } + if (!tcfs_close()) { + fprintf(stderr, _("Cannot commit TCFS changes.\n")); + SYSLOG((LOG_ERR, TCFSCLSERROR2)); + fail_exit(E_FAILURE); + } + tcfs_unlock(); + } +} +#endif /* HAVE_TCFS */ + +#ifdef SHADOWPWD +static void +update_shadow(void) +{ + const struct spwd *sp; + struct spwd *nsp; + + if (!spw_lock()) { + fprintf(stderr, + _("Cannot lock the password file; try again later.\n")); + SYSLOG((LOG_WARN, PWDBUSY2)); + exit(E_PWDBUSY); + } + if (!spw_open(O_RDWR)) { + fprintf(stderr, _("Cannot open the password file.\n")); + SYSLOG((LOG_ERR, OPNERROR2)); + fail_exit(E_FAILURE); + } + sp = spw_locate(name); + if (!sp) { + /* Try to update the password in /etc/passwd instead. */ + spw_close(); + update_noshadow(); + spw_unlock(); + return; + } + nsp = __spw_dup(sp); + if (!nsp) + oom(); + nsp->sp_pwdp = update_crypt_pw(nsp->sp_pwdp); + if (xflg) + nsp->sp_max = (age_max * DAY) / SCALE; + if (nflg) + nsp->sp_min = (age_min * DAY) / SCALE; + if (wflg) + nsp->sp_warn = (warn * DAY) / SCALE; + if (iflg) + nsp->sp_inact = (inact * DAY) / SCALE; + if (do_update_age) + nsp->sp_lstchg = time((time_t *) 0) / SCALE; + /* + * Force change on next login, like SunOS 4.x passwd -e or + * Solaris 2.x passwd -f. Solaris 2.x seems to do the same + * thing (set sp_lstchg to 0). + */ + if (eflg) + nsp->sp_lstchg = 0; + + if (!spw_update(nsp)) { + fprintf(stderr, _("Error updating the password entry.\n")); + SYSLOG((LOG_ERR, UPDERROR2)); + fail_exit(E_FAILURE); + } +#ifdef NDBM + if (sp_dbm_present() && !sp_dbm_update(nsp)) { + fprintf(stderr, _("Error updating the DBM password entry.\n")); + SYSLOG((LOG_ERR, DBMERROR2)); + fail_exit(E_FAILURE); + } + endspent(); +#endif + if (!spw_close()) { + fprintf(stderr, _("Cannot commit password file changes.\n")); + SYSLOG((LOG_ERR, CLSERROR2)); + fail_exit(E_FAILURE); + } + spw_unlock(); +} +#endif /* SHADOWPWD */ + +#ifdef HAVE_USERSEC_H +static void +update_userpw(char *cp) +{ + struct userpw userpw; + + /* + * AIX very conveniently has its own mechanism for updating + * passwords. Use it instead ... + */ + + strcpy(userpw.upw_name, name); + userpw.upw_passwd = update_crypt_pw(cp); + userpw.upw_lastupdate = time (0); + userpw.upw_flags = 0; + + setpwdb(S_WRITE); + + if (putuserpw(&userpw)) { + fprintf(stderr, _("Error updating the password entry.\n")); + SYSLOG((LOG_ERR, UPDERROR2)); + closelog(); + exit(E_FAILURE); + } + endpwdb(); +} +#endif + +static long +getnumber(const char *str) +{ + long val; + char *cp; + + val = strtol(str, &cp, 10); + if (*cp) + usage(E_BAD_ARG); + return val; +} + +/* + * passwd - change a user's password file information + * + * This command controls the password file and commands which are + * used to modify it. + * + * The valid options are + * + * -l lock the named account (*) + * -u unlock the named account (*) + * -d delete the password for the named account (*) + * -e expire the password for the named account (*) + * -x # set sp_max to # days (*) + * -n # set sp_min to # days (*) + * -w # set sp_warn to # days (*) + * -i # set sp_inact to # days (*) + * -S show password status of named account + * -g execute gpasswd command to interpret flags + * -f execute chfn command to interpret flags + * -s execute chsh command to interpret flags + * -k change password only if expired + * -t force 'passwd' to change the password regardless of TCFS + * + * (*) requires root permission to execute. + * + * All of the time fields are entered in days and converted to the + * appropriate internal format. For finer resolute the chage + * command must be used. + */ + +int +main(int argc, char **argv) +{ + int flag; /* Current option to process */ + const struct passwd *pw; /* Password file entry for user */ +#ifndef USE_PAM + char *cp; /* Miscellaneous character pointing */ +#ifdef SHADOWPWD + const struct spwd *sp; /* Shadow file entry for user */ +#endif +#endif + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* + * The program behaves differently when executed by root + * than when executed by a normal user. + */ + amroot = (getuid () == 0); + + /* + * Get the program name. The program name is used as a + * prefix to most error messages. + */ + Prog = Basename(argv[0]); + + sanitize_env(); + + OPENLOG("passwd"); + + /* + * Start with the flags which cause another command to be + * executed. The effective UID will be set back to the + * real UID and the new command executed with the flags + * + * These flags are deprecated, may change in a future + * release. Please run these programs directly. --marekm + */ + + if (argc > 1 && argv[1][0] == '-' && strchr ("gfs", argv[1][1])) { + char buf[200]; + + setuid(getuid()); + switch (argv[1][1]) { + case 'g': + argv[1] = GPASSWD_PROGRAM; /* XXX warning: const */ + break; + case 'f': + argv[1] = CHFN_PROGRAM; /* XXX warning: const */ + break; + case 's': + argv[1] = CHSH_PROGRAM; /* XXX warning: const */ + break; + default: + usage(E_BAD_ARG); + } + snprintf(buf, sizeof buf, _("%s: Cannot execute %s"), + Prog, argv[1]); + execvp(argv[1], &argv[1]); + perror(buf); + SYSLOG((LOG_ERR, EXECFAILED2, argv[1])); + closelog(); + exit(E_FAILURE); + } + + /* + * The remaining arguments will be processed one by one and + * executed by this command. The name is the last argument + * if it does not begin with a "-", otherwise the name is + * determined from the environment and must agree with the + * real UID. Also, the UID will be checked for any commands + * which are restricted to root only. + */ + +#ifdef SHADOWPWD +#define FLAGS "adlqr:uSekn:x:i:w:" +#ifdef HAVE_TCFS +#undef FLAGS +#define FLAGS "adlqr:uSekn:x:i:w:t" +#endif +#else +#ifdef AGING +#define FLAGS "adlqr:uSekn:x:" +#ifdef HAVE_TCFS +#undef FLAGS +#define FLAGS "adlqr:uSekn:x:t" +#endif +#else +#define FLAGS "adlqr:uS" +#ifdef HAVE_TCFS +#undef FLAGS +#define FLAGS "adlqr:uSt" +#endif +#endif +#endif + while ((flag = getopt(argc, argv, FLAGS)) != EOF) { +#undef FLAGS + switch (flag) { +#ifdef AGING + case 'x': + age_max = getnumber(optarg); + xflg++; + anyflag = 1; + break; + case 'n': + age_min = getnumber(optarg); + nflg++; + anyflag = 1; + break; +#ifdef HAVE_TCFS + case 't': + tcfs_force = 1; + break; +#endif +#ifdef SHADOWPWD + case 'w': + warn = getnumber(optarg); + if (warn >= -1) + wflg++; + anyflag = 1; + break; + case 'i': + inact = getnumber(optarg); + if (inact >= -1) + iflg++; + anyflag = 1; + break; +#endif /* SHADOWPWD */ + case 'e': + eflg++; + anyflag = 1; + break; + case 'k': + /* change only if expired, like Linux-PAM passwd -k. */ + kflg++; /* ok for users */ + break; +#endif /* AGING */ + case 'a': + aflg++; + break; + case 'q': + qflg++; /* ok for users */ + break; + case 'S': + Sflg++; /* ok for users */ + break; + case 'd': + dflg++; + anyflag = 1; + break; + case 'l': + lflg++; + anyflag = 1; + break; + case 'u': + uflg++; + anyflag = 1; + break; + case 'r': + /* -r repository (files|nis|nisplus) */ + /* only "files" supported for now */ + if (strcmp(optarg, "files") != 0) { + fprintf(stderr, + _("%s: repository %s not supported\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + break; + default: + usage(E_BAD_ARG); + } + } + +#ifdef HAVE_USERSEC_H + /* + * The aging information lives someplace else. Get it from the + * login.cfg file + */ + + if (getconfattr(SC_SYS_PASSWD, SC_MINAGE, &minage, SEC_INT)) + minage = -1; + + if (getconfattr(SC_SYS_PASSWD, SC_MAXAGE, &maxage, SEC_INT)) + maxage = -1; +#endif /* HAVE_USERSEC_H */ + + /* + * Now I have to get the user name. The name will be gotten + * from the command line if possible. Otherwise it is figured + * out from the environment. + */ + + pw = get_my_pwent(); + if (!pw) { + fprintf(stderr, _("%s: Cannot determine your user name.\n"), + Prog); + exit(E_NOPERM); + } + myname = xstrdup(pw->pw_name); + if (optind < argc) + name = argv[optind]; + else + name = myname; + + /* + * The -a flag requires -S, no other flags, no username, and + * you must be root. --marekm + */ + + if (aflg) { + if (anyflag || !Sflg || (optind < argc)) + usage(E_USAGE); + if (!amroot) { + fprintf(stderr, _("%s: Permission denied.\n"), Prog); + exit(E_NOPERM); + } + setpwent(); + while ((pw = getpwent())) + print_status(pw); + exit(E_SUCCESS); + } + +#if 0 + /* + * Allow certain users (administrators) to change passwords of + * certain users. Not implemented yet... --marekm + */ + if (may_change_passwd(myname, name)) + amroot = 1; +#endif + + /* + * If any of the flags were given, a user name must be supplied + * on the command line. Only an unadorned command line doesn't + * require the user's name be given. Also, -x, -n, -w, -i, -e, -d, + * -l, -u may appear with each other. -S, -k must appear alone. + */ + + /* + * -S now ok for normal users (check status of my own account), + * and doesn't require username. --marekm + */ + + if (anyflag && optind >= argc) + usage(E_USAGE); + + if (anyflag + Sflg + kflg > 1) + usage(E_USAGE); + + if (anyflag && !amroot) { + fprintf(stderr, _("%s: Permission denied\n"), Prog); + exit(E_NOPERM); + } + +#ifdef NDBM + endpwent(); + pw_dbm_mode = O_RDWR; +#ifdef SHADOWPWD + sp_dbm_mode = O_RDWR; +#endif +#endif + + pw = getpwnam(name); + if (!pw) { + fprintf(stderr, _("%s: Unknown user %s\n"), Prog, name); + exit(E_NOPERM); + } + + /* + * Now I have a name, let's see if the UID for the name + * matches the current real UID. + */ + + if (!amroot && pw->pw_uid != getuid ()) { + fprintf(stderr, _("You may not change the password for %s.\n"), + name); + SYSLOG((LOG_WARN, NOPERM2, name)); + closelog(); + exit(E_NOPERM); + } + + if (Sflg) { + print_status(pw); + exit(E_SUCCESS); + } + +#ifndef USE_PAM +#ifdef SHADOWPWD + /* + * The user name is valid, so let's get the shadow file + * entry. + */ + + sp = getspnam(name); + if (!sp) + sp = pwd_to_spwd(pw); + + cp = sp->sp_pwdp; +#else + cp = pw->pw_passwd; +#endif + + /* + * If there are no other flags, just change the password. + */ + + if (!anyflag) { +#ifdef AUTH_METHODS + if (strchr(cp, '@')) { + if (pw_auth(cp, name, PW_CHANGE, (char *)0)) { + SYSLOG((LOG_INFO, NOCHGPASSWD, name)); + closelog(); + exit(E_NOPERM); + } else if (! uses_default_method(cp)) { + do_update_age = 1; + goto done; + } + } else +#endif + STRFCPY(crypt_passwd, cp); + + /* + * See if the user is permitted to change the password. + * Otherwise, go ahead and set a new password. + */ + +#ifdef SHADOWPWD + check_password(pw, sp); +#else + check_password(pw); +#endif + +#ifdef HAVE_TCFS + tcfspword = (struct tcfspwd *)calloc(1, sizeof (struct tcfspwd)); +#endif + /* + * Let the user know whose password is being changed. + */ + if (!qflg) + printf(_("Changing password for %s\n"), name); + + if (new_password(pw)) { + fprintf(stderr, + _("The password for %s is unchanged.\n"), + name); + closelog(); + exit(E_NOPERM); + } + do_update_pwd = 1; + do_update_age = 1; + } + +#ifdef AUTH_METHODS +done: +#endif +#endif /* !USE_PAM */ + /* + * Before going any further, raise the ulimit to prevent + * colliding into a lowered ulimit, and set the real UID + * to root to protect against unexpected signals. Any + * keyboard signals are set to be ignored. + */ + + pwd_init(); + + /* + * Don't set the real UID for PAM... + */ +#ifdef USE_PAM + if (!anyflag) { + do_pam_passwd(name, qflg, kflg); + exit(E_SUCCESS); + } +#endif /* USE_PAM */ + if (setuid(0)) { + fprintf(stderr, _("Cannot change ID to root.\n")); + SYSLOG((LOG_ERR, NOTROOT2)); + closelog(); + exit(E_NOPERM); + } +#ifdef HAVE_USERSEC_H + update_userpw(pw->pw_passwd); +#else /* !HAVE_USERSEC_H */ + +#ifdef SHADOWPWD + if (spw_file_present()) + update_shadow(); + else +#endif + update_noshadow(); + +#ifdef HAVE_TCFS + if (tcfs_locate(name) && tcfs_file_present()) + update_tcfs(); +#endif +#endif /* !HAVE_USERSEC_H */ + SYSLOG((LOG_INFO, CHGPASSWD, name, myname)); + closelog(); + if (!qflg) + printf(_("Password changed.\n")); + exit(E_SUCCESS); + /*NOTREACHED*/ +} diff --git a/current/src/patchlevel.h b/current/src/patchlevel.h new file mode 100644 index 00000000..3fb8dce4 --- /dev/null +++ b/current/src/patchlevel.h @@ -0,0 +1,58 @@ +/* + * Copyright 1991 - 1995, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + * + * Revision History + * 11/25/91 3.1.1 patchlevel 14 + * Added "login.defs" to Makefile + * 12/02/91 3.1.2 patchlevel 15 + * Bugs found by users + * 12/28/91 3.1.3 patchlevel 16 + * Changes for SunOS 4.1.1 + * 02/08/92 3.1.4 patchlevel 17 + * Changes for SVR4, plus bug fixes + * 04/03/92 3.2.1 patchlevel 18 + * Minor bug fixes, new baseline + * 07/07/92 3.2.2 patchlevel 20 + * Added administrator defined authentication + * 11/04/92 3.2.3 patchlevel 21 + * Bug fixes for SVR4 + * 07/23/93 3.3.0 patchlevel 23 + * New baseline release + * 08/23/93 3.3.1 patchlevel 24 + * Bug fixes for SunOS 4.1.1 + * 08/27/93 3.3.2 patchlevel 25 + * Initial NIS support changes + * 12/03/95 3.3.3 patchlevel 26 + * This is the Linux beta baseline. Marek will + * change the name some other day. -- jfh + * $Id: patchlevel.h,v 1.2 1997/05/01 23:07:16 marekm Exp $ + */ + +#define RELEASE 3 +#define PATCHLEVEL 26 +#define VERSION "3.3.3" diff --git a/current/src/pwck.c b/current/src/pwck.c new file mode 100644 index 00000000..00551794 --- /dev/null +++ b/current/src/pwck.c @@ -0,0 +1,616 @@ +/* + * Copyright 1992 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: pwck.c,v 1.15 2000/09/02 18:40:44 marekm Exp $") + +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" +#include "chkname.h" +#include + +#include "commonio.h" + +#include "pwio.h" +extern void __pw_del_entry(const struct commonio_entry *); +extern struct commonio_entry *__pw_get_head(void); + +#ifdef SHADOWPWD +#include "shadowio.h" +extern void __spw_del_entry(const struct commonio_entry *); +extern struct commonio_entry *__spw_get_head(void); +#endif + +/* + * Exit codes + */ + +#define E_OKAY 0 +#define E_USAGE 1 +#define E_BADENTRY 2 +#define E_CANTOPEN 3 +#define E_CANTLOCK 4 +#define E_CANTUPDATE 5 + +/* + * Global variables + */ + +extern int optind; +extern char *optarg; + +/* + * Local variables + */ + +static char *Prog; +static const char *pwd_file = PASSWD_FILE; +#ifdef SHADOWPWD +static const char *spw_file = SHADOW_FILE; +#endif +static int read_only = 0; +static int quiet = 0; /* don't report warnings, only errors */ + +/* local function prototypes */ +static void usage(void); +static int yes_or_no(void); + +/* + * usage - print syntax message and exit + */ + +static void +usage(void) +{ +#ifdef SHADOWPWD + fprintf(stderr, _("Usage: %s [ -qr ] [ passwd [ shadow ] ]\n"), Prog); +#else + fprintf(stderr, _("Usage: %s [ -qr ] [ passwd ]\n"), Prog); +#endif + exit(E_USAGE); +} + +/* + * yes_or_no - get answer to question from the user + */ + +static int +yes_or_no(void) +{ + char buf[80]; + + /* + * In read-only mode all questions are answered "no". + */ + + if (read_only) { + puts(_("No")); + return 0; + } + + /* + * Get a line and see what the first character is. + */ + + if (fgets(buf, sizeof buf, stdin)) + return buf[0] == 'y' || buf[0] == 'Y'; + + return 0; +} + +/* + * pwck - verify password file integrity + */ + +int +main(int argc, char **argv) +{ + int arg; + int errors = 0; + int deleted = 0; + struct commonio_entry *pfe, *tpfe; + struct passwd *pwd; +#ifdef SHADOWPWD + struct commonio_entry *spe, *tspe; + struct spwd *spw; + int is_shadow = 0; +#endif + + /* + * Get my name so that I can use it to report errors. + */ + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + + /* + * Parse the command line arguments + */ + + while ((arg = getopt(argc, argv, "eqr")) != EOF) { + switch (arg) { + case 'e': /* added for Debian shadow-961025-2 compatibility */ + case 'q': + quiet = 1; + break; + case 'r': + read_only = 1; + break; + default: + usage(); + } + } + + /* + * Make certain we have the right number of arguments + */ + +#ifdef SHADOWPWD + if (optind != argc && optind + 1 != argc && optind + 2 != argc) +#else + if (optind != argc && optind + 1 != argc) +#endif + usage(); + + /* + * If there are two left over filenames, use those as the + * password and shadow password filenames. + */ + + if (optind != argc) { + pwd_file = argv[optind]; + pw_name(pwd_file); + } +#ifdef SHADOWPWD + if (optind + 2 == argc) { + spw_file = argv[optind + 1]; + spw_name(spw_file); + is_shadow = 1; + } else if (optind == argc) + is_shadow = spw_file_present(); +#endif + + /* + * Lock the files if we aren't in "read-only" mode + */ + + if (!read_only) { + if (!pw_lock()) { + fprintf(stderr, _("%s: cannot lock file %s\n"), + Prog, pwd_file); + if (optind == argc) + SYSLOG((LOG_WARN,"cannot lock %s\n",pwd_file)); + closelog(); + exit(E_CANTLOCK); + } +#ifdef SHADOWPWD + if (is_shadow && !spw_lock()) { + fprintf(stderr, _("%s: cannot lock file %s\n"), + Prog, spw_file); + if (optind == argc) + SYSLOG((LOG_WARN,"cannot lock %s\n",spw_file)); + closelog(); + exit(E_CANTLOCK); + } +#endif + } + + /* + * Open the files. Use O_RDONLY if we are in read_only mode, + * O_RDWR otherwise. + */ + + if (!pw_open(read_only ? O_RDONLY:O_RDWR)) { + fprintf(stderr, _("%s: cannot open file %s\n"), + Prog, pwd_file); + if (optind == argc) + SYSLOG((LOG_WARN, "cannot open %s\n", pwd_file)); + closelog(); + exit(E_CANTOPEN); + } +#ifdef SHADOWPWD + if (is_shadow && !spw_open(read_only ? O_RDONLY : O_RDWR)) { + fprintf(stderr, _("%s: cannot open file %s\n"), + Prog, spw_file); + if (optind == argc) + SYSLOG((LOG_WARN, "cannot open %s\n", spw_file)); + closelog(); + exit(E_CANTOPEN); + } +#endif + + /* + * Loop through the entire password file. + */ + + for (pfe = __pw_get_head(); pfe; pfe = pfe->next) { + /* + * If this is a NIS line, skip it. You can't "know" what + * NIS is going to do without directly asking NIS ... + */ + + if (pfe->line[0] == '+' || pfe->line[0] == '-') + continue; + + /* + * Start with the entries that are completely corrupt. + * They have no (struct passwd) entry because they couldn't + * be parsed properly. + */ + + if (!pfe->eptr) { + + /* + * Tell the user this entire line is bogus and + * ask them to delete it. + */ + + printf(_("invalid password file entry\n")); + printf(_("delete line `%s'? "), pfe->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (!yes_or_no()) + continue; + + /* + * All password file deletions wind up here. This + * code removes the current entry from the linked + * list. When done, it skips back to the top of + * the loop to try out the next list element. + */ + +delete_pw: + SYSLOG((LOG_INFO, "delete passwd line `%s'\n", + pfe->line)); + deleted++; + + __pw_del_entry(pfe); + continue; + } + + /* + * Password structure is good, start using it. + */ + + pwd = pfe->eptr; + + /* + * Make sure this entry has a unique name. + */ + + for (tpfe = __pw_get_head(); tpfe; tpfe = tpfe->next) { + const struct passwd *ent = tpfe->eptr; + + /* + * Don't check this entry + */ + + if (tpfe == pfe) + continue; + + /* + * Don't check invalid entries. + */ + + if (!ent) + continue; + + if (strcmp(pwd->pw_name, ent->pw_name) != 0) + continue; + + /* + * Tell the user this entry is a duplicate of + * another and ask them to delete it. + */ + + puts(_("duplicate password entry\n")); + printf(_("delete line `%s'? "), pfe->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (yes_or_no()) + goto delete_pw; + } + + /* + * Check for invalid usernames. --marekm + */ + if (!check_user_name(pwd->pw_name)) { + printf(_("invalid user name `%s'\n"), pwd->pw_name); + errors++; + } + + /* + * Check for a Slackware bug. Make sure UID is not -1 + * (it has special meaning for some syscalls). --marekm + */ + + if (pwd->pw_uid == (uid_t) -1) { + printf(_("user %s: bad UID (%d)\n"), + pwd->pw_name, (int) pwd->pw_uid); + errors++; + } + + /* + * Make sure the primary group exists + */ + + if (!quiet && !getgrgid(pwd->pw_gid)) { + + /* + * No primary group, just give a warning + */ + + printf(_("user %s: no group %d\n"), + pwd->pw_name, (int) pwd->pw_gid); + errors++; + } + + /* + * Make sure the home directory exists + */ + + if (!quiet && access(pwd->pw_dir, F_OK)) { + + /* + * Home directory doesn't exist, give a warning + */ + + printf(_("user %s: directory %s does not exist\n"), + pwd->pw_name, pwd->pw_dir); + errors++; + } + + /* + * Make sure the login shell is executable + */ + + if (!quiet && pwd->pw_shell[0] && access(pwd->pw_shell, F_OK)) { + + /* + * Login shell doesn't exist, give a warning + */ + + printf(_("user %s: program %s does not exist\n"), + pwd->pw_name, pwd->pw_shell); + errors++; + } + } + +#ifdef SHADOWPWD + if (!is_shadow) + goto shadow_done; + + /* + * Loop through the entire shadow password file. + */ + + for (spe = __spw_get_head(); spe; spe = spe->next) { + /* + * If this is a NIS line, skip it. You can't "know" what + * NIS is going to do without directly asking NIS ... + */ + + if (spe->line[0] == '+' || spe->line[0] == '-') + continue; + + /* + * Start with the entries that are completely corrupt. + * They have no (struct spwd) entry because they couldn't + * be parsed properly. + */ + + if (!spe->eptr) { + + /* + * Tell the user this entire line is bogus and + * ask them to delete it. + */ + + printf(_("invalid shadow password file entry\n")); + printf(_("delete line `%s'? "), spe->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (!yes_or_no()) + continue; + + /* + * All shadow file deletions wind up here. This + * code removes the current entry from the linked + * list. When done, it skips back to the top of + * the loop to try out the next list element. + */ + +delete_spw: + SYSLOG((LOG_INFO, "delete shadow line `%s'\n", + spe->line)); + deleted++; + + __spw_del_entry(spe); + continue; + } + + /* + * Shadow password structure is good, start using it. + */ + + spw = spe->eptr; + + /* + * Make sure this entry has a unique name. + */ + + for (tspe = __spw_get_head(); tspe; tspe = tspe->next) { + const struct spwd *ent = tspe->eptr; + + /* + * Don't check this entry + */ + + if (tspe == spe) + continue; + + /* + * Don't check invalid entries. + */ + + if (!ent) + continue; + + if (strcmp(spw->sp_namp, ent->sp_namp) != 0) + continue; + + /* + * Tell the user this entry is a duplicate of + * another and ask them to delete it. + */ + + puts(_("duplicate shadow password entry\n")); + printf(_("delete line `%s'? "), spe->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (yes_or_no()) + goto delete_spw; + } + + /* + * Make sure this entry exists in the /etc/passwd + * file. + */ + + if (!pw_locate(spw->sp_namp)) { + + /* + * Tell the user this entry has no matching + * /etc/passwd entry and ask them to delete it. + */ + + puts(_("no matching password file entry\n")); + printf(_("delete line `%s'? "), spe->line); + errors++; + + /* + * prompt the user to delete the entry or not + */ + + if (yes_or_no()) + goto delete_spw; + } + + /* + * Warn if last password change in the future. --marekm + */ + + if (!quiet && spw->sp_lstchg > time((time_t *)0) / SCALE) { + printf(_("user %s: last password change in the future\n"), spw->sp_namp); + errors++; + } + } + +shadow_done: +#endif + + /* + * All done. If there were no deletions we can just abandon any + * changes to the files. + */ + + if (deleted) { + if (!pw_close()) { + fprintf(stderr, _("%s: cannot update file %s\n"), + Prog, pwd_file); + SYSLOG((LOG_WARN, "cannot update %s\n", pwd_file)); + closelog(); + exit(E_CANTUPDATE); + } +#ifdef SHADOWPWD + if (is_shadow && !spw_close()) { + fprintf(stderr, _("%s: cannot update file %s\n"), + Prog, spw_file); + SYSLOG((LOG_WARN, "cannot update %s\n", spw_file)); + closelog(); + exit(E_CANTUPDATE); + } +#endif + } + + /* + * Don't be anti-social - unlock the files when you're done. + */ + +#ifdef SHADOWPWD + if (is_shadow) + spw_unlock(); +#endif + (void) pw_unlock(); + + /* + * Tell the user what we did and exit. + */ + + if (errors) +#ifdef NDBM + printf(deleted ? + _("%s: the files have been updated; run mkpasswd\n") : + _("%s: no changes\n"), Prog); +#else + printf(deleted ? + _("%s: the files have been updated\n") : + _("%s: no changes\n"), Prog); +#endif + + closelog(); + exit(errors ? E_BADENTRY : E_OKAY); +} diff --git a/current/src/pwconv.c b/current/src/pwconv.c new file mode 100644 index 00000000..3a32370b --- /dev/null +++ b/current/src/pwconv.c @@ -0,0 +1,187 @@ +/* + * pwconv - create or update /etc/shadow with information from + * /etc/passwd. + * + * It is more like SysV pwconv, slightly different from the + * original Shadow pwconv. Depends on "x" as password in + * /etc/passwd which means that the password has already been + * moved to /etc/shadow. There is no need to move /etc/npasswd + * to /etc/passwd, password files are updated using library + * routines with proper locking. + * + * Can be used to update /etc/shadow after adding/deleting users + * by editing /etc/passwd. There is no man page yet, but this + * program should be close to pwconv(1M) on Solaris 2.x. + * + * Warning: make sure that all users have "x" as the password in + * /etc/passwd before running this program for the first time on + * a system which already has shadow passwords. Anything else + * (like "*" from old versions of the shadow suite) will replace + * the user's encrypted password in /etc/shadow. + * + * Doesn't currently support pw_age information in /etc/passwd, + * and doesn't support DBM files. Add it if you need it... + * + * Copyright (C) 1996-1997, Marek Michalkiewicz + * + * This program may be freely used and distributed for any purposes. + * If you improve it, please send me your changes. Thanks! + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: pwconv.c,v 1.11 2000/08/26 18:27:18 marekm Exp $") + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "prototypes.h" +#include "defines.h" +#include "pwio.h" +#include "shadowio.h" +#include "getdef.h" + +/* + * exit status values + */ + +#define E_SUCCESS 0 /* success */ +#define E_NOPERM 1 /* permission denied */ +#define E_USAGE 2 /* bad command syntax */ +#define E_FAILURE 3 /* unexpected failure, nothing done */ +#define E_MISSING 4 /* unexpected failure, passwd file missing */ +#define E_PWDBUSY 5 /* passwd file(s) busy */ +#define E_BADENTRY 6 /* bad shadow entry */ + +static int + shadow_locked = 0, + passwd_locked = 0; + +/* local function prototypes */ +static void fail_exit(int); + +static void +fail_exit(int status) +{ + if (shadow_locked) + spw_unlock(); + if (passwd_locked) + pw_unlock(); + exit(status); +} + +int +main(int argc, char **argv) +{ + const struct passwd *pw; + struct passwd pwent; + const struct spwd *sp; + struct spwd spent; + char *Prog = argv[0]; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (!pw_lock()) { + fprintf(stderr, _("%s: can't lock passwd file\n"), Prog); + fail_exit(E_PWDBUSY); + } + passwd_locked++; + if (!pw_open(O_RDWR)) { + fprintf(stderr, _("%s: can't open passwd file\n"), Prog); + fail_exit(E_MISSING); + } + + if (!spw_lock()) { + fprintf(stderr, _("%s: can't lock shadow file\n"), Prog); + fail_exit(E_PWDBUSY); + } + shadow_locked++; + if (!spw_open(O_CREAT | O_RDWR)) { + fprintf(stderr, _("%s: can't open shadow file\n"), Prog); + fail_exit(E_FAILURE); + } + + /* + * Remove /etc/shadow entries for users not in /etc/passwd. + */ + spw_rewind(); + while ((sp = spw_next())) { + if (pw_locate(sp->sp_namp)) + continue; + + if (!spw_remove(sp->sp_namp)) { + /* + * This shouldn't happen (the entry exists) but... + */ + fprintf(stderr, + _("%s: can't remove shadow entry for %s\n"), + Prog, sp->sp_namp); + fail_exit(E_FAILURE); + } + } + + /* + * Update shadow entries which don't have "x" as pw_passwd. + * Add any missing shadow entries. + */ + pw_rewind(); + while ((pw = pw_next())) { + sp = spw_locate(pw->pw_name); + if (sp) { + /* do we need to update this entry? */ + if (strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) + continue; + /* update existing shadow entry */ + spent = *sp; + } else { + /* add new shadow entry */ + memset(&spent, 0, sizeof spent); + spent.sp_namp = pw->pw_name; + spent.sp_min = getdef_num("PASS_MIN_DAYS", -1); + spent.sp_max = getdef_num("PASS_MAX_DAYS", -1); + spent.sp_warn = getdef_num("PASS_WARN_AGE", -1); + spent.sp_inact = -1; + spent.sp_expire = -1; + spent.sp_flag = -1; + } + spent.sp_pwdp = pw->pw_passwd; + spent.sp_lstchg = time((time_t *) 0) / (24L*3600L); + if (!spw_update(&spent)) { + fprintf(stderr, + _("%s: can't update shadow entry for %s\n"), + Prog, spent.sp_namp); + fail_exit(E_FAILURE); + } + /* remove password from /etc/passwd */ + pwent = *pw; + pwent.pw_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */ + if (!pw_update(&pwent)) { + fprintf(stderr, + _("%s: can't update passwd entry for %s\n"), + Prog, pwent.pw_name); + fail_exit(E_FAILURE); + } + } + + if (!spw_close()) { + fprintf(stderr, _("%s: can't update shadow file\n"), Prog); + fail_exit(E_FAILURE); + } + if (!pw_close()) { + fprintf(stderr, _("%s: can't update passwd file\n"), Prog); + fail_exit(E_FAILURE); + } + chmod(PASSWD_FILE "-", 0600); /* /etc/passwd- (backup file) */ + spw_unlock(); + pw_unlock(); + exit(E_SUCCESS); +} diff --git a/current/src/pwunconv.c b/current/src/pwunconv.c new file mode 100644 index 00000000..9335a489 --- /dev/null +++ b/current/src/pwunconv.c @@ -0,0 +1,196 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + * + * pwunconv - restore old password file from shadow password file. + * + * Pwunconv copies the password file information from the shadow + * password file, merging entries from an optional existing shadow + * file. + * + * Modifed by Guy Maor to acquire necessary locks + * and modify the files in place. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: pwunconv.c,v 1.9 2000/08/26 18:27:18 marekm Exp $") + +#include "defines.h" +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "pwio.h" +#include "shadowio.h" + +#ifndef SHADOWPWD +int +main(int argc, char **argv) +{ + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + fprintf(stderr, _("%s: Shadow passwords are not configured.\n"), + argv[0]); + exit(1); +} + +#else /*{*/ + +char *l64a (); + +static int shadow_locked = 0, + passwd_locked = 0; + +/* local function prototypes */ +static void fail_exit(int); + +static void +fail_exit(int status) +{ + if (shadow_locked) + spw_unlock(); + if (passwd_locked) + pw_unlock(); + exit(status); +} + + +int +main(int argc, char **argv) +{ + const struct passwd *pw; + struct passwd pwent; + const struct spwd *spwd; +#ifdef ATT_AGE + char newage[5]; +#endif + char *Prog = argv[0]; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + if (!spw_file_present()) + /* shadow not installed, do nothing */ + exit(0); + + if (!pw_lock()) { + fprintf(stderr, _("%s: can't lock passwd file\n"), Prog); + fail_exit(5); + } + passwd_locked++; + if (!pw_open(O_RDWR)) { + fprintf(stderr, _("%s: can't open passwd file\n"), Prog); + fail_exit(1); + } + + if (!spw_lock()) { + fprintf(stderr, _("%s: can't open shadow file\n"), Prog); + fail_exit(5); + } + shadow_locked++; + if (!spw_open(O_RDWR)) { + fprintf(stderr, _("%s: can't open shadow file\n"), Prog); + fail_exit(1); + } + + pw_rewind(); + while ((pw = pw_next())) { + if (!(spwd = spw_locate(pw->pw_name))) + continue; + + pwent = *pw; + + /* + * Update password if non-shadow is "x". + */ + if (strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) + pwent.pw_passwd = spwd->sp_pwdp; + + /* + * Password aging works differently in the two different systems. + * With shadow password files you apparently must have some aging + * information. The maxweeks or minweeks may not map exactly. + * In pwconv we set max == 10000, which is about 30 years. Here + * we have to undo that kludge. So, if maxdays == 10000, no aging + * information is put into the new file. Otherwise, the days are + * converted to weeks and so on. + */ + +#ifdef ATT_AGE + if (spwd->sp_max > (63*WEEK/SCALE) && spwd->sp_max < 10000) + spwd->sp_max = (63*WEEK/SCALE); /* 10000 is infinity */ + + if (spwd->sp_min >= 0 && spwd->sp_min <= 63*7 && + spwd->sp_max >= 0 && spwd->sp_max <= 63*7) { + if (spwd->sp_lstchg == -1) + spwd->sp_lstchg = 0; + + spwd->sp_max /= WEEK/SCALE; /* turn it into weeks */ + spwd->sp_min /= WEEK/SCALE; + spwd->sp_lstchg /= WEEK/SCALE; + + strncpy (newage, l64a (spwd->sp_lstchg * (64L*64L) + + spwd->sp_min * (64L) + spwd->sp_max), 5); + pwent.pw_age = newage; + } else + pwent.pw_age = ""; +#endif /* ATT_AGE */ + if (!pw_update(&pwent)) { + fprintf(stderr, + _("%s: can't update entry for user %s\n"), + Prog, pwent.pw_name); + fail_exit(3); + } + } + + if (!spw_close()) { + fprintf(stderr, _("%s: can't update shadow password file\n"), Prog); + fail_exit(3); + } + + if (!pw_close()) { + fprintf(stderr, _("%s: can't update password file\n"), Prog); + fail_exit(3); + } + + if (unlink(SHADOW) != 0) { + fprintf(stderr, _("%s: can't delete shadow password file\n"), Prog); + fail_exit(3); + } + + spw_unlock(); + pw_unlock(); + return 0; +} +#endif diff --git a/current/src/shadowconfig.sh b/current/src/shadowconfig.sh new file mode 100755 index 00000000..17b8aa9e --- /dev/null +++ b/current/src/shadowconfig.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# turn shadow passwords on or off on a Debian system + +set -e + +permfix () { + [ -f $1 ] || return 0 + chown root:shadow $1 + chmod 2755 $1 +} +export -f permfix + +shadowon () { +bash<<- EOF + set -e + + permfix /usr/X11R6/bin/xlock + permfix /usr/X11R6/bin/xtrlock + permfix /bin/vlock + + pwck -q + grpck + pwconv + grpconv + cd /etc + chown root:root passwd group + chmod 644 passwd group + chown root:shadow shadow gshadow + chmod 640 shadow gshadow +EOF +} + +shadowoff () { +bash<<- EOF + set -e + pwck -q + grpck + pwunconv + grpunconv + cd /etc + # sometimes the passwd perms get munged + chown root:root passwd group + chmod 644 passwd group +EOF +} + +case "$1" in + "on") + if shadowon ; then + echo Shadow passwords are now on. + else + echo Please correct the error and rerun \`$0 on\' + exit 1 + fi + ;; + "off") + if shadowoff ; then + echo Shadow passwords are now off. + else + echo Please correct the error and rerun \`$0 off\' + exit 1 + fi + ;; + *) + echo Usage: $0 on \| off + ;; +esac diff --git a/current/src/su.c b/current/src/su.c new file mode 100644 index 00000000..c8b88030 --- /dev/null +++ b/current/src/su.c @@ -0,0 +1,637 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: su.c,v 1.15 2000/09/02 18:40:44 marekm Exp $") + +#include +#include + +#ifdef USE_PAM +#include "pam_defs.h" + +static const struct pam_conv conv = { + misc_conv, + NULL +}; + +static pam_handle_t *pamh = NULL; +#endif + +#include "prototypes.h" +#include "defines.h" + +#include +#include +#include +#include "pwauth.h" +#include "getdef.h" + +/* + * Assorted #defines to control su's behavior + */ + +/* + * Global variables + */ + +/* not needed by sulog.c anymore */ +static char name[BUFSIZ]; +static char oldname[BUFSIZ]; + +static char *Prog; + +struct passwd pwent; + +/* + * External identifiers + */ + +extern char **newenvp; +extern size_t newenvc; + +extern char **environ; + +/* local function prototypes */ + +#ifndef USE_PAM + +static RETSIGTYPE die(int); +static int iswheel(const char *); + +/* + * die - set or reset termio modes. + * + * die() is called before processing begins. signal() is then + * called with die() as the signal handler. If signal later + * calls die() with a signal number, the terminal modes are + * then reset. + */ + +static RETSIGTYPE +die(int killed) +{ + static TERMIO sgtty; + + if (killed) + STTY(0, &sgtty); + else + GTTY(0, &sgtty); + + if (killed) { + closelog(); + exit(killed); + } +} + +static int +iswheel(const char *username) +{ + struct group *grp; + + grp = getgrgid(0); + if (!grp || !grp->gr_mem) + return 0; + return is_on_list(grp->gr_mem, username); +} +#endif /* !USE_PAM */ + + +static void +su_failure(const char *tty) +{ + sulog(tty, 0, oldname, name); /* log failed attempt */ +#ifdef USE_SYSLOG + if (getdef_bool("SYSLOG_SU_ENAB")) + SYSLOG((pwent.pw_uid ? LOG_INFO:LOG_NOTICE, + "- %s %s-%s\n", tty, + oldname[0] ? oldname:"???", + name[0] ? name:"???")); + closelog(); +#endif + puts(_("Sorry.")); + exit(1); +} + + +/* + * su - switch user id + * + * su changes the user's ids to the values for the specified user. + * if no new user name is specified, "root" is used by default. + * + * The only valid option is a "-" character, which is interpreted + * as requiring a new login session to be simulated. + * + * Any additional arguments are passed to the user's shell. In + * particular, the argument "-c" will cause the next argument to + * be interpreted as a command by the common shell programs. + */ + +int +main(int argc, char **argv) +{ + char *cp; + const char *tty = 0; /* Name of tty SU is run from */ + int doshell = 0; + int fakelogin = 0; + int amroot = 0; + uid_t my_uid; + struct passwd *pw = 0; + char **envp = environ; +#ifdef USE_PAM + int ret; +#else /* !USE_PAM */ + RETSIGTYPE (*oldsig)(); + int is_console = 0; +#ifdef SHADOWPWD + struct spwd *spwd = 0; +#endif +#ifdef SU_ACCESS + char *oldpass; +#endif +#endif /* !USE_PAM */ + + sanitize_env(); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + /* + * Get the program name. The program name is used as a + * prefix to most error messages. + */ + + Prog = Basename(argv[0]); + + OPENLOG("su"); + + initenv(); + + my_uid = getuid(); + amroot = (my_uid == 0); + + /* + * Get the tty name. Entries will be logged indicating that + * the user tried to change to the named new user from the + * current terminal. + */ + + if (isatty(0) && (cp = ttyname(0))) { + if (strncmp (cp, "/dev/", 5) == 0) + tty = cp + 5; + else + tty = cp; +#ifndef USE_PAM + is_console = console(tty); +#endif + } else { + /* + * Be more paranoid, like su from SimplePAMApps. --marekm + */ + if (!amroot) { + fprintf(stderr, _("%s: must be run from a terminal\n"), + Prog); + exit(1); + } + tty = "???"; + } + + /* + * Process the command line arguments. + */ + + argc--; argv++; /* shift out command name */ + + if (argc > 0 && strcmp(argv[0], "-") == 0) { + fakelogin = 1; + argc--; argv++; /* shift ... */ + } + + /* + * If a new login is being set up, the old environment will + * be ignored and a new one created later on. + */ + + if (fakelogin) { + if ((cp=getdef_str("ENV_TZ"))) + addenv(*cp == '/' ? tz(cp) : cp, NULL); + /* + * The clock frequency will be reset to the login value if required + */ + if ((cp=getdef_str("ENV_HZ"))) + addenv(cp, NULL); /* set the default $HZ, if one */ + /* + * The terminal type will be left alone if it is present in the + * environment already. + */ + if ((cp = getenv ("TERM"))) + addenv("TERM", cp); + } else { + while (*envp) + addenv(*envp++, NULL); + } + + /* + * The next argument must be either a user ID, or some flag to + * a subshell. Pretty sticky since you can't have an argument + * which doesn't start with a "-" unless you specify the new user + * name. Any remaining arguments will be passed to the user's + * login shell. + */ + + if (argc > 0 && argv[0][0] != '-') { + STRFCPY(name, argv[0]); /* use this login id */ + argc--; argv++; /* shift ... */ + } + if (! name[0]) /* use default user ID */ + (void) strcpy (name, "root"); + + doshell = argc == 0; /* any arguments remaining? */ + + /* + * Get the user's real name. The current UID is used to determine + * who has executed su. That user ID must exist. + */ + + pw = get_my_pwent(); + if (!pw) { + SYSLOG((LOG_CRIT, "Unknown UID: %d\n", (int) my_uid)); + su_failure(tty); + } + STRFCPY(oldname, pw->pw_name); + +#ifndef USE_PAM +#ifdef SU_ACCESS + /* + * Sort out the password of user calling su, in case needed later + * -- chris + */ +#ifdef SHADOWPWD + if ((spwd = getspnam(oldname))) + pw->pw_passwd = spwd->sp_pwdp; +#endif + oldpass = xstrdup(pw->pw_passwd); +#endif /* SU_ACCESS */ +#endif /* !USE_PAM */ + +#ifdef USE_PAM + ret = pam_start("su", name, &conv, &pamh); + if (ret != PAM_SUCCESS) { + SYSLOG((LOG_ERR, "pam_start: error %d\n", ret); + fprintf(stderr, _("%s: pam_start: error %d\n"), Prog, ret)); + exit(1); + } + + ret = pam_set_item(pamh, PAM_TTY, (const void *) tty); + if (ret == PAM_SUCCESS) + ret = pam_set_item(pamh, PAM_RUSER, (const void *) oldname); + if (ret != PAM_SUCCESS) { + SYSLOG((LOG_ERR, "pam_set_item: %s\n", PAM_STRERROR(pamh, ret))); + fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret)); + pam_end(pamh, ret); + exit(1); + } +#endif /* USE_PAM */ + +top: + /* + * This is the common point for validating a user whose name + * is known. It will be reached either by normal processing, + * or if the user is to be logged into a subsystem root. + * + * The password file entries for the user is gotten and the + * account validated. + */ + + if (!(pw = getpwnam(name))) { + (void) fprintf (stderr, _("Unknown id: %s\n"), name); + closelog(); + exit(1); + } + +#ifndef USE_PAM +#ifdef SHADOWPWD + spwd = NULL; + if (strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING) == 0 && (spwd = getspnam(name))) + pw->pw_passwd = spwd->sp_pwdp; +#endif +#endif /* !USE_PAM */ + pwent = *pw; + +#ifndef USE_PAM + /* + * BSD systems only allow "wheel" to SU to root. USG systems + * don't, so we make this a configurable option. + */ + + /* The original Shadow 3.3.2 did this differently. Do it like BSD: + + - check for uid 0 instead of name "root" - there are systems + with several root accounts under different names, + + - check the contents of /etc/group instead of the current group + set (you must be listed as a member, GID 0 is not sufficient). + + In addition to this traditional feature, we now have complete + su access control (allow, deny, no password, own password). + Thanks to Chris Evans . */ + + if (!amroot) { + if (pwent.pw_uid == 0 && getdef_bool("SU_WHEEL_ONLY") + && !iswheel(oldname)) { + fprintf(stderr, _("You are not authorized to su %s\n"), name); + exit(1); + } +#ifdef SU_ACCESS + switch (check_su_auth(oldname, name)) { + case 0: /* normal su, require target user's password */ + break; + case 1: /* require no password */ + pwent.pw_passwd = ""; /* XXX warning: const */ + break; + case 2: /* require own password */ + puts(_("(Enter your own password.)")); + pwent.pw_passwd = oldpass; + break; + default: /* access denied (-1) or unexpected value */ + fprintf(stderr, _("You are not authorized to su %s\n"), name); + exit(1); + } +#endif /* SU_ACCESS */ + } +#endif /* !USE_PAM */ + + /* + * Set the default shell. + */ +#if 0 + /* + * XXX - GNU and *BSD versions of su support the -m option. + * Need to add some option parsing code. + */ + if (mflg) { + if (!amroot && !check_shell(pwent.pw_shell)) { + fprintf(stderr, _("%s: permission denied (shell).\n"), Prog); + exit(1); + } + if ((cp = getenv("SHELL"))) + pwent.pw_shell = cp; + } +#endif + + if (pwent.pw_shell[0] == '\0') + pwent.pw_shell = "/bin/sh"; /* XXX warning: const */ + +#ifdef USE_PAM + ret = pam_authenticate(pamh, 0); + if (ret != PAM_SUCCESS) { + SYSLOG((LOG_ERR, "pam_authenticate: %s\n", + PAM_STRERROR(pamh, ret))); + fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret)); + pam_end(pamh, ret); + su_failure(tty); + } + + ret = pam_acct_mgmt(pamh, 0); + if (ret != PAM_SUCCESS) { + if (amroot) { + fprintf(stderr, _("%s: %s\n(Ignored)\n"), Prog, PAM_STRERROR(pamh, ret)); + } else { + SYSLOG((LOG_ERR, "pam_acct_mgmt: %s\n", + PAM_STRERROR(pamh, ret))); + fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret)); + pam_end(pamh, ret); + su_failure(tty); + } + } +#else /* !USE_PAM */ + /* + * Set up a signal handler in case the user types QUIT. + */ + + die (0); + oldsig = signal (SIGQUIT, die); + + /* + * See if the system defined authentication method is being used. + * The first character of an administrator defined method is an + * '@' character. + */ + + if (! amroot && pw_auth (pwent.pw_passwd, name, PW_SU, (char *) 0)) { + SYSLOG((pwent.pw_uid ? LOG_NOTICE:LOG_WARN, + "Authentication failed for %s\n", name)); + su_failure(tty); + } + signal (SIGQUIT, oldsig); + + /* + * Check to see if the account is expired. root gets to + * ignore any expired accounts, but normal users can't become + * a user with an expired password. + */ + + if (! amroot) { +#ifdef SHADOWPWD + if (!spwd) + spwd = pwd_to_spwd(&pwent); + + if (isexpired(&pwent, spwd)) { + SYSLOG((pwent.pw_uid ? LOG_WARN : LOG_CRIT, + "Expired account %s\n", name)); + su_failure(tty); + } +#else +#if defined(ATT_AGE) && defined(AGING) + else if (pwent.pw_age[0] && + isexpired (&pwent)) { + SYSLOG((pwent.pw_uid ? LOG_WARN:LOG_CRIT, + "Expired account %s\n", name)); + su_failure(tty); + } +#endif /* ATT_AGE */ +#endif + } + + /* + * Check to see if the account permits "su". root gets to + * ignore any restricted accounts, but normal users can't become + * a user if there is a "SU" entry in the /etc/porttime file + * denying access to the account. + */ + + if (! amroot) { + if (! isttytime (pwent.pw_name, "SU", time ((time_t *) 0))) { + SYSLOG((pwent.pw_uid ? LOG_WARN : LOG_CRIT, + "SU by %s to restricted account %s\n", + oldname, name)); + su_failure(tty); + } + } +#endif /* !USE_PAM */ + + cp = getdef_str((pwent.pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH"); +#if 0 + addenv(cp ? cp : "PATH=/bin:/usr/bin", NULL); +#else + /* XXX very similar code duplicated in libmisc/setupenv.c */ + if (!cp) { + addenv("PATH=/bin:/usr/bin", NULL); + } else if (strchr(cp, '=')) { + addenv(cp, NULL); + } else { + addenv("PATH", cp); + } +#endif + + environ = newenvp; /* make new environment active */ + + if (getenv ("IFS")) /* don't export user IFS ... */ + addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */ + + if (pwent.pw_shell[0] == '*') { /* subsystem root required */ + subsystem (&pwent); /* figure out what to execute */ + endpwent (); +#ifdef SHADOWPWD + endspent (); +#endif + goto top; + } + + sulog(tty, 1, oldname, name); /* save SU information */ + endpwent (); +#ifdef SHADOWPWD + endspent (); +#endif +#ifdef USE_SYSLOG + if (getdef_bool("SYSLOG_SU_ENAB")) + SYSLOG((LOG_INFO, "+ %s %s-%s\n", tty, + oldname[0] ? oldname:"???", name[0] ? name:"???")); +#endif + +#ifdef USE_PAM + /* set primary group id and supplementary groups */ + if (setup_groups(&pwent)) { + pam_end(pamh, PAM_ABORT); + exit(1); + } + + /* pam_setcred() may do things like resource limits, console groups, + and much more, depending on the configured modules */ + ret = pam_setcred(pamh, PAM_ESTABLISH_CRED); + if (ret != PAM_SUCCESS) { + SYSLOG((LOG_ERR, "pam_setcred: %s\n", PAM_STRERROR(pamh, ret))); + fprintf(stderr, "%s: %s\n", Prog, PAM_STRERROR(pamh, ret)); + pam_end(pamh, ret); + exit(1); + } + + /* become the new user */ + if (change_uid(&pwent)) { + pam_setcred(pamh, PAM_DELETE_CRED); + pam_end(pamh, PAM_ABORT); + exit(1); + } + + /* now we are done using PAM */ + pam_end(pamh, PAM_SUCCESS); + +#else /* !USE_PAM */ + if (!amroot) /* no limits if su from root */ + setup_limits(&pwent); + + if (setup_uid_gid(&pwent, is_console)) + exit(1); +#endif /* !USE_PAM */ + + if (fakelogin) + setup_env(&pwent); +#if 1 /* Suggested by Joey Hess. XXX - is this right? */ + else + addenv("HOME", pwent.pw_dir); +#endif + + /* + * This is a workaround for Linux libc bug/feature (?) - the + * /dev/log file descriptor is open without the close-on-exec + * flag and used to be passed to the new shell. There is + * "fcntl(LogFile, F_SETFD, 1)" in libc/misc/syslog.c, but + * it is commented out (at least in 5.4.33). Why? --marekm + */ + closelog(); + + /* + * See if the user has extra arguments on the command line. In + * that case they will be provided to the new user's shell as + * arguments. + */ + + if (fakelogin) { + char *arg0; + +#if 0 /* XXX - GNU su doesn't do this. --marekm */ + if (! hushed (&pwent)) { + motd (); + mailcheck (); + } +#endif + cp = getdef_str("SU_NAME"); + if (!cp) + cp = Basename(pwent.pw_shell); + + arg0 = xmalloc(strlen(cp) + 2); + arg0[0] = '-'; + strcpy(arg0 + 1, cp); + cp = arg0; + } else + cp = Basename(pwent.pw_shell); + + if (! doshell) { + + /* + * Use new user's shell from /etc/passwd and create an + * argv with the rest of the command line included. + */ + + argv[-1] = pwent.pw_shell; + (void) execv (pwent.pw_shell, &argv[-1]); + (void) fprintf (stderr, _("No shell\n")); + SYSLOG((LOG_WARN, "Cannot execute %s\n", pwent.pw_shell)); + closelog(); + exit (1); + } + + shell(pwent.pw_shell, cp); + /*NOTREACHED*/ + exit(1); +} diff --git a/current/src/sulogin.c b/current/src/sulogin.c new file mode 100644 index 00000000..e33aec62 --- /dev/null +++ b/current/src/sulogin.c @@ -0,0 +1,273 @@ +/* + * Copyright 1989 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: sulogin.c,v 1.12 2000/09/02 18:40:44 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include "getdef.h" + +#if HAVE_UTMPX_H +#include +#else +#include +#endif + +#include +#include +#include +#include +#include "pwauth.h" + +static char name[BUFSIZ]; +static char pass[BUFSIZ]; + +static struct passwd pwent; +#if 0 +#if HAVE_UTMPX_H +static struct utmpx utent; +#else +static struct utmp utent; +#endif +#endif + + +extern char **newenvp; +extern size_t newenvc; + +extern char **environ; + +#ifndef ALARM +#define ALARM 60 +#endif + +/* local function prototypes */ +static RETSIGTYPE catch(int); + +static RETSIGTYPE +catch(int sig) +{ + exit(1); +} + +/* syslogd is usually not running at the time when sulogin is typically + called, cluttering the screen with unnecessary messages. Suggested + by Ivan Nejgebauer . --marekm */ +#undef USE_SYSLOG + +/*ARGSUSED*/ +int +main(int argc, char **argv) +{ + char *cp; + char **envp = environ; + TERMIO termio; + +#ifdef USE_TERMIO + ioctl (0, TCGETA, &termio); + termio.c_iflag |= (ICRNL|IXON); + termio.c_oflag |= (OPOST|ONLCR); + termio.c_cflag |= (CREAD); + termio.c_lflag |= (ISIG|ICANON|ECHO|ECHOE|ECHOK); + ioctl (0, TCSETAF, &termio); +#endif +#ifdef USE_TERMIOS + tcgetattr (0, &termio); + termio.c_iflag |= (ICRNL|IXON); + termio.c_oflag |= (CREAD); + termio.c_lflag |= (ECHO|ECHOE|ECHOK|ICANON|ISIG); + tcsetattr (0, TCSANOW, &termio); +#endif + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + +#ifdef USE_SYSLOG + OPENLOG("sulogin"); +#endif + initenv(); + if (argc > 1) { + close (0); + close (1); + close (2); + + if (open (argv[1], O_RDWR) >= 0) { + dup (0); + dup (0); + } else { +#ifdef USE_SYSLOG + syslog (LOG_WARN, "cannot open %s\n", argv[1]); + closelog (); +#endif + exit (1); + } + } + if (access(PASSWD_FILE, F_OK) == -1) { /* must be a password file! */ + printf(_("No password file\n")); +#ifdef USE_SYSLOG + syslog(LOG_WARN, "No password file\n"); + closelog (); +#endif + exit (1); + } +#if !defined(DEBUG) && defined(SULOGIN_ONLY_INIT) + if (getppid () != 1) { /* parent must be INIT */ +#ifdef USE_SYSLOG + syslog (LOG_WARN, "Pid == %d, not 1\n", getppid ()); + closelog (); +#endif + exit (1); + } +#endif + if (! isatty (0) || ! isatty (1) || ! isatty (2)) { +#ifdef USE_SYSLOG + closelog (); +#endif + exit (1); /* must be a terminal */ + } + while (*envp) /* add inherited environment, */ + addenv(*envp++, NULL); /* some variables change later */ + + if ((cp = getdef_str("ENV_TZ"))) + addenv(*cp == '/' ? tz(cp) : cp, NULL); + if ((cp = getdef_str("ENV_HZ"))) + addenv(cp, NULL); /* set the default $HZ, if one */ + (void) strcpy (name, "root"); /* KLUDGE!!! */ + + signal (SIGALRM, catch); /* exit if the timer expires */ + alarm (ALARM); /* only wait so long ... */ + + while (1) { /* repeatedly get login/password pairs */ + pw_entry(name, &pwent); /* get entry from password file */ + if (pwent.pw_name == (char *) 0) { + + /* + * Fail secure + */ + + printf(_("No password entry for 'root'\n")); +#ifdef USE_SYSLOG + syslog (LOG_WARN, "No password entry for 'root'\n"); + closelog (); +#endif + exit (1); + } + + /* + * Here we prompt for the root password, or if no password is + * given we just exit. + */ + + /* get a password for root */ + cp = getpass(_("\nType control-d to proceed with normal startup,\n(or give root password for system maintenance):")); + /* + * XXX - can't enter single user mode if root password is empty. + * I think this doesn't happen very often :-). But it will work + * with standard getpass() (no NULL on EOF). --marekm + */ + if (!cp || !*cp) { +#ifdef USE_SYSLOG + syslog (LOG_INFO, "Normal startup\n"); + closelog (); +#endif + puts("\n"); +#ifdef TELINIT + execl (PATH_TELINIT, "telinit", RUNLEVEL, (char *) 0); +#endif + exit (0); + } else { + STRFCPY(pass, cp); + strzero(cp); + } +#ifdef AUTH_METHODS + if (pwent.pw_name && pwent.pw_passwd[0] == '@') { + if (pw_auth (pwent.pw_passwd + 1, name, PW_LOGIN, (char *) 0)) { +#ifdef USE_SYSLOG + syslog (LOG_WARN, + "Incorrect root authentication"); +#endif + continue; + } + goto auth_done; + } +#endif + if (valid (pass, &pwent)) /* check encrypted passwords ... */ + break; /* ... encrypted passwords matched */ + +#ifdef USE_SYSLOG + syslog (LOG_WARN, "Incorrect root password\n"); +#endif + sleep(2); + puts (_("Login incorrect")); + } +#ifdef AUTH_METHODS +auth_done: +#endif + strzero(pass); + alarm (0); + signal (SIGALRM, SIG_DFL); + environ = newenvp; /* make new environment active */ + + puts(_("Entering System Maintenance Mode\n")); +#ifdef USE_SYSLOG + syslog (LOG_INFO, "System Maintenance Mode\n"); +#endif + +#if 0 /* do we need all this? we are logging in as root anyway... --marekm */ + /* + * Normally there would be a utmp entry for login to mung on + * to get the tty name, date, etc. from. We don't need all that + * stuff because we won't update the utmp or wtmp files. BUT!, + * we do need the tty name so we can set the permissions and + * ownership. + */ + + if ((cp = ttyname (0))) { /* found entry in /dev/ */ + if (strncmp(cp, "/dev/", 5) == 0) + cp += 5; + + strncpy(utent.ut_line, cp, sizeof utent.ut_line); + } + if (getenv ("IFS")) /* don't export user IFS ... */ + addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */ + + setup (&pwent, 0); /* set UID, GID, HOME, etc ... */ +#endif + +#ifdef USE_SYSLOG + closelog (); +#endif + shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */ + /*NOTREACHED*/ + return (0); +} diff --git a/current/src/useradd.c b/current/src/useradd.c new file mode 100644 index 00000000..880d854e --- /dev/null +++ b/current/src/useradd.c @@ -0,0 +1,1746 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: useradd.c,v 1.18 2000/09/02 18:40:44 marekm Exp $") + +#include "prototypes.h" +#include "defines.h" +#include "chkname.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pwauth.h" +#if HAVE_LASTLOG_H +#include +#else +#include "lastlog_.h" +#endif +#include "faillog.h" + +#ifndef SKEL_DIR +#define SKEL_DIR "/etc/skel" +#endif + +#ifndef USER_DEFAULTS_FILE +#define USER_DEFAULTS_FILE "/etc/default/useradd" +#define NEW_USER_FILE "/etc/default/nuaddXXXXXX" +#endif + +/* + * Needed for MkLinux DR1/2/2.1 - J. + */ +#ifndef LASTLOG_FILE +#define LASTLOG_FILE "/var/log/lastlog" +#endif + +/* + * These defaults are used if there is no defaults file. + */ +static gid_t def_group = 100; +static const char *def_gname = "other"; +static const char *def_home = "/home"; +static const char *def_shell = ""; +static const char *def_template = SKEL_DIR; +#ifdef SHADOWPWD +static long def_inactive = -1; +static const char *def_expire = ""; +#endif + +static char def_file[] = USER_DEFAULTS_FILE; + +#define VALID(s) (strcspn (s, ":\n") == strlen (s)) + +static const char *user_name = ""; +static const char *user_pass = "!"; +static uid_t user_id; +static gid_t user_gid; +static const char *user_comment = ""; +static const char *user_home = ""; +static const char *user_shell = ""; +#ifdef SHADOWPWD +static long user_expire = -1; +static int is_shadow_pwd; +#endif +#ifdef SHADOWGRP +static int is_shadow_grp; +#endif +static char *user_groups[NGROUPS_MAX+1]; /* NULL-terminated list */ +static int do_grp_update = 0; /* group files need to be updated */ + +static char *Prog; + +static int + uflg = 0, /* specify user ID for new account */ + oflg = 0, /* permit non-unique user ID to be specified with -u */ + gflg = 0, /* primary group ID for new account */ + Gflg = 0, /* secondary group set for new account */ + dflg = 0, /* home directory for new account */ + bflg = 0, /* new default root of home directory */ + sflg = 0, /* shell program for new account */ + cflg = 0, /* comment (GECOS) field for new account */ + mflg = 0, /* create user's home directory if it doesn't exist */ + kflg = 0, /* specify a directory to fill new user directory */ + fflg = 0, /* days until account with expired password is locked */ + eflg = 0, /* days since 1970-01-01 when account is locked */ + Dflg = 0; /* set/show new user default values */ + +#ifdef AUTH_METHODS +static int Aflg = 0; /* specify authentication method for user */ +static char user_auth[1024]; +static char *auth_arg; +#endif + +extern char *optarg; +extern int optind; + +#ifdef NDBM +extern int pw_dbm_mode; +#ifdef SHADOWPWD +extern int sp_dbm_mode; +#endif +extern int gr_dbm_mode; +#ifdef SHADOWGRP +extern int sg_dbm_mode; +#endif +#endif + +static int home_added; + +#ifdef NDBM +static int pw_dbm_added; +static int gr_dbm_added; +#ifdef SHADOWPWD +static int sp_dbm_added; +#endif +#ifdef SHADOWGRP +static int sg_dbm_added; +#endif +#endif /* NDBM */ + +#include "groupio.h" + +#ifdef SHADOWGRP +#include "sgroupio.h" +#endif + +#include "pwio.h" + +#ifdef SHADOWPWD +#include "shadowio.h" +#endif + +#include "getdef.h" + +/* + * exit status values + */ +#define E_SUCCESS 0 /* success */ +#define E_PW_UPDATE 1 /* can't update password file */ +#define E_USAGE 2 /* bad command syntax */ +#define E_BAD_ARG 3 /* invalid argument to option */ +#define E_UID_IN_USE 4 /* uid already in use (and no -o) */ +#define E_NOTFOUND 6 /* specified group doesn't exist */ +#define E_NAME_IN_USE 9 /* username already in use */ +#define E_GRP_UPDATE 10 /* can't update group file */ +#define E_HOMEDIR 12 /* can't create home directory */ + +#ifdef SVR4 +#define DGROUP "defgroup=" +#define HOME "defparent=" +#define SHELL "defshell=" +#define INACT "definact=" +#define EXPIRE "defexpire=" +#define SKEL "defskel=" +#else +#define DGROUP "GROUP=" +#define HOME "HOME=" +#define SHELL "SHELL=" +#define INACT "INACTIVE=" +#define EXPIRE "EXPIRE=" +#define SKEL "SKEL=" +#endif + +/* local function prototypes */ +static void fail_exit(int); +static struct group *getgr_nam_gid(const char *); +static long get_number(const char *); +static void get_defaults(void); +static void show_defaults(void); +static int set_defaults(void); +static int get_groups(char *); +static void usage(void); +static void new_pwent(struct passwd *); +#ifdef SHADOWPWD +static long scale_age(long); +static void new_spent(struct spwd *); +#endif +static void grp_update(void); +static void find_new_uid(void); +#ifdef AUTH_METHODS +static void convert_auth(char *, const char *); +static int valid_auth(const char *); +#endif +static void process_flags(int argc, char **argv); +static void close_files(void); +static void open_files(void); +static void faillog_reset(uid_t); +static void lastlog_reset(uid_t); +static void usr_update(void); +static void create_home(void); + +/* + * fail_exit - undo as much as possible + */ + +static void +fail_exit(int code) +{ +#ifdef NDBM + struct passwd pwent; + + if (pw_dbm_added) { + pwent.pw_name = user_name; + pwent.pw_uid = user_id; + pw_dbm_remove(&pwent); + } + if (gr_dbm_added) + fprintf(stderr, _("%s: rebuild the group database\n"), Prog); +#ifdef SHADOWPWD + if (sp_dbm_added) + sp_dbm_remove(user_name); +#endif +#ifdef SHADOWGRP + if (sg_dbm_added) + fprintf(stderr, _("%s: rebuild the shadow group database\n"), + Prog); +#endif +#endif /* NDBM */ + if (home_added) + rmdir(user_home); + + SYSLOG((LOG_INFO, "failed adding user `%s', data deleted\n", + user_name)); + exit(code); +} + + +static struct group * +getgr_nam_gid(const char *name) +{ + gid_t gid; + char *ep; + + gid = strtol(name, &ep, 10); + if (*name != '\0' && *ep == '\0') /* valid numeric gid */ + return getgrgid(gid); + + return getgrnam(name); +} + + +static long +get_number(const char *cp) +{ + long val; + char *ep; + + val = strtol(cp, &ep, 10); + if (*cp != '\0' && *ep == '\0') /* valid number */ + return val; + + fprintf(stderr, _("%s: invalid numeric argument `%s'\n"), Prog, cp); + exit(E_BAD_ARG); +} + +#define MATCH(x,y) (strncmp((x),(y),strlen(y)) == 0) + +/* + * get_defaults - read the defaults file + * + * get_defaults() reads the defaults file for this command. It sets + * the various values from the file, or uses built-in default values + * if the file does not exist. + */ + +static void +get_defaults(void) +{ + FILE *fp; + char buf[1024]; + char *cp, *ep; + const struct group *grp; + long val; + + /* + * Open the defaults file for reading. + */ + + if (!(fp = fopen(def_file, "r"))) + return; + + /* + * Read the file a line at a time. Only the lines that have + * relevant values are used, everything else can be ignored. + */ + + while (fgets(buf, sizeof buf, fp)) { + if ((cp = strrchr (buf, '\n'))) + *cp = '\0'; + + if (!(cp = strchr(buf, '='))) + continue; + + cp++; + + /* + * Primary GROUP identifier + */ + + if (MATCH(buf, DGROUP)) { + val = strtol(cp, &ep, 10); + if (*cp != '\0' && *ep == '\0') { /* valid number */ + def_group = val; + if ((grp = getgrgid(def_group))) { + def_gname = xstrdup(grp->gr_name); + } else { + fprintf(stderr, + _("%s: unknown gid %s\n"), + Prog, cp); + } + } else if ((grp = getgrnam(cp))) { + def_group = grp->gr_gid; + def_gname = xstrdup(cp); + } else { + fprintf(stderr, _("%s: unknown group %s\n"), + Prog, cp); + } + } + + /* + * Default HOME filesystem + */ + + else if (MATCH(buf, HOME)) { + def_home = xstrdup(cp); + } + + /* + * Default Login Shell command + */ + + else if (MATCH(buf, SHELL)) { + def_shell = xstrdup(cp); + } + +#ifdef SHADOWPWD + /* + * Default Password Inactive value + */ + + else if (MATCH(buf, INACT)) { + val = strtol(cp, &ep, 10); + if (*cp != '\0' && *ep == '\0') /* valid number */ + def_inactive = val; + else + def_inactive = -1; + } + + /* + * Default account expiration date + */ + + else if (MATCH(buf, EXPIRE)) { + def_expire = xstrdup(cp); + } +#endif + + /* + * Default Skeleton information + */ + + else if (MATCH(buf, SKEL)) { + if (*cp == '\0') + cp = SKEL_DIR; /* XXX warning: const */ + + def_template = xstrdup(cp); + } + } +} + + +/* + * show_defaults - show the contents of the defaults file + * + * show_defaults() displays the values that are used from the default + * file and the built-in values. + */ + +static void +show_defaults(void) +{ +#ifdef SVR4 + printf(_("group=%s,%ld basedir=%s skel=%s\n"), + def_gname, (long) def_group, def_home, def_template); + + printf(_("shell=%s "), def_shell); +#ifdef SHADOWPWD + printf(_("inactive=%ld expire=%s"), def_inactive, def_expire); +#endif + printf("\n"); +#else /* !SVR4 */ + printf(_("GROUP=%ld\n"), (long) def_group); + printf(_("HOME=%s\n"), def_home); +#ifdef SHADOWPWD + printf(_("INACTIVE=%ld\n"), def_inactive); + printf(_("EXPIRE=%s\n"), def_expire); +#endif + printf(_("SHELL=%s\n"), def_shell); + printf(_("SKEL=%s\n"), def_template); +#endif /* !SVR4 */ +} + +/* + * set_defaults - write new defaults file + * + * set_defaults() re-writes the defaults file using the values that + * are currently set. Duplicated lines are pruned, missing lines are + * added, and unrecognized lines are copied as is. + */ + +static int +set_defaults(void) +{ + FILE *ifp; + FILE *ofp; + char buf[1024]; + static char new_file[] = NEW_USER_FILE; + char *cp; + int out_group = 0; + int out_home = 0; + int out_inactive = 0; + int out_expire = 0; + int out_shell = 0; + int out_skel = 0; +#ifdef SVR4 + int out_gname = 0; +#endif + + /* + * Create a temporary file to copy the new output to. + */ + + mktemp (new_file); + if (!(ofp = fopen (new_file, "w"))) { + fprintf(stderr, _("%s: cannot create new defaults file\n"), + Prog); + return -1; + } + + /* + * Open the existing defaults file and copy the lines to the + * temporary file, using any new values. Each line is checked + * to insure that it is not output more than once. + */ + + if (!(ifp = fopen(def_file, "r"))) { + fprintf(ofp, "# useradd defaults file\n"); + goto skip; + } + + while (fgets(buf, sizeof buf, ifp)) { + if ((cp = strrchr(buf, '\n'))) + *cp = '\0'; + + if (!out_group && MATCH(buf, DGROUP)) { + fprintf(ofp, DGROUP "%d\n", (int) def_group); + out_group++; + } +#ifdef SVR4 + else if (!out_gname && MATCH(buf, "defgname=")) { + fprintf(ofp, "defgname=%s\n", def_gname); + out_gname++; + } +#endif + else if (!out_home && MATCH(buf, HOME)) { + fprintf(ofp, HOME "%s\n", def_home); + out_home++; +#ifdef SHADOWPWD + } else if (!out_inactive && MATCH(buf, INACT)) { + fprintf(ofp, INACT "%ld\n", def_inactive); + out_inactive++; + } else if (!out_expire && MATCH(buf, EXPIRE)) { + fprintf(ofp, EXPIRE "%s\n", def_expire); + out_expire++; + } +#endif + else if (!out_shell && MATCH(buf, SHELL)) { + fprintf(ofp, SHELL "%s\n", def_shell); + out_shell++; + } + else if (!out_skel && MATCH(buf, SKEL)) { + fprintf(ofp, SKEL "%s\n", def_template); + out_skel++; + } + else + fprintf(ofp, "%s\n", buf); + } + fclose(ifp); + +skip: + /* + * Check each line to insure that every line was output. This + * causes new values to be added to a file which did not previously + * have an entry for that value. + */ + + if (!out_group) + fprintf(ofp, DGROUP "%d\n", (int) def_group); + if (!out_home) + fprintf(ofp, HOME "%s\n", def_home); +#ifdef SHADOWPWD + if (!out_inactive) + fprintf(ofp, INACT "%ld\n", def_inactive); + if (!out_expire) + fprintf(ofp, EXPIRE "%s\n", def_expire); +#endif + if (!out_shell) + fprintf(ofp, SHELL "%s\n", def_shell); + if (!out_skel) + fprintf(ofp, SKEL "%s\n", def_template); + + /* + * Flush and close the file. Check for errors to make certain + * the new file is intact. + */ + + fflush(ofp); + if (ferror(ofp) || fclose(ofp)) { + unlink(new_file); + return -1; + } + + /* + * Rename the current default file to its backup name. + */ + + snprintf(buf, sizeof buf, "%s-", def_file); + if (rename(def_file, buf) && errno != ENOENT) { + snprintf(buf, sizeof buf, _("%s: rename: %s"), Prog, def_file); + perror(buf); + unlink(new_file); + return -1; + } + + /* + * Rename the new default file to its correct name. + */ + + if (rename(new_file, def_file)) { + snprintf(buf, sizeof buf, _("%s: rename: %s"), Prog, new_file); + perror(buf); + return -1; + } +#ifdef SHADOWPWD + SYSLOG((LOG_INFO, + "defaults: group=%d, home=%s, inactive=%ld, expire=%s\n", + (int) def_group, def_home, def_inactive, def_expire)); +#else + SYSLOG((LOG_INFO, "defaults: group=%d, home=%s\n", + (int) def_group, def_home)); +#endif + return 0; +} + +/* + * get_groups - convert a list of group names to an array of group IDs + * + * get_groups() takes a comma-separated list of group names and + * converts it to a NULL-terminated array. Any unknown group + * names are reported as errors. + */ + +static int +get_groups(char *list) +{ + char *cp; + const struct group *grp; + int errors = 0; + int ngroups = 0; + + /* + * Initialize the list to be empty + */ + + user_groups[0] = (char *) 0; + + if (! *list) + return 0; + + /* + * So long as there is some data to be converted, strip off + * each name and look it up. A mix of numerical and string + * values for group identifiers is permitted. + */ + + do { + /* + * Strip off a single name from the list + */ + + if ((cp = strchr (list, ','))) + *cp++ = '\0'; + + /* + * Names starting with digits are treated as numerical + * GID values, otherwise the string is looked up as is. + */ + + grp = getgr_nam_gid(list); + + /* + * There must be a match, either by GID value or by + * string name. + */ + + if (! grp) { + fprintf(stderr, _("%s: unknown group %s\n"), + Prog, list); + errors++; + } + list = cp; + + /* + * If the group doesn't exist, don't dump core... + * Instead, try the next one. --marekm + */ + if (! grp) + continue; + +#ifdef USE_NIS + /* + * Don't add this group if they are an NIS group. Tell + * the user to go to the server for this group. + */ + + if (__isgrNIS ()) { + fprintf(stderr, _("%s: group `%s' is a NIS group.\n"), + Prog, grp->gr_name); + continue; + } +#endif + + if (ngroups == NGROUPS_MAX) { + fprintf(stderr, + _("%s: too many groups specified (max %d).\n"), + Prog, ngroups); + break; + } + + /* + * Add the group name to the user's list of groups. + */ + + user_groups[ngroups++] = xstrdup(grp->gr_name); + } while (list); + + user_groups[ngroups] = (char *) 0; + + /* + * Any errors in finding group names are fatal + */ + + if (errors) + return -1; + + return 0; +} + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, + _("usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"), + Prog); + fprintf(stderr, + _("\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n")); + fprintf(stderr, "\t\t"); +#ifdef SHADOWPWD + fprintf(stderr, _("[-f inactive] [-e expire ] ")); +#endif +#ifdef AUTH_METHODS + fprintf(stderr, _("[-A program] ")); +#endif + fprintf(stderr, _("[-p passwd] name\n")); + + fprintf(stderr, _(" %s\t-D [-g group] [-b base] [-s shell]\n"), + Prog); +#ifdef SHADOWPWD + fprintf(stderr, _("\t\t[-f inactive] [-e expire ]\n")); +#endif + + exit(E_USAGE); +} + +/* + * new_pwent - initialize the values in a password file entry + * + * new_pwent() takes all of the values that have been entered and + * fills in a (struct passwd) with them. + */ + +static void +new_pwent(struct passwd *pwent) +{ + memzero(pwent, sizeof *pwent); + pwent->pw_name = (char *) user_name; +#ifdef SHADOWPWD + if (is_shadow_pwd) + pwent->pw_passwd = (char *) SHADOW_PASSWD_STRING; + else +#endif + pwent->pw_passwd = (char *) user_pass; + +#ifdef ATT_AGE + pwent->pw_age = (char *) ""; +#endif + pwent->pw_uid = user_id; + pwent->pw_gid = user_gid; + pwent->pw_gecos = (char *) user_comment; +#ifdef ATT_COMMENT + pwent->pw_comment = (char *) ""; +#endif +#ifdef BSD_QUOTA + pwent->pw_quota = 0; +#endif + pwent->pw_dir = (char *) user_home; + pwent->pw_shell = (char *) user_shell; +} + +#ifdef SHADOWPWD +static long +scale_age(long x) +{ + if (x <= 0) + return x; + + return x * (DAY/SCALE); +} + +/* + * new_spent - initialize the values in a shadow password file entry + * + * new_spent() takes all of the values that have been entered and + * fills in a (struct spwd) with them. + */ + +static void +new_spent(struct spwd *spent) +{ + memzero(spent, sizeof *spent); + spent->sp_namp = (char *) user_name; + spent->sp_pwdp = (char *) user_pass; + spent->sp_lstchg = time((time_t *) 0) / SCALE; + spent->sp_min = scale_age(getdef_num("PASS_MIN_DAYS", -1)); + spent->sp_max = scale_age(getdef_num("PASS_MAX_DAYS", -1)); + spent->sp_warn = scale_age(getdef_num("PASS_WARN_AGE", -1)); + spent->sp_inact = scale_age(def_inactive); + spent->sp_expire = scale_age(user_expire); + spent->sp_flag = -1; +} +#endif + +/* + * grp_update - add user to secondary group set + * + * grp_update() takes the secondary group set given in user_groups + * and adds the user to each group given by that set. + */ + +static void +grp_update(void) +{ + const struct group *grp; + struct group *ngrp; +#ifdef SHADOWGRP + const struct sgrp *sgrp; + struct sgrp *nsgrp; +#endif + + /* + * Lock and open the group file. This will load all of the group + * entries. + */ + + if (! gr_lock ()) { + fprintf(stderr, _("%s: error locking group file\n"), Prog); + fail_exit(E_GRP_UPDATE); + } + if (! gr_open (O_RDWR)) { + fprintf(stderr, _("%s: error opening group file\n"), Prog); + fail_exit(E_GRP_UPDATE); + } +#ifdef SHADOWGRP + if (is_shadow_grp && ! sgr_lock ()) { + fprintf(stderr, _("%s: error locking shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } + if (is_shadow_grp && ! sgr_open (O_RDWR)) { + fprintf(stderr, _("%s: error opening shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } +#endif + + /* + * Scan through the entire group file looking for the groups that + * the user is a member of. + */ + + for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) { + + /* + * See if the user specified this group as one of their + * concurrent groups. + */ + + if (!is_on_list(user_groups, grp->gr_name)) + continue; + + /* + * Make a copy - gr_update() will free() everything + * from the old entry, and we need it later. + */ + + ngrp = __gr_dup(grp); + if (!ngrp) { + fail_exit(E_GRP_UPDATE); /* XXX */ + } + + /* + * Add the username to the list of group members and + * update the group entry to reflect the change. + */ + + ngrp->gr_mem = add_list (ngrp->gr_mem, user_name); + if (!gr_update(ngrp)) { + fprintf(stderr, "%s: error adding new group entry\n", + Prog); + fail_exit(E_GRP_UPDATE); + } +#ifdef NDBM + /* + * Update the DBM group file with the new entry as well. + */ + + if (!gr_dbm_update(ngrp)) { + fprintf(stderr, "%s: cannot add new dbm group entry\n", + Prog); + fail_exit(E_GRP_UPDATE); + } else + gr_dbm_added++; +#endif + SYSLOG((LOG_INFO, "add `%s' to group `%s'\n", + user_name, ngrp->gr_name)); + } +#ifdef NDBM + endgrent (); +#endif + +#ifdef SHADOWGRP + if (!is_shadow_grp) + return; + + /* + * Scan through the entire shadow group file looking for the groups + * that the user is a member of. The administrative list isn't + * modified. + */ + + for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) { + + /* + * See if the user specified this group as one of their + * concurrent groups. + */ + + if (!gr_locate(sgrp->sg_name)) + continue; + + if (!is_on_list(user_groups, sgrp->sg_name)) + continue; + + /* + * Make a copy - sgr_update() will free() everything + * from the old entry, and we need it later. + */ + + nsgrp = __sgr_dup(sgrp); + if (!nsgrp) { + fail_exit(E_GRP_UPDATE); /* XXX */ + } + + /* + * Add the username to the list of group members and + * update the group entry to reflect the change. + */ + + nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name); + if (!sgr_update(nsgrp)) { + fprintf(stderr, + _("%s: error adding new group entry\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } +#ifdef NDBM + /* + * Update the DBM group file with the new entry as well. + */ + + if (!sg_dbm_update(nsgrp)) { + fprintf(stderr, + _("%s: cannot add new dbm group entry\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } else + sg_dbm_added++; +#endif /* NDBM */ + SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n", + user_name, nsgrp->sg_name)); + } +#ifdef NDBM + endsgent (); +#endif /* NDBM */ +#endif /* SHADOWGRP */ +} + +/* + * find_new_uid - find the next available UID + * + * find_new_uid() locates the next highest unused UID in the password + * file, or checks the given user ID against the existing ones for + * uniqueness. + */ + +static void +find_new_uid(void) +{ + const struct passwd *pwd; + uid_t uid_min, uid_max; + + uid_min = getdef_num("UID_MIN", 100); + uid_max = getdef_num("UID_MAX", 60000); + + /* + * Start with some UID value if the user didn't provide us with + * one already. + */ + + if (! uflg) + user_id = uid_min; + + /* + * Search the entire password file, either looking for this + * UID (if the user specified one with -u) or looking for the + * largest unused value. + */ + +#ifdef NO_GETPWENT + pw_rewind(); + while ((pwd = pw_next())) { +#else /* using getpwent() we can check against NIS users etc. */ + setpwent(); + while ((pwd = getpwent())) { +#endif + if (strcmp(user_name, pwd->pw_name) == 0) { + fprintf(stderr, _("%s: name %s is not unique\n"), + Prog, user_name); + exit(E_NAME_IN_USE); + } + if (uflg && user_id == pwd->pw_uid) { + fprintf(stderr, _("%s: uid %d is not unique\n"), + Prog, (int) user_id); + exit(E_UID_IN_USE); + } + if (! uflg && pwd->pw_uid >= user_id) { + if (pwd->pw_uid > uid_max) + continue; + user_id = pwd->pw_uid + 1; + } + } + /* + * If a user with uid equal to UID_MAX exists, the above algorithm + * will give us UID_MAX+1 even if not unique. Search for the first + * free uid starting with UID_MIN (it's O(n*n) but can be avoided + * by not having users with uid equal to UID_MAX). --marekm + */ + if (!uflg && user_id == uid_max + 1) { + for (user_id = uid_min; user_id < uid_max; user_id++) { +#ifdef NO_GETPWENT + pw_rewind(); + while ((pwd = pw_next()) && pwd->pw_uid != user_id) + ; + if (!pwd) + break; +#else + if (!getpwuid(user_id)) + break; +#endif + } + if (user_id == uid_max) { + fprintf(stderr, _("%s: can't get unique uid\n"), + Prog); + fail_exit(E_UID_IN_USE); + } + } +} + +#ifdef AUTH_METHODS +/* + * convert_auth - convert the argument list to a authentication list + */ + +static void +convert_auth(char *auths, const char *list) +{ + char *cp, *end; + char buf[257]; + + /* + * Copy each method. DEFAULT is replaced by an encrypted string + * if one can be found in the current authentication list. + */ + + strcpy(buf, list); + auths[0] = '\0'; + for (cp = buf; cp; cp = end) { + if (auths[0]) + strcat(auths, ";"); + + if ((end = strchr(cp, ','))) + *end++ = '\0'; + + if (strcmp(cp, "DEFAULT") == 0) { + strcat(auths, user_pass); + } else { + strcat(auths, "@"); + strcat(auths, cp); + } + } +} + +/* + * valid_auth - check authentication list for validity + */ + +static int +valid_auth(const char *methods) +{ + char *cp, *end; + char buf[257]; + int default_cnt = 0; + + /* + * Cursory checks, length and illegal characters + */ + + if ((int) strlen (methods) > 256) + return 0; + + if (! VALID (methods)) + return 0; + + /* + * Pick each method apart and check it. + */ + + strcpy (buf, methods); + for (cp = buf;cp;cp = end) { + if ((end = strchr (cp, ','))) + *end++ = '\0'; + + if (strcmp (cp, "DEFAULT") == 0) { + if (default_cnt++ > 0) + return 0; + } + } + return 1; +} +#endif /* AUTH_METHODS */ + +/* + * process_flags - perform command line argument setting + * + * process_flags() interprets the command line arguments and sets + * the values that the user will be created with accordingly. The + * values are checked for sanity. + */ + +static void +process_flags(int argc, char **argv) +{ + const struct group *grp; + int anyflag = 0; + int arg; + char *cp; + +#ifdef SHADOWPWD +#define FLAGS "A:Du:og:G:d:s:c:mk:p:f:e:b:O:M" +#else +#define FLAGS "A:Du:og:G:d:s:c:mk:p:b:O:M" +#endif + while ((arg = getopt(argc, argv, FLAGS)) != EOF) { +#undef FLAGS + switch (arg) { +#ifdef AUTH_METHODS + case 'A': + if (! valid_auth (optarg)) { + fprintf(stderr, + _("%s: invalid field `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + auth_arg = optarg; + Aflg++; + break; +#endif + case 'b': + if (!Dflg) + usage (); + + if (!VALID(optarg) || optarg[0] != '/') { + fprintf(stderr, + _("%s: invalid base directory `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + def_home = optarg; + bflg++; + break; + case 'c': + if (!VALID(optarg)) { + fprintf(stderr, + _("%s: invalid comment `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + user_comment = optarg; + cflg++; + break; + case 'd': + if (!VALID(optarg) || optarg[0] != '/') { + fprintf(stderr, + _("%s: invalid home directory `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + user_home = optarg; + dflg++; + break; + case 'D': + if (anyflag) + usage(); + Dflg++; + break; +#ifdef SHADOWPWD + case 'e': + if (*optarg) { + user_expire = strtoday(optarg); + if (user_expire == -1) { + fprintf(stderr, + _("%s: invalid date `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + } else + user_expire = -1; + + /* + * -e "" is allowed - it's a no-op without /etc/shadow + */ + if (*optarg && !is_shadow_pwd) { + fprintf(stderr, + _("%s: shadow passwords required for -e\n"), + Prog); + exit(E_USAGE); + } + if (Dflg) + def_expire = optarg; + eflg++; + break; + case 'f': + def_inactive = get_number(optarg); + /* + * -f -1 is allowed - it's a no-op without /etc/shadow + */ + if (def_inactive != -1 && !is_shadow_pwd) { + fprintf(stderr, + _("%s: shadow passwords required for -f\n"), + Prog); + exit(E_USAGE); + } + fflg++; + break; +#endif + case 'g': + grp = getgr_nam_gid(optarg); + if (!grp) { + fprintf(stderr, _("%s: unknown group %s\n"), + Prog, optarg); + exit(E_NOTFOUND); + } + if (Dflg) { + def_group = grp->gr_gid; + def_gname = optarg; + } else { + user_gid = grp->gr_gid; + } + gflg++; + break; + case 'G': + if (get_groups(optarg)) + exit(E_NOTFOUND); + if (user_groups[0]) + do_grp_update++; + Gflg++; + break; + case 'k': + def_template = optarg; + kflg++; + break; + case 'm': + mflg++; + break; + case 'M': + /* + * don't create home dir - this is the default, + * ignored for RedHat/PLD adduser compatibility. + */ + break; + case 'o': + oflg++; + break; + case 'O': + /* + * override login.defs defaults (-O name=value) + * example: -O UID_MIN=100 -O UID_MAX=499 + * note: -O UID_MIN=10,UID_MAX=499 doesn't work yet + */ + cp = strchr(optarg, '='); + if (!cp) { + fprintf(stderr, + _("%s: -O requires NAME=VALUE\n"), + Prog); + exit(E_BAD_ARG); + } + /* terminate name, point to value */ + *cp++ = '\0'; + if (putdef_str(optarg, cp) < 0) + exit(E_BAD_ARG); + break; + case 'p': /* set encrypted password */ + if (!VALID(optarg)) { + fprintf(stderr, _("%s: invalid field `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + user_pass = optarg; + break; + case 's': + if (!VALID(optarg) || (optarg[0] && + (optarg[0] != '/' && optarg[0] != '*'))) { + fprintf(stderr, _("%s: invalid shell `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + user_shell = optarg; + def_shell = optarg; + sflg++; + break; + case 'u': + user_id = get_number(optarg); + uflg++; + break; + default: + usage(); + } + anyflag++; + } + + /* + * Certain options are only valid in combination with others. + * Check it here so that they can be specified in any order. + */ + if ((oflg && !uflg) || (kflg && !mflg)) + usage(); + + /* + * Either -D or username is required. Defaults can be set with -D + * for the -b, -e, -f, -g, -s options only. + */ + if (Dflg) { + if (optind != argc) + usage(); + + if (uflg || oflg || Gflg || dflg || cflg || mflg) + usage(); + } else { + if (optind != argc - 1) + usage(); + + user_name = argv[optind]; + if (!check_user_name(user_name)) { + fprintf(stderr, _("%s: invalid user name `%s'\n"), + Prog, user_name); + exit(E_BAD_ARG); + } + if (!dflg) { + char *uh; + + uh = xmalloc(strlen(def_home) + strlen(user_name) + 2); + sprintf(uh, "%s/%s", def_home, user_name); + user_home = uh; + } + } + +#ifdef SHADOWPWD + if (!eflg) + user_expire = strtoday(def_expire); +#endif + + if (!gflg) + user_gid = def_group; + + if (!sflg) + user_shell = def_shell; +} + +/* + * close_files - close all of the files that were opened + * + * close_files() closes all of the files that were opened for this + * new user. This causes any modified entries to be written out. + */ + +static void +close_files(void) +{ + if (!pw_close()) { + fprintf(stderr, _("%s: cannot rewrite password file\n"), Prog); + fail_exit(E_PW_UPDATE); + } +#ifdef SHADOWPWD + if (is_shadow_pwd && !spw_close()) { + fprintf(stderr, _("%s: cannot rewrite shadow password file\n"), + Prog); + fail_exit(E_PW_UPDATE); + } +#endif + if (do_grp_update) { + if (!gr_close()) { + fprintf(stderr, _("%s: cannot rewrite group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } + gr_unlock(); +#ifdef SHADOWGRP + if (is_shadow_grp && !sgr_close()) { + fprintf (stderr, + _("%s: cannot rewrite shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } + if (is_shadow_grp) + sgr_unlock(); +#endif + } +#ifdef SHADOWPWD + if (is_shadow_pwd) + spw_unlock(); +#endif + pw_unlock(); +} + +/* + * open_files - lock and open the password files + * + * open_files() opens the two password files. + */ + +static void +open_files(void) +{ + if (!pw_lock()) { + fprintf(stderr, _("%s: unable to lock password file\n"), Prog); + exit(E_PW_UPDATE); + } + if (!pw_open(O_RDWR)) { + fprintf(stderr, _("%s: unable to open password file\n"), Prog); + pw_unlock(); + exit(E_PW_UPDATE); + } +#ifdef SHADOWPWD + if (is_shadow_pwd && !spw_lock()) { + fprintf(stderr, _("%s: cannot lock shadow password file\n"), + Prog); + pw_unlock(); + exit(E_PW_UPDATE); + } + if (is_shadow_pwd && !spw_open(O_RDWR)) { + fprintf(stderr, _("%s: cannot open shadow password file\n"), + Prog); + spw_unlock(); + pw_unlock(); + exit(E_PW_UPDATE); + } +#endif +} + + +static void +faillog_reset(uid_t uid) +{ + struct faillog fl; + int fd; + + fd = open(FAILLOG_FILE, O_RDWR); + if (fd >= 0) { + memzero(&fl, sizeof(fl)); + lseek(fd, (off_t) sizeof(fl) * uid, SEEK_SET); + write(fd, &fl, sizeof(fl)); + close(fd); + } +} + +static void +lastlog_reset(uid_t uid) +{ + struct lastlog ll; + int fd; + + fd = open(LASTLOG_FILE, O_RDWR); + if (fd >= 0) { + memzero(&ll, sizeof(ll)); + lseek(fd, (off_t) sizeof(ll) * uid, SEEK_SET); + write(fd, &ll, sizeof(ll)); + close(fd); + } +} + +/* + * usr_update - create the user entries + * + * usr_update() creates the password file entries for this user + * and will update the group entries if required. + */ + +static void +usr_update(void) +{ + struct passwd pwent; +#ifdef SHADOWPWD + struct spwd spent; +#endif + + if (! oflg) + find_new_uid (); + +#ifdef AUTH_METHODS + if (Aflg) { + convert_auth(user_auth, auth_arg); + user_pass = user_auth; + } +#endif + + /* + * Fill in the password structure with any new fields, making + * copies of strings. + */ + + new_pwent (&pwent); +#ifdef SHADOWPWD + new_spent (&spent); +#endif + + /* + * Create a syslog entry. We need to do this now in case anything + * happens so we know what we were trying to accomplish. + */ + +#ifdef AUTH_METHODS + SYSLOG((LOG_INFO, + "new user: name=%s, uid=%d, gid=%d, home=%s, shell=%s, auth=%s\n", + user_name, user_id, user_gid, user_home, user_shell, + Aflg ? auth_arg : "DEFAULT")); +#else + SYSLOG((LOG_INFO, + "new user: name=%s, uid=%d, gid=%d, home=%s, shell=%s\n", + user_name, user_id, user_gid, user_home, user_shell)); +#endif + +#ifdef AUTH_METHODS + /* + * Attempt to add the new user to any authentication programs + * which have been requested. Since this is more likely to fail + * than the update of the password file, we do this first. + */ + + if (Aflg && pw_auth(user_auth, pwent.pw_name, PW_ADD, (char *) 0)) { + fprintf(stderr, _("%s: error adding authentication method\n"), + Prog); + fail_exit(E_PW_UPDATE); /* XXX */ + } +#endif /* AUTH_METHODS */ + + /* + * Initialize faillog and lastlog entries for this UID in case + * it belongs to a previously deleted user. We do it only if + * no user with this UID exists yet (entries for shared UIDs + * are left unchanged). --marekm + */ + + if (!getpwuid(user_id)) { + faillog_reset(user_id); + lastlog_reset(user_id); + } + + /* + * Put the new (struct passwd) in the table. + */ + + if (! pw_update (&pwent)) { + fprintf(stderr, _("%s: error adding new password entry\n"), + Prog); + exit(E_PW_UPDATE); + } + +#ifdef NDBM + /* + * Update the DBM files. This creates the user before the flat + * files are updated. This is safe before the password field is + * either locked, or set to a valid authentication string. + */ + + if (pw_dbm_present()) { + if (!pw_dbm_update(&pwent)) { + fprintf(stderr, + _("%s: error updating password dbm entry\n"), + Prog); + exit(E_PW_UPDATE); + } else + pw_dbm_added = 1; + } + endpwent(); +#endif + +#ifdef SHADOWPWD + /* + * Put the new (struct spwd) in the table. + */ + + if (is_shadow_pwd && !spw_update(&spent)) { + fprintf(stderr, + _("%s: error adding new shadow password entry\n"), + Prog); + exit(E_PW_UPDATE); + } + +#ifdef NDBM + /* + * Update the DBM files for the shadow password. This entry is + * output before the entry in the flat file, but this is safe as + * the password is locked or the authentication string has the + * proper values. + */ + + if (is_shadow_pwd && sp_dbm_present()) { + if (!sp_dbm_update(&spent)) { + fprintf(stderr, + _("%s: error updating shadow passwd dbm entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } else + sp_dbm_added++; + endspent(); + } +#endif +#endif /* SHADOWPWD */ + + /* + * Do any group file updates for this user. + */ + + if (do_grp_update) + grp_update(); +} + +/* + * create_home - create the user's home directory + * + * create_home() creates the user's home directory if it does not + * already exist. It will be created mode 755 owned by the user + * with the user's default group. + */ + +static void +create_home(void) +{ + if (access(user_home, F_OK)) { + /* XXX - create missing parent directories. --marekm */ + if (mkdir (user_home, 0)) { + fprintf(stderr, _("%s: cannot create directory %s\n"), + Prog, user_home); + fail_exit(E_HOMEDIR); + } + chown (user_home, user_id, user_gid); +#if 1 + chmod(user_home, 0777 & ~getdef_num("UMASK", 077)); +#else + chmod (user_home, 0755); +#endif + home_added++; + } +} + +/* + * main - useradd command + */ + +int +main(int argc, char **argv) +{ + /* + * Get my name so that I can use it to report errors. + */ + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + +#ifdef SHADOWPWD + is_shadow_pwd = spw_file_present(); +#endif +#ifdef SHADOWGRP + is_shadow_grp = sgr_file_present(); +#endif + + /* + * The open routines for the NDBM files don't use read-write + * as the mode, so we have to clue them in. + */ + +#ifdef NDBM + pw_dbm_mode = O_RDWR; +#ifdef SHADOWPWD + sp_dbm_mode = O_RDWR; +#endif + gr_dbm_mode = O_RDWR; +#ifdef SHADOWGRP + sg_dbm_mode = O_RDWR; +#endif +#endif + get_defaults(); + + process_flags(argc, argv); + + /* + * See if we are messing with the defaults file, or creating + * a new user. + */ + + if (Dflg) { + if (gflg || bflg || fflg || eflg || sflg) + exit (set_defaults () ? 1:0); + + show_defaults(); + exit(E_SUCCESS); + } + + /* + * Start with a quick check to see if the user exists. + */ + + if (getpwnam(user_name)) { + fprintf(stderr, _("%s: user %s exists\n"), Prog, user_name); + exit(E_NAME_IN_USE); + } + + /* + * Do the hard stuff - open the files, create the user entries, + * create the home directory, then close and update the files. + */ + + open_files (); + + usr_update (); + + if (mflg) { + create_home (); + copy_tree (def_template, user_home, user_id, user_gid); + } else if (getdef_str("CREATE_HOME")) { + /* + * RedHat added the CREATE_HOME option in login.defs in their + * version of shadow-utils (which makes -m the default, with + * new -M option to turn it off). Unfortunately, this + * changes the way useradd works (it can be run by scripts + * expecting some standard behaviour), compared to other + * Unices and other Linux distributions, and also adds a lot + * of confusion :-(. + * So we now recognize CREATE_HOME and give a warning here + * (better than "configuration error ... notify administrator" + * errors in every program that reads /etc/login.defs). -MM + */ + fprintf(stderr, + _("%s: warning: CREATE_HOME not supported, please use -m instead.\n"), + Prog); + } + + close_files (); + + exit(E_SUCCESS); + /*NOTREACHED*/ +} diff --git a/current/src/userdel.c b/current/src/userdel.c new file mode 100644 index 00000000..7637a4f1 --- /dev/null +++ b/current/src/userdel.c @@ -0,0 +1,846 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: userdel.c,v 1.17 2000/09/02 18:40:44 marekm Exp $") + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" +#include "getdef.h" +#include "pwauth.h" + +/* + * exit status values + */ +#define E_SUCCESS 0 +#define E_PW_UPDATE 1 /* can't update password file */ +#define E_USAGE 2 /* bad command syntax */ +#define E_NOTFOUND 6 /* specified user doesn't exist */ +#define E_USER_BUSY 8 /* user currently logged in */ +#define E_GRP_UPDATE 10 /* can't update group file */ +#define E_HOMEDIR 12 /* can't remove home directory */ + +static char *user_name; +static uid_t user_id; +static char *user_home; + +static char *Prog; +static int fflg = 0, rflg = 0; + +#ifdef NDBM +extern int pw_dbm_mode; +#ifdef SHADOWPWD +extern int sp_dbm_mode; +#endif +extern int gr_dbm_mode; +#ifdef SHADOWGRP +extern int sg_dbm_mode; +#endif +#endif + +#include "groupio.h" +#include "pwio.h" + +#ifdef SHADOWPWD +#include "shadowio.h" +#endif + +#ifdef HAVE_TCFS +#include +#include "tcfsio.h" +#endif + +#ifdef SHADOWGRP +#include "sgroupio.h" +#endif + +#ifdef SHADOWPWD +static int is_shadow_pwd; +#endif +#ifdef SHADOWGRP +static int is_shadow_grp; +#endif + +extern int optind; + +/* local function prototypes */ +static void usage(void); +static void update_groups(void); +static void close_files(void); +static void fail_exit(int); +static void open_files(void); +static void update_user(void); +static void user_busy(const char *, uid_t); +static void user_cancel(const char *); +#ifdef EXTRA_CHECK_HOME_DIR +static int path_prefix(const char *, const char *); +#endif +static int is_owner(uid_t, const char *); +#ifndef NO_REMOVE_MAILBOX +static void remove_mailbox(void); +#endif + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, _("usage: %s [-r] name\n"), Prog); + exit(E_USAGE); +} + +/* + * update_groups - delete user from secondary group set + * + * update_groups() takes the user name that was given and searches + * the group files for membership in any group. + * + * we also check to see if they have any groups they own (the same + * name is their user name) and delete them too (only if USERGROUPS_ENAB + * is enabled). + */ + +static void +update_groups(void) +{ + const struct group *grp; + struct group *ngrp; +#ifdef SHADOWGRP + const struct sgrp *sgrp; + struct sgrp *nsgrp; +#endif /* SHADOWGRP */ + + /* + * Scan through the entire group file looking for the groups that + * the user is a member of. + */ + + for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) { + + /* + * See if the user specified this group as one of their + * concurrent groups. + */ + + if (!is_on_list(grp->gr_mem, user_name)) + continue; + + /* + * Delete the username from the list of group members and + * update the group entry to reflect the change. + */ + + ngrp = __gr_dup(grp); + if (!ngrp) { + exit(13); /* XXX */ + } + ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); + if (!gr_update(ngrp)) + fprintf(stderr, _("%s: error updating group entry\n"), + Prog); + + /* + * Update the DBM group file with the new entry as well. + */ + +#ifdef NDBM + if (!gr_dbm_update(ngrp)) + fprintf(stderr, + _("%s: cannot update dbm group entry\n"), + Prog); +#endif /* NDBM */ + SYSLOG((LOG_INFO, "delete `%s' from group `%s'\n", + user_name, ngrp->gr_name)); + } +#ifdef NDBM + endgrent(); +#endif + /* + * we've removed their name from all the groups above, so + * now if they have a group with the same name as their + * user name, with no members, we delete it. + */ + + grp = getgrnam(user_name); + if (grp && getdef_bool("USERGROUPS_ENAB") && (grp->gr_mem[0] == NULL)) { + + gr_remove(grp->gr_name); + + /* + * Update the DBM group file with the new entry as well. + */ + +#ifdef NDBM + if (!gr_dbm_remove(grp)) + fprintf(stderr, + _("%s: cannot remove dbm group entry\n"), + Prog); +#endif + SYSLOG((LOG_INFO, "removed group `%s' owned by `%s'\n", + grp->gr_name, user_name)); + } +#ifdef NDBM + endgrent (); +#endif +#ifdef SHADOWGRP + if (!is_shadow_grp) + return; + + /* + * Scan through the entire shadow group file looking for the groups + * that the user is a member of. Both the administrative list and + * the ordinary membership list is checked. + */ + + for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) { + int was_member, was_admin; + + /* + * See if the user specified this group as one of their + * concurrent groups. + */ + + was_member = is_on_list(sgrp->sg_mem, user_name); + was_admin = is_on_list(sgrp->sg_adm, user_name); + + if (!was_member && !was_admin) + continue; + + nsgrp = __sgr_dup(sgrp); + if (!nsgrp) { + exit(13); /* XXX */ + } + + if (was_member) + nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); + + if (was_admin) + nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); + + if (!sgr_update(nsgrp)) + fprintf(stderr, _("%s: error updating group entry\n"), + Prog); +#ifdef NDBM + /* + * Update the DBM group file with the new entry as well. + */ + + if (!sg_dbm_update(nsgrp)) + fprintf(stderr, + _("%s: cannot update dbm group entry\n"), + Prog); +#endif /* NDBM */ + SYSLOG((LOG_INFO, "delete `%s' from shadow group `%s'\n", + user_name, nsgrp->sg_name)); + } +#ifdef NDBM + endsgent (); +#endif /* NDBM */ +#endif /* SHADOWGRP */ +} + +/* + * close_files - close all of the files that were opened + * + * close_files() closes all of the files that were opened for this + * new user. This causes any modified entries to be written out. + */ + +static void +close_files(void) +{ + if (!pw_close()) + fprintf(stderr, _("%s: cannot rewrite password file\n"), Prog); +#ifdef SHADOWPWD + if (is_shadow_pwd && !spw_close()) + fprintf(stderr, _("%s: cannot rewrite shadow password file\n"), + Prog); +#endif +#ifdef HAVE_TCFS + if (!tcfs_close()) + fprintf(stderr, _("%s: cannot rewrite TCFS key file\n"), Prog); +#endif + if (! gr_close ()) + fprintf(stderr, _("%s: cannot rewrite group file\n"), + Prog); + + (void) gr_unlock (); +#ifdef SHADOWGRP + if (is_shadow_grp && !sgr_close()) + fprintf(stderr, _("%s: cannot rewrite shadow group file\n"), + Prog); + + if (is_shadow_grp) + (void) sgr_unlock(); +#endif +#ifdef SHADOWPWD + if (is_shadow_pwd) + (void) spw_unlock(); +#endif +#ifdef HAVE_TCFS + (void) tcfs_unlock(); +#endif + (void) pw_unlock(); +} + +/* + * fail_exit - exit with a failure code after unlocking the files + */ + +static void +fail_exit(int code) +{ + (void) pw_unlock (); + (void) gr_unlock (); +#ifdef SHADOWPWD + if (is_shadow_pwd) + spw_unlock (); +#endif +#ifdef SHADOWGRP + if (is_shadow_grp) + sgr_unlock (); +#endif +#ifdef HAVE_TCFS + (void) tcfs_unlock (); +#endif + + exit(code); +} + +/* + * open_files - lock and open the password files + * + * open_files() opens the two password files. + */ + +static void +open_files(void) +{ + if (!pw_lock()) { + fprintf(stderr, _("%s: unable to lock password file\n"), Prog); + exit(E_PW_UPDATE); + } + if (! pw_open (O_RDWR)) { + fprintf(stderr, _("%s: unable to open password file\n"), Prog); + fail_exit(E_PW_UPDATE); + } +#ifdef SHADOWPWD + if (is_shadow_pwd && ! spw_lock ()) { + fprintf(stderr, _("%s: cannot lock shadow password file\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + if (is_shadow_pwd && ! spw_open (O_RDWR)) { + fprintf(stderr, _("%s: cannot open shadow password file\n"), + Prog); + fail_exit(E_PW_UPDATE); + } +#endif +#ifdef HAVE_TCFS + if (!tcfs_lock()) { + fprintf(stderr, _("%s: cannot lock TCFS key file\n"), Prog); + fail_exit(E_PW_UPDATE); + } + if (!tcfs_open(O_RDWR)) { + fprintf(stderr, _("%s: cannot open TCFS key file\n"), Prog); + fail_exit(E_PW_UPDATE); + } +#endif + if (! gr_lock ()) { + fprintf(stderr, _("%s: unable to lock group file\n"), Prog); + fail_exit(E_GRP_UPDATE); + } + if (! gr_open (O_RDWR)) { + fprintf(stderr, _("%s: cannot open group file\n"), Prog); + fail_exit(E_GRP_UPDATE); + } +#ifdef SHADOWGRP + if (is_shadow_grp && ! sgr_lock ()) { + fprintf(stderr, _("%s: unable to lock shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } + if (is_shadow_grp && ! sgr_open (O_RDWR)) { + fprintf(stderr, _("%s: cannot open shadow group file\n"), + Prog); + fail_exit(E_GRP_UPDATE); + } +#endif +} + +/* + * update_user - delete the user entries + * + * update_user() deletes the password file entries for this user + * and will update the group entries as required. + */ + +static void +update_user(void) +{ +#if defined(AUTH_METHODS) || defined(NDBM) + struct passwd *pwd; +#endif +#ifdef AUTH_METHODS +#ifdef SHADOWPWD + struct spwd *spwd; + + if (is_shadow_pwd && (spwd = spw_locate (user_name)) && + spwd->sp_pwdp[0] == '@') { + if (pw_auth (spwd->sp_pwdp + 1, user_name, PW_DELETE, (char *) 0)) { + SYSLOG((LOG_ERR, + "failed deleting auth `%s' for user `%s'\n", + spwd->sp_pwdp + 1, user_name)); + fprintf(stderr, + _("%s: error deleting authentication\n"), + Prog); + } else { + SYSLOG((LOG_INFO, + "delete auth `%s' for user `%s'\n", + spwd->sp_pwdp + 1, user_name)); + } + } +#endif /* SHADOWPWD */ + if ((pwd = pw_locate(user_name)) && pwd->pw_passwd[0] == '@') { + if (pw_auth(pwd->pw_passwd + 1, user_name, PW_DELETE, (char *) 0)) { + SYSLOG((LOG_ERR, + "failed deleting auth `%s' for user `%s'\n", + pwd->pw_passwd + 1, user_name)); + fprintf(stderr, + _("%s: error deleting authentication\n"), + Prog); + } else { + SYSLOG((LOG_INFO, "delete auth `%s' for user `%s'\n", + pwd->pw_passwd + 1, user_name); + } + } +#endif /* AUTH_METHODS */ + if (!pw_remove(user_name)) + fprintf(stderr, _("%s: error deleting password entry\n"), Prog); +#ifdef SHADOWPWD + if (is_shadow_pwd && ! spw_remove (user_name)) + fprintf(stderr, _("%s: error deleting shadow password entry\n"), + Prog); +#endif +#ifdef HAVE_TCFS + if (tcfs_locate (user_name)) { + if (!tcfs_remove (user_name)) { + SYSLOG((LOG_ERR, + "failed deleting TCFS entry for user `%s'\n", + user_name)); + fprintf(stderr, _("%s: error deleting TCFS entry\n"), + Prog); + } else { + SYSLOG((LOG_INFO, + "delete TCFS entry for user `%s'\n", + user_name)); + } + } +#endif /* HAVE_TCFS */ +#ifdef NDBM + if (pw_dbm_present()) { + if ((pwd = getpwnam (user_name)) && ! pw_dbm_remove (pwd)) + fprintf(stderr, + _("%s: error deleting password dbm entry\n"), + Prog); + } + + /* + * If the user's UID is a duplicate the duplicated entry needs + * to be updated so that a UID match can be found in the DBM + * files. + */ + + for (pw_rewind (), pwd = pw_next ();pwd;pwd = pw_next ()) { + if (pwd->pw_uid == user_id) { + pw_dbm_update (pwd); + break; + } + } +#ifdef SHADOWPWD + if (is_shadow_pwd && sp_dbm_present() && !sp_dbm_remove(user_name)) + fprintf(stderr, + _("%s: error deleting shadow passwd dbm entry\n"), + Prog); + + endspent (); +#endif + endpwent (); +#endif /* NDBM */ + SYSLOG((LOG_INFO, "delete user `%s'\n", user_name)); +} + +/* + * user_busy - see if user is logged in. + * + * XXX - should probably check if there are any processes owned + * by this user. Also, I think this check should be in usermod + * as well (at least when changing username or uid). --marekm + */ + +static void +user_busy(const char *name, uid_t uid) +{ + struct utmp *utent; + + /* + * We see if the user is logged in by looking for the user name + * in the utmp file. + */ + + setutent (); + + while ((utent = getutent ())) { +#ifdef USER_PROCESS + if (utent->ut_type != USER_PROCESS) + continue; +#else + if (utent->ut_user[0] == '\0') + continue; +#endif + if (strncmp(utent->ut_user, name, sizeof utent->ut_user)) + continue; + + fprintf(stderr, _("%s: user %s is currently logged in\n"), + Prog, name); + exit(E_USER_BUSY); + } +} + +/* + * user_cancel - cancel cron and at jobs + * + * user_cancel removes the crontab and any at jobs for a user + */ + +/* + * We used to have all this stuff hardcoded here, but now + * we just run an external script - it may need to do other + * things as well (like removing print jobs) and we may not + * want to recompile userdel too often. Below is a sample + * script (should work at least on Debian 1.1). --marekm +========== +#! /bin/sh + +# Check for the required argument. +if [ $# != 1 ]; then + echo Usage: $0 username + exit 1 +fi + +# Remove cron jobs. +crontab -r -u $1 + +# Remove at jobs. XXX - will remove any jobs owned by the +# same UID, even if it was shared by a different username. +# at really should store the username somewhere, and atrm +# should support an option to remove all jobs owned by the +# specified user - for now we have to do this ugly hack... +find /var/spool/cron/atjobs -name "[^.]*" -type f -user $1 -exec rm {} \; + +# Remove print jobs. +lprm $1 + +# All done. +exit 0 +========== + */ + +static void +user_cancel(const char *user) +{ + char *cmd; + int pid, wpid; + int status; + + if (!(cmd = getdef_str("USERDEL_CMD"))) + return; + + pid = fork(); + if (pid == 0) { + execl(cmd, cmd, user, (char *) 0); + if (errno == ENOENT) { + perror(cmd); + _exit(127); + } else { + perror(cmd); + _exit(126); + } + } else if (pid == -1) { + perror("fork"); + return; + } + + do { + wpid = wait(&status); + } while (wpid != pid && wpid != -1); +} + +#ifdef EXTRA_CHECK_HOME_DIR +static int +path_prefix(const char *s1, const char *s2) +{ + return (strncmp(s2, s1, strlen(s1)) == 0); +} +#endif + +static int +is_owner(uid_t uid, const char *path) +{ + struct stat st; + + if (stat(path, &st)) + return -1; + return (st.st_uid == uid); +} + +#ifndef NO_REMOVE_MAILBOX +static void +remove_mailbox(void) +{ + const char *maildir; + char mailfile[1024]; + int i; + + maildir = getdef_str("MAIL_DIR"); +#ifdef MAIL_SPOOL_DIR + if (!maildir && !getdef_str("MAIL_FILE")) + maildir = MAIL_SPOOL_DIR; +#endif + if (!maildir) + return; + + snprintf(mailfile, sizeof mailfile, "%s/%s", maildir, user_name); + if (fflg) { + unlink(mailfile); /* always remove, ignore errors */ + return; + } + i = is_owner(user_id, mailfile); + if (i == 0) { + fprintf(stderr, + _("%s: warning: %s not owned by %s, not removing\n"), + Prog, mailfile, user_name); + return; + } else if (i == -1) + return; /* mailbox doesn't exist */ + if (unlink(mailfile)) { + fprintf(stderr, _("%s: warning: can't remove "), Prog); + perror(mailfile); + } +} +#endif + +/* + * main - userdel command + */ + +int +main(int argc, char **argv) +{ + struct passwd *pwd; + int arg; + int errors = 0; + + /* + * Get my name so that I can use it to report errors. + */ + + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + +#ifdef SHADOWPWD + is_shadow_pwd = spw_file_present(); +#endif + +#ifdef SHADOWGRP + is_shadow_grp = sgr_file_present(); +#endif + + /* + * The open routines for the DBM files don't use read-write + * as the mode, so we have to clue them in. + */ + +#ifdef NDBM + pw_dbm_mode = O_RDWR; +#ifdef SHADOWPWD + sp_dbm_mode = O_RDWR; +#endif + gr_dbm_mode = O_RDWR; +#ifdef SHADOWGRP + sg_dbm_mode = O_RDWR; +#endif +#endif + while ((arg = getopt (argc, argv, "fr")) != EOF) { + switch (arg) { + case 'f': /* force remove even if not owned by user */ + fflg++; + break; + case 'r': /* remove home dir and mailbox */ + rflg++; + break; + default: + usage(); + } + } + + if (optind + 1 != argc) + usage (); + + /* + * Start with a quick check to see if the user exists. + */ + + user_name = argv[argc - 1]; + + if (! (pwd = getpwnam (user_name))) { + fprintf(stderr, _("%s: user %s does not exist\n"), + Prog, user_name); + exit(E_NOTFOUND); + } +#ifdef USE_NIS + + /* + * Now make sure it isn't an NIS user. + */ + + if (__ispwNIS ()) { + char *nis_domain; + char *nis_master; + + fprintf(stderr, _("%s: user %s is a NIS user\n"), + Prog, user_name); + + if (! yp_get_default_domain (&nis_domain) && + ! yp_master (nis_domain, "passwd.byname", + &nis_master)) { + fprintf(stderr, _("%s: %s is the NIS master\n"), + Prog, nis_master); + } + exit(E_NOTFOUND); + } +#endif + user_id = pwd->pw_uid; + user_home = xstrdup(pwd->pw_dir); + + /* + * Check to make certain the user isn't logged in. + */ + + user_busy (user_name, user_id); + + /* + * Do the hard stuff - open the files, create the user entries, + * create the home directory, then close and update the files. + */ + + open_files (); + + update_user (); + update_groups (); + +#ifndef NO_REMOVE_MAILBOX + if (rflg) + remove_mailbox(); +#endif + + if (rflg && !fflg && !is_owner(user_id, user_home)) { + fprintf(stderr, _("%s: %s not owned by %s, not removing\n"), + Prog, user_home, user_name); + rflg = 0; + errors++; + } + +/* This may be slow, the above should be good enough. */ +#ifdef EXTRA_CHECK_HOME_DIR + if (rflg && !fflg) { + /* + * For safety, refuse to remove the home directory + * if it would result in removing some other user's + * home directory. Still not perfect so be careful, + * but should prevent accidents if someone has /home + * or / as home directory... --marekm + */ + setpwent(); + while ((pwd = getpwent())) { + if (strcmp(pwd->pw_name, user_name) == 0) + continue; + + if (path_prefix(user_home, pwd->pw_dir)) { + fprintf(stderr, + _("%s: not removing directory %s (would remove home of user %s)\n"), + Prog, user_home, pwd->pw_name); + + rflg = 0; + errors++; + break; + } + } + } +#endif + + if (rflg) { + if (remove_tree(user_home) || rmdir(user_home)) { + fprintf(stderr, _("%s: error removing directory %s\n"), + Prog, user_home); + + errors++; + } + } + + /* + * Cancel any crontabs or at jobs. Have to do this before we + * remove the entry from /etc/passwd. + */ + + user_cancel(user_name); + + close_files (); + + exit(errors ? E_HOMEDIR : E_SUCCESS); + /*NOTREACHED*/ +} diff --git a/current/src/usermod.c b/current/src/usermod.c new file mode 100644 index 00000000..447e3c64 --- /dev/null +++ b/current/src/usermod.c @@ -0,0 +1,1705 @@ +/* + * Copyright 1991 - 1994, Julianne Frances Haugh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Julianne F. Haugh nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: usermod.c,v 1.19 2000/09/02 18:40:44 marekm Exp $") + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "defines.h" +#include "chkname.h" +#include "faillog.h" +#if HAVE_LASTLOG_H +#include +#else +#include "lastlog_.h" +#endif +#include "pwauth.h" +#include "getdef.h" + +/* + * exit status values + * for E_GRP_UPDATE and E_NOSPACE (not used yet), other update requests + * will be implemented (as documented in the Solaris 2.x man page). + */ +#define E_SUCCESS 0 /* success */ +#define E_PW_UPDATE 1 /* can't update password file */ +#define E_USAGE 2 /* invalid command syntax */ +#define E_BAD_ARG 3 /* invalid argument to option */ +#define E_UID_IN_USE 4 /* uid already in use (and no -o) */ +/* #define E_BAD_PWFILE 5 */ /* passwd file contains errors */ +#define E_NOTFOUND 6 /* specified user/group doesn't exist */ +#define E_USER_BUSY 8 /* user to modify is logged in */ +#define E_NAME_IN_USE 9 /* username already in use */ +#define E_GRP_UPDATE 10 /* can't update group file */ +/* #define E_NOSPACE 11 */ /* insufficient space to move home dir */ +#define E_HOMEDIR 12 /* unable to complete home dir move */ + +#define VALID(s) (strcspn (s, ":\n") == strlen (s)) + +static char *user_name; +static char *user_newname; +static char *user_pass; +static uid_t user_id; +static uid_t user_newid; +static gid_t user_gid; +static gid_t user_newgid; +static char *user_comment; +static char *user_home; +static char *user_newhome; +static char *user_shell; +#ifdef SHADOWPWD +static long user_expire; +static long user_inactive; +#endif +static char *user_groups[NGROUPS_MAX+1]; /* NULL-terminated list */ + +static char *Prog; + +#ifdef AUTH_METHODS +static char *auth_arg; +static char user_auth[BUFSIZ]; +static int Aflg = 0; /* specify user defined authentication method */ +#else +#define Aflg 0 +#endif + +static int + uflg = 0, /* specify new user ID */ + oflg = 0, /* permit non-unique user ID to be specified with -u */ + gflg = 0, /* new primary group ID */ + Gflg = 0, /* new secondary group set */ + dflg = 0, /* new home directory */ + sflg = 0, /* new shell program */ + cflg = 0, /* new comment (GECOS) field */ + mflg = 0, /* create user's home directory if it doesn't exist */ +#ifdef SHADOWPWD + fflg = 0, /* days until account with expired password is locked */ + eflg = 0, /* days since 1970-01-01 when account becomes expired */ +#endif + Lflg = 0, /* lock the password */ + Uflg = 0, /* unlock the password */ + pflg = 0, /* new encrypted password */ + lflg = 0; /* new user name */ + +#ifdef NDBM +extern int pw_dbm_mode; +#ifdef SHADOWPWD +extern int sp_dbm_mode; +#endif +extern int gr_dbm_mode; +#ifdef SHADOWGRP +extern int sg_dbm_mode; +#endif +#endif + +#ifdef SHADOWPWD +static int is_shadow_pwd; +#endif +#ifdef SHADOWGRP +static int is_shadow_grp; +#endif + +#include "groupio.h" + +#ifdef SHADOWGRP +#include "sgroupio.h" +#endif + +#include "pwio.h" + +#ifdef SHADOWPWD +#include "shadowio.h" +#endif + +extern char *optarg; +extern int optind; + +/* local function prototypes */ +static int get_groups(char *); +static void usage(void); +static void new_pwent(struct passwd *); +#ifdef SHADOWPWD +static void new_spent(struct spwd *); +#endif +static void fail_exit(int); +static int update_group(void); +#ifdef SHADOWGRP +static int update_gshadow(void); +#endif +static int grp_update(void); +#ifdef AUTH_METHODS +static char *get_password(const char *); +static void split_auths(char *, char **); +static void update_auths(const char *, const char *, char *); +static void add_auths(const char *, const char *, char *); +static void delete_auths(const char *, const char *, char *); +static void convert_auth(char *, const char *, const char *); +static int valid_auth(const char *); +#endif +static long get_number(const char *); +static void process_flags(int, char **); +static void close_files(void); +static void open_files(void); +static void usr_update(void); +static void move_home(void); +static void update_files(void); +#ifndef NO_MOVE_MAILBOX +static void move_mailbox(void); +#endif + +/* Had to move this over from useradd.c since we have groups named + * "56k-family"... ergh. + * --Pac. */ +static struct group * +getgr_nam_gid(const char *name) +{ + gid_t gid; + char *ep; + + gid = strtol(name, &ep, 10); + if (*name != '\0' && *ep == '\0') /* valid numeric gid */ + return getgrgid(gid); + + return getgrnam(name); +} + + +/* + * get_groups - convert a list of group names to an array of group IDs + * + * get_groups() takes a comma-separated list of group names and + * converts it to a NULL-terminated array. Any unknown group + * names are reported as errors. + */ + +static int +get_groups(char *list) +{ + char *cp; + const struct group *grp; + int errors = 0; + int ngroups = 0; + + /* + * Initialize the list to be empty + */ + + user_groups[0] = (char *) 0; + + if (! *list) + return 0; + + /* + * So long as there is some data to be converted, strip off + * each name and look it up. A mix of numerical and string + * values for group identifiers is permitted. + */ + + do { + /* + * Strip off a single name from the list + */ + if ((cp = strchr (list, ','))) + *cp++ = '\0'; + + /* + * Names starting with digits are treated as numerical + * GID values, otherwise the string is looked up as is. + */ + grp = getgr_nam_gid(list); + + /* + * There must be a match, either by GID value or by + * string name. + */ + if (!grp) { + fprintf(stderr, _("%s: unknown group %s\n"), + Prog, list); + errors++; + } + list = cp; + + /* + * If the group doesn't exist, don't dump core... + * Instead, try the next one. --marekm + */ + if (! grp) + continue; + +#ifdef USE_NIS + /* + * Don't add this group if they are an NIS group. Tell + * the user to go to the server for this group. + */ + + if (__isgrNIS ()) { + fprintf(stderr, _("%s: group `%s' is a NIS group.\n"), + Prog, grp->gr_name); + continue; + } +#endif + + if (ngroups == NGROUPS_MAX) { + fprintf(stderr, + _("%s: too many groups specified (max %d).\n"), + Prog, ngroups); + break; + } + + /* + * Add the group name to the user's list of groups. + */ + + user_groups[ngroups++] = xstrdup(grp->gr_name); + } while (list); + + user_groups[ngroups] = (char *) 0; + + /* + * Any errors in finding group names are fatal + */ + + if (errors) + return -1; + + return 0; +} + +/* + * usage - display usage message and exit + */ + +static void +usage(void) +{ + fprintf(stderr, + _("usage: %s\t[-u uid [-o]] [-g group] [-G group,...] \n"), + Prog); + fprintf(stderr, + _("\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n")); + fprintf(stderr, "\t\t"); +#ifdef SHADOWPWD + fprintf(stderr, _("[-f inactive] [-e expire ] ")); +#endif +#ifdef AUTH_METHODS + fprintf(stderr, _("[-A {DEFAULT|program},... ] ")); +#endif + fprintf(stderr, _("[-p passwd] [-L|-U] name\n")); + exit(E_USAGE); +} + +/* update encrypted password string (for both shadow and non-shadow passwords) */ + +static char * +new_pw_passwd(char *pw_pass, const char *pw_name) +{ + if (Lflg && pw_pass[0] != '!') { + char *buf = xmalloc(strlen(pw_pass) + 2); + + SYSLOG((LOG_INFO, "lock user `%s' password\n", + pw_name)); + strcpy(buf, "!"); + strcat(buf, pw_pass); + pw_pass = buf; + } else if (Uflg && pw_pass[0] == '!') { + char *s; + + SYSLOG((LOG_INFO, "unlock user `%s' password\n", + pw_name)); + s = pw_pass; + while (*s) { + *s = *(s + 1); + s++; + } + } else if (pflg) { + SYSLOG((LOG_INFO, "change user `%s' password\n", + pw_name)); + pw_pass = xstrdup(user_pass); + } + return pw_pass; +} + +/* + * new_pwent - initialize the values in a password file entry + * + * new_pwent() takes all of the values that have been entered and + * fills in a (struct passwd) with them. + */ + +static void +new_pwent(struct passwd *pwent) +{ + if (lflg) { + SYSLOG((LOG_INFO, "change user name `%s' to `%s'\n", + pwent->pw_name, user_newname)); + pwent->pw_name = xstrdup (user_newname); + } + +#ifdef SHADOWPWD + if (!is_shadow_pwd) +#endif + pwent->pw_passwd = new_pw_passwd(pwent->pw_passwd, pwent->pw_name); + + if (uflg) { + SYSLOG((LOG_INFO, "change user `%s' UID from `%d' to `%d'\n", + pwent->pw_name, pwent->pw_uid, user_newid)); + pwent->pw_uid = user_newid; + } + if (gflg) { + SYSLOG((LOG_INFO, "change user `%s' GID from `%d' to `%d'\n", + pwent->pw_name, pwent->pw_gid, user_newgid)); + pwent->pw_gid = user_newgid; + } + if (cflg) + pwent->pw_gecos = user_comment; + + if (dflg) { + SYSLOG((LOG_INFO, "change user `%s' home from `%s' to `%s'\n", + pwent->pw_name, pwent->pw_dir, user_newhome)); + pwent->pw_dir = user_newhome; + } + if (sflg) { + SYSLOG((LOG_INFO, "change user `%s' shell from `%s' to `%s'\n", + pwent->pw_name, pwent->pw_shell, user_shell)); + pwent->pw_shell = user_shell; + } +} + +#ifdef SHADOWPWD +/* + * new_spent - initialize the values in a shadow password file entry + * + * new_spent() takes all of the values that have been entered and + * fills in a (struct spwd) with them. + */ + +static void +new_spent(struct spwd *spent) +{ + if (lflg) + spent->sp_namp = xstrdup (user_newname); + + if (fflg) { + SYSLOG((LOG_INFO, + "change user `%s' inactive from `%ld' to `%ld'\n", + spent->sp_namp, spent->sp_inact, user_inactive)); + spent->sp_inact = user_inactive; + } + if (eflg) { + /* XXX - dates might be better than numbers of days. --marekm */ + SYSLOG((LOG_INFO, + "change user `%s' expiration from `%ld' to `%ld'\n", + spent->sp_namp, spent->sp_expire, user_expire)); + spent->sp_expire = user_expire; + } + spent->sp_pwdp = new_pw_passwd(spent->sp_pwdp, spent->sp_namp); +} +#endif /* SHADOWPWD */ + +/* + * fail_exit - exit with an error code after unlocking files + */ + +static void +fail_exit(int code) +{ + (void) gr_unlock (); +#ifdef SHADOWGRP + if (is_shadow_grp) + sgr_unlock (); +#endif +#ifdef SHADOWPWD + if (is_shadow_pwd) + spw_unlock (); +#endif + (void) pw_unlock (); + exit(code); +} + + +static int +update_group(void) +{ + int is_member; + int was_member; + int changed; + const struct group *grp; + struct group *ngrp; + + /* + * Lock and open the group file. This will load all of the group + * entries. + */ + if (! gr_lock ()) { + fprintf(stderr, _("%s: error locking group file\n"), Prog); + SYSLOG((LOG_ERR, "error locking group file")); + return -1; + } + if (! gr_open (O_RDWR)) { + fprintf(stderr, _("%s: error opening group file\n"), Prog); + SYSLOG((LOG_ERR, "error opening group file")); + gr_unlock(); + return -1; + } + + changed = 0; + + /* + * Scan through the entire group file looking for the groups that + * the user is a member of. + */ + while ((grp = gr_next())) { + + /* + * See if the user specified this group as one of their + * concurrent groups. + */ + was_member = is_on_list(grp->gr_mem, user_name); + is_member = Gflg && is_on_list(user_groups, grp->gr_name); + + if (!was_member && !is_member) + continue; + + ngrp = __gr_dup(grp); + if (!ngrp) { + fprintf(stderr, + _("%s: out of memory in update_group\n"), + Prog); + gr_unlock(); + return -1; + } + + if (was_member && (!Gflg || is_member)) { + if (lflg) { + ngrp->gr_mem = del_list(ngrp->gr_mem, + user_name); + ngrp->gr_mem = add_list(ngrp->gr_mem, + user_newname); + changed = 1; + SYSLOG((LOG_INFO, + "change `%s' to `%s' in group `%s'\n", + user_name, user_newname, + ngrp->gr_name)); + } + } else if (was_member && Gflg && !is_member) { + ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); + changed = 1; + SYSLOG((LOG_INFO, "delete `%s' from group `%s'\n", + user_name, ngrp->gr_name)); + } else if (!was_member && Gflg && is_member) { + ngrp->gr_mem = add_list (ngrp->gr_mem, + lflg ? user_newname:user_name); + changed = 1; + SYSLOG((LOG_INFO, "add `%s' to group `%s'\n", + lflg ? user_newname:user_name, ngrp->gr_name)); + } + if (!changed) + continue; + + changed = 0; + if (! gr_update (ngrp)) { + fprintf(stderr, _("%s: error adding new group entry\n"), + Prog); + SYSLOG((LOG_ERR, "error adding group entry")); + gr_unlock(); + return -1; + } +#ifdef NDBM + /* + * Update the DBM group file with the new entry as well. + */ + if (! gr_dbm_update (ngrp)) { + fprintf(stderr, + _("%s: cannot add new dbm group entry\n"), + Prog); + SYSLOG((LOG_ERR, "error adding dbm group entry")); + gr_unlock(); + return -1; + } +#endif /* NDBM */ + } +#ifdef NDBM + endgrent (); +#endif /* NDBM */ + if (!gr_close()) { + fprintf(stderr, _("%s: cannot rewrite group file\n"), + Prog); + gr_unlock(); + return -1; + } + gr_unlock(); + return 0; +} + +#ifdef SHADOWGRP +static int +update_gshadow(void) +{ + int is_member; + int was_member; + int was_admin; + int changed; + const struct sgrp *sgrp; + struct sgrp *nsgrp; + + if (!sgr_lock()) { + fprintf(stderr, _("%s: error locking shadow group file\n"), + Prog); + SYSLOG((LOG_ERR, "error locking shadow group file")); + return -1; + } + if (!sgr_open(O_RDWR)) { + fprintf(stderr, _("%s: error opening shadow group file\n"), + Prog); + SYSLOG((LOG_ERR, "error opening shadow group file")); + sgr_unlock(); + return -1; + } + + changed = 0; + + /* + * Scan through the entire shadow group file looking for the groups + * that the user is a member of. + */ + while ((sgrp = sgr_next())) { + + /* + * See if the user was a member of this group + */ + was_member = is_on_list(sgrp->sg_mem, user_name); + + /* + * See if the user was an administrator of this group + */ + was_admin = is_on_list(sgrp->sg_adm, user_name); + + /* + * See if the user specified this group as one of their + * concurrent groups. + */ + is_member = Gflg && is_on_list(user_groups, sgrp->sg_name); + + if (!was_member && !was_admin && !is_member) + continue; + + nsgrp = __sgr_dup(sgrp); + if (!nsgrp) { + fprintf(stderr, + _("%s: out of memory in update_gshadow\n"), + Prog); + sgr_unlock(); + return -1; + } + + if (was_admin && lflg) { + nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); + nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); + changed = 1; + SYSLOG((LOG_INFO, + "change admin `%s' to `%s' in shadow group `%s'\n", + user_name, user_newname, nsgrp->sg_name)); + } + if (was_member && (!Gflg || is_member)) { + if (lflg) { + nsgrp->sg_mem = del_list (nsgrp->sg_mem, + user_name); + nsgrp->sg_mem = add_list (nsgrp->sg_mem, + user_newname); + changed = 1; + SYSLOG((LOG_INFO, + "change `%s' to `%s' in shadow group `%s'\n", + user_name, user_newname, nsgrp->sg_name)); + } + } else if (was_member && Gflg && !is_member) { + nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); + changed = 1; + SYSLOG((LOG_INFO, + "delete `%s' from shadow group `%s'\n", + user_name, nsgrp->sg_name)); + } else if (!was_member && Gflg && is_member) { + nsgrp->sg_mem = add_list (nsgrp->sg_mem, + lflg ? user_newname:user_name); + changed = 1; + SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n", + lflg ? user_newname:user_name,nsgrp->sg_name)); + } + if (!changed) + continue; + + changed = 0; + + /* + * Update the group entry to reflect the changes. + */ + if (! sgr_update (nsgrp)) { + fprintf(stderr, + _("%s: error adding new group entry\n"), + Prog); + SYSLOG((LOG_ERR, "error adding shadow group entry\n")); + sgr_unlock(); + return -1; + } +#ifdef NDBM + /* + * Update the DBM group file with the new entry as well. + */ + if (! sg_dbm_update (nsgrp)) { + fprintf(stderr, + _("%s: cannot add new dbm group entry\n"), + Prog); + SYSLOG((LOG_ERR, + "error adding dbm shadow group entry\n")); + sgr_unlock(); + return -1; + } +#endif /* NDBM */ + } +#ifdef NDBM + endsgent (); +#endif /* NDBM */ + if (!sgr_close()) { + fprintf(stderr, _("%s: cannot rewrite shadow group file\n"), + Prog); + sgr_unlock(); + return -1; + } + sgr_unlock(); + return 0; +} +#endif /* SHADOWGRP */ + +/* + * grp_update - add user to secondary group set + * + * grp_update() takes the secondary group set given in user_groups + * and adds the user to each group given by that set. + */ + +static int +grp_update(void) +{ + int ret; + + ret = update_group(); +#ifdef SHADOWGRP + if (!ret && is_shadow_grp) + ret = update_gshadow(); +#endif + return ret; +} + +#ifdef AUTH_METHODS +/* + * get_password - locate encrypted password in authentication list + */ + +static char * +get_password(const char *list) +{ + char *cp, *end; + static char buf[257]; + + strcpy (buf, list); + for (cp = buf;cp;cp = end) { + if ((end = strchr (cp, ';'))) + *end++ = 0; + + if (cp[0] == '@') + continue; + + return cp; + } + return (char *) 0; +} + +/* + * split_auths - break up comma list into (char *) array + */ + +static void +split_auths(char *list, char **array) +{ + char *cp, *end; + int i = 0; + + for (cp = list;cp;cp = end) { + if ((end = strchr (cp, ';'))) + *end++ = '\0'; + + array[i++] = cp; + } + array[i] = 0; +} + +/* + * update_auths - find list of methods to update + */ + +static void +update_auths(const char *old, const char *new, char *update) +{ + char oldbuf[257], newbuf[257]; + char *oldv[32], *newv[32], *updatev[32]; + int i, j, k; + + strcpy (oldbuf, old); + split_auths (oldbuf, oldv); + + strcpy (newbuf, new); + split_auths (newbuf, newv); + + for (i = j = k = 0;oldv[i];i++) { + for (j = 0;newv[j];j++) + if (strcmp (oldv[i], newv[j]) != 0) + break; + + if (newv[j] != (char *) 0) + updatev[k++] = oldv[i]; + } + updatev[k] = 0; + + update[0] = '\0'; + for (i = 0;updatev[i];i++) { + if (i) + strcat (update, ";"); + + strcat (update, updatev[i]); + } +} + +/* + * add_auths - find list of methods to add + */ + +static void +add_auths(const char *old, const char *new, char *add) +{ + char oldbuf[257], newbuf[257]; + char *oldv[32], *newv[32], *addv[32]; + int i, j, k; + + strcpy (oldbuf, old); + split_auths (oldbuf, oldv); + + strcpy (newbuf, new); + split_auths (newbuf, newv); + + for (i = j = k = 0;newv[i];i++) { + for (j = 0;oldv[j];j++) + if (strcmp (oldv[i], newv[j]) == 0) + break; + + if (oldv[j] == (char *) 0) + addv[k++] = newv[i]; + } + addv[k] = 0; + + add[0] = '\0'; + for (i = 0;addv[i];i++) { + if (i) + strcat (add, ";"); + + strcat (add, addv[i]); + } +} + +/* + * delete_auths - find list of methods to delete + */ + +static void +delete_auths(const char *old, const char *new, char *remove) +{ + char oldbuf[257], newbuf[257]; + char *oldv[32], *newv[32], *removev[32]; + int i, j, k; + + strcpy (oldbuf, old); + split_auths (oldbuf, oldv); + + strcpy (newbuf, new); + split_auths (newbuf, newv); + + for (i = j = k = 0;oldv[i];i++) { + for (j = 0;newv[j];j++) + if (strcmp (oldv[i], newv[j]) == 0) + break; + + if (newv[j] == (char *) 0) + removev[k++] = oldv[i]; + } + removev[k] = 0; + + remove[0] = '\0'; + for (i = 0;removev[i];i++) { + if (i) + strcat (remove, ";"); + + strcat (remove, removev[i]); + } +} + +/* + * convert_auth - convert the argument list to a authentication list + */ + +static void +convert_auth(char *auths, const char *oldauths, const char *list) +{ + char *cp, *end; + char *old; + char buf[257]; + + /* + * Copy each method. DEFAULT is replaced by an encrypted string + * if one can be found in the current authentication list. + */ + + strcpy (buf, list); + auths[0] = '\0'; + for (cp = buf;cp;cp = end) { + if (auths[0]) + strcat (auths, ";"); + + if ((end = strchr (cp, ','))) + *end++ = '\0'; + + if (strcmp (cp, "DEFAULT") == 0) { + if ((old = get_password (oldauths))) + strcat (auths, old); + else + strcat (auths, "!"); + } else { + strcat (auths, "@"); + strcat (auths, cp); + } + } +} + +/* + * valid_auth - check authentication list for validity + */ + +static int +valid_auth(const char *methods) +{ + char *cp, *end; + char buf[257]; + int default_cnt = 0; + + /* + * Cursory checks, length and illegal characters + */ + + if ((int) strlen (methods) > 256) + return 0; + + if (! VALID (methods)) + return 0; + + /* + * Pick each method apart and check it. + */ + + strcpy (buf, methods); + for (cp = buf;cp;cp = end) { + if ((end = strchr (cp, ','))) + *end++ = '\0'; + + if (strcmp (cp, "DEFAULT") == 0) { + if (default_cnt++ > 0) + return 0; + } + } + return 1; +} +#endif + +static long +get_number(const char *cp) +{ + long val; + char *ep; + + val = strtol(cp, &ep, 10); + if (*cp != '\0' && *ep == '\0') /* valid number */ + return val; + + fprintf(stderr, _("%s: invalid numeric argument `%s'\n"), Prog, cp); + exit(E_BAD_ARG); +} + +/* + * process_flags - perform command line argument setting + * + * process_flags() interprets the command line arguments and sets + * the values that the user will be created with accordingly. The + * values are checked for sanity. + */ + +static void +process_flags(int argc, char **argv) +{ + const struct group *grp; + const struct passwd *pwd; +#ifdef SHADOWPWD + const struct spwd *spwd = NULL; +#endif + int anyflag = 0; + int arg; + + if (argc == 1 || argv[argc - 1][0] == '-') + usage (); + + if (! (pwd = getpwnam (argv[argc - 1]))) { + fprintf(stderr, _("%s: user %s does not exist\n"), + Prog, argv[argc - 1]); + exit(E_NOTFOUND); + } + user_name = argv[argc - 1]; + +#ifdef USE_NIS + + /* + * Now make sure it isn't an NIS user. + */ + + if (__ispwNIS ()) { + char *nis_domain; + char *nis_master; + + fprintf(stderr, _("%s: user %s is a NIS user\n"), + Prog, user_name); + + if (! yp_get_default_domain (&nis_domain) && + ! yp_master (nis_domain, "passwd.byname", + &nis_master)) { + fprintf(stderr, _("%s: %s is the NIS master\n"), + Prog, nis_master); + } + exit(E_NOTFOUND); + } +#endif + user_id = pwd->pw_uid; + user_gid = pwd->pw_gid; + user_comment = xstrdup(pwd->pw_gecos); + user_home = xstrdup(pwd->pw_dir); + user_shell = xstrdup(pwd->pw_shell); + +#ifdef SHADOWPWD + if (is_shadow_pwd && (spwd = getspnam (user_name))) { + user_expire = spwd->sp_expire; + user_inactive = spwd->sp_inact; + } +#endif +#ifdef SHADOWPWD +#define FLAGS "A:u:og:G:d:s:c:mf:e:l:p:LU" +#else +#define FLAGS "A:u:og:G:d:s:c:ml:p:LU" +#endif + while ((arg = getopt(argc, argv, FLAGS)) != EOF) { +#undef FLAGS + switch (arg) { +#ifdef AUTH_METHODS + case 'A': + if (! valid_auth (optarg)) { + fprintf(stderr, + _("%s: invalid field `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + auth_arg = optarg; + Aflg++; + break; +#endif + case 'c': + if (! VALID (optarg)) { + fprintf(stderr, + _("%s: invalid field `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + user_comment = optarg; + cflg++; + break; + case 'd': + if (! VALID (optarg)) { + fprintf(stderr, + _("%s: invalid field `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + dflg++; + user_newhome = optarg; + break; +#ifdef SHADOWPWD + case 'e': + if (*optarg) { + user_expire = strtoday(optarg); + if (user_expire == -1) { + fprintf(stderr, + _("%s: invalid date `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + user_expire *= DAY/SCALE; + } else + user_expire = -1; + eflg++; + break; + case 'f': + user_inactive = get_number(optarg); + fflg++; + break; +#endif + case 'g': + grp = getgr_nam_gid(optarg); + if (!grp) { + fprintf(stderr, + _("%s: unknown group %s\n"), + Prog, optarg); + exit(E_NOTFOUND); + } + user_newgid = grp->gr_gid; + gflg++; + break; + case 'G': + if (get_groups(optarg)) + exit(E_NOTFOUND); + Gflg++; + break; + case 'l': + if (!check_user_name(optarg)) { + fprintf(stderr, + _("%s: invalid field `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + + /* + * If the name does not really change, we + * mustn't set the flag as this will cause + * rather serious problems later! + */ + + if (strcmp (user_name, optarg)) + lflg++; + + user_newname = optarg; + break; + case 'L': + if (Uflg || pflg) + usage (); + + Lflg++; + break; + case 'm': + if (! dflg) + usage (); + + mflg++; + break; + case 'o': + if (! uflg) + usage (); + + oflg++; + break; + case 'p': + if (Lflg || Uflg) + usage (); + + user_pass = optarg; + pflg++; + break; + case 's': + if (! VALID (optarg)) { + fprintf(stderr, + _("%s: invalid field `%s'\n"), + Prog, optarg); + exit(E_BAD_ARG); + } + user_shell = optarg; + sflg++; + break; + case 'u': + user_newid = get_number(optarg); + uflg++; + break; + case 'U': + if (Lflg && pflg) + usage (); + + Uflg++; + break; + default: + usage (); + } + anyflag++; + } + if (anyflag == 0) { + fprintf(stderr, _("%s: no flags given\n"), Prog); + exit(E_USAGE); + } + +#ifdef SHADOWPWD + if (!is_shadow_pwd && (eflg || fflg)) { + fprintf(stderr, + _("%s: shadow passwords required for -e and -f\n"), + Prog); + exit(E_USAGE); + } +#endif + + if (optind != argc - 1) + usage (); + + if (dflg && strcmp (user_home, user_newhome) == 0) + dflg = mflg = 0; + + if (uflg && user_id == user_newid) + uflg = oflg = 0; + + if (lflg && getpwnam (user_newname)) { + fprintf(stderr, _("%s: user %s exists\n"), Prog, user_newname); + exit(E_NAME_IN_USE); + } + + if (uflg && !oflg && getpwuid(user_newid)) { + fprintf(stderr, _("%s: uid %ld is not unique\n"), + Prog, (long) user_newid); + exit(E_UID_IN_USE); + } +} + +/* + * close_files - close all of the files that were opened + * + * close_files() closes all of the files that were opened for this + * new user. This causes any modified entries to be written out. + */ + +static void +close_files(void) +{ + if (! pw_close ()) { + fprintf(stderr, _("%s: cannot rewrite password file\n"), Prog); + fail_exit(E_PW_UPDATE); + } +#ifdef SHADOWPWD + if (is_shadow_pwd && ! spw_close ()) { + fprintf(stderr, _("%s: cannot rewrite shadow password file\n"), + Prog); + fail_exit(E_PW_UPDATE); + } +#endif +#ifdef SHADOWPWD + if (is_shadow_pwd) + spw_unlock (); +#endif + (void) pw_unlock (); + + /* + * Close the DBM and/or flat files + */ + + endpwent (); +#ifdef SHADOWPWD + endspent (); +#endif + endgrent (); +#ifdef SHADOWGRP + endsgent (); +#endif +} + +/* + * open_files - lock and open the password files + * + * open_files() opens the two password files. + */ + +static void +open_files(void) +{ + if (!pw_lock()) { + fprintf(stderr, _("%s: unable to lock password file\n"), Prog); + exit(E_PW_UPDATE); + } + if (! pw_open (O_RDWR)) { + fprintf(stderr, _("%s: unable to open password file\n"), Prog); + fail_exit(E_PW_UPDATE); + } +#ifdef SHADOWPWD + if (is_shadow_pwd && ! spw_lock ()) { + fprintf(stderr, _("%s: cannot lock shadow password file\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + if (is_shadow_pwd && ! spw_open (O_RDWR)) { + fprintf(stderr, _("%s: cannot open shadow password file\n"), + Prog); + fail_exit(E_PW_UPDATE); + } +#endif +} + +/* + * usr_update - create the user entries + * + * usr_update() creates the password file entries for this user + * and will update the group entries if required. + */ + +static void +usr_update(void) +{ + struct passwd pwent; + const struct passwd *pwd; +#ifdef SHADOWPWD + struct spwd spent; + const struct spwd *spwd = NULL; +#endif +#ifdef AUTH_METHODS + char old_auth[BUFSIZ]; + char auth_buf[BUFSIZ]; +#endif + + /* + * Locate the entry in /etc/passwd, which MUST exist. + */ + + pwd = pw_locate(user_name); + if (!pwd) { + fprintf(stderr, _("%s: %s not found in /etc/passwd\n"), + Prog, user_name); + fail_exit(E_NOTFOUND); + } + pwent = *pwd; + new_pwent (&pwent); + +#ifdef SHADOWPWD + + /* + * Locate the entry in /etc/shadow. It doesn't have to + * exist, and won't be created if it doesn't. + */ + + if (is_shadow_pwd && (spwd = spw_locate(user_name))) { + spent = *spwd; + new_spent (&spent); + } +#endif + +#ifdef AUTH_METHODS + +#ifdef SHADOWPWD + strcpy (old_auth, spwd ? spent.sp_pwdp : pwent.pw_passwd); +#else + strcpy (old_auth, pwent.pw_passwd); +#endif + + if (Aflg) + convert_auth (user_auth, old_auth, auth_arg); + + /* + * XXX - this code needs some checking, changing the user name with + * "usermod -l new old" clears the password for this user :-(. + * For now, just don't define AUTH_METHODS and all will be well. + * Most programs don't support "administrator defined authentication + * methods" and PAM (when done) will be better anyway :-). --marekm + */ + if (lflg || (Aflg && strcmp (old_auth, user_auth) != 0)) { + delete_auths (old_auth, user_auth, auth_buf); + if (auth_buf[0] && pw_auth (auth_buf, user_name, + PW_DELETE, (char *) 0)) { + fprintf(stderr, + _("%s: error deleting authentication method\n"), + Prog); + SYSLOG((LOG_ERR, "error deleting auth for `%s'\n", + user_name)); + fail_exit(E_PW_UPDATE); + } + add_auths (old_auth, user_auth, auth_buf); + if (auth_buf[0] == '@' && pw_auth (auth_buf, + lflg ? user_newname:user_name, PW_ADD, (char *) 0)) { + fprintf(stderr, + _("%s: error adding authentication method\n"), + Prog); + SYSLOG((LOG_ERR, "error adding auth for `%s'\n", + lflg ? user_newname:user_name)); + fail_exit(E_PW_UPDATE); + } + update_auths (old_auth, user_auth, auth_buf); + if (lflg && auth_buf[0] == '@' && pw_auth (auth_buf, + user_newname, PW_CHANGE, user_name)) { + fprintf(stderr, + _("%s: error changing authentication method\n"), + Prog); + SYSLOG((LOG_ERR, "error changing auth for `%s'\n", + lflg ? user_newname:user_name)); + fail_exit(E_PW_UPDATE); + } +#ifdef SHADOWPWD + if (spwd) + spent.sp_pwdp = user_auth; + else +#endif + pwent.pw_passwd = user_auth; + } +#endif /* AUTH_METHODS */ + if (lflg || uflg || gflg || cflg || dflg || sflg || Aflg || pflg || Lflg || Uflg) { + if (! pw_update (&pwent)) { + fprintf(stderr, + _("%s: error changing password entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + if (lflg && ! pw_remove (user_name)) { + fprintf(stderr, + _("%s: error removing password entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } +#ifdef NDBM + if (pw_dbm_present()) { + if (! pw_dbm_update (&pwent)) { + fprintf(stderr, + _("%s: error adding password dbm entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + if (lflg && (pwd = getpwnam (user_name)) && + ! pw_dbm_remove (pwd)) { + fprintf(stderr, + _("%s: error removing passwd dbm entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + } +#endif + } +#ifdef SHADOWPWD + if (spwd && (lflg || eflg || fflg || Aflg || pflg || Lflg || Uflg)) { + if (! spw_update (&spent)) { + fprintf(stderr, + _("%s: error adding new shadow password entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + if (lflg && ! spw_remove (user_name)) { + fprintf(stderr, + _("%s: error removing shadow password entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + } +#ifdef NDBM + if (spwd && sp_dbm_present()) { + if (! sp_dbm_update (&spent)) { + fprintf(stderr, + _("%s: error updating shadow passwd dbm entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + if (lflg && ! sp_dbm_remove (user_name)) { + fprintf(stderr, + _("%s: error removing shadow passwd dbm entry\n"), + Prog); + fail_exit(E_PW_UPDATE); + } + } +#endif /* NDBM */ +#endif /* SHADOWPWD */ +} + +/* + * move_home - move the user's home directory + * + * move_home() moves the user's home directory to a new location. + * The files will be copied if the directory cannot simply be + * renamed. + */ + +static void +move_home(void) +{ + struct stat sb; + + if (mflg && stat (user_home, &sb) == 0) { + /* + * Don't try to move it if it is not a directory + * (but /dev/null for example). --marekm + */ + if (!S_ISDIR(sb.st_mode)) + return; + + if (access(user_newhome, F_OK) == 0) { + fprintf(stderr, _("%s: directory %s exists\n"), + Prog, user_newhome); + fail_exit(E_HOMEDIR); + } else if (rename (user_home, user_newhome)) { + if (errno == EXDEV) { + if (mkdir (user_newhome, sb.st_mode & 0777)) { + fprintf(stderr, + _("%s: can't create %s\n"), + Prog, user_newhome); + } + if (chown (user_newhome, + sb.st_uid, sb.st_gid)) { + fprintf(stderr, + _("%s: can't chown %s\n"), + Prog, user_newhome); + rmdir (user_newhome); + fail_exit(E_HOMEDIR); + } + if (copy_tree (user_home, user_newhome, + uflg ? user_newid:-1, + gflg ? user_newgid:-1) == 0 && + remove_tree (user_home) == 0 && + rmdir (user_home) == 0) + return; + + (void) remove_tree (user_newhome); + (void) rmdir (user_newhome); + } + fprintf(stderr, + _("%s: cannot rename directory %s to %s\n"), + Prog, user_home, user_newhome); + fail_exit(E_HOMEDIR); + } + } + if (uflg || gflg) + chown (dflg ? user_newhome:user_home, + uflg ? user_newid:user_id, + gflg ? user_newgid:user_gid); +} + +/* + * update_files - update the lastlog and faillog files + */ + +static void +update_files(void) +{ + struct lastlog ll; + struct faillog fl; + int fd; + + /* + * Relocate the "lastlog" entries for the user. The old entry + * is left alone in case the UID was shared. It doesn't hurt + * anything to just leave it be. + */ + + if ((fd = open(LASTLOG_FILE, O_RDWR)) != -1) { + lseek(fd, (off_t) user_id * sizeof ll, SEEK_SET); + if (read(fd, (char *) &ll, sizeof ll) == sizeof ll) { + lseek(fd, (off_t) user_newid * sizeof ll, SEEK_SET); + write(fd, (char *) &ll, sizeof ll); + } + close(fd); + } + + /* + * Relocate the "faillog" entries in the same manner. + */ + + if ((fd = open(FAILLOG_FILE, O_RDWR)) != -1) { + lseek(fd, (off_t) user_id * sizeof fl, SEEK_SET); + if (read(fd, (char *) &fl, sizeof fl) == sizeof fl) { + lseek(fd, (off_t) user_newid * sizeof fl, SEEK_SET); + write(fd, (char *) &fl, sizeof fl); + } + close(fd); + } +} + +#ifndef NO_MOVE_MAILBOX +/* + * This is the new and improved code to carefully chown/rename the user's + * mailbox. Maybe I am too paranoid but the mail spool dir sometimes + * happens to be mode 1777 (this makes mail user agents work without + * being setgid mail, but is NOT recommended; they all should be fixed + * to use movemail). --marekm + */ +static void +move_mailbox(void) +{ + const char *maildir; + char mailfile[1024], newmailfile[1024]; + int fd; + struct stat st; + + maildir = getdef_str("MAIL_DIR"); +#ifdef MAIL_SPOOL_DIR + if (!maildir && !getdef_str("MAIL_FILE")) + maildir = MAIL_SPOOL_DIR; +#endif + if (!maildir) + return; + + /* + * O_NONBLOCK is to make sure open won't hang on mandatory locks. + * We do fstat/fchown to make sure there are no races (someone + * replacing /var/spool/mail/luser with a hard link to /etc/passwd + * between stat and chown). --marekm + */ + + snprintf(mailfile, sizeof mailfile, "%s/%s", maildir, user_name); + fd = open(mailfile, O_RDONLY | O_NONBLOCK, 0); + if (fd < 0) { + /* no need for warnings if the mailbox doesn't exist */ + if (errno != ENOENT) + perror(mailfile); + return; + } + if (fstat(fd, &st) < 0) { + perror("fstat"); + close(fd); + return; + } + if (st.st_uid != user_id) { + /* better leave it alone */ + fprintf(stderr, _("%s: warning: %s not owned by %s\n"), + Prog, mailfile, user_name); + close(fd); + return; + } + if (uflg && fchown(fd, user_newid, (gid_t) -1) < 0) + perror(_("failed to change mailbox owner")); + + close(fd); + + if (lflg) { + snprintf(newmailfile, sizeof newmailfile, "%s/%s", maildir, user_newname); + if (link(mailfile, newmailfile) || unlink(mailfile)) + perror(_("failed to rename mailbox")); + } +} +#endif + +/* + * main - usermod command + */ + +int +main(int argc, char **argv) +{ + int grp_err = 0; + + /* + * Get my name so that I can use it to report errors. + */ + Prog = Basename(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + OPENLOG(Prog); + +#ifdef SHADOWPWD + is_shadow_pwd = spw_file_present(); +#endif +#ifdef SHADOWGRP + is_shadow_grp = sgr_file_present(); +#endif + + /* + * The open routines for the NDBM files don't use read-write + * as the mode, so we have to clue them in. + */ + +#ifdef NDBM + pw_dbm_mode = O_RDWR; +#ifdef SHADOWPWD + sp_dbm_mode = O_RDWR; +#endif + gr_dbm_mode = O_RDWR; +#ifdef SHADOWGRP + sg_dbm_mode = O_RDWR; +#endif +#endif /* NDBM */ + process_flags (argc, argv); + + /* + * Do the hard stuff - open the files, change the user entries, + * change the home directory, then close and update the files. + */ + + open_files(); + + usr_update(); + + close_files(); + + if (Gflg || lflg) + grp_err = grp_update(); + + if (mflg) + move_home(); + +#ifndef NO_MOVE_MAILBOX + if (lflg || uflg) + move_mailbox(); +#endif + + if (uflg) { + update_files(); + + /* + * Change the UID on all of the files owned by `user_id' + * to `user_newid' in the user's home directory. + */ + + chown_tree(dflg ? user_newhome:user_home, + user_id, user_newid, + user_gid, gflg ? user_newgid:user_gid); + } + + if (grp_err) + exit(E_GRP_UPDATE); + + exit(E_SUCCESS); + /*NOTREACHED*/ +} diff --git a/current/src/vipw.c b/current/src/vipw.c new file mode 100644 index 00000000..ed450d47 --- /dev/null +++ b/current/src/vipw.c @@ -0,0 +1,252 @@ +/* + vipw, vigr edit the password or group file + with -s will edit shadow or gshadow file + + Copyright (C) 1997 Guy Maor + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include + +#include "rcsid.h" +RCSID(PKG_VER "$Id: vipw.c,v 1.2 2000/08/26 18:27:19 marekm Exp $") + +#include "defines.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "pwio.h" +#include "shadowio.h" +#include "groupio.h" +#include "sgroupio.h" + + +static const char *progname, *filename, *fileeditname; +static int filelocked = 0, createedit = 0; +static int (*unlock)(void); + +/* local function prototypes */ +static int create_backup_file(FILE *, const char *, struct stat *); +static void vipwexit(const char *, int, int); +static void vipwedit(const char *, int (*)(void), int (*)(void)); + +static int +create_backup_file(FILE *fp, const char *backup, struct stat *sb) +{ + struct utimbuf ub; + FILE *bkfp; + int c; + mode_t mask; + + mask = umask(077); + bkfp = fopen(backup, "w"); + umask(mask); + if (!bkfp) return -1; + + rewind(fp); + while ((c = getc(fp)) != EOF) { + if (putc(c, bkfp) == EOF) break; + } + + if (c != EOF || fflush(bkfp)) { + fclose(bkfp); + unlink(backup); + return -1; + } + if (fclose(bkfp)) { + unlink(backup); + return -1; + } + + ub.actime = sb->st_atime; + ub.modtime = sb->st_mtime; + if (utime(backup, &ub) || + chmod(backup, sb->st_mode) || + chown(backup, sb->st_uid, sb->st_gid)) { + unlink(backup); + return -1; + } + return 0; +} + + +static void +vipwexit(const char *msg, int syserr, int ret) +{ + int err = errno; + if (filelocked) (*unlock)(); + if (createedit) unlink(fileeditname); + if (msg) fprintf(stderr, "%s: %s", progname, msg); + if (syserr) fprintf(stderr, ": %s", strerror(err)); + fprintf(stderr, _("\n%s: %s is unchanged\n"), progname, filename); + exit(ret); +} + +#ifndef DEFAULT_EDITOR +#define DEFAULT_EDITOR "vi" +#endif + +static void +vipwedit(const char *file, int (*file_lock)(void), int (*file_unlock)(void)) +{ + const char *editor; + pid_t pid; + struct stat st1, st2; + int status; + FILE *f; + char filebackup[1024], fileedit[1024]; + + snprintf(filebackup, sizeof filebackup, "%s-", file); + snprintf(fileedit, sizeof fileedit, "%s.edit", file); + unlock = file_unlock; + filename = file; + fileeditname = fileedit; + + if (access(file, F_OK)) vipwexit(file, 1, 1); + if (!file_lock()) vipwexit(_("Couldn't lock file"), errno, 5); + filelocked = 1; + + /* edited copy has same owners, perm */ + if (stat(file, &st1)) vipwexit(file, 1, 1); + if (!(f = fopen(file, "r"))) vipwexit(file, 1, 1); + if (create_backup_file(f, fileedit, &st1)) + vipwexit(_("Couldn't make backup"), errno, 1); + createedit = 1; + + editor = getenv("VISUAL"); + if (!editor) + editor = getenv("EDITOR"); + if (!editor) + editor = DEFAULT_EDITOR; + + if ((pid = fork()) == -1) vipwexit("fork", 1, 1); + else if (!pid) { +#if 0 + execlp(editor, editor, fileedit, (char *) 0); + fprintf(stderr, "%s: %s: %s\n", progname, editor, strerror(errno)); + exit(1); +#else + /* use the system() call to invoke the editor so that it accepts + command line args in the EDITOR and VISUAL environment vars */ + char *buf; + buf = (char *) malloc (strlen(editor) + strlen(fileedit) + 2); + snprintf(buf, strlen(editor) + strlen(fileedit) + 2, "%s %s", + editor, fileedit); + if (system(buf) != 0) { + fprintf(stderr, "%s: %s: %s\n", progname, editor, strerror(errno)); + exit(1); + } else + exit(0); +#endif + } + + for (;;) { + pid = waitpid(pid, &status, WUNTRACED); + if (WIFSTOPPED(status)) { + kill(getpid(), SIGSTOP); + kill(getpid(), SIGCONT); + } + else break; + } + + if (pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status)) + vipwexit(editor, 1, 1); + + if (stat(fileedit, &st2)) vipwexit(fileedit, 1, 1); + if (st1.st_mtime == st2.st_mtime) vipwexit(0, 0, 0); + + /* XXX - here we should check fileedit for errors; if there are any, + ask the user what to do (edit again, save changes anyway, or quit + without saving). Use pwck or grpck to do the check. --marekm */ + + createedit = 0; + unlink(filebackup); + link(file, filebackup); + if (rename(fileedit, file) == -1) { + fprintf(stderr, _("%s: can't restore %s: %s (your changes are in %s)\n"), + progname, file, strerror(errno), fileedit); + vipwexit(0,0,1); + } + + (*file_unlock)(); +} + + +int +main(int argc, char **argv) +{ + int flag; + int editshadow = 0; + char *c; + int e = 1; + int do_vipw; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + progname = ((c = strrchr(*argv, '/')) ? c+1 : *argv); + do_vipw = (strcmp(progname, "vigr") != 0); + + while ((flag = getopt(argc, argv, "ghps")) != EOF) { + switch (flag) { + case 'p': + do_vipw = 1; + break; + case 'g': + do_vipw = 0; + break; + case 's': + editshadow = 1; + break; + case 'h': + e = 0; + default: + printf(_("Usage:\n\ +`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n\ +`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n\ +")); + exit(e); + } + } + + if (do_vipw) { +#ifdef SHADOWPWD + if (editshadow) + vipwedit(SHADOW_FILE, spw_lock, spw_unlock); + else +#endif + vipwedit(PASSWD_FILE, pw_lock, pw_unlock); + } + else { +#ifdef SHADOWGRP + if (editshadow) + vipwedit(SGROUP_FILE, sgr_lock, sgr_unlock); + else +#endif + vipwedit(GROUP_FILE, gr_lock, gr_unlock); + } + + return 0; +} diff --git a/current/stamp-h.in b/current/stamp-h.in new file mode 100644 index 00000000..9788f702 --- /dev/null +++ b/current/stamp-h.in @@ -0,0 +1 @@ +timestamp -- 2.40.0