From 0dfb168e84ea3f6bf65c88e408dd0ddeeee792d6 Mon Sep 17 00:00:00 2001 From: arthur Date: Sun, 4 Sep 2011 19:19:42 +0000 Subject: [PATCH] release 0.8.4 git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd-0.8.4@1537 ef36b2f9-881f-0410-afb5-c4e39611909c --- AUTHORS | 116 ++ COPYING | 504 +++++ ChangeLog | 905 +++++++++ ChangeLog-2006 | 801 ++++++++ ChangeLog-2007 | 1051 +++++++++++ ChangeLog-2008 | 792 ++++++++ ChangeLog-2009 | 711 +++++++ ChangeLog-2010 | 934 +++++++++ HACKING | 241 +++ INSTALL | 365 ++++ Makefile.am | 125 ++ NEWS | 2415 ++++++++++++++++++++++++ README | 403 ++++ TODO | 31 + autogen.sh | 31 + common/Makefile.am | 32 + common/dict.c | 294 +++ common/dict.h | 71 + common/expr.c | 234 +++ common/expr.h | 41 + common/nslcd-prot.c | 89 + common/nslcd-prot.h | 358 ++++ common/set.c | 75 + common/set.h | 64 + common/tio.c | 511 +++++ common/tio.h | 81 + compat/Makefile.am | 34 + compat/attrs.h | 91 + compat/daemon.c | 71 + compat/daemon.h | 34 + compat/ether.c | 60 + compat/ether.h | 64 + compat/getopt_long.c | 92 + compat/getopt_long.h | 50 + compat/getpeercred.c | 106 ++ compat/getpeercred.h | 35 + compat/ldap_compat.h | 65 + compat/ldap_initialize.c | 64 + compat/ldap_passwd_s.c | 107 ++ compat/nss_compat.h | 151 ++ compat/pagectrl.c | 217 +++ compat/pam_compat.h | 87 + compat/pam_get_authtok.c | 101 + compat/pam_prompt.c | 72 + compat/strndup.c | 41 + compat/strndup.h | 33 + compile | 143 ++ config.guess | 1517 +++++++++++++++ config.sub | 1760 +++++++++++++++++ configure.ac | 762 ++++++++ debian/NEWS | 12 + debian/changelog | 1383 ++++++++++++++ debian/compat | 1 + debian/control | 49 + debian/copyright | 98 + debian/libnss-ldapd.config | 49 + debian/libnss-ldapd.install | 1 + debian/libnss-ldapd.lintian-overrides | 6 + debian/libnss-ldapd.postinst | 91 + debian/libnss-ldapd.postrm | 94 + debian/libnss-ldapd.templates | 27 + debian/libpam-ldapd.install | 2 + debian/libpam-ldapd.lintian-overrides | 6 + debian/libpam-ldapd.manpages | 1 + debian/libpam-ldapd.postinst | 63 + debian/libpam-ldapd.prerm | 12 + debian/libpam-ldapd.templates | 12 + debian/nslcd.conffile | 1 + debian/nslcd.config | 368 ++++ debian/nslcd.default | 14 + debian/nslcd.docs | 3 + debian/nslcd.examples | 1 + debian/nslcd.init | 176 ++ debian/nslcd.install | 1 + debian/nslcd.manpages | 2 + debian/nslcd.postinst | 262 +++ debian/nslcd.postrm | 17 + debian/nslcd.templates | 123 ++ debian/pam-configs/ldap | 19 + debian/po/POTFILES.in | 3 + debian/po/ca.po | 626 +++++++ debian/po/cs.po | 609 ++++++ debian/po/da.po | 492 +++++ debian/po/de.po | 506 +++++ debian/po/es.po | 632 +++++++ debian/po/fi.po | 481 +++++ debian/po/fr.po | 580 ++++++ debian/po/gl.po | 497 +++++ debian/po/it.po | 501 +++++ debian/po/ja.po | 457 +++++ debian/po/nb.po | 474 +++++ debian/po/nl.po | 489 +++++ debian/po/pt.po | 516 +++++ debian/po/pt_BR.po | 611 ++++++ debian/po/ru.po | 515 +++++ debian/po/sk.po | 488 +++++ debian/po/sv.po | 474 +++++ debian/po/templates.pot | 409 ++++ debian/po/vi.po | 476 +++++ debian/po/zh_CN.po | 450 +++++ debian/rules | 20 + debian/source/format | 1 + debian/source/lintian-overrides | 3 + depcomp | 630 +++++++ install-sh | 520 +++++ m4/ax_pthread.m4 | 302 +++ man/Makefile.am | 48 + man/nslcd.8.xml | 145 ++ man/nslcd.conf.5.xml | 907 +++++++++ man/pam_ldap.8.xml | 220 +++ missing | 376 ++++ mkinstalldirs | 162 ++ nslcd.conf | 142 ++ nslcd.h | 261 +++ nslcd/Makefile.am | 38 + nslcd/alias.c | 140 ++ nslcd/attmap.c | 295 +++ nslcd/attmap.h | 98 + nslcd/cfg.c | 1295 +++++++++++++ nslcd/cfg.h | 156 ++ nslcd/common.c | 288 +++ nslcd/common.h | 266 +++ nslcd/ether.c | 196 ++ nslcd/group.c | 377 ++++ nslcd/host.c | 192 ++ nslcd/log.c | 165 ++ nslcd/log.h | 53 + nslcd/myldap.c | 1860 ++++++++++++++++++ nslcd/myldap.h | 154 ++ nslcd/netgroup.c | 249 +++ nslcd/network.c | 190 ++ nslcd/nslcd.c | 827 ++++++++ nslcd/nsswitch.c | 116 ++ nslcd/pam.c | 676 +++++++ nslcd/passwd.c | 626 +++++++ nslcd/protocol.c | 197 ++ nslcd/rpc.c | 198 ++ nslcd/service.c | 243 +++ nslcd/shadow.c | 378 ++++ nss/Makefile.am | 55 + nss/aliases.c | 82 + nss/bsdnss.c | 155 ++ nss/common.c | 22 + nss/common.h | 227 +++ nss/ethers.c | 184 ++ nss/exports.freebsd | 16 + nss/exports.glibc | 88 + nss/exports.solaris | 25 + nss/group.c | 303 +++ nss/hosts.c | 382 ++++ nss/netgroup.c | 332 ++++ nss/networks.c | 263 +++ nss/passwd.c | 192 ++ nss/protocols.c | 190 ++ nss/prototypes.h | 156 ++ nss/rpc.c | 190 ++ nss/services.c | 196 ++ nss/shadow.c | 207 ++ nss/solnss.c | 49 + pam/Makefile.am | 43 + pam/common.h | 100 + pam/pam.c | 661 +++++++ pam/pam_ldap.map | 16 + py-compile | 146 ++ pynslcd/Makefile.am | 46 + pynslcd/alias.py | 65 + pynslcd/attmap.py | 194 ++ pynslcd/cfg.py | 58 + pynslcd/common.py | 134 ++ pynslcd/config.py.in | 61 + pynslcd/ether.py | 86 + pynslcd/group.py | 137 ++ pynslcd/host.py | 72 + pynslcd/mypidfile.py | 71 + pynslcd/netgroup.py | 71 + pynslcd/network.py | 73 + pynslcd/pam.py | 130 ++ pynslcd/passwd.py | 144 ++ pynslcd/protocol.py | 75 + pynslcd/pynslcd.py | 282 +++ pynslcd/rpc.py | 75 + pynslcd/service.py | 96 + pynslcd/shadow.py | 106 ++ pynslcd/tio.py | 122 ++ tests/Makefile.am | 74 + tests/README | 85 + tests/common.h | 69 + tests/in_testenv.sh | 61 + tests/nslcd-test.conf | 28 + tests/test.ldif.gz | Bin 0 -> 182197 bytes tests/test_cfg.c | 227 +++ tests/test_common.c | 62 + tests/test_dict.c | 203 ++ tests/test_expr.c | 139 ++ tests/test_getpeercred.c | 132 ++ tests/test_myldap.c | 431 +++++ tests/test_myldap.sh | 42 + tests/test_nsscmds.sh | 428 +++++ tests/test_pamcmds.expect | 204 ++ tests/test_pamcmds.sh | 39 + tests/test_set.c | 82 + tests/test_tio.c | 358 ++++ tests/usernames.txt | 2500 +++++++++++++++++++++++++ 203 files changed, 54764 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 ChangeLog-2006 create mode 100644 ChangeLog-2007 create mode 100644 ChangeLog-2008 create mode 100644 ChangeLog-2009 create mode 100644 ChangeLog-2010 create mode 100644 HACKING create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100755 autogen.sh create mode 100644 common/Makefile.am create mode 100644 common/dict.c create mode 100644 common/dict.h create mode 100644 common/expr.c create mode 100644 common/expr.h create mode 100644 common/nslcd-prot.c create mode 100644 common/nslcd-prot.h create mode 100644 common/set.c create mode 100644 common/set.h create mode 100644 common/tio.c create mode 100644 common/tio.h create mode 100644 compat/Makefile.am create mode 100644 compat/attrs.h create mode 100644 compat/daemon.c create mode 100644 compat/daemon.h create mode 100644 compat/ether.c create mode 100644 compat/ether.h create mode 100644 compat/getopt_long.c create mode 100644 compat/getopt_long.h create mode 100644 compat/getpeercred.c create mode 100644 compat/getpeercred.h create mode 100644 compat/ldap_compat.h create mode 100644 compat/ldap_initialize.c create mode 100644 compat/ldap_passwd_s.c create mode 100644 compat/nss_compat.h create mode 100644 compat/pagectrl.c create mode 100644 compat/pam_compat.h create mode 100644 compat/pam_get_authtok.c create mode 100644 compat/pam_prompt.c create mode 100644 compat/strndup.c create mode 100644 compat/strndup.h create mode 100755 compile create mode 100755 config.guess create mode 100755 config.sub create mode 100644 configure.ac create mode 100644 debian/NEWS create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/libnss-ldapd.config create mode 100644 debian/libnss-ldapd.install create mode 100644 debian/libnss-ldapd.lintian-overrides create mode 100644 debian/libnss-ldapd.postinst create mode 100644 debian/libnss-ldapd.postrm create mode 100644 debian/libnss-ldapd.templates create mode 100644 debian/libpam-ldapd.install create mode 100644 debian/libpam-ldapd.lintian-overrides create mode 100644 debian/libpam-ldapd.manpages create mode 100644 debian/libpam-ldapd.postinst create mode 100644 debian/libpam-ldapd.prerm create mode 100644 debian/libpam-ldapd.templates create mode 100644 debian/nslcd.conffile create mode 100644 debian/nslcd.config create mode 100644 debian/nslcd.default create mode 100644 debian/nslcd.docs create mode 100644 debian/nslcd.examples create mode 100644 debian/nslcd.init create mode 100644 debian/nslcd.install create mode 100644 debian/nslcd.manpages create mode 100644 debian/nslcd.postinst create mode 100644 debian/nslcd.postrm create mode 100644 debian/nslcd.templates create mode 100644 debian/pam-configs/ldap create mode 100644 debian/po/POTFILES.in create mode 100644 debian/po/ca.po create mode 100644 debian/po/cs.po create mode 100644 debian/po/da.po create mode 100644 debian/po/de.po create mode 100644 debian/po/es.po create mode 100644 debian/po/fi.po create mode 100644 debian/po/fr.po create mode 100644 debian/po/gl.po create mode 100644 debian/po/it.po create mode 100644 debian/po/ja.po create mode 100644 debian/po/nb.po create mode 100644 debian/po/nl.po create mode 100644 debian/po/pt.po create mode 100644 debian/po/pt_BR.po create mode 100644 debian/po/ru.po create mode 100644 debian/po/sk.po create mode 100644 debian/po/sv.po create mode 100644 debian/po/templates.pot create mode 100644 debian/po/vi.po create mode 100644 debian/po/zh_CN.po create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/source/lintian-overrides create mode 100644 depcomp create mode 100755 install-sh create mode 100644 m4/ax_pthread.m4 create mode 100644 man/Makefile.am create mode 100644 man/nslcd.8.xml create mode 100644 man/nslcd.conf.5.xml create mode 100644 man/pam_ldap.8.xml create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 nslcd.conf create mode 100644 nslcd.h create mode 100644 nslcd/Makefile.am create mode 100644 nslcd/alias.c create mode 100644 nslcd/attmap.c create mode 100644 nslcd/attmap.h create mode 100644 nslcd/cfg.c create mode 100644 nslcd/cfg.h create mode 100644 nslcd/common.c create mode 100644 nslcd/common.h create mode 100644 nslcd/ether.c create mode 100644 nslcd/group.c create mode 100644 nslcd/host.c create mode 100644 nslcd/log.c create mode 100644 nslcd/log.h create mode 100644 nslcd/myldap.c create mode 100644 nslcd/myldap.h create mode 100644 nslcd/netgroup.c create mode 100644 nslcd/network.c create mode 100644 nslcd/nslcd.c create mode 100644 nslcd/nsswitch.c create mode 100644 nslcd/pam.c create mode 100644 nslcd/passwd.c create mode 100644 nslcd/protocol.c create mode 100644 nslcd/rpc.c create mode 100644 nslcd/service.c create mode 100644 nslcd/shadow.c create mode 100644 nss/Makefile.am create mode 100644 nss/aliases.c create mode 100644 nss/bsdnss.c create mode 100644 nss/common.c create mode 100644 nss/common.h create mode 100644 nss/ethers.c create mode 100644 nss/exports.freebsd create mode 100644 nss/exports.glibc create mode 100644 nss/exports.solaris create mode 100644 nss/group.c create mode 100644 nss/hosts.c create mode 100644 nss/netgroup.c create mode 100644 nss/networks.c create mode 100644 nss/passwd.c create mode 100644 nss/protocols.c create mode 100644 nss/prototypes.h create mode 100644 nss/rpc.c create mode 100644 nss/services.c create mode 100644 nss/shadow.c create mode 100644 nss/solnss.c create mode 100644 pam/Makefile.am create mode 100644 pam/common.h create mode 100644 pam/pam.c create mode 100644 pam/pam_ldap.map create mode 100755 py-compile create mode 100644 pynslcd/Makefile.am create mode 100644 pynslcd/alias.py create mode 100644 pynslcd/attmap.py create mode 100644 pynslcd/cfg.py create mode 100644 pynslcd/common.py create mode 100644 pynslcd/config.py.in create mode 100644 pynslcd/ether.py create mode 100644 pynslcd/group.py create mode 100644 pynslcd/host.py create mode 100644 pynslcd/mypidfile.py create mode 100644 pynslcd/netgroup.py create mode 100644 pynslcd/network.py create mode 100644 pynslcd/pam.py create mode 100644 pynslcd/passwd.py create mode 100644 pynslcd/protocol.py create mode 100755 pynslcd/pynslcd.py create mode 100644 pynslcd/rpc.py create mode 100644 pynslcd/service.py create mode 100644 pynslcd/shadow.py create mode 100644 pynslcd/tio.py create mode 100644 tests/Makefile.am create mode 100644 tests/README create mode 100644 tests/common.h create mode 100755 tests/in_testenv.sh create mode 100644 tests/nslcd-test.conf create mode 100644 tests/test.ldif.gz create mode 100644 tests/test_cfg.c create mode 100644 tests/test_common.c create mode 100644 tests/test_dict.c create mode 100644 tests/test_expr.c create mode 100644 tests/test_getpeercred.c create mode 100644 tests/test_myldap.c create mode 100755 tests/test_myldap.sh create mode 100755 tests/test_nsscmds.sh create mode 100644 tests/test_pamcmds.expect create mode 100755 tests/test_pamcmds.sh create mode 100644 tests/test_set.c create mode 100644 tests/test_tio.c create mode 100644 tests/usernames.txt diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..b38cb63 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,116 @@ +The original nss_ldap library was written by Luke Howard of PADL Software Pty +Ltd. In 2006 Arthur de Jong of West Consuling forked the library to split it +into a thin NSS part and a server part. The copyright holders of most of the +code are: + +Luke Howard +West Consulting +Arthur de Jong +Howard Chu +Symas Corporation (contributed by Ted C. Cheng ) + +The following people (in no particular order) have also volunteered their +time, effort, and ideas to make this software available. If you feel you are +unjustly left out of this list, please send an email. + +Steven Barrus +David Begley +Maxim Batourine +Michael Brownea +Max Caines +Carlos Celso +Peter Cherny +Ben Collins +Stephan Cremer +Alejandro Forero Cuervo +Guenther Deschner +Luca Filipozzi +Andrew Findlay +Cristian Gafton +Gabor Gombas +DJ Gregor +Bob Guo +Daniel Hanks +Leif Hedstrom +Emile Heitor +Geert Jansen +Szymon Juraszczyk +Anselm Kruis +Thorsten Kukuk +Steve Langasek +Joe Little +Phillip Liu +Larry Lile +Jeff Mandel +Peter Marschall +Michael Mattice +Dejan Muhamedagic +Doug Nazar +Frode Nordahl +Lars Oergel +Fredrik Ohrn +Rakesh Patel +Nathan Hawkins +Andrew Rechenberg +Greg Retowski +Alain Richard +Michael Shuey +Oliver Schulze L. +Alexander Spannagel +Scott M. Stone +Gero Treuner +Jarkko Turkulainen +Stein Vrale +Simon Wilkinson +Davide Puricelli +Sami Haahtinen +Stephen Frost +Américo Monteiro +Cyril Brulebois +Kenshi Muto +Andreas Schneider +Ralf Haferkamp +Michael Calmer +Erik Schanze +Bart Cornelis +Rudy Godoy Guillén +Petter Reinholdtsen +Dan White +Leigh Wedding +Jan Schampera +Nalin Dahyabhai +Daniel Dehennin +Bjørn Steensrud +Chris Leick +Christian Perrier +David Bartley +Esko Arajärvi +Francisco Javier Cuadrado +Guillaume Delacour +Jonas Smedegaard +Justin B Rye +Marce Villarino +Martin Ågren +Miroslav Kure +Thaddeus J. Kollar +Vincenzo Campanella +Yuri Kozlov +zym +Agustí Grau +Clytie Siddall +Pierre Gambarotto +Ted C. Cheng +Jacques Vidrine +Artem Kazakov +Alexander V. Chernikov +SATOH Fumiyasu +Wesley Mason +Stefan Völkel +Slavko +Joe Hansen +Denis Doria +James M. Leddy +Jakub Hrozek +Andreas B. Mundt +Paul Gevers +Jeroen Schot diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..5ab7695 --- /dev/null +++ b/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..660214f --- /dev/null +++ b/ChangeLog @@ -0,0 +1,905 @@ +2011-09-04 08:48 arthur + + * [r1535] tests/test_getpeercred.c: warn when we couldn't get the + gid or pid, the uid is the only really interesting bit + +2011-09-04 08:42 arthur + + * [r1534] tests/test_tio.c: add casts from size_t to int for printf + +2011-09-04 08:40 arthur + + * [r1533] debian/rules: ignore failures in tests + +2011-09-04 08:40 arthur + + * [r1532] debian/rules: use auto-detection for LDAP library and + defaults for config file, socket and pidfile (no changes) + +2011-09-03 15:57 arthur + + * [r1531] debian/libnss-ldapd.config, debian/libnss-ldapd.postinst, + debian/libnss-ldapd.postrm, debian/libpam-ldapd.postinst: support + spaces before and after database name while parsing + /etc/nsswitch.conf and reduce the number of places where parsing + is done + +2011-08-30 18:58 arthur + + * [r1530] debian/nslcd.postinst: correctly handle leading and + trailing spaces in preseeded uri option (patch by Andreas B. + Mundt) + +2011-08-30 18:47 arthur + + * [r1529] configure.ac, nslcd/myldap.c: move LDAP_DEPRECATED and + LDAP_REFERRALS to configure.ac to ensure that tests from + configure see the same API + +2011-08-29 20:57 arthur + + * [r1528] configure.ac, nslcd/common.c, nslcd/common.h: implement + and use a strtoui() function if uid_t or gid_t is of size + unsigned int (thanks Jakub Hrozek) + +2011-08-29 19:18 arthur + + * [r1527] pynslcd/Makefile.am: get rid of automake warning + +2011-08-29 19:16 arthur + + * [r1526] configure.ac: silence autoconf warnings, patch by Jakub + Hrozek + +2011-08-29 19:01 arthur + + * [r1525] debian/po/nl.po: some changes based on feedback by Jeroen + Schot + +2011-08-27 21:22 arthur + + * [r1524] configure.ac, nslcd/cfg.c, nslcd/common.h, nslcd/group.c, + nslcd/passwd.c: provide strtouid() and strtogid() functions that + use strtoul() or strtoull() (thanks Jakub Hrozek) + +2011-08-27 20:57 arthur + + * [r1523] nslcd/cfg.c, nslcd/group.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + check errno after calls to strtol() to ensure that numbers that + are too large for type will be reported (thanks Jakub Hrozek) + +2011-08-27 15:08 arthur + + * [r1522] AUTHORS, nslcd/myldap.c: pass a statically allocated + callback structure to OpenLDAP because it doesn't make it's own + copy (thanks Jakub Hrozek) + +2011-08-27 14:48 arthur + + * [r1521] debian/po/nl.po: some changes based on feedback by Paul + Gevers + +2011-08-26 19:21 arthur + + * [r1520] debian/po/nl.po: first attempt at Dutch (nl) translation + +2011-08-26 10:11 arthur + + * [r1519] debian/po/ca.po, debian/po/fi.po, debian/po/gl.po, + debian/po/it.po, debian/po/nb.po, debian/po/nl.po, + debian/po/sv.po, debian/po/vi.po, debian/po/zh_CN.po: small + formatting changes to header + +2011-08-25 20:05 arthur + + * [r1518] debian/po/es.po: updated Spanish (es) translation of + debconf templates by Francisco Javier Cuadrado + +2011-08-24 20:47 arthur + + * [r1517] nslcd/cfg.c: fix typo (thanks Nalin Dahyabhai) + +2011-08-24 20:22 arthur + + * [r1515] nslcd/cfg.c: fix a problem with uninitialised memory + while parsing the tls_ciphers option (was broken in r853, similar + problem was fixed in r910, reported by Isaac Freeman) + +2011-08-24 19:02 arthur + + * [r1514] debian/po/de.po: updated German (de) translation of + debconf templates by Chris Leick + +2011-08-24 18:51 arthur + + * [r1513] AUTHORS, man/nslcd.conf.5.xml, nslcd/cfg.c: support + querying DNS SRV records from a different domain than the current + one (based on a patch by James M. Leddy) + +2011-08-23 20:03 arthur + + * [r1512] debian/po/cs.po: updated Czech (cs) translation of + debconf templates by Miroslav Kure + +2011-08-19 15:57 arthur + + * [r1511] debian/po/fr.po: typo fix provided by Christian Perrier + +2011-08-17 19:38 arthur + + * [r1510] AUTHORS: add new translators to AUTHORS file + +2011-08-17 19:04 arthur + + * [r1509] debian/po/ja.po: updated Japanese (ja) translation of + debconf templates by Kenshi Muto + +2011-08-17 18:44 arthur + + * [r1508] debian/po/pt.po: updated Portuguese (pt) translation of + debconf templates by Américo Monteiro + +2011-08-14 19:29 arthur + + * [r1507] debian/po/pt_BR.po: updated Brazilian Portuguese (pt_BR) + translation of debconf templates by Denis Doria + +2011-08-14 17:03 arthur + + * [r1506] ChangeLog, ChangeLog-2009, ChangeLog-2010, Makefile.am: + split 2009 and 2010 changes to separate ChangeLog files + +2011-08-14 15:39 arthur + + * [r1505] nss/networks.c: remove unused variable + +2011-08-14 14:09 arthur + + * [r1504] nslcd/Makefile.am, pam/Makefile.am, tests/Makefile.am: + put external libraries at the end when linking + +2011-08-14 14:03 arthur + + * [r1503] configure.ac: remove some tests for symbols we aren't + using + +2011-08-14 14:02 arthur + + * [r1502] debian/libnss-ldapd.lintian-overrides: add lintian + override for SONAME check + +2011-08-14 12:54 arthur + + * [r1501] debian/po/pt_BR.po: updated Brazilian Portuguese (pt_BR) + translation of debconf templates by Denis Doria + +2011-08-14 10:34 arthur + + * [r1500] debian/po/da.po: update Danish (da) translation of + debconf templates by Joe Hansen + +2011-08-14 10:27 arthur + + * [r1499] debian/po/sk.po: added Slovak (sk) translation of debconf + templates by Slavko + +2011-08-14 10:18 arthur + + * [r1498] debian/po/fr.po: updated French (fr) translation of + debconf templates by Christian Perrier + +2011-08-14 10:04 arthur + + * [r1497] debian/po/ru.po: updated Russian (ru) translation of + debconf templates by Yuri Kozlov + +2011-08-10 20:02 arthur + + * [r1496] AUTHORS: fix spelling of name (sorry about that) + +2011-08-09 15:36 arthur + + * [r1495] nslcd/passwd.c: check nsswitch.conf mtime to see whether + file should be reloaded + +2011-08-09 09:09 arthur + + * [r1494] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fi.po, + debian/po/fr.po, debian/po/gl.po, debian/po/it.po, + debian/po/ja.po, debian/po/nb.po, debian/po/nl.po, + debian/po/pt.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po, + debian/po/zh_CN.po: run debconf-updatepo to update .pot and .po + files + +2011-08-09 09:02 arthur + + * [r1493] debian/nslcd.templates, man/nslcd.conf.5.xml: small + language updates based on feedback by Justin B Rye + +2011-08-08 08:09 arthur + + * [r1492] debian/nslcd.templates: incorporate feedback on debconf + templates by debian-l10n-english@lists.debian.org (thanks Justin + B Rye and Christian PERRIER) + +2011-08-07 16:40 arthur + + * [r1491] Makefile.am, debian/compat, debian/control, + debian/libnss-ldapd.install, + debian/libnss-ldapd.lintian-overrides, + debian/libnss-ldapd.postinst, debian/libpam-ldapd.install, + debian/rules, debian/source/lintian-overrides: build Debian + packages with multiarch support + +2011-08-07 13:10 arthur + + * [r1490] AUTHORS, nslcd/myldap.c: set the socket timeout in a + connection callback to avoid timeout issues during the SSL + handshake (based on a patch by Stefan Völkel) + +2011-08-06 20:36 arthur + + * [r1489] debian/copyright, m4/ax_pthread.m4: update AX_PTHREAD + from http://www.gnu.org/software/autoconf-archive/ax_pthread.html + +2011-08-05 21:42 arthur + + * [r1488] pynslcd/group.py, tests/test_myldap.c: replace last + traces of groupOfUniqueNames + +2011-08-05 21:28 arthur + + * [r1487] nslcd/Makefile.am, nslcd/common.h, nslcd/nsswitch.c, + nslcd/passwd.c, tests/Makefile.am: check whether the NSS shadow + map queries LDAP before returning x as a password has for shadow + users + +2011-08-05 20:58 arthur + + * [r1486] tests/README, tests/test.ldif.gz, tests/test_nsscmds.sh: + update tests with change of member/uniqueMember default change + (r1484) + +2011-08-05 11:52 arthur + + * [r1485] nslcd/group.c, nslcd/myldap.c, nslcd/myldap.h, + nslcd/passwd.c: implementation of myldap_get_values_len() to use + ldap_get_values_len() instead of ldap_get_values() to fix some + problems with binary data in returned attribute values (patch by + Wesley Mason) + +2011-08-03 19:54 arthur + + * [r1484] README, nslcd.conf, nslcd/attmap.c, nslcd/attmap.h, + nslcd/group.c, pynslcd/group.py, tests/test_myldap.c: switch to + using the member attribute by default instead of uniqueMember + +2011-07-21 20:41 arthur + + * [r1483] README: remove obsolete attribute from documentation + +2011-07-15 20:13 arthur + + * [r1482] debian/nslcd.init: on restart only log_end_msg once + +2011-07-04 21:18 arthur + + * [r1481] configure.ac: show the default value for the + pam-seclib-dir option + +2011-07-03 20:34 arthur + + * [r1480] compat/getpeercred.c: fix header + +2011-07-03 20:34 arthur + + * [r1479] compat/pam_compat.h: provide PAM_AUTHTOK_RECOVERY_ERR for + systems with only PAM_AUTHTOK_RECOVER_ERR + +2011-07-02 21:50 arthur + + * [r1478] Makefile.am, debian/compat, debian/control, + debian/libpam-ldapd.install, debian/libpam-ldapd.pam-auth-update, + debian/nslcd.install, debian/pam-configs, + debian/pam-configs/ldap, debian/rules: switch to dh for + debian/rules and bump debhelper compatibility to 8 + +2011-07-02 21:20 arthur + + * [r1476] nslcd/group.c, nslcd/host.c, nslcd/network.c, + nslcd/passwd.c, nslcd/shadow.c: make buffer sizes consistent, + grow gidNumber buffer to hold larger numbers and small + consistency improvements + +2011-06-10 08:49 arthur + + * [r1475] nslcd/pam.c: correctly only check password expiration + when authenticating, only check account expiration when doing + authorisation check + +2011-06-05 20:18 arthur + + * [r1474] nslcd/cfg.c, nslcd/pam.c: check all variables in + pam_authz_search to see if they exist + +2011-06-05 20:15 arthur + + * [r1473] nslcd/cfg.c, nslcd/common.c: mark more strings as const + and don't free() data returned by cfg_getdomainname() + +2011-06-05 09:14 arthur + + * [r1471] common/expr.c, tests/test_expr.c: handle expressions + where the expander function returns NULL (handle it as an empty + string) + +2011-06-05 08:58 arthur + + * [r1470] nslcd/myldap.c: fix r1468 + +2011-06-05 08:54 arthur + + * [r1468] nslcd/myldap.c: simplify and correct find_rdn_value() to + handle splitting attribute and value correctly + +2011-06-05 08:03 arthur + + * [r1467] config.guess, config.sub: include updated files + +2011-05-23 20:05 arthur + + * [r1466] tests/test_common.c: add test case for two-character user + name + +2011-05-21 14:52 arthur + + * [r1464] nslcd/myldap.c: fix problem with partial attribute name + matches in DN (e.g. uid vs. uidNumber) (thanks to Timothy White + for the fix) + +2011-05-13 13:10 arthur + + * [r1462] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.8.3 release + +2011-05-13 13:02 arthur + + * [r1461] debian/libnss-ldapd.postinst: don't unconditionally + restart nscd but just try to invalidate the cache for the maps + that change + +2011-05-13 13:01 arthur + + * [r1460] debian/libnss-ldapd.config: correctly pick up current + configuration of /etc/nsswitch.conf when running dpkg-reconfigure + +2011-05-13 12:41 arthur + + * [r1459] debian/control: upgrade to standards-version 3.9.2 + +2011-05-13 12:15 arthur + + * [r1458] common/expr.c, common/expr.h: switch variable expander + function type name because _t suffix is reserved + +2011-05-13 11:57 arthur + + * [r1457] debian/control, debian/nslcd.config: search for LDAP + server by looking for SRV _ldap._tcp DNS records and try to query + LDAP server for base DN during package configuration (based on + work by Petter Reinholdtsen for the sssd package) + +2011-05-13 07:48 arthur + + * [r1456] debian/nslcd.config: fix domain to basedn expansion when + having more than two domain parts (patch by Per Carlson) + +2011-05-13 07:04 arthur + + * [r1455] pynslcd/alias.py, pynslcd/common.py, pynslcd/ether.py, + pynslcd/group.py, pynslcd/host.py, pynslcd/netgroup.py, + pynslcd/network.py, pynslcd/pam.py, pynslcd/passwd.py, + pynslcd/protocol.py, pynslcd/rpc.py, pynslcd/service.py, + pynslcd/shadow.py: simplify request handling by passing read + parameters around in a dict instead of setting object properties + (this mainly simplifies search filter building) + +2011-05-01 19:08 arthur + + * [r1454] pynslcd/alias.py, pynslcd/attmap.py, pynslcd/common.py, + pynslcd/ether.py, pynslcd/group.py, pynslcd/host.py, + pynslcd/netgroup.py, pynslcd/network.py, pynslcd/pam.py, + pynslcd/passwd.py, pynslcd/protocol.py, pynslcd/rpc.py, + pynslcd/service.py, pynslcd/shadow.py, pynslcd/tio.py: implement + attribute mapping functionality and do some refactoring + +2011-05-01 12:18 arthur + + * [r1453] pynslcd/pam.py: remove unneeded import + +2011-05-01 12:14 arthur + + * [r1452] pynslcd/alias.py, pynslcd/common.py, pynslcd/ether.py, + pynslcd/host.py, pynslcd/netgroup.py, pynslcd/network.py, + pynslcd/pam.py, pynslcd/passwd.py, pynslcd/protocol.py, + pynslcd/rpc.py, pynslcd/service.py, pynslcd/shadow.py: pass dn + and attributes to functions separately + +2011-05-01 12:06 arthur + + * [r1451] pynslcd/group.py, pynslcd/pam.py, pynslcd/pynslcd.py: + small code improvements + +2011-04-30 21:28 arthur + + * [r1450] pam/common.h: make log message clearer when nslcd returns + an empty response (user not handled) + +2011-04-30 21:26 arthur + + * [r1449] nslcd/pam.c: close the nslcd connection to signal LDAP + server unavailable to PAM module + +2011-04-30 21:01 arthur + + * [r1448] pam/pam.c: split setting up of configuration into + separate function + +2011-04-30 19:54 arthur + + * [r1447] nslcd/pam.c: improve password change failed error message + +2011-04-30 14:37 arthur + + * [r1446] nslcd/common.h, nslcd/pam.c, nslcd/shadow.c: check shadow + properties (similarly to what pam_unix does) in the PAM handling + code + +2011-04-30 09:15 arthur + + * [r1445] pam/pam.c: do not attempt to change password as root when + changing an expired password + +2011-04-30 08:39 arthur + + * [r1444] nslcd/pam.c: fix return value of try_autzsearch() when no + match found + +2011-04-30 08:12 arthur + + * [r1443] nslcd/pam.c: use the right DN in the pam_authz_search + option + +2011-04-30 08:00 arthur + + * [r1442] nslcd/shadow.c: move code for getting shadow expiry + properties to a separate function + +2011-04-29 21:06 arthur + + * [r1441] nslcd/pam.c: move most of the code for building the + authorisation search into the try_autzsearch() function + +2011-04-29 18:21 arthur + + * [r1440] nslcd.h, pam/pam.c: support more PAM status codes over + the nslcd protocol + +2011-04-29 18:19 arthur + + * [r1439] nslcd/shadow.c, pynslcd/shadow.py: set maxdays to -1 to + indicate no expiry (instead of a long time) + +2011-04-28 18:47 arthur + + * [r1438] pynslcd/alias.py, pynslcd/common.py, pynslcd/ether.py, + pynslcd/group.py, pynslcd/host.py, pynslcd/netgroup.py, + pynslcd/network.py, pynslcd/pam.py, pynslcd/passwd.py, + pynslcd/protocol.py, pynslcd/rpc.py, pynslcd/service.py, + pynslcd/shadow.py: put standard library imports before + application imports and remove some unused imports + +2011-04-28 18:32 arthur + + * [r1437] pynslcd/group.py: remove duplicate and wrong write() + method + +2011-04-24 21:01 arthur + + * [r1436] nslcd/pam.c: make request indicator shorter + +2011-04-24 20:54 arthur + + * [r1435] nslcd.h: document use of returned authorisation message + +2011-04-24 20:52 arthur + + * [r1434] nslcd/pam.c: no longer use the userdn parameter passed + along with each request (this may mean one or two more lookups + when doing authentication but simplifies things) + +2011-04-24 20:26 arthur + + * [r1433] tests/test_pamcmds.expect: improve handling of + test_login_unknown + +2011-04-22 10:02 arthur + + * [r1431] nslcd/myldap.c: report correct reported error from + ldap_abandon() + +2011-04-18 21:30 arthur + + * [r1430] nslcd/nslcd.c: fix r1429 to properly handle absence of + RTLD_NODELETE + +2011-04-18 20:53 arthur + + * [r1429] nslcd/nslcd.c: support systems without RTLD_NODELETE + +2011-04-16 14:00 arthur + + * [r1428] nslcd.conf: add example configuration provided by Wesley + Mason + +2011-04-15 21:20 arthur + + * [r1427] compat/Makefile.am, compat/strndup.c, compat/strndup.h, + configure.ac, nslcd/group.c, nslcd/passwd.c: provide replacement + implementation for strndup() for systems that don't have it + +2011-04-15 21:20 arthur + + * [r1426] AUTHORS: add Wesley Mason to AUTHOS file (was missing + from r1425) + +2011-04-15 21:16 arthur + + * [r1425] man/nslcd.conf.5.xml, nslcd/common.c, nslcd/common.h, + nslcd/group.c, nslcd/passwd.c: support using the objectSid + attribute to provide numeric user and group ids, based on a patch + by Wesley Mason + +2011-04-15 19:10 arthur + + * [r1424] tests/test_nsscmds.sh, tests/test_pamcmds.expect, + tests/test_pamcmds.sh: allow running test_{nss,pam}cmds tests + from another directory + +2011-04-03 21:10 arthur + + * [r1423] nslcd/group.c, nslcd/pam.c, nslcd/passwd.c: make user and + group name validation errors a little more informative + +2011-03-31 20:50 arthur + + * [r1422] AUTHORS: add some people who seemed to be missing from + the AUTHORS file + +2011-03-31 20:22 arthur + + * [r1421] common/tio.c: tv_usec in struct timeval must be lower + than 1000000 (patch by SATOH Fumiyasu) + +2011-03-31 20:16 arthur + + * [r1420] AUTHORS, Makefile.am: use $(mkinstalldirs) instead of + $(INSTALL_DATA) -D because -D is not supported on all operating + systems (patch by SATOH Fumiyasu) + +2011-03-31 19:16 arthur + + * [r1419] man/nslcd.conf.5.xml, nslcd/cfg.c: allow usernames of + only two characters + +2011-03-26 20:51 arthur + + * [r1417] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.8.2 release + +2011-03-26 16:16 arthur + + * [r1416] tests/Makefile.am, tests/test_nsscmds.sh, + tests/test_pamcmds.sh: ensure that all test source files are + distibuted and can tests can be run when source directory differs + from build directory + +2011-03-26 14:36 arthur + + * [r1415] pynslcd/common.py: sync validname regular expression with + nslcd + +2011-03-25 21:39 arthur + + * [r1414] configure.ac, nslcd/nslcd.c: no longer indefinitely wait + for all worker threads to finish before exiting (but wait a few + seconds on platforms with pthread_timedjoin_np()) + +2011-03-25 16:15 arthur + + * [r1413] tests/Makefile.am, tests/test_cfg.c, tests/test_common.c, + tests/test_myldap.c: re-organise tests somewhat making things + more consistent + +2011-03-25 16:08 arthur + + * [r1412] debian/nslcd.config, debian/nslcd.postinst: integrate + patch by Daniel Dehennin to not loose debconf values of + previously set options with dpkg-reconfigure + +2011-03-25 13:30 arthur + + * [r1411] configure.ac, man/nslcd.conf.5.xml, nslcd/cfg.c, + nslcd/cfg.h, nslcd/common.c, tests/Makefile.am, + tests/test_common.c: implement a validnames option that can be + used to fine-tune the test for valid user and group names using a + regular expression + +2011-03-24 22:19 arthur + + * [r1410] pynslcd/protocol.py, pynslcd/pynslcd.py, pynslcd/rpc.py, + pynslcd/service.py: implement service, protocol and rpc lookups + +2011-03-24 22:18 arthur + + * [r1409] pynslcd/host.py, pynslcd/network.py: fix the case where + the RDN is for some reason not in the cn + +2011-03-24 22:15 arthur + + * [r1408] pynslcd/pam.py: fix configuration name + +2011-03-24 22:09 arthur + + * [r1407] pynslcd/mypidfile.py: truncate pidfile to ensure remains + of previous value is gone + +2011-03-23 21:55 arthur + + * [r1406] pynslcd/host.py: fix use of spaces + +2011-03-23 21:43 arthur + + * [r1405] nslcd/protocol.c, nslcd/shadow.c: fix descriptions of + files + +2011-03-23 21:28 arthur + + * [r1403] compat/daemon.h, configure.ac, nslcd/nslcd.c: provide a + definition of daemon() for systems that lack it + +2011-03-23 20:30 arthur + + * [r1402] compat/ether.h: typo fix in comment + +2011-03-19 15:14 arthur + + * [r1401] Makefile.am, common, compat, nslcd, nss, pam, tests, + tests/test_expr.c, tests/test_pamcmds.expect, tests/test_tio.c: + more tests and general test improvements + +2011-03-19 15:14 arthur + + * [r1400] common/expr.c, nslcd/myldap.h, nslcd/nslcd.c, + nss/common.h, nss/prototypes.h, pam/common.h, pam/pam.c: small + code improvements + +2011-03-19 15:13 arthur + + * [r1399] nslcd/log.c, nslcd/log.h: remove logging functionality + that isn't used + +2011-03-18 14:33 arthur + + * [r1398] tests, tests/Makefile.am, tests/in_testenv.sh, + tests/test_nsscmds.sh, tests/test_pamcmds.expect, + tests/test_pamcmds.sh: implement test cases for some of the + common PAM actions (test environment required for this) + +2011-03-17 21:02 arthur + + * [r1397] configure.ac, tests/Makefile.am, tests/common.h, + tests/test_cfg.c, tests/test_common.c, tests/test_expr.c, + tests/test_getpeercred.c, tests/test_myldap.c, tests/test_tio.c: + put all assertion functions and compatibility code into one + header file + +2011-03-17 21:01 arthur + + * [r1396] nslcd.conf: put idle_timelimit option in Active Directory + example with low enough default + +2011-03-16 21:54 arthur + + * [r1395] tests/Makefile.am, tests/test_aliases.c, + tests/test_ethers.c, tests/test_group.c, tests/test_hosts.c, + tests/test_netgroup.c, tests/test_networks.c, + tests/test_nslcd_group.c, tests/test_passwd.c, + tests/test_protocols.c, tests/test_rpc.c, tests/test_services.c, + tests/test_shadow.c: remove legacy test code that is no longer + used + +2011-03-14 21:42 arthur + + * [r1394] pam/pam.c: check for user existence before trying + password change + +2011-03-14 20:19 arthur + + * [r1393] common/tio.c: fix a problem in the timeout paramater that + was being passed to select() and could contain too many µsec + (fixes Solaris runtime issue) + +2011-03-13 15:25 arthur + + * [r1392] tests/test_nsscmds.sh: fix name of script in header + +2011-03-12 08:41 arthur + + * [r1391] configure.ac: include the resolv library for hstrerror() + on platforms that need it (thanks Peter Bray) + +2011-03-12 08:34 arthur + + * [r1390] nslcd/common.h, nslcd/pam.c: put all HOST_NAME_MAX + fallbacks in common.h and fall back to _POSIX_HOST_NAME_MAX + (thanks Peter Bray) + +2011-03-11 20:37 arthur + + * [r1389] Makefile.am: ensure that permissions are sane in the + distributed tarball + +2011-03-11 18:02 arthur + + * [r1388] nslcd/myldap.c: fix problem with endless loop on + incorrect password + +2011-03-11 15:49 arthur + + * [r1387] nslcd/common.c, nslcd/common.h: move HOST_NAME_MAX + fallback definition to header file + +2011-03-10 21:45 arthur + + * [r1385] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.8.1 release + +2011-03-10 20:35 arthur + + * [r1384] Makefile.am, common/tio.c, compat/Makefile.am, + compat/ether.h, compat/ldap_compat.h, compat/pam_get_authtok.c, + man/Makefile.am, nslcd/attmap.c, nslcd/attmap.h, nslcd/common.c, + nslcd/common.h, nss/prototypes.h, pam/common.h, pynslcd/ether.py, + pynslcd/pynslcd.py, pynslcd/tio.py: update copyright headers to + add missing years + +2011-03-09 22:33 arthur + + * [r1383] nslcd/pam.c: fix compiler warning + +2011-03-09 22:32 arthur + + * [r1382] nslcd/pam.c, nslcd/passwd.c: properly handle + user-not-found errors when doing authentication (CVE-2011-0438) + +2011-03-06 15:58 arthur + + * [r1381] pynslcd/Makefile.am, pynslcd/netgroup.py, + pynslcd/pynslcd.py: implement module for netgroup lookups + +2011-03-06 15:09 arthur + + * [r1380] pynslcd/Makefile.am, pynslcd/network.py, + pynslcd/pynslcd.py: add network name lookups + +2011-03-06 15:06 arthur + + * [r1379] tests/test.ldif.gz, tests/test_nsscmds.sh: add some test + groups and add the arthur user to them to test whether all are + returned correctly + +2011-03-06 14:52 arthur + + * [r1378] Makefile.am: pass --enable-pynslcd with distcheck + +2011-03-06 14:52 arthur + + * [r1377] pynslcd/Makefile.am: clean up compiled python files + +2011-03-06 14:49 arthur + + * [r1376] pynslcd/host.py: fix search filter objectClass for hosts + +2011-03-06 14:23 arthur + + * [r1375] nslcd/log.c, nslcd/log.h, nslcd/nslcd.c: ensure that + session id is only logged while handling a connection + +2011-03-06 13:01 arthur + + * [r1374] man/nslcd.conf.5.xml: note that attribute mapping + expressions cannot be used for all attributes + +2011-02-14 21:12 arthur + + * [r1373] pynslcd/Makefile.am, pynslcd/host.py, pynslcd/pynslcd.py, + pynslcd/tio.py: implement module for hostname lookups + +2011-02-14 21:11 arthur + + * [r1372] pynslcd/ether.py: fix comment + +2011-02-14 21:08 arthur + + * [r1371] pynslcd/Makefile.am, pynslcd/debugio.py: clean up and add + missing files to installation + +2011-02-11 22:18 arthur + + * [r1370] configure.ac: fix FreeBSD nss_ldap soname (as seen in + current FreeBSD packaging) + +2011-02-11 22:16 arthur + + * [r1369] nslcd/nslcd.c: create the directory for the socket and + pidfile + +2011-01-29 20:19 arthur + + * [r1368] man/nslcd.conf.5.xml: document a proper replacement for + pam_check_host_attr (thanks Luca Capello) and add a section on + quoting + +2011-01-29 20:15 arthur + + * [r1367] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/common.c, + nslcd/common.h, nslcd/pam.c: implement a fqdn variable that can + be used inside pam_authz_search filters + +2011-01-23 20:59 arthur + + * [r1366] man/nslcd.conf.5.xml: name pam_check_service_attr and + pam_check_host_attr options in manual page and indicate how + pam_authz_search replaces them + +2011-01-05 19:39 arthur + + * [r1365] AUTHORS, HACKING, configure.ac, debian/copyright, + nss/Makefile.am, nss/bsdnss.c, nss/exports.freebsd, + nss/prototypes.h: add FreeBSD support, partially imported from + the FreeBSD port (thanks to Jacques Vidrine, Artem Kazakov and + Alexander V. Chernikov) + +2011-01-01 14:46 arthur + + * [r1364] nss/Makefile.am: put solnss.c under + EXTRA_nss_ldap_so_SOURCES + +2011-01-01 14:25 arthur + + * [r1363] man/nslcd.8.xml, man/nslcd.conf.5.xml, + man/pam_ldap.8.xml: add ids to options so we can more easily + reference them from elsewhere (especially useful for generated + HTML) + +2011-01-01 14:12 arthur + + * [r1362] nslcd/myldap.c: include definition of rc in all code + paths because it's used most of the time + +2011-01-01 14:10 arthur + + * [r1361] configure.ac: fix quoting of NSS_MODULE_OBJS expression + to one that is supported by more shells + +2011-01-01 14:07 arthur + + * [r1360] nss/Makefile.am: ensure that solnss.c ends up in tarball + diff --git a/ChangeLog-2006 b/ChangeLog-2006 new file mode 100644 index 0000000..98745ac --- /dev/null +++ b/ChangeLog-2006 @@ -0,0 +1,801 @@ +2006-12-31 arthur + + * [r210] nslcd-common.h: if the string to write is NULL, write an + empty string + * [r209] nslcd-common.h: ensure that all arrays that are allocated + in the buffer are now aligned to the pointer size + * [r208] nslcd-common.h, nss/hosts.c: extract some more common + macros + +2006-12-30 arthur + + * [r207] nslcd/ldap-nss.c, tests/test_group.c: get rid of a few + warnings + +2006-12-29 arthur + + * [r206] config.sub: update to newer version again (got lost in + r205) + * [r205] config.sub, nslcd/group.c, nslcd/ldap-nss.c, + nslcd/ldap-nss.h, nslcd/util.c: get rid of debug() function and + call log_log() instead + +2006-12-27 arthur + + * [r204] nslcd-common.h, nslcd/alias.c, nslcd/common.h, + nslcd/ether.c, nslcd/group.c, nslcd/host.c, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c: do not allocate new memory with + malloc() for each request with a string parameter but use a + buffer allocated on the stack instead (this simplifies free()-ing + the buffer(s) in case of problems) + +2006-12-25 arthur + + * [r203] nslcd/dnsconfig.c, nslcd/group.c, nslcd/ldap-nss.c, + nslcd/ldap-nss.h, nslcd/passwd.c, nslcd/util.c, nslcd/util.h: get + rid of NSS_BUFSIZ, rename _nss_ldap_oc_check() to + has_objectclass(), redo _nss_ldap_escape_string() with simpler + logic and slightly different signature and redid layout of some + code + +2006-12-23 arthur + + * [r201] ChangeLog, NEWS, TODO, configure.ac, debian/changelog: get + files ready for 0.1 release + +2006-12-22 arthur + + * [r200] nslcd.8: fix name of configuration file and update date + and version number + * [r199] NEWS, TODO, nslcd/alias.c, nslcd/dnsconfig.c, + nslcd/dnsconfig.h, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/ldap-schema.c, + nslcd/ldap-schema.h, nslcd/netgroup.c, nslcd/network.c, + nslcd/pagectrl.c, nslcd/pagectrl.h, nslcd/passwd.c, + nslcd/protocol.c, nslcd/resolve.c, nslcd/resolve.h, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, nslcd/util.c, nslcd/util.h, + nss-ldapd.conf, nss-ldapd.conf.5, nss/exports.linux: remove last + keyword and disable keyword expansion + * [r198] nslcd/Makefile.am: make list of source files a little + clearer + * [r197] HACKING: change reference to directory name + +2006-12-21 arthur + + * [r196] Makefile.am, configure.ac, debian/copyright, nslcd, + server: rename server directory to nslcd + * [r195] ChangeLog, Makefile.am: add code for generating ChangeLog + and add initial ChangeLog + +2006-12-21 arthur + + * [r194] .: change trunk location in repository to match package + name + * [r193] server/alias.c, server/dnsconfig.c, server/dnsconfig.h, + server/ether.c, server/group.c, server/host.c, server/ldap-nss.c, + server/ldap-nss.h, server/ldap-schema.c, server/ldap-schema.h, + server/log.c, server/log.h, server/netgroup.c, server/network.c, + server/pagectrl.c, server/pagectrl.h, server/passwd.c, + server/protocol.c, server/rpc.c, server/service.c, + server/shadow.c, server/util.c, server/util.h, server/xmalloc.c, + server/xmalloc.h: normalize copyright headers + +2006-12-20 arthur + + * [r192] debian/copyright: update copyright file with current + copyright information + * [r191] Makefile.am, nss/Makefile.am, server/Makefile.am, + tests/Makefile.am: properly capitalize company name + * [r190] README: fix wrapping + * [r189] README: integrate remaining parts in documentation + * [r188] Makefile.am, debian/libnss-ldapd.examples: ship + nss-ldapd.conf as an example in the Debian package + +2006-12-19 arthur + + * [r187] ., debian/changelog, debian/control: change Debian source + package name to nss-ldapd + * [r186] Makefile.am: do not try to ship gone README.Debian but do + ship new HACKING + * [r185] nss-ldapd.conf: get rid of pam stuff + * [r184] HACKING, NEWS, README, TODO: first step at improving + documentation + * [r183] configure.ac, debian/changelog: change version number to + 0.1 + * [r182] debian/libnss-ldapd.postinst: change some tests with grep + to be correct, add some comments and improve import of old + configuration file + * [r181] debian/README.Debian: the README.Debian does not contain + any more relevant information + * [r180] server/nslcd.c: add TODO + * [r179] Makefile.am, configure.ac, debian/libnss-ldapd.config, + debian/libnss-ldapd.nslcd.init, debian/libnss-ldapd.postinst, + debian/libnss-ldapd.postrm, debian/rules, ldap.conf, + nss-ldapd.conf, nss-ldapd.conf.5, nss_ldap.5: change default + configuration file name to /etc/nss-ldapd.conf + +2006-12-18 arthur + + * [r178] Makefile.am, nslcd.8: add initial nslcd manual page + * [r177] server/nslcd.c: output of --help no longer shows --config + option (which isn't there) + * [r176] configure.ac: change name of package also in configure + * [r175] debian/libnss-ldapd.config: handle cases where commands in + backticks return an error code + * [r174] nss/hosts.c: only set h_errno to error value on problems + and change the returned value in some cases + +2006-12-17 arthur + + * [r173] debian/libnss-ldapd.nslcd.init: report process id in + status + * [r172] configure.ac, debian/changelog, + debian/libnss-ldapd.config, debian/libnss-ldapd.nslcd.init, + debian/libnss-ldapd.postinst, nss/common.h, server/nslcd.c, + tests/test_networks.c: remove trailing spaces + * [r171] nss/prototypes.h: add note about glibc manual + * [r170] nss/Makefile.am: fix comment as to installing libraries + * [r169] debian/control: add a snippet to the package description + as to what the main differences to libnss-ldap are + * [r168] debian/rules: move the nss libraries to /lib instead of + /usr/lib + * [r167] debian/rules: remove some unneeded configure options + +2006-12-16 arthur + + * [r166] Makefile.am, debian/libnss-ldapd.lintian-overrides, + debian/rules: fix some lintian warnings regarding shared + libraries with an override file and generating shlibs for now + * [r165] debian/rules: fix configuration file manual page name + * [r164] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fr.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po: end + every short description line with a colon (and run + debconf-updatepo) (thanks lintian) + * [r163] server/nslcd.c: set correct permissions on socket creation + and remove socket and pidfile on exit + * [r162] nss/exports.linux, nss/group.c, nss/prototypes.h, + tests/test_group.c: remove _nss_ldap_initgroups_dyn() from + interface for now because it is currently not working + * [r161] configure.ac: fix configure --help strings to be more + consistent and list default values + * [r160] Makefile.am: fix debian files to ship and split off those + files into a separate variable + * [r159] debian/po/POTFILES.in, debian/po/ca.po, debian/po/cs.po, + debian/po/da.po, debian/po/de.po, debian/po/es.po, + debian/po/fr.po, debian/po/ja.po, debian/po/nl.po, + debian/po/pt_BR.po, debian/po/ru.po, debian/po/sv.po, + debian/po/templates.pot, debian/po/vi.po: update po and pot files + based on current templates + * [r158] debian/config, debian/libnss-ldapd.config, + debian/libnss-ldapd.postinst, debian/libnss-ldapd.postrm, + debian/libnss-ldapd.templates, debian/rules, debian/templates: + redid Debian packaging: on installation a search is done for any + reasonable configuration information (existing nss_ldap config, + hostname info, etc), configuring nsswitch.conf is also done and + all files in the debian directory have more logical names + * [r157] Makefile.am, debian/libnss-ldapd.nslcd.init, debian/rules: + ship an init script for starting nslcd + +2006-12-14 arthur + + * [r156] AUTHORS: fix format of AUTHORS file and include new + authors + * [r155] ANNOUNCE, README: include ANNOUNCE document in README + * [r154] ChangeLog, NEWS: rename ChangeLog to NEWS and change + formatting of file to follow common format + +2006-12-13 arthur + + * [r153] NEWS, TODO: NEWS looks more like a TODO + +2006-12-08 arthur + + * [r152] Makefile.am, debian/changelog, debian/control, + debian/libnss-ldapd.postinst, debian/rules: clean up Debian + packaging a bit + * [r151] tests/ldaptest.pl, tests/nsswitch.test, tests/testd.c, + tests/testgr.c, tests/testnss.c, tests/testpw.c, tests/testpw3.c, + tests/testpw4.c, tests/testpw5.c, tests/testpw6.c: get rid of old + test code (most of it should be covered by the new test code) + * [r150] .: ignore generated debuild files + * [r149] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fr.po, + debian/po/ja.po, debian/po/nl.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po, debian/templates: do not make default values + translatable + * [r148] nss/common.c: fix indentation + * [r147] README, debian/LDAP-Permissions.txt, debian/examples, + debian/libnss-ldapd.docs: get rid of more documentation in an + attempt to include all useful documentation in one place + * [r146] Makefile.am, README, doc: reasonable configuration + information (existing nss_ldap config, parts in top-level README + * [r145] configure.ac, nslcd.h: specify socket and pidfile location + with configure script + * [r144] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fr.po, + debian/po/ja.po, debian/po/nl.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: run debconf-updatepo to get pot and po files in + a consistent state + * [r143] debian/control: get rid of cdbs build dependency + +2006-12-07 arthur + + * [r142] debian, debian/README.Debian, debian/changelog, + debian/control, debian/libnss-ldap.dirs, debian/libnss-ldap.init, + debian/libnss-ldap.install, debian/libnss-ldap.links, + debian/libnss-ldap.postinst, debian/libnss-ldap.postrm, + debian/libnss-ldapd.docs, debian/libnss-ldapd.postinst, + debian/libnss-ldapd.postrm, debian/rules: initial step to get + working Debian packaging + +2006-12-05 arthur + + * [r141] Makefile.am, compile, config.sub, configure.ac, + nss/Makefile.am, server/Makefile.am: clean up build scripts to + only link nslcd to OpenSSL and to cleanly create a nss_ldap.so + file + * [r140] server/ldap-nss.c, server/ldap-nss.h: get rid of + _nss_ldap_get_ld_errno() which wasn't used + +2006-12-03 arthur + + * [r139] server/nslcd.c: fix logging levels and remove some + commented out code + * [r138] server/ldap-nss.c, server/ldap-schema.c, server/passwd.c: + get rid of some more unneeded code + * [r137] tests/Makefile.am: split out common files into own + variable and disable (comment out) protocol debugging + * [r136] nss/exports.linux: regenerate from prototypes.h + +2006-11-30 arthur + + * [r135] server/Makefile.am, server/alias.c, server/common.h, + server/ether.c, server/group.c, server/host.c, server/ldap-nss.c, + server/netgroup.c, server/network.c, server/nslcd-server.c, + server/nslcd-server.h, server/nslcd.c, server/passwd.c, + server/protocol.c, server/rpc.c, server/service.c, + server/shadow.c, server/util.c: implement a simple threading + solution and move code from nslcd-server.c to nslcd.c + +2006-11-28 arthur + + * [r134] nslcd.h, nss/aliases.c, nss/ethers.c, nss/group.c, + nss/passwd.c, nss/protocols.c, nss/rpc.c, nss/services.c, + nss/shadow.c, server/alias.c, server/ether.c, server/group.c, + server/passwd.c, server/protocol.c, server/rpc.c, + server/service.c, server/shadow.c: rename LDF_ marcos to NSLCD_ + macros to have a single namespace + * [r133] server: ignore generated nslcd binary + * [r132] configure.ac: look for nslcd.h now since nslcd.c has been + moved into the server directory + * [r131] ., Makefile.am, configure.ac, exports.linux, log.c, log.h, + nslcd-common.h, nslcd-server.c, nslcd-server.h, nslcd.c, + nss/Makefile.am, nss/exports.linux, server, server/Makefile.am, + server/log.c, server/log.h, server/nslcd-server.c, + server/nslcd-server.h, server/nslcd.c, server/xmalloc.c, + server/xmalloc.h, testnss.c, tests, tests/Makefile.am, + tests/test_aliases.c, tests/test_ethers.c, tests/test_group.c, + tests/test_hosts.c, tests/test_netgroup.c, tests/test_networks.c, + tests/test_passwd.c, tests/test_protocols.c, tests/test_rpc.c, + tests/test_services.c, tests/test_shadow.c, tests/testnss.c, + xmalloc.c, xmalloc.h: get as many files from the root directory + as possible, moving all server related code to the server + directory and moving and splitting the test code to the tests + directory + * [r130] nslcd-server.c, nss/networks.c, server/network.c, + testnss.c: implement network name lookups on server side plus + some fixes on the client side + * [r129] nslcd-server.c, server/common.c: include config.h as first + statement + * [r128] nslcd-common.h: implement more detailed protocol logging + (dumping the actual byte values read and written) + +2006-11-27 arthur + + * [r127] Makefile.am, nslcd-client.c, nslcd-client.h, + nss/Makefile.am, nss/aliases.c, nss/common.c, nss/common.h, + nss/ethers.c, nss/group.c, nss/hosts.c, nss/netgroup.c, + nss/networks.c, nss/passwd.c, nss/protocols.c, nss/rpc.c, + nss/services.c, nss/shadow.c: get rid of nslcd-client.{c,h} and + move it to nss/common.{c,h}, this ensures that all code that is + needed for the nss part is in the nss directory + * [r126] server/host.c, server/rpc.c: fix typos + +2006-11-26 arthur + + * [r125] server/Makefile.am, server/dnsconfig.c, + server/dnsconfig.h, server/ether.c, server/group.c, + server/ldap-nss.c, server/ldap-nss.h, server/ldap-parse.h, + server/ldap-schema.c, server/ldap-schema.h, server/network.c, + server/passwd.c, server/util.c, server/util.h: clean up header + files + * [r124] doc/autofs-4.1.3-lookup-nssldap.patch, + doc/lookup_nssldap.c, ldap.conf, nslcd-server.c, nslcd-server.h, + nslcd.h, nss/Makefile.am, nss/automount.c, nss/prototypes.h, + server/Makefile.am, server/automount.c, server/ldap-nss.h, + server/ldap-schema.c, server/ldap-schema.h, server/rpc.c, + server/util.c, server/util.h: get rid of automount map + information lookups through NSS as this is not used (at least not + with glibc), autofs-ldap looks up the information on it's own + (but does parse /etc/nsswitch.conf) + +2006-11-25 arthur + + * [r123] nslcd-server.c, nss/services.c, server/service.c, + testnss.c: implement server end of service name lookup and fix + client end to translate between host and network byte order and + to also pass protocol in request + * [r122] nslcd-common.h: fix bug that always causes a + READ_STRING_ALLOC to read to a variable called name + * [r121] nslcd-server.c, server/rpc.c, testnss.c: implement rpc + service on server side + * [r120] server/host.c: get rid of superfluous test + * [r119] server/protocol.c: only flush the stream after writing all + records + * [r118] nslcd-server.c, server/protocol.c, testnss.c: implement + protocol handling (server side) + * [r117] nslcd.h, nss/netgroup.c, nss/prototypes.h: trip trailing + whitespace + * [r116] nslcd-common.h: include stdio for definitions of fread(), + fwrite() etc + +2006-11-24 arthur + + * [r115] nslcd-server.c, server/host.c, testnss.c: implement server + end of host name lookups (without IPv6 support sofar) + * [r114] nss/hosts.c: fix problem with allocated array for storing + addresses, properly set h_errnop and check empty address (only + addresses of other address family) in nss functions, not in + read_hostent() + * [r113] nslcd-common.h: make protocol logging a little more + readable and do not use fseek() in streams because that is not + supported + +2006-11-22 arthur + + * [r112] server/alias.c, server/ether.c, server/group.c, + server/passwd.c, server/shadow.c: only flush the stream after + writing all records (not every time) and more logging consistency + * [r111] nslcd-server.c, server/shadow.c, testnss.c: implement + server end of shadow lookups + * [r110] server/alias.c, server/passwd.c: make logging a little bit + more consistent + * [r109] server/netgroup.c: add extra copyright information (the + exact same code was seen in glibc) + +2006-11-21 arthur + + * [r108] nslcd-server.c, nslcd.h, nss/netgroup.c, + server/netgroup.c, testnss.c: implement netgroup lookups, + including test code + +2006-11-19 arthur + + * [r107] nslcd.h: include a note about encoding of strings + * [r106] nslcd-server.c, server/ether.c: implement nslcd_ether_*() + functions + * [r105] nslcd-server.c, nslcd-server.h: create prototypes for all + server methods + * [r104] nss/ethers.c: write contents of ethernet address not + pointer + * [r103] server/group.c: add missing semicolon + * [r102] nslcd-common.h: add more verbose protocol logging, + including logging of errors + * [r101] ., debian, doc, nss, server, tests: ignore stale nfs files + * [r100] nss/common.h: fix bug: the readfn() function was executed + twice + +2006-11-18 arthur + + * [r99] server/group.c, server/netgroup.c: some layout changes + * [r98] nslcd.h: include changes to handle protocol, rpc, service + and netgroup nslcd calls + +2006-11-17 arthur + + * [r97] nss/Makefile.am, nss/netgroup.c, nss/prototypes.h: + implement netgroup lookups + * [r96] nss/aliases.c, nss/automount.c, nss/common.h, nss/ethers.c, + nss/group.c, nss/hosts.c, nss/networks.c, nss/passwd.c, + nss/protocols.c, nss/rpc.c, nss/services.c, nss/shadow.c: do some + refactoring in the generated code and add some documentation on + generated code in comments in common.h + +2006-11-16 arthur + + * [r95] nss/Makefile.am, nss/services.c: implement reading of + services entities + * [r94] nss/Makefile.am, nss/rpc.c: implement reading of rpc + entities + * [r93] nss/Makefile.am, nss/protocols.c: implement reading of + protocol entities + * [r92] nss/aliases.c, nss/common.h, nss/ethers.c, nss/group.c, + nss/hosts.c, nss/networks.c, nss/passwd.c, nss/shadow.c: switch + to a simpler and more compact framework to generate methods (one + reader function to deserialize a struct from the stream and + auto-generated functions) + +2006-11-15 arthur + + * [r91] nslcd.h, nss/Makefile.am, nss/networks.c, nss/prototypes.h: + implement network information lookups through NSS + * [r90] nss/hosts.c: properly filter out empty returned address + records and return NOTFOUND for entries without addresses in our + address family + +2006-11-14 arthur + + * [r89] xmalloc.h: add xxmalloc() macro to simply allocate a + structure of a certain type + * [r88] nslcd.h, nss/Makefile.am, nss/automount.c, + nss/prototypes.h: implement automounter maps lookups + * [r87] nss/common.h: just close the stream in case of problems + instead of calling endent() + +2006-11-11 arthur + + * [r86] server/group.c: include some other functions into lookup + functions to increase readability + * [r85] server/Makefile.am, server/alias.c, server/aliases.c, + server/automount.c, server/common.c, server/common.h, + server/ether.c, server/ethers.c, server/group.c, server/host.c, + server/hosts.c, server/ldap-nss.c, server/ldap-nss.h, + server/ldap-parse.h, server/ldap-schema.c, server/ldap-schema.h, + server/netgroup.c, server/network.c, server/networks.c, + server/passwd.c, server/protocol.c, server/protocols.c, + server/rpc.c, server/service.c, server/services.c, + server/shadow.c, server/util.c, server/util.h: fix naming and + copyright headers + * [r84] server/aliases.c, server/ldap-nss.c, server/ldap-nss.h, + server/util.c, server/util.h: simplify some functions to pass + file pointer around instead of struct and buffer (initially only + for alias_byname()) + * [r83] server/ldap-nss.h: some reformatting + +2006-11-10 arthur + + * [r82] nslcd.h, nss/Makefile.am, nss/aliases.c, nss/ethers.c, + nss/exports.h, nss/group.c, nss/hosts.c, nss/passwd.c, + nss/prototypes.h, nss/shadow.c, testnss.c: rename nss/exports.h + to nss/prototypes.h + * [r81] nss/exports.h, nss/group.c, nss/hosts.c, nss/passwd.c, + nss/shadow.c: switch to using prototypes that are defined in + glibc 2.3.6 + * [r80] nslcd.h, nss/Makefile.am, nss/shadow.c, testnss.c: + implement NSS-side shadow lookups (plus test code) + * [r79] nslcd.h, nss/Makefile.am, nss/ethers.c, nss/exports.h, + testnss.c: implement NSS-side ethers database lookups plus test + code + * [r78] nss/exports.h, nss/hosts.c, testnss.c: add test code for + host database and add const to function definition + * [r77] nss/aliases.c, nss/group.c, nss/hosts.c: use better names + for our thread-local file pointer + +2006-11-07 arthur + + * [r76] server/aliases.c: expand some marcos and combine some code + * [r75] server/passwd.c: expand some marcos and combine some code + +2006-11-05 arthur + + * [r74] nslcd-common.h, testnss.c: add proper copyright headers + * [r73] nslcd-server.c, nslcd-server.h, server/group.c, testnss.c: + implement group functions in server but currently + group_bymember() does not work + * [r72] nslcd-common.h: remove testing stuff + * [r71] nslcd-common.h: fix some variable usage bugs in READ_* + marcos and change protocol debugging marcos to not use variadic + arguments + +2006-11-04 arthur + + * [r70] Makefile.am, certutil, doc/nsswitch.ldap, nsswitch.ldap: + reorganize (and get rid of) some files + +2006-11-03 arthur + + * [r69] nslcd.h, nss/Makefile.am, nss/hosts.c: implement initial + host database lookups NSS-side + * [r68] nslcd-common.h: make SKIP more consistent with READ + * [r67] nslcd-server.c: clean struct sockaddr_un structure before + usage + * [r66] nslcd-common.h, nss/group.c: fix bogus reuse of tmpint32, + introducing tmp3int32 + * [r65] nslcd-common.h: split buffer management macros into + separate macros + * [r64] nslcd-common.h, nslcd.h, nss/aliases.c, nss/group.c, + server/aliases.c: rename LOOP to STRINGLIST as that is currently + the only supported format + * [r63] nslcd-common.h, nss/group.c: add _nss_ldap_initgroups_dyn() + function + * [r62] nslcd-common.h, nss/aliases.c, nss/common.h, nss/group.c, + nss/passwd.c: make loop macros common, create macros for + expanding {set,get,end}ent() functions and implement + {set,get,end}aliasent + * [r61] nslcd.h: small documentation fixes + * [r60] nslcd-server.h: implement nslcd_alias_all() server-side + * [r59] nslcd-server.c, server/aliases.c: implement + nslcd_alias_all() server-side + * [r58] server/group.c: get rid of some more unneeded code + +2006-11-02 arthur + + * [r57] server/aliases.c, server/passwd.c: some small fixes + * [r56] nslcd-client.h, nslcd-server.c, nslcd-server.h, nslcd.h, + nss/aliases.c, nss/common.c, nss/passwd.c, server/aliases.c, + server/common.c, server/passwd.c: rename some constants and + switch to a more sane naming scheme + * [r55] nss/exports.h: we only need to export + _nss_ldap_initgroups_dyn(), not _nss_ldap_initgroups() + * [r54] nslcd-client.h, nss/aliases.c, nss/group.c, nss/passwd.c: + rename READ_RESPONSE() macro to READ_RESPONSE_CODE() + +2006-11-01 arthur + + * [r53] nslcd.h, nss/Makefile.am, nss/group.c, testnss.c: implement + NSS side of getgrnam(), getgrgid() and {set,get,end}grent() + * [r52] nss/aliases.c, nss/common.h, nss/passwd.c: always set + *errnop correctly + * [r51] CVSVersionInfo.txt, Makefile.am: get rid of + CVSVersionInfo.txt + * [r50] nslcd.c: prevent recursive hostname lookups through ldap + * [r49] Makefile.am: add some files to EXTRA_DIST + * [r48] nslcd-server.c, nslcd.h, server/common.c, server/group.c, + server/passwd.c: get rid of some trailing spaces + * [r47] nslcd.c: ignore SIGPIPE and get rid of some trailing spaces + * [r46] testnss.c: only print result on success and errors on + failure + * [r45] server/common.h: do not close the server-side stream as the + main dispatcher will close it + * [r44] nss/passwd.c: implement _nss_ldap_{set,get,end}pwent() + functions with thread-local opened file + * [r43] nss/common.h: also set file pointer to NULL when closing a + stream to properly handle reuse of stream + * [r42] log.c: prefix debugging messages with DEBUG + * [r41] configure.ac: look for different file in source directory, + improve --enable-debug option and add checking for __thread + keyword + * [r40] nslcd-common.h: do not try to read and write zero length + strings and add protocol debugging option + * [r39] Makefile.am, dnsconfig.c, dnsconfig.h, ldap-nss.c, + ldap-nss.h, ldap-parse.h, ldap-schema.c, ldap-schema.h, nslcd.c, + pagectrl.c, pagectrl.h, resolve.c, resolve.h, server/Makefile.am, + server/dnsconfig.c, server/dnsconfig.h, server/ldap-nss.c, + server/ldap-nss.h, server/ldap-parse.h, server/ldap-schema.c, + server/ldap-schema.h, server/pagectrl.c, server/pagectrl.h, + server/resolve.c, server/resolve.h, server/util.c, server/util.h, + util.c, util.h: move some remaining files into the server/ + directory + +2006-10-31 arthur + + * [r38] nslcd-common.h, nslcd-server.c, nslcd-server.h, nslcd.h, + nss/aliases.c, server/aliases.c, server/passwd.c, testnss.c: + implement reading of alias information through getaliasbyname() + * [r37] nss/aliases.c, nss/common.c, nss/common.h, nss/exports.h, + nss/passwd.c: make code consistent by adding headers, removing + trailing whitespace and proper ifdefs for header files + * [r36] .: ignore more files + * [r35] nslcd-common.h: add header file defining read and write + macros + * [r34] nslcd-client.c, nslcd-client.h, nslcd-server.c, + nslcd-server.h, nslcd.h, nss/Makefile.am, nss/common.c, + nss/common.h, nss/passwd.c, server/common.h, server/passwd.c, + testnss.c: clear up protocol macros while implementing getpwuid() + and {set,get,end}pwent() functions (last not yet on NSS side) + * [r33] nslcd.h: document protocol a little better + +2006-10-30 arthur + + * [r32] Makefile.am, nslcd-client.c, nslcd-client.h, + nslcd-server.c, nslcd-server.h, nslcd.c, nslcd.h, testnss.c: get + first working version of end-to-end test of nss call using simple + test program + * [r31] Makefile.am, configure.ac: add server directory + * [r30] nss/passwd.c: get rid of some empty lines + * [r29] server, server/Makefile.am, server/common.c, + server/common.h, server/passwd.c: implement simple password + lookup with nslcd_getpwnam() function + * [r28] nss/common.h, nss/passwd.c: return read data in struct and + fix some marcos + * [r27] nss/Makefile.am: do not build libnss_ldap.so in this + directory, only build nss object functions + +2006-10-25 arthur + + * [r26] configure.ac, nss: build nss directory + * [r25] ldap-alias.c, ldap-automount.c, ldap-ethers.c, ldap-grp.c, + ldap-hosts.c, ldap-netgrp.c, ldap-network.c, ldap-proto.c, + ldap-pwd.c, ldap-rpc.c, ldap-service.c, ldap-spwd.c, server, + server/aliases.c, server/automount.c, server/ethers.c, + server/group.c, server/hosts.c, server/netgroup.c, + server/networks.c, server/passwd.c, server/protocols.c, + server/rpc.c, server/services.c, server/shadow.c: move ldap + server code into separate directory + * [r24] Makefile.am, nslcd-client.c, nslcd-client.h, nslcd.h, nss, + nss/Makefile.am, nss/aliases.c, nss/common.c, nss/common.h, + nss/exports.h, nss/passwd.c: add some basic minimal NSS code that + can be generated from macros + +2006-10-23 arthur + + * [r23] ., Makefile.am, configure.ac, log.c, log.h, nslcd-client.c, + nslcd-client.h, nslcd-server.c, nslcd-server.h, nslcd.c, nslcd.h, + xmalloc.c, xmalloc.h: implemented basic client/server setup with + a thin client comminicating with a local server over a socket + (initial version of code, much needs to be done) + * [r22] ldap-grp.c, ldap-parse.h: rearrange functions in more + logical order + * [r21] ldap-nss.h: align comments + * [r20] ldap-pwd.c: export function _nss_ldap_parse_pw() + +2006-10-17 arthur + + * [r19] Makefile.am, dnsconfig.c, dnsconfig.h, ldap-alias.c, + ldap-automount.c, ldap-ethers.c, ldap-grp.c, ldap-hosts.c, + ldap-netgrp.c, ldap-network.c, ldap-nss.c, ldap-nss.h, + ldap-parse.h, ldap-proto.c, ldap-pwd.c, ldap-rpc.c, + ldap-schema.c, ldap-schema.h, ldap-service.c, ldap-spwd.c, ltf.c, + ltf.h, pagectrl.c, pagectrl.h, resolve.c, resolve.h, util.c: get + rid of ltf files (which contain NPL licenced code btw) clean up + includes and general small code cleanups + * [r18] .cvsignore: get rid of this file + +2006-10-16 arthur + + * [r17] Makefile.am, dnsconfig.c, dnsconfig.h, ldap-alias.c, + ldap-automount.c, ldap-ethers.c, ldap-grp.c, ldap-hosts.c, + ldap-netgrp.c, ldap-network.c, ldap-nss.c, ldap-nss.h, + ldap-parse.h, ldap-proto.c, ldap-pwd.c, ldap-rpc.c, + ldap-schema.h, ldap-service.c, ldap-spwd.c, ltf.c, nss_common.h, + nss_ldap.spec, util.c, util.h: some more cleanups, expanding some + MACROs and typedefs and get rid of some more code + +2006-10-15 arthur + + * [r16] configure.ac: add --enable-warnings option for extra + compiler warnings + +2006-10-12 arthur + + * [r15] Makefile.am, exports.solaris, ldap-alias.c, ldap-alias.h, + ldap-automount.c, ldap-automount.h, ldap-bp.c, ldap-bp.h, + ldap-ethers.c, ldap-ethers.h, ldap-grp.c, ldap-grp.h, + ldap-hosts.c, ldap-hosts.h, ldap-netgrp.c, ldap-netgrp.h, + ldap-network.c, ldap-network.h, ldap-proto.c, ldap-proto.h, + ldap-pwd.c, ldap-pwd.h, ldap-rpc.c, ldap-rpc.h, ldap-service.c, + ldap-service.h, ldap-spwd.c, ldap-spwd.h: get rid of some + unnecessary header files (and a c file) + * [r14] ANNOUNCE, AUTHORS, COPYING, ChangeLog, Makefile.am, NEWS, + README, certutil, configure.ac, dnsconfig.c, dnsconfig.h, + ldap-alias.c, ldap-alias.h, ldap-automount.c, ldap-automount.h, + ldap-bp.c, ldap-bp.h, ldap-ethers.c, ldap-ethers.h, ldap-grp.c, + ldap-grp.h, ldap-hosts.c, ldap-hosts.h, ldap-netgrp.c, + ldap-netgrp.h, ldap-network.c, ldap-network.h, ldap-nss.c, + ldap-nss.h, ldap-parse.h, ldap-proto.c, ldap-proto.h, ldap-pwd.c, + ldap-pwd.h, ldap-rpc.c, ldap-rpc.h, ldap-schema.c, ldap-schema.h, + ldap-service.c, ldap-service.h, ldap-spwd.c, ldap-spwd.h, + ldap.conf, ltf.c, ltf.h, nss_common.h, nss_ldap.5, nss_ldap.spec, + pagectrl.c, pagectrl.h, resolve.c, resolve.h, util.c, util.h: + remove trailing spaces + * [r13] ANNOUNCE, AUTHORS, Makefile.am, NEWS, README, certutil, + configure.ac, dnsconfig.c, dnsconfig.h, exports.aix, + exports.hpux, exports.linux, exports.solaris, ldap-alias.c, + ldap-alias.h, ldap-automount.c, ldap-automount.h, ldap-bp.c, + ldap-bp.h, ldap-ethers.c, ldap-ethers.h, ldap-grp.c, ldap-grp.h, + ldap-hosts.c, ldap-hosts.h, ldap-netgrp.c, ldap-netgrp.h, + ldap-network.c, ldap-network.h, ldap-nss.c, ldap-nss.h, + ldap-parse.h, ldap-proto.c, ldap-proto.h, ldap-pwd.c, ldap-rpc.c, + ldap-rpc.h, ldap-schema.c, ldap-schema.h, ldap-service.c, + ldap-service.h, ldap-spwd.c, ldap-spwd.h, ldap.conf, ltf.c, + nsswitch.ldap, pagectrl.c, resolve.c, resolve.h, util.c, util.h: + some more small cleanups of code for non-supported systems and + convert tabs to spaces + * [r12] configure.ac: include templates from acconfig.h into + configure.ac + * [r11] debian/rules: set as executable + * [r10] Makefile.am, aix_authmeth.c, dnsconfig.c, dnsconfig.h, + irs-grp.c, irs-hosts.c, irs-netgrp.c, irs-network.c, irs-nss.c, + irs-nss.h, irs-proto.c, irs-pwd.c, irs-service.c, irs.h, + ldap-alias.c, ldap-alias.h, ldap-automount.c, ldap-automount.h, + ldap-bp.c, ldap-bp.h, ldap-ethers.c, ldap-ethers.h, ldap-grp.c, + ldap-grp.h, ldap-hosts.c, ldap-hosts.h, ldap-netgrp.c, + ldap-netgrp.h, ldap-network.c, ldap-network.h, ldap-nss.c, + ldap-nss.h, ldap-parse.h, ldap-proto.c, ldap-proto.h, ldap-pwd.c, + ldap-pwd.h, ldap-rpc.c, ldap-rpc.h, ldap-schema.c, ldap-schema.h, + ldap-service.c, ldap-service.h, ldap-sldap.c, ldap-sldap.h, + ldap-spwd.c, ldap-spwd.h, ltf.c, ltf.h, nss_common.h, + nss_dbdefs.h, nss_ldap.5, pagectrl.c, pagectrl.h, resolve.c, + resolve.h, snprintf.c, snprintf.h, util.c, util.h: first round of + cleanups, all non-glibc NSS stuff has been removed, because we + are going to do some major restructuring it will not likely + remain valid anyway and we can always re-add it later + * [r9] CVSVersionInfo.txt, ChangeLog, NEWS, aix_authmeth.c, + certutil, dnsconfig.c, dnsconfig.h, + doc/autofs-4.1.3-lookup-nssldap.patch, doc/lookup_nssldap.c, + exports.linux, exports.solaris, irs-grp.c, irs-hosts.c, + irs-netgrp.c, irs-network.c, irs-nss.c, irs-nss.h, irs-proto.c, + irs-pwd.c, irs-service.c, irs.h, ldap-alias.c, ldap-alias.h, + ldap-automount.c, ldap-automount.h, ldap-bp.c, ldap-bp.h, + ldap-ethers.c, ldap-ethers.h, ldap-grp.c, ldap-grp.h, + ldap-hosts.c, ldap-hosts.h, ldap-netgrp.c, ldap-netgrp.h, + ldap-network.c, ldap-network.h, ldap-nss.c, ldap-nss.h, + ldap-parse.h, ldap-proto.c, ldap-proto.h, ldap-pwd.c, ldap-pwd.h, + ldap-rpc.c, ldap-rpc.h, ldap-schema.c, ldap-schema.h, + ldap-service.c, ldap-service.h, ldap-sldap.c, ldap-sldap.h, + ldap-spwd.c, ldap-spwd.h, ldap.conf, ltf.c, ltf.h, nss_common.h, + nss_dbdefs.h, nss_ldap.5, nsswitch.ldap, pagectrl.c, pagectrl.h, + resolve.c, resolve.h, snprintf.c, snprintf.h, + tests/nsswitch.test, tests/testpw.c, tests/testpw4.c, + tests/testpw5.c, tests/testpw6.c, util.c, util.h: add keyword + expansion (svn:keywords) to all files containing keywords + * [r8] Makefile.am, configure.ac: add West to copyrights notice + +2006-10-11 arthur + + * [r7] INSTALL: install newer version from automake + * [r6] Makefile.am, acconfig.h, aclocal.m4, autogen.sh, + config.guess, config.h.in, config.sub, configure.ac, + configure.in, depcomp, install-sh, missing, mkinstalldirs, + stamp-h, stamp-h.in: first step in cleaning up build process + (switch to newer autoconf/automake and remove generated files + from version control) + * [r5] ., Makefile.in, configure: remove some files from version + control and add more ignores + * [r4] ., debian: ignore some generated files + * [r3] .: branch off latest Debian version + +2006-10-11 arthur + + * [r2] ., Makefile.am, Makefile.in, aclocal.m4, configure, + configure.in, debian, debian/LDAP-Permissions.txt, + debian/README.Debian, debian/changelog, debian/compat, + debian/config, debian/control, debian/copyright, debian/examples, + debian/examples/groups.ldif, debian/examples/people.ldif, + debian/libnss-ldap.dirs, debian/libnss-ldap.init, + debian/libnss-ldap.install, debian/libnss-ldap.links, + debian/libnss-ldap.postinst, debian/libnss-ldap.postrm, + debian/po, debian/po/POTFILES.in, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fr.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po, + debian/rules, debian/templates, ldap-nss.c, ldap-nss.h, + ldap-pwd.c, ldap.conf, stamp-h: import Debian release 251-5.2 + +2006-10-11 arthur + + * [r1] ., .cvsignore, ANNOUNCE, AUTHORS, COPYING, + CVSVersionInfo.txt, ChangeLog, INSTALL, Makefile.am, Makefile.in, + NEWS, README, acconfig.h, aclocal.m4, aix_authmeth.c, autogen.sh, + certutil, config.guess, config.h.in, config.sub, configure, + configure.in, depcomp, dnsconfig.c, dnsconfig.h, doc, + doc/README.AIX, doc/README.HPUX, doc/README.IRS, doc/README.SFU, + doc/README.paged, doc/SolarisInstallNotes.txt, + doc/autofs-4.1.3-lookup-nssldap.patch, doc/lookup_nssldap.c, + exports.aix, exports.hpux, exports.linux, exports.solaris, + install-sh, irs-grp.c, irs-hosts.c, irs-netgrp.c, irs-network.c, + irs-nss.c, irs-nss.h, irs-proto.c, irs-pwd.c, irs-service.c, + irs.h, ldap-alias.c, ldap-alias.h, ldap-automount.c, + ldap-automount.h, ldap-bp.c, ldap-bp.h, ldap-ethers.c, + ldap-ethers.h, ldap-grp.c, ldap-grp.h, ldap-hosts.c, + ldap-hosts.h, ldap-netgrp.c, ldap-netgrp.h, ldap-network.c, + ldap-network.h, ldap-nss.c, ldap-nss.h, ldap-parse.h, + ldap-proto.c, ldap-proto.h, ldap-pwd.c, ldap-pwd.h, ldap-rpc.c, + ldap-rpc.h, ldap-schema.c, ldap-schema.h, ldap-service.c, + ldap-service.h, ldap-sldap.c, ldap-sldap.h, ldap-spwd.c, + ldap-spwd.h, ldap.conf, ltf.c, ltf.h, missing, mkinstalldirs, + nss_common.h, nss_dbdefs.h, nss_ldap.5, nss_ldap.spec, + nsswitch.ldap, pagectrl.c, pagectrl.h, resolve.c, resolve.h, + snprintf.c, snprintf.h, stamp-h.in, tests, tests/ldaptest.pl, + tests/nsswitch.test, tests/testd.c, tests/testgr.c, + tests/testpw.c, tests/testpw3.c, tests/testpw4.c, + tests/testpw5.c, tests/testpw6.c, util.c, util.h: import release + 251 of nss-ldap + diff --git a/ChangeLog-2007 b/ChangeLog-2007 new file mode 100644 index 0000000..5137e4e --- /dev/null +++ b/ChangeLog-2007 @@ -0,0 +1,1051 @@ +2007-12-31 arthur + + * [r546] nslcd/common.h: fix get_userpassword() function + description + * [r545] nslcd/shadow.c: fix incorrect references to attribute map + entries + * [r544] nslcd/group.c: remove TODO (was done) + * [r543] nslcd/common.c: fix bug that would return a password of + one character short + +2007-12-27 arthur + + * [r542] nslcd/cfg.c: do not define variable if we're not going to + use it + * [r541] configure.ac: check for all used ldap functions + * [r539] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.5 release + +2007-12-26 arthur + + * [r538] tests/test_cfg.c: remove temporary file to make distcheck + succeed + * [r537] README, debian/copyright: some documentation cleanups + * [r536] tests/test_nsscmds.sh: ignore erros in nss commands + * [r535] nslcd/myldap.c: only log "connected to LDAP server" if it + is a new connection + * [r534] nslcd/cfg.c, nslcd/cfg.h, tests, tests/test_cfg.c: + properly handle spaces in some configuration options (major + change in code in cfg module) + * [r533] tests/test_myldap.c: in test_two_searches() test that we + can read from the second search if the first search as abandoned + * [r532] nslcd/myldap.c: properly flag running searches as invalid + if the connection to the LDAP server is reset + +2007-12-25 arthur + + * [r531] nslcd/common.h, nslcd/myldap.c, nslcd/myldap.h, + tests/test_myldap.c: have myldap_get_entry() return an LDAP + status code that can signal errors in the lookup + * [r530] nslcd.h, nslcd/common.h, nss/common.c, nss/group.c: remove + NSLCD_RESULT_UNAVAIL because it's not needed anymore (the + connection is broken when an error occurs) and rename + NSLCD_RESULT_NOTFOUND into NSLCD_RESULT_END to better match its + meaning + * [r529] nslcd/common.h: no need for us to flush the buffer since + our caller closes the stream immediatly (or could otherwise pass + the flushing to another thread) + +2007-12-24 arthur + + * [r528] man/nss-ldapd.conf.5.xml: some general cleanups and + document the krb5_ccname option + * [r527] debian/libnss-ldapd.config: disable rootbinddn and + rootbindpw questions for now because they are not supported + * [r526] man/nss-ldapd.conf.5.xml: document current timing and + reconnect options + * [r525] nslcd/myldap.c: merge the do_map_error(), + do_with_reconnect() into the myldap_search() and do_try_search() + functions having more understandable reconnect and retry logic + * [r524] nslcd/myldap.h: add some more documentation for using the + myldap module + +2007-12-22 arthur + + * [r523] tests/nss-ldapd-test.conf, tests/test_myldap.c: add + limited test for reconnect logic + * [r522] nslcd/cfg.c, nslcd/cfg.h, nslcd/myldap.c: remove + bind_policy option because the same effect is achieved by setting + reconnect_tries to 1 + * [r521] nslcd/cfg.c, nslcd/cfg.h: reorder timing and reconnect + options to be more logical and remove nss_ prefix from reconnect + options + * [r520] tests/test_myldap.c: limit printing of results in test to + just 10 + * [r519] tests/test_myldap.sh: include script name in messages and + have srcdir default to . + * [r518] nslcd/myldap.c: integrate do_result() into + myldap_get_entry() reducing complexity and improving error + handling + * [r517] nslcd/myldap.c: remove duplicate comment + * [r516] nslcd/cfg.c, nslcd/cfg.h: remove some unused configuration + file options + * [r515] nslcd/myldap.c: bring more uniformity to log messages + * [r514] nslcd/myldap.c: give struct myldap_session members more + logical names + +2007-12-21 arthur + + * [r513] tests/test_myldap.sh, tests/test_nsscmds.sh: only test the + first URI in the configfile + +2007-12-20 arthur + + * [r512] tests/Makefile.am, tests/test_myldap.c, + tests/test_myldap.sh: pass configfile to use as a command-line + paramter to test_myldap, use the myldap_session_close() function, + print a limited number of results, add a wrapper script to test + whether the LDAP server is available for the test and ship all + needed files in the tarball + * [r511] tests/test_nsscmds.sh: fail on any command and specify + configfile separately + * [r510] debian/copyright: remove FSF copyright since we no longer + use their code + * [r509] nslcd/myldap.c, nslcd/myldap.h: refactor myldap code to + get rid of most of the old nss status codes, properly handle + failures of ldap function calls and improve sourcecode comments + * [r508] nslcd/myldap.c, nslcd/myldap.h: add myldap_session_close() + function (mainly for testing purposes) + * [r507] nslcd/myldap.c: move checks of validity of passed entries + to separate functions + * [r506] nslcd/myldap.c: remove msg member from struct myldap_entry + and just reference the same message in the search + * [r505] nslcd/shadow.c: rewrite GET_OPTIONAL_DATE() as an + extension to GET_OPTIONAL_LONG() + * [r504] configure.ac: add/change some tests for currently used + functions, relayout some complexer tests and use AC_CHECK_TYPE + instead of custom test + * [r503] nslcd/ether.c: use ether_ntoa_r() instead of ether_ntoa() + * [r502] compat/ldap.h, configure.ac: remove unused tests and + compatibility code + * [r501] tests/nss-ldapd-test.conf: set pagesize to some more + reasonable value + * [r500] tests/test_myldap.c: have assertion on correct search + +2007-12-16 arthur + + * [r498] nss-ldapd.conf: fix typo in description + +2007-12-14 arthur + + * [r497] nslcd/myldap.c: potential fix for double free() bug like + in nss_ldap (Debian bug #366172) + * [r496] nslcd/myldap.h: improve description of myldap interface in + comments + * [r495] nslcd/common.c: explain why we write an invalid address + (in comment) and add TODO to describe we need to change the log + format + * [r494] tests/test_myldap.c: fix typo in comment + +2007-12-09 arthur + + * [r493] debian/control: update package description + * [r492] tests/Makefile.am: fix objects that are needed to get + tests linkable (due to namechange from ldap-nss to myldap) + * [r491] compat/ldap.h, nslcd/cfg.c, nslcd/cfg.h, nslcd/myldap.c: + some small layout changes + * [r490] tests/test_nsscmds.sh: remove ugly space + * [r489] nslcd-common.h, nslcd/Makefile.am, nslcd/alias.c, + nslcd/attmap.h, nslcd/cfg.c, nslcd/common.h, nslcd/group.c, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/myldap.c, + nslcd/myldap.h: get rid of some old code and rename ldap-nss to + myldap since there is no more NSS-related code in there + * [r488] nslcd-common.h, nslcd/alias.c, nslcd/common.c, + nslcd/common.h, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + switch to new LDAP entry parsing code that is much simpler and + more readable + * [r487] tests/test_nsscmds.sh: add some comments to tests, enable + netgroup tests and extend ether and services tests + * [r486] nslcd/ldap-nss.c: ignore decoding errors from + ldap_get_values() as they are just nonexisting attribute values + +2007-12-07 arthur + + * [r485] debian/control: fix Vcs-* links to point to the trunk + * [r484] debian/control: upgrade to standards-version 3.7.3 (no + changes needed) + * [r483] nslcd/nslcd.c: don't use backticks as quote mark + +2007-12-01 arthur + + * [r482] common/dict.c: simple check for validity of key value in + dict_put() + +2007-11-26 arthur + + * [r481] configure.ac, man/nss-ldapd.conf.5.xml, nslcd/cfg.c, + nslcd/cfg.h, nslcd/ldap-nss.c: clean up Kerberos ccname code, + moving it to cfg.c, fixing some bugs in the putenv() code, making + the gss_krb5_ccache_name() automatically used if the function is + available and removing the --with-gssapi-dir, + --enable-configurable-krb5-ccname-gssapi and + --enable-configurable-krb5-ccname-env configure options + +2007-11-25 arthur + + * [r480] AUTHORS, README, configure.ac, man/nss-ldapd.conf.5.xml, + nslcd/cfg.c: implement LDAP server discovery through DNS, based + on a patch by Ralf Haferkamp and Michael Calmer + + +2007-11-24 arthur + + * [r479] HACKING: update versions of used tools + +2007-11-20 arthur + + * [r478] debian/control: remove XS- prefix from version control + fields + * [r477] debian/control: put Homepage field in source stanza + +2007-11-16 arthur + + * [r476] AUTHORS, nslcd/ldap-nss.c: patch from Andreas Schneider + to get krb5_ccname option working + +2007-10-31 arthur + + * [r475] nslcd.h: improve comments about protocol, also describing + the final NSLCD_RESULT_NOTFOUND + +2007-10-28 arthur + + * [r474] nslcd/ldap-nss.c: some smaller cleanups and + simplifications to the code (getting rid of the is_connected flag + * [r473] nslcd/ldap-nss.c: remove sizelimit parameter + * [r472] nslcd/ldap-nss.c: integrate ent_context attributes into + ldap_search + * [r471] nslcd/ldap-nss.c: remove session from context and remove + sycnhronous search functions + * [r470] nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/netgroup.c, + nslcd/service.c: replace calls to _nss_ldap_get_values() by + myldap_get_values(), remove unused functions, remove struct + ldap_state and replace remaining references to context to use + search instead + * [r469] man/nss-ldapd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/ldap-nss.c: remove support for nss_connect_policy + configfile option and remove some supporting code for it + * [r468] nslcd/alias.c, nslcd/common.h, nslcd/ether.c, + nslcd/group.c, nslcd/host.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + first step to use the new myldap interface + * [r467] tests/test_nsscmds.sh: script to run a number of NSS + commands (mainly getent) and check the result (this requires an + LDAP setup that is yet to be documented) + +2007-10-27 arthur + + * [r466] man/nss-ldapd.conf.5.xml: include pagesize option in + manual page since this is tested now + * [r465] nss-ldapd.conf: add pointer to pagesize in AD section of + sample configfile + * [r464] nslcd/nslcd.c: clean up myldap session after each request + * [r463] nslcd/cfg.c: make cfg_init() only callable once and add + note about not free()ing memory + * [r462] common/tio.c: fix memory leak in I/O module not free()ing + allocated storage for file info on file close + * [r461] common/tio.c: portability improvement to fall back to + ETIMEDOUT when ETIME is unavailable + +2007-10-26 arthur + + * [r460] NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: integrate changes from + 0.4.1 release + +2007-10-25 arthur + + * [r455] nslcd/rpc.c: fix rpc filter and remove unused objectClass + attmap entry + * [r454] nslcd/ldap-nss.c: clean up any messages after abandoning + the search because that returns a new message (fix memory leak) + * [r453] nslcd/ldap-nss.c: fix a memory leak, not storing search + entries so they could be freed later on + * [r452] nslcd/ldap-nss.c: fix using unassigned status + * [r451] nslcd/ldap-nss.c: fix memory leak + * [r450] debian/libnss-ldapd.nslcd.init: remove S runlevel from + Default-Stop in init script + +2007-10-21 arthur + + * [r449] nss/networks.c: correct calls to + NSLCD_ACTION_NETWORK_BYNAME and NSLCD_ACTION_NETWORK_BYADDR and + get address in correct byte order with the last call + +2007-10-20 arthur + + * [r448] nslcd/passwd.c, nslcd/protocol.c: call mysnprintf() + instead of snprintf() where needed (bugfix) + +2007-10-19 arthur + + * [r444] nslcd/ldap-nss.c: make a replacement for + _nss_ldap_getbyname() which uses the myldap calls internally + * [r443] nslcd/Makefile.am, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/myldap.h, tests, tests/Makefile.am, + tests/nss-ldapd-test.conf, tests/test_myldap.c: integrate basic + myldap interface (partially merged from dev-myldap branch) + * [r442] tests/Makefile.am: include debugging information in object + files + * [r441] tests/Makefile.am: move most C[PP]FLAGS options to + AM_C[PP]FLAGS and clean up a little + * [r440] common/tio.c: fix usage of DEBUG_TIO_STATS + +2007-10-14 arthur + + * [r438] AUTHORS: add translator to Japanese of templates + * [r437] debian/po/ja.po: update Japanese (ja) translation of + debconf templates by Kenshi Muto + +2007-10-08 arthur + + * [r436] debian/copyright, debian/po/fr.po: update French (fr) + translation of debconf templates by Cyril Brulebois + + +2007-10-05 arthur + + * [r434] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.4 release + +2007-10-04 arthur + + * [r433] .: ignore tarballs + * [r432] configure.ac: remove linking with libresolv because it's + not needed on Linux + +2007-10-03 arthur + + * [r431] nss-ldapd.conf: some reordering to make the file more + logical and minor fixes + * [r430] Makefile.am: pass --enable-warnings when running the + distcheck target + * [r429] README: some general documentation improvements + +2007-09-28 arthur + + * [r428] man/nss-ldapd.conf.5.xml: add note about escaping of + ldapi:// scheme + * [r427] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fr.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: remove note about escaping of ldapi:// url + scheme + * [r426] nslcd/cfg.c: add warnings and errors to untested and + unsupported configfile options + +2007-09-25 arthur + + * [r425] man/nss-ldapd.conf.5.xml: manual page improvements + +2007-09-24 arthur + + * [r424] configure.ac: switch to defining __thread as empty string + and issue warning if __thread keyword is not supported + * [r423] common/tio.c: also initialize sa_sigaction although it's + not used + * [r422] debian/libnss-ldapd.postinst: do something special for + setting the uri parameter because it may be speicified multiple + times + * [r421] debian/libnss-ldapd.config: fix newline mangling + +2007-09-23 arthur + + * [r420] debian/libnss-ldapd.config: properly handle multiple uri + lines in config file + * [r419] debian/libnss-ldapd.postinst: trim preceding spaces when + adding an entry in /etc/nsswitch.conf + * [r418] Makefile.am, common/tio.c, nslcd/ldap-nss.h, + nslcd/nslcd.c, nss/common.c: some small improvements to the code + based on some source code checks + * [r417] Makefile.am: remove pscan target as these checks are + sufficiently covered by the other tests + +2007-09-22 arthur + + * [r416] nslcd/Makefile.am: add compat files to sources so they end + up in the tarball + * [r415] tests/Makefile.am: add all objects that are now needed to + test the configuration module + * [r414] tests/test_cfg.c: remove test for alloc_lsd() because we + don't use struct ldap_service_search_descriptor any more + +2007-09-21 arthur + + * [r412] nslcd/ldap-nss.c: remove unneeded variables and slightly + improve logging + * [r411] common/Makefile.am: just use -fPIC on all files in this + directory + +2007-09-19 arthur + + * [r410] nslcd/cfg.c, nslcd/cfg.h, nslcd/nslcd.c: put config + filename as a parameter to cfg_init() + +2007-09-15 arthur + + * [r409] nslcd/ldap-nss.c: centralize opening of connection to LDAP + server in do_open() and refactor do_bind() to be simpler (making + do_rebind() just one line) + * [r408] man/nss-ldapd.conf.5.xml: remove documentation for + nss_schema option since it isn't used any more and probably never + will be + * [r407] nslcd/attmap.c, nslcd/attmap.h, nslcd/cfg.c, nslcd/cfg.h, + nslcd/common.h, nslcd/group.c, nslcd/ldap-nss.c, + nslcd/ldap-nss.h, nslcd/passwd.c: remove support for nested + groups and use of uniqueMember and member attributes as well as + memberOf attribute (this removes quite some functionality but + helps us in refactoring because the code was one big exception to + all the other modules) + * [r406] nslcd/group.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h: some + more code cleanup, changing return type of _nss_ldap_init(), + integrating _nss_ldap_init(), do_init_session(), do_parse_async() + and _nss_ldap_search_async() into the functions that call them + (each was only called once) + * [r404] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c: do not pass useless errnos + around because they aren't used anymore + * [r403] nslcd/cfg.h: remove unused include + +2007-09-14 arthur + + * [r402] nslcd/ldap-nss.c: some type fixes and logic + simplifications + * [r401] nslcd/group.c: minor code improvements + * [r400] nslcd/Makefile.am, nslcd/alias.c, nslcd/cfg.c, + nslcd/ether.c, nslcd/group.c, nslcd/host.c, nslcd/ldap-nss.c, + nslcd/ldap-nss.h, nslcd/netgroup.c, nslcd/network.c, + nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, + nslcd/shadow.c, nslcd/util.c, nslcd/util.h: move the two + remaining useful functions from util.c to ldap-nss.c + * [r399] nslcd/group.c, nslcd/util.c, nslcd/util.h: move + _nss_ldap_dn2uid() from util.c to group.c + * [r398] nslcd/common.h, nslcd/passwd.c: add note about free()ing + the returned value and add logging + * [r397] nslcd/common.h, nslcd/group.c, nslcd/passwd.c: move + user2dn() from group.c to passwd_username2dn() in passwd.c + * [r396] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c: do not flush streams: our caller + closes the streams flusing them + * [r395] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c: make use of write_*ent() + functions consistent + * [r394] nslcd/alias.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/util.c, nslcd/util.h: revert special casing for + alias_byname() to other functions and some logging strings + simplifications + * [r393] nslcd/group.c: remove some more references to the old + locked functions + * [r392] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/network.c, + nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, + nslcd/shadow.c, nslcd/util.c: remove mutex from all LDAP + operations because we now have a session and a connection per + thread + * [r391] nslcd/alias.c, nslcd/common.h, nslcd/ether.c, + nslcd/group.c, nslcd/host.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/netgroup.c, nslcd/network.c, nslcd/nslcd.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c, + nslcd/util.c, nslcd/util.h: get rid of global session and instead + pass the session as a parameter with every request and allocate a + session per thread + +2007-09-12 arthur + + * [r390] nslcd/ldap-nss.c: some code cleanup and fixes to the + layout + +2007-09-09 arthur + + * [r389] nslcd/group.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/util.c: change naming of search functions to clearly + indicate whether the synchronous or the asynchronous interface is + used + * [r388] compat/ldap.h, nslcd/cfg.c, nslcd/cfg.h, nslcd/ldap-nss.c: + some simplifications in the reconnect loging, removing the + undocumented nss_reconnect_maxconntries configfile option and + some work to split out LDAP compatibility code to a separate file + +2007-09-08 arthur + + * [r387] nslcd/common.c, nslcd/common.h, nslcd/ldap-nss.c: move + nss2nslcd() to ldap-nss.c + * [r386] nslcd/group.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h: rename + a function and a little bit of cleanup + * [r385] nslcd/ldap-nss.c: fix endless loop bug + * [r384] nslcd/alias.c, nslcd/attmap.c, nslcd/attmap.h, + nslcd/cfg.c, nslcd/cfg.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c, + nslcd/util.c: move base and scope handling to database specific + modules, gettting rid of ldap_service_search_descriptor + * [r383] nslcd/alias.c, nslcd/attmap.c, nslcd/attmap.h, + nslcd/cfg.c, nslcd/cfg.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/ldap-nss.c, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, nslcd/util.c: move filters + definitions to the database modules themselves (and already + define base and scope but don't use them yet) + +2007-09-07 arthur + + * [r382] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c: make handling of ent_context + consistent and simpler + * [r381] nslcd/alias.c, nslcd/ether.c, nslcd/host.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, nslcd/util.h: properly + initialize all contexts + * [r380] nslcd/ldap-nss.h: remove struct ldap_args stuff + * [r379] nslcd/group.c: remove last usage of struct ldap_args and + add FIXME + * [r378] nslcd/Makefile.am, nslcd/alias.c, nslcd/cfg.c, + nslcd/ether.c, nslcd/group.c, nslcd/host.c, nslcd/ldap-nss.c, + nslcd/ldap-schema.c, nslcd/ldap-schema.h, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, nslcd/util.c: remove the + ldap-schema.[ch] files since this is now fully implemented in the + database specific files + * [r377] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/ldap-schema.c, + nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + also pass search filter for the *_all() functions from the + database module instead of doing it in ldap-nss.c + * [r376] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + rename attlst stuff to attrs since that is the name of the + parameter that is passed + * [r375] nslcd/alias.c, nslcd/common.c, nslcd/common.h, + nslcd/ether.c, nslcd/group.c, nslcd/host.c, nslcd/ldap-nss.c, + nslcd/ldap-nss.h, nslcd/ldap-schema.c, nslcd/ldap-schema.h, + nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c, + nslcd/util.h: move some of the filter code to the database + specific modules to be able to reduce complexity of ldap-nss.c + later on + +2007-09-05 arthur + + * [r374] man/Makefile.am: clean generated manual pages in + maintainer-clean target + +2007-09-03 arthur + + * [r373] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + include service name in attlst storage and functions + * [r372] nslcd/ldap-nss.c: remove sigpipe handling code since + sigpipe is ignored throughout the program + +2007-08-27 arthur + + * [r371] man/Makefile.am: always ship docbook sources and generated + manual pages and always install manual pages (even without + docbook2x-man) + * [r370] INSTALL, autogen.sh, depcomp, install-sh, missing, + mkinstalldirs: upgrade to using automake 1.10 + * [r369] configure.ac: use AM_PROG_CC_C_O to have per-target + compiler flags + +2007-08-26 arthur + + * [r366] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.3 release + * [r365] Makefile.am: workaround for problems splint has in parsing + system header files + * [r364] nslcd/cfg.h, nslcd/ldap-nss.h: move enum ldap_map_selector + and struct ldap_service_search_descriptor from ldap-nss.h to + cfg.h + +2007-08-25 arthur + + * [r363] debian/libnss-ldapd.postinst: fix handling of configfile + values with spaces and symbols that could cause problems with sed + * [r362] debian/libnss-ldapd.postinst: change regular expression + boundry to | instead of % because it is less likely to appear + with normal use + * [r361] debian/libnss-ldapd.config: clear password informating in + Debconf database if binddn is not used + +2007-08-19 arthur + + * [r360] tests, tests/Makefile.am, tests/test_cfg.c: add some + checks for the configuration module + * [r359] configure.ac, tests/Makefile.am, tests/dict, + tests/test_dict.c, tests/test_tio.c, tests/tio: move dict and tio + tests into the tests directory + * [r358] debian/po/pt.po: include updated Portugese translation by + Américo Monteiro + * [r357] debian/po/templates.pot: change Project-Id-Version project + name + * [r356] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fr.po, + debian/po/ja.po, debian/po/nl.po, debian/po/pt.po, + debian/po/pt_BR.po, debian/po/ru.po, debian/po/sv.po, + debian/po/templates.pot, debian/po/vi.po: update + Project-Id-Version and Report-Msgid-Bugs-To headers + * [r355] debian/copyright, m4/acx_pthread.m4: include newer version + of acx_pthread.m4 + * [r354] README: add a note about case-sensitivity of NSS and LDAP + databases + * [r353] debian/libnss-ldapd.config, debian/libnss-ldapd.postinst: + fix some bugs in mangling of configfile and be more cautious + about replacing values (only replace first occurrence and only + match options with the correct number of options) + * [r352] debian/libnss-ldapd.postinst: remove passwords from + configfile if the [root]binddn option was removed and always + unset the passwd in the debconf database + * [r351] config.guess, config.sub: include updated files + * [r350] debian/libnss-ldapd.postinst: no longer use + /etc/libnss-ldap.conf as a basis for creating a new configuration + file since the syntax is no longer compatible + * [r349] debian/libnss-ldapd.postinst: only restart nscd on + configure + * [r348] debian/libnss-ldapd.config, debian/libnss-ldapd.postinst, + debian/libnss-ldapd.templates, debian/po/ca.po, debian/po/cs.po, + debian/po/da.po, debian/po/de.po, debian/po/es.po, + debian/po/fr.po, debian/po/ja.po, debian/po/nl.po, + debian/po/pt.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po: remove + the ldap-version question as it should be unneeded in the most + common installations (where it needs to be set the whole config + is likely te need tweaking) + +2007-08-18 arthur + + * [r347] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fr.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: rephrase the uri question and add some more + pointers on how to specify the value + * [r346] debian/libnss-ldapd.nslcd.init: change remaining reference + to $PIDFILE into $NSLCD_PIDFILE + * [r345] nslcd/ldap-nss.c: fix a couple of uses of per-map bases + that could be NULL and remove the ldap_proxy_bind_args that + wasn't used anywhere + * [r344] man/nslcd.8.xml: replace remaining \- with - + * [r343] configure.ac, man/nss-ldapd.conf.5.xml, nslcd/attmap.c, + nslcd/attmap.h, nslcd/cfg.c, nslcd/cfg.h, nslcd/ldap-nss.c, + nslcd/ldap-schema.h, nslcd/nslcd.c, nss-ldapd.conf: rewrite + configuration file handling to be simpler and more consistent, + this does mean that the syntax of the configfile has changed from + the PADL one and that some options were removed (also update + manual page and sample config file to reflect changes) + +2007-08-03 arthur + + * [r342] nslcd/cfg.c, nslcd/cfg.h, nslcd/group.c: remove + nss_initgroups and nss_initgroups_ignoreusers configfile options + * [r341] HACKING, README: documentation improvements + * [r340] README, configure.ac, man/nss-ldapd.conf.5.xml, + nslcd/cfg.c, nslcd/cfg.h, nslcd/ldap-nss.c, nslcd/ldap-nss.h: + remove --enable-paged-results configure option and now always do + runtime configuration, remove nss_paged_results configfile option + and use pagesize option to specify usage of paging or not + +2007-08-02 arthur + + * [r339] README: some spelling fixes, added a section on + unsupported features and rephrased default LDAP schema + objectclasses as filters + +2007-07-31 arthur + + * [r338] Makefile.am, configure.ac, debian/control, man, + man/Makefile.am, man/nslcd.8.xml, man/nss-ldapd.conf.5.xml, + nslcd.8, nss-ldapd.conf.5: switch to using docbook for manual + pages, use docbook2x-man for generating the manual pages and + update the nss-ldapd.conf manual page slightly + +2007-07-28 arthur + + * [r337] nslcd/alias.c, nslcd/cfg.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/ldap-schema.c, nslcd/ldap-schema.h, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c: define the list of attributes to + look up in searches in the service modules instead of in + ldap-schema + * [r336] nslcd/attmap.h: fix typo in comment + +2007-07-27 arthur + + * [r334] nslcd.h: fix typo + +2007-07-26 arthur + + * [r332] nslcd/cfg.c, nslcd/ldap-schema.h: remove some more old + mapping stuff and change configuration file keyword to map with + the new syntax + * [r331] nslcd/alias.c, nslcd/attmap.c, nslcd/attmap.h, + nslcd/cfg.c, nslcd/cfg.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/ldap-nss.c, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c: switch to the new attribute + mapping code + * [r330] nslcd/cfg.c, nslcd/cfg.h, nslcd/ldap-nss.c, + nslcd/ldap-nss.h, nslcd/ldap-schema.c: get rid of default and + override attribute value mappings and remove host and port + configuration options + * [r329] nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/shadow.c: move + some shadow specific functions to shadow.c + * [r328] nslcd/cfg.c, nslcd/cfg.h: make function + _nss_ldap_add_uri() static + +2007-07-24 arthur + + * [r327] nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/ldap-schema.c: + remove some more unused code + * [r326] nslcd/Makefile.am, nslcd/alias.c, nslcd/attmap.c, + nslcd/attmap.h, nslcd/cfg.c, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/ldap-schema.c, nslcd/ldap-schema.h, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, nslcd/util.c: switch to a new + interface for doing attribute mapping, splitting the attribute + mapping stuff into a separate file + * [r325] nslcd/cfg.c, nslcd/ldap-schema.c, nslcd/ldap-schema.h: get + rid of some unused attribute mappings and a small reorganisation + of code + * [r324] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fr.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: rephrase nsswitch.conf question and removed + reference to example file we don't ship + * [r323] debian/copyright, nslcd/Makefile.am, nslcd/cfg.c, + nslcd/cfg.h, nslcd/dnsconfig.c, nslcd/dnsconfig.h, + nslcd/resolve.c, nslcd/resolve.h, nss-ldapd.conf.5: get rid of + dnsconfig stuff since that probably didn't work anyway and it + cleans up some stuff + +2007-07-23 arthur + + * [r315] common/dict.c, tests/dict/test_dict.c: fix a serious bug + in dict_values_next() that would return map pointers instead of + values and write a test for it + * [r314] debian/rules: use stricter distclean run in clean target + as suggested by lintian + * [r313] common/dict.c, common/dict.h, tests/dict/test_dict.c: add + support for removing entries from a DICT by setting the value to + NULL (this does not free any memory) + +2007-07-21 arthur + + * [r310] AUTHORS: include translater of debconf templates to French + +2007-07-18 arthur + + * [r309] debian/po/fr.po: typo fix by Cyril Brulebois + + +2007-07-16 arthur + + * [r308] debian/po/fr.po: update French (fr) translation of debconf + templates by Cyril Brulebois + +2007-07-15 arthur + + * [r307] tests/tio/test_tio.c: disable test that will always fail + * [r306] common/tio.c: fix typo + * [r305] common/tio.c: fix bug with buffer magic in writing code + +2007-07-14 arthur + + * [r304] AUTHORS, debian/copyright, debian/po/pt.po: add Portuguese + (pt) translation of debconf templates by Américo Monteiro + + +2007-07-13 arthur + + * [r303] tests/dict/Makefile.am, tests/tio/Makefile.am: do the + simple unit tests at make check time + * [r302] Makefile.am: don't include config diretory which we don't + use + * [r301] common/tio.c: add const and add FIXME about a to-be-fixed + race condition + * [r300] nss/networks.c: flag the address family parameter as + unused + * [r299] README: add notes about format of host and ethers entries + in LDAP database + * [r298] debian/control: add XS-Vcs-Svn and XS-Vcs-Browser as + specified in #391023 + +2007-06-18 arthur + + * [r297] nslcd/nslcd.c: add comment explaining the use of chmod() + over fchmod() + +2007-06-17 arthur + + * [r294] ChangeLog, NEWS, configure.ac, debian/changelog, + nss-ldapd.conf.5: get files ready for 0.2.1 release + * [r293] Makefile.am: do proper wildcard expansion + * [r292] Makefile.am, nss/Makefile.am: add proper support for make + uninstall + * [r291] autogen.sh: force regeneration of all files + * [r290] Makefile.am, autogen.sh, configure.ac: include stuff from + the m4 directory automatically + * [r289] common/Makefile.am, nslcd/Makefile.am, nss/Makefile.am, + tests/Makefile.am, tests/dict/Makefile.am, tests/tio/Makefile.am: + support building outside the source directory + * [r288] Makefile.am, configure.ac, debian/copyright, m4, + m4/acx_pthread.m4, nslcd/Makefile.am: use the ACX_PTHREAD macro + to check for platform independant pthread support and required + options + * [r287] debian/copyright: further clarification of use of + autoconf/automake code + +2007-06-16 arthur + + * [r286] nslcd/nslcd.c: change fchmod() into chmod() since fchmod() + has undifined behaviour on named sockets (fails silently) + +2007-06-12 arthur + + * [r285] common/dict.c, nslcd/ldap-nss.c, nslcd/ldap-schema.c, + nslcd/util.c: fix casts of types where needed + * [r284] nslcd/host.c: fix type of host address and handle errors + in writing hostent + +2007-06-11 arthur + + * [r280] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + nss-ldapd.conf.5: get files ready for 0.2 release + * [r279] common/Makefile.am, common/dict.c, common/dict.h, + nslcd/Makefile.am, nslcd/cfg.h, nslcd/dict.c, nslcd/dict.h, + tests/dict/Makefile.am, tests/dict/test_dict.c: move dict into + the common directory + * [r278] nss-ldapd.conf.5: add a note about the status of this + manual page + +2007-06-10 arthur + + * [r277] common/Makefile.am: compile tio module with -fPIC because + it is used in the NSS shared library + * [r276] debian/libnss-ldapd.postinst: add note about modifying + /etc/nsswitch.conf in postinst + +2007-06-09 arthur + + * [r275] Makefile.am: have better rules to generate ChangeLog + * [r274] common/tio.h: remove some trailing spaces + * [r273] nss-ldapd.conf.5: add proper copyright header + +2007-06-08 arthur + + * [r272] Makefile.am, common, common/Makefile.am, common/tio.c, + common/tio.h, configure.ac, nslcd-common.h, nslcd/Makefile.am, + nslcd/alias.c, nslcd/common.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/netgroup.c, nslcd/network.c, nslcd/nslcd.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c, + nslcd/util.c, nslcd/util.h, nss/Makefile.am, nss/aliases.c, + nss/common.c, nss/common.h, nss/ethers.c, nss/group.c, + nss/hosts.c, nss/netgroup.c, nss/networks.c, nss/passwd.c, + nss/protocols.c, nss/rpc.c, nss/services.c, nss/shadow.c, + tests/Makefile.am, tests/tio, tests/tio/Makefile.am, + tests/tio/test_tio.c: implement our own stdio-like library that + handles IO with a simple configurable timeout mechanism with + buffering + +2007-06-05 arthur + + * [r271] NEWS, README, configure.ac, tests/dict/test_dict.c: some + remaining tabs to spaces and trim trailing spaces + +2007-06-02 arthur + + * [r270] configure.ac, debian/copyright: fix some remaining + references to the GNU Library General Public License + +2007-06-01 arthur + + * [r269] nslcd/nslcd.c: add some comments describing some problems + that this code may have + +2007-05-20 arthur + + * [r268] HACKING: add a section on build dependencies + +2007-05-13 arthur + + * [r267] config.guess, config.sub: include updated files + +2007-03-05 arthur + + * [r266] ., Makefile.am: include some targets to tun flawfinder, + pscan, rats and splint + +2007-03-04 arthur + + * [r265] nslcd-common.h, nslcd/alias.c, nslcd/ether.c, + nslcd/group.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/ldap-schema.c, nslcd/ldap-schema.h, nslcd/log.c, + nslcd/nslcd.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/shadow.c, nslcd/util.c, nslcd/util.h, nss/common.c, + nss/common.h, nss/group.c, nss/hosts.c, nss/netgroup.c, + nss/networks.c, nss/prototypes.h, nss/services.c: code + improvements by making type casts explicit, flagging ignored + return values, renames and flagging of parameters and some + miscelanious improvements (thanks to gcc warnings, splint, rats + and flawfinder) + +2007-03-02 arthur + + * [r264] nslcd/ldap-nss.c: remove runtime checking for existance of + /lib/init/rw/libnss-ldap.bind_policy_soft + * [r263] nss-ldapd.conf: add missing attribute mapping for AD + * [r262] nslcd/nslcd.c: do chmod on file descriptor instead of on + file name + +2007-02-17 arthur + + * [r251] nslcd-common.h, nslcd/cfg.c, nss/hosts.c: fix a few bugs + found thanks to the new warnings + * [r250] compat, compat/attrs.h, nslcd/cfg.h, nslcd/common.h, + nslcd/dict.h, nslcd/log.h, nslcd/nslcd.c, nss/Makefile.am, + nss/common.h, nss/ethers.c, nss/group.c, nss/hosts.c, + nss/netgroup.c, nss/networks.c, nss/passwd.c, nss/protocols.c, + nss/rpc.c, nss/services.c, nss/shadow.c, tests/dict/test_dict.c, + tests/test_aliases.c: add gcc attributes to some functions and + parameters + * [r249] configure.ac: add some extra type checks and worarounds + * [r248] configure.ac: add extra compiler warnings + +2007-02-10 arthur + + * [r240] nslcd/dnsconfig.c, nslcd/ldap-nss.c, nslcd/ldap-nss.h, + nslcd/ldap-schema.c, nslcd/util.c: replace syslog calls to calls + with our own logging module + +2007-02-06 arthur + + * [r237] README: fix a typo and update copyright info + +2007-02-04 arthur + + * [r236] configure.ac, tests/Makefile.am, tests/dict, + tests/dict/Makefile.am, tests/dict/test_dict.c: add simple test + for dict module + * [r235] nslcd/dict.c: fix list corruption bug in dict_put() and + ignore setting value to NULL + * [r234] nslcd/dict.c, nslcd/dict.h: don't store const void * as + value, just void * + +2007-02-01 arthur + + * [r233] nslcd/util.c, nslcd/util.h: declare old dict functions + static as thay are only used from within util.c + * [r232] nslcd/dict.h, nslcd/ldap-nss.h: trim trailing whitespace + * [r231] nslcd/Makefile.am, nslcd/cfg.c, nslcd/cfg.h, nslcd/dict.c, + nslcd/dict.h, nslcd/ldap-nss.c, nslcd/util.c, nslcd/util.h: add + new dictionary module and use it for the attribute mapping stuff + * [r230] nslcd/Makefile.am, nslcd/log.c, nslcd/xmalloc.c, + nslcd/xmalloc.h: get rid of xmalloc.[ch] + +2007-01-17 arthur + + * [r229] nss/Makefile.am: no longer install libc-versioned symlink + and hardcode nss soname because we will likely need to change our + code if the ABI changes + * [r228] debian/rules: in Debian package install NSS files in + /usr/lib instead of /lib + * [r227] nss/aliases.c, nss/common.h, nss/ethers.c, nss/group.c, + nss/hosts.c, nss/netgroup.c, nss/networks.c, nss/passwd.c, + nss/protocols.c, nss/rpc.c, nss/services.c, nss/shadow.c: ensure + that all NSS functions can be generated by the marcos in common.h + and spell out the read_..() function for every type + * [r226] debian/copyright: indent license blubs and include license + information for nslcd/resolve.[ch] + * [r225] nslcd.h: add a little bit more documentation + * [r224] nslcd/cfg.c: remove a const where it really wasn't + * [r223] nslcd/cfg.c, nslcd/cfg.h, nslcd/group.c, nslcd/ldap-nss.c, + nslcd/util.c, nslcd/util.h: move most config code into cfg.c, + clean up dictornary stuff in util.c and do some more smaller + restructuring + * [r222] nslcd/group.c, nslcd/ldap-nss.h, nslcd/util.c, + nslcd/util.h: move name_list stuff to group.c as that is the only + place it's used at the moment + * [r221] nslcd/netgroup.c: replace __netgrent with mynetgrent + removing the fields that are not used + * [r220] nslcd/Makefile.am, nslcd/cfg.c, nslcd/cfg.h, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/ldap-schema.h, + nslcd/util.c, nslcd/util.h: first step to split out all + configuration stuff into separate file + * [r219] nslcd/ldap-nss.c, nslcd/ldap-nss.h: get rid of more code + that would check if the socket was changed from under us by our + caller + * [r218] nslcd/ldap-nss.c: get rid of rebinding-on-fork() logic as + our threading model is very predictable + +2007-01-10 arthur + + * [r217] nslcd/netgroup.c: write a final result code of + NSLCD_RESULT_NOTFOUND for netgroup lookups + * [r216] nss/netgroup.c, nss/prototypes.h: fix netgroup lookups so + that _nss_ldap_getnetgrent_r() returns NSS_STATUS_RETURN if there + are no more entries to return but there was a first entry + +2007-01-09 arthur + + * [r215] COPYING, Makefile.am, README, configure.ac, + debian/copyright, debian/libnss-ldapd.nslcd.init, nslcd-common.h, + nslcd.8, nslcd.h, nslcd/Makefile.am, nslcd/alias.c, + nslcd/common.c, nslcd/common.h, nslcd/dnsconfig.c, + nslcd/dnsconfig.h, nslcd/ether.c, nslcd/group.c, nslcd/host.c, + nslcd/ldap-nss.c, nslcd/ldap-nss.h, nslcd/ldap-schema.c, + nslcd/ldap-schema.h, nslcd/log.c, nslcd/log.h, nslcd/netgroup.c, + nslcd/network.c, nslcd/nslcd.c, nslcd/pagectrl.c, + nslcd/pagectrl.h, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, nslcd/util.c, nslcd/util.h, + nslcd/xmalloc.c, nslcd/xmalloc.h, nss/Makefile.am, nss/aliases.c, + nss/common.c, nss/common.h, nss/ethers.c, nss/group.c, + nss/hosts.c, nss/netgroup.c, nss/networks.c, nss/passwd.c, + nss/protocols.c, nss/prototypes.h, nss/rpc.c, nss/services.c, + nss/shadow.c, tests/Makefile.am, tests/test_aliases.c, + tests/test_ethers.c, tests/test_group.c, tests/test_hosts.c, + tests/test_netgroup.c, tests/test_networks.c, + tests/test_passwd.c, tests/test_protocols.c, tests/test_rpc.c, + tests/test_services.c, tests/test_shadow.c: change license from + GNU Library General Public License v.2 to GNU Lesser General + Public License v.2.1 with permission from Luke Howard + +2007-01-08 arthur + + * [r214] nss/netgroup.c, nss/prototypes.h: use our own thread-local + file pointer for doing requests instead of misusing the data + field in the __netgrent struct + * [r213] debian/control: add a provide line for libnss-ldap so we + can seamlessly replace it (it should provide the same + functionality) + * [r212] debian/libnss-ldapd.postinst: only modify nsswitch + databases we support, leave everything else alone (e.g. + automount) + +2007-01-02 arthur + + * [r211] debian/libnss-ldapd.nslcd.init: change description in init + script + diff --git a/ChangeLog-2008 b/ChangeLog-2008 new file mode 100644 index 0000000..f9c5229 --- /dev/null +++ b/ChangeLog-2008 @@ -0,0 +1,792 @@ +2008-12-15 arthur + + * [r806] man/nss-ldapd.conf.5.xml: add a note about permissions of + configfile when bindpw is used + +2008-12-06 arthur + + * [r805] man/nss-ldapd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/myldap.c, nss-ldapd.conf: rename the tls_checkpeer option + to tls_reqcert, deprecating the old name and supporting all + options that OpenLDAP supports for that value + +2008-12-03 arthur + + * [r804] nslcd/common.c, tests/test_common.c: allow backslashes in + names execpt as first or last character + * [r803] configure.ac, nslcd/nslcd.c: clean the environment and set + LDAPNOINIT to disable parsing of LDAP configfiles (.ldaprc, + /etc/ldap/ldap.conf, etc) + +2008-11-29 arthur + + * [r802] nslcd/myldap.c: use tls_* options also for StartTLS + connections + * [r801] man/nss-ldapd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h: remove + sslpath option because it wasn't used for anything + * [r800] debian/changelog: add missing pound sign + +2008-11-14 arthur + + * [r798] ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.7 release + +2008-11-13 arthur + + * [r797] debian/libnss-ldapd.templates: also leave out empty + Default line for libnss-ldapd/ldap-binddn + * [r796] debian/libnss-ldapd.config, debian/libnss-ldapd.templates: + set debconf values from the environment only when they are empty + or if configfile is present to fix installation problem + +2008-11-11 arthur + + * [r795] debian/libnss-ldapd.postinst: any output should go to + stderr to not confuse debconf + +2008-11-04 arthur + + * [r793] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.6 release + * [r792] NEWS: some spelling fixes + * [r791] man/nss-ldapd.conf.5.xml: update manual page with current + timeout numbers + +2008-11-01 arthur + + * [r790] debian/libnss-ldapd.postrm: fail on errors + +2008-10-31 arthur + + * [r789] debian/libnss-ldapd.postinst: check for existance of init + script instead of daemon + +2008-10-01 arthur + + * [r788] nslcd/common.c: also allow spaces in user and group names + because it was causing problems in some environments + +2008-09-24 arthur + + * [r787] nslcd/myldap.c: also retry if ldap_result() failed and + getting error number returned LDAP_SUCCESS + * [r786] nslcd/myldap.c: log option name instead of option value + for ldap_set_option() value + * [r785] debian/control: clarify relationship to nss_ldap in + package description + +2008-08-22 arthur + + * [r783] ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.5 release + +2008-08-07 arthur + + * [r782] debian/copyright, debian/po/da.po: updated Danish (da) + translation of debconf templates by Jonas Smedegaard + + * [r781] debian/po/sv.po: updated Swedish (sv) translation of + debconf templates by Martin Ågren + +2008-07-20 arthur + + * [r778] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.4 release + * [r777] nslcd/cfg.c: rename get_base_from_dse() to + get_base_from_rootdse() + * [r776] nslcd/cfg.c: make the get_base_from_dse() function cleaner + and add a comment describing the function + * [r775] man/nss-ldapd.conf.5.xml, nslcd/cfg.c: implement looking + up search base in DSE of LDAP server + * [r774] tests/test_nsscmds.sh: reflect change in test LDAP setup + +2008-07-10 arthur + + * [r773] nslcd/myldap.c: LDAP_OPT_X_TLS_REQUIRE_CERT is not a + boolean + +2008-06-21 arthur + + * [r772] README: small change to documentation + * [r771] nss-ldapd.conf: further improvements to Active Directory + filters and attribute mappings by Petter Reinholdtsen + + +2008-06-17 arthur + + * [r770] nslcd/cfg.c, nslcd/myldap.c: replace https:// by ldaps:// + (stupid typo) + * [r769] nss-ldapd.conf: Active Directory sample configuration + improvement by Jelmer Jaarsma + +2008-06-15 arthur + + * [r767] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.3 release + * [r766] Makefile.am, debian/libnss-ldapd.lintian-overrides, + debian/rules: lintian override seems to be no longer necessary + * [r765] debian/control: upgrade to standards-version 3.8.0 (no + changes needed) + * [r764] debian/libnss-ldapd.nslcd.init: create /var/run/nslcd + directory with owner nslcd:nslcd by default so nslcd can remove + socket and pidfile at exit + * [r763] nslcd/nslcd.c: give pidfile and socket creation functions + more logical names + +2008-06-14 arthur + + * [r762] AUTHORS, configure.ac, man/nss-ldapd.conf.5.xml, + nslcd/cfg.c, nslcd/cfg.h, nslcd/myldap.c: implement SASL + authentication based on a patch by Dan White + * [r761] man/nss-ldapd.conf.5.xml: make formatting of manual page + options consistent + +2008-06-13 arthur + + * [r760] tests, tests/Makefile.am, tests/test_common.c: add some + very basic tests for the isvalidname() function + * [r759] nslcd/common.c, nslcd/common.h, nslcd/group.c, + nslcd/passwd.c: combine isvalidusername() and isvalidgroupname() + into isvalidname() because they are similar enough and we just + want to check to see if it is a reasonable name (e.g. not a DN) + +2008-06-12 arthur + + * [r758] common/tio.c: restore the old writing code which masks + SIGPIPE on platforms that can't use send() + * [r757] nslcd/cfg.c: don't perform SSL/TLS sanity checks if it + isn't available on the platform + * [r756] tests: ignore test_getpeercred + +2008-06-11 arthur + + * [r755] tests: ignore core files + * [r754] tests/test_getpeercred.c: remove test socket at end of + test + +2008-06-06 arthur + + * [r753] compat/getpeercred.c: use the cr_ prefix when getting a + xucred struct (needed for kfreebsd) + * [r752] tests/Makefile.am, tests/test_getpeercred.c: implement a + very basic test for getpeercred() + * [r751] nslcd/cfg.c: remove warning on using ssl option + * [r750] nslcd/cfg.c: check that all URLs start with https:// if + "ssl on" is specified + * [r749] nslcd/myldap.c: also set TLS options if an ldaps:// URL is + specified + * [r748] debian/control: add dependency on adduser as required by + the previous commit + * [r747] debian/libnss-ldapd.postinst: create a nslcd user in + postinst and ensure that it is used by default + * [r746] man/nss-ldapd.conf.5.xml: add uid and gid options to + manual page + * [r745] nslcd/cfg.c, nslcd/cfg.h, nslcd/nslcd.c: add uid and gid + configuration keywords that set the user id and group id of the + running nslcd process + * [r744] nslcd/nslcd.c: environ is defined in unistd.h + * [r743] nslcd/nslcd.c, nss/common.c: increase write buffer size in + nslcd to free up threads earlier and increase timeout for nslcd + to nss communication to one minute (at both places) + * [r742] common/dict.c, compat/ether.c, nslcd/group.c, + nslcd/myldap.c, nslcd/passwd.c, tests/test_tio.c: miscellaneous + portability improvements + +2008-05-18 arthur + + * [r741] TODO: from a review of glibc 2.3.6 code it shows that + strerror() is only non-threadsafe in some very unlikely + circumstances + +2008-05-17 arthur + + * [r740] common/tio.c: use send() with a flag to ignore SIGPIPE + instead of write() so we don't have to muck with signal handlers + +2008-05-16 arthur + + * [r739] nslcd/log.c, nslcd/log.h, nslcd/nslcd.c: include a random + string in every log message to be able to group log messages for + a single request + * [r738] common/tio.c, nslcd/myldap.c: add sanity checks to sleep + calls to never sleep too long (problems could occur when the + clock moves backwards) + * [r737] nss/group.c: remove comment about limitation that has now + been removed + * [r736] nss/common.c: grow the read buffer maximum size to 2Mbyte + to allow for groups with about 150000 members maximum + +2008-05-15 arthur + + * [r735] README: add some documentation on supported group to + member mappings + * [r734] nslcd/myldap.h: improve documentation for + myldap_get_rdn_value() function + +2008-05-11 arthur + + * [r733] nslcd/myldap.c: close the connection and retry the search + (once) if the search fails with the first call to + myldap_get_entry() (starting a search doesn't always give an + error when the connection has been broken) + * [r732] nslcd/myldap.c: split retry mechanism of myldap_search() + into a new do_retry_search() function + * [r731] nslcd/myldap.c: allocate the search memory region in + myldap_search() instead of in do_try_search() and have the latter + return an LDAP status code + * [r730] nslcd/myldap.c: also allow closing of searches that no + longer have a valid connection and integrate myldap_search_free() + into myldap_search_close() + +2008-05-04 arthur + + * [r728] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.2 release + * [r727] HACKING, README: some documentation cleanups and updates + * [r726] tests/test_nslcd_group.c: add some tests for + isvalidgroupname() + * [r725] man/nss-ldapd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/nslcd.c: make number of threads configurable with the + threads keyword + * [r724] nslcd/myldap.h: add reference to note about + thread-safeness of OpenLDAP + * [r723] nslcd/nslcd.c: fix copyright year + +2008-05-03 arthur + + * [r722] nslcd/passwd.c: implement a cache for dn2uid() lookups + that saves some time doing LDAP searches for groups with a lot of + members, based on a patch by Petter Reinholdtsen + + * [r721] debian/libnss-ldapd.nslcd.init: add soft dependency on + slapd, simplify network and file system dependencies and add + reverse dependencies on some common daemons that may want to do + NSS lookups + +2008-05-02 arthur + + * [r720] nss/netgroup.c, nss/prototypes.h: remove checking for + first entry and always return NSS_STATUS_RETURN when no more data + is available in the netgroup (this has the side effect of not + returning NSS_STATUS_NOTFOUND for non-existing netgroups but + seems to be what other NSS modules do) to properly handle empty + netgroups + * [r719] tests, tests/Makefile.am, tests/test_nslcd_group.c: add + file for testing nslcd/group.c + * [r718] tests/Makefile.am: don't even compile the test programs on + make check + * [r717] tests/Makefile.am: don't compile test code on every build + and fix LDADD lists to include correct objects + * [r716] nslcd/cfg.c, nslcd/cfg.h, nslcd/myldap.c: only support + tls-related options if LDAP library supports TLS, only add rebind + code if ldap_set_rebind_proc() is found and only set + LDAP_X_OPT_CONNECT_TIMEOUT if that option is supported + +2008-05-01 arthur + + * [r715] nslcd/myldap.c: support ranged attribute values + * [r714] nss/common.h: fix comment of return value of + NSS_STATUS_TRYAGAIN + * [r713] tests/test_myldap.c: fix a warning + * [r712] tests/test_myldap.c: ensure that filter_get_var() and + filter_get_var() return non-NULL to enable parsing of config file + with attribute mapping and filter settings and use base from + config file + +2008-04-29 arthur + + * [r711] man/nss-ldapd.conf.5.xml: make language about pagesize + option a little clearer + +2008-04-27 arthur + + * [r710] nslcd/cfg.c: support the case where an attribute mapping + variable is NULL + +2008-04-26 arthur + + * [r709] nslcd/myldap.c: also close the LDAP connection on + LDAP_SERVER_DOWN (besides LDAP_UNAVAILABLE) + * [r708] man/nss-ldapd.conf.5.xml, nss/common.c: increase time out + values because now nslcd will error out more quickly if the LDAP + server is known to be unavailable + * [r707] nslcd/nslcd.c: spelling fix in comment + * [r706] man/nss-ldapd.conf.5.xml: some spelling fixes and a + clarification of the retry mechanism + * [r705] nslcd/cfg.c: fix log message of incorrect map statement + * [r704] nslcd/passwd.c: make log message a little more descriptive + * [r703] configure.ac: fix quote in comment + * [r702] nslcd/myldap.c: ensure that the connection to the LDAP + server is closed whenever any of the ldap_*() functions return + LDAP_UNAVAILABLE + +2008-04-25 arthur + + * [r701] man/nss-ldapd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/myldap.c, tests/nss-ldapd-test.conf, tests/test_cfg.c, + tests/test_myldap.c: implement new timing mechanism for retries + to quickly fail lookups to LDAP server that have been failing for + some time, removing the reconnect_tries option and giving + reconnect_sleeptime and reconnect_maxsleeptime options a new + meaning + * [r700] tests/test_myldap.c: include missing include + * [r699] tests/test_myldap.c: ignore SIGPIPE in myldap tests + * [r698] tests/test_myldap.c: fix assert to be test instead of + assignment + * [r697] tests/test_myldap.c, tests/test_myldap.sh: have the binary + look up the file name and only use the shell script wrapper to + determine if LDAP server is available + * [r696] compat/ether.h: fix typos in references to + HAVE_ETHER_NTOA_R and HAVE_ETHER_ATON_R macros + +2008-04-23 arthur + + * [r695] tests/test_nsscmds.sh: fix order of members in group in + tests because of new hashing dict (maybe we should fix the script + instead to always sort members properly) + * [r694] common/dict.c: fix problem where first item in the + hashtable could be returned twice while looping + * [r693] tests/test_dict.c: add test for problem with duplicate + entries being returned while looping over results + * [r692] nslcd/passwd.c: don't issue warning when + myldap_get_entry() returns NULL and LDAP_SUCCESS + +2008-04-21 arthur + + * [r691] common/dict.c: allocate room for key string just after + entry to save on calls to malloc() and make it simpler + +2008-04-20 arthur + + * [r690] nslcd/group.c, nslcd/passwd.c: fix tests for valid user + and group names + * [r689] nslcd/common.h, nslcd/group.c, nslcd/passwd.c: add checks + for valid user and group names in incoming requests and for data + returned from LDAP + * [r688] nslcd/group.c: only support uniqueMember containing DN + values + * [r687] nslcd/group.c: fix warning message to not refer to alias + * [r686] nslcd/myldap.c: make warning message more verbose, fix + comment and don't try to store empty results + +2008-04-19 arthur + + * [r685] debian/libnss-ldapd.config: only guess the searchbase if + the value doesn't seem to be preseeded (based on a patch by + Petter Reinholdtsen ) + * [r684] common/dict.c: fix wrapping and indenting of comments + * [r683] nslcd/group.c: correctly call set_free() instead of free() + * [r682] nslcd/group.c: use the new set data structure to gather + the group members + * [r681] common/Makefile.am, common/set.c, common/set.h, tests, + tests/Makefile.am, tests/test_set.c: implement a set that uses + the dict module as back-end + * [r680] common/dict.c: implement new dict module that uses a + hashtable which is around 40 times faster for large (around 2000) + entries but with around 40% more memory used + * [r679] tests/Makefile.am, tests/test_dict.c, tests/usernames.txt: + some new tests for the dictionary module + * [r678] nslcd/passwd.c: add test for emtpy DN + +2008-04-18 arthur + + * [r677] nslcd/myldap.c: instead of using the dict module to build + a cache just store the values in an fixed-sized array because no + more than 9 attributes are currently retrieved from an entry and + we never retrieve the same value more than once (so the cache is + useless) + +2008-04-17 arthur + + * [r676] common/dict.h: add note about freed values + * [r675] common/dict.c, common/dict.h, nslcd/myldap.c, + tests/test_dict.c: change dict_values_first() and + dict_values_next() into dict_loop_first() and dict_loop_next() to + have a looping mechanism over keys and values + +2008-04-13 arthur + + * [r674] tests/nss-ldapd-test.conf: remote hopefully last reference + to rootbind{dn,pw} + +2008-04-06 arthur + + * [r673] nslcd/common.h: return values of dn2uid() and uid2dn() + should always be used + * [r672] nslcd/group.c: properly handle the case where dn2uid() + couldn't do a DN->uid lookup + * [r670] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.1 release + * [r669] config.guess, config.sub: include updated files + +2008-04-05 arthur + + * [r668] AUTHORS: include Petter Reinholdtsen for reporting many + bugs and even some fixes + * [r667] debian/libnss-ldapd.postinst: handle case where value + contains spaces properly + * [r666] debian/libnss-ldapd.postinst: support having a binddn set + without a bindpw + * [r665] debian/libnss-ldapd.config: fix typo in comment + * [r664] debian/libnss-ldapd.config, debian/libnss-ldapd.postinst, + debian/libnss-ldapd.templates, debian/po/ca.po, debian/po/cs.po, + debian/po/da.po, debian/po/de.po, debian/po/es.po, + debian/po/fr.po, debian/po/ja.po, debian/po/nl.po, + debian/po/pt.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po: remove + rootbind{dn,pw} options from packaging because the options are + not likely to be implemented in the future + * [r663] nslcd/common.h, nslcd/group.c, nslcd/passwd.c: fix + member->group searches by also searching for DN in uniqueMember + attribute + * [r662] nslcd/log.c: make log line a little bigger to properly log + more search filters + * [r661] nslcd/nslcd.c: only return shadow entries to root users + * [r660] nss/group.c: correctly implement buffer handling in + _nss_ldap_initgroups_dyn() to grow buffer when needed, check + limits and handle extra group parameter (had a closer look at + nis-initgroups.c) + * [r659] tests/test_nsscmds.sh: no problem to shout a little with + failed tests + * [r658] nss/group.c: properly check the limit (as seen in + nis-initgroups.c) + * [r657] nslcd/shadow.c: partial support for reading AD date format + for pwdLastSet attribute + * [r656] nslcd/myldap.c: split closing of LDAP session to separate + funtion to invalidate running searches always and closes + connection if setting up search failed + * [r655] tests/test_group.c: use a larger buffer for group + membership results + * [r654] tests/test_myldap.c: check that the last + myldap_get_entry() returned success + +2008-04-04 arthur + + * [r653] README, man/nss-ldapd.conf.5.xml, nslcd/cfg.c, + nslcd/cfg.h, nslcd/myldap.c, nss-ldapd.conf: remove code that + handles special cases when calling as root (removing rootbinddn, + rootbindpw, rootuse_sasl and rootsasl_authid options) + * [r652] nslcd/myldap.c: revert r628 (using ldap_str2dn() instead + of ldap_explode_r?dn()) for now to make this compile on older + versions of OpenLDAP + * [r651] man/nss-ldapd.conf.5.xml: add some more documentation to + the pagesize option + +2008-04-02 arthur + + * [r650] debian/libnss-ldapd.nslcd.init: make start not fail if + nslcd is already running and stop not fail if it wasn't running + before + +2008-03-30 arthur + + * [r649] nss-ldapd.conf: some fixes to the configuration when using + Active Directory (provided by Petter Reinholdtsen + ) + * [r648] configure.ac, nslcd/myldap.c: only define and use + do_sasl_interact() if we have a sasl library + * [r647] compat/attrs.h: make test for compiler versions simpler + and per used attribute + +2008-03-29 arthur + + * [r646] HACKING, README: add contact information on reporting bugs + and contributing patches + * [r645] HACKING: add some more notes about the design and + direction I want to go in + +2008-03-28 arthur + + * [r644] nslcd/myldap.c: don't warn about problems retreiving the + objectClass from en entry + +2008-03-27 arthur + + * [r643] nslcd/group.c: fix a problem where the newly allocated + storage by realloc() wasn't used (thanks to Petter Reinholdtsen + for the patch) + +2008-03-16 arthur + + * [r642] debian/libnss-ldapd.config, debian/libnss-ldapd.postinst: + comment out all rootbind{dn,pw} code as to not copy those + directives because they are unsupported + * [r641] debian/libnss-ldapd.config: use tail instead of head to + avoid conflicts becase nss_ldap seems to pick up the last option + in the file + * [r640] debian/libnss-ldapd.config: handle the case where an + option is defined multiple times + +2008-03-06 arthur + + * [r639] AUTHORS, debian/copyright, debian/po/es.po: updated + Spanish (es) translation of debconf templates by Rudy Godoy + Guillén + +2008-03-04 arthur + + * [r638] AUTHORS, debian/po/nl.po: updated Dutch (nl) translation + of debconf templates by Bart Cornelis + +2008-02-19 arthur + + * [r637] README: some updates to reflect recent changes + * [r636] man/Makefile.am: have a better way to specify the manual + page rule + +2008-02-15 arthur + + * [r635] common/tio.c: split out the flushing of the buffers to + separate functions and see if we can flush some data from the + buffer if it is overflowing before growing the buffer + * [r634] nslcd/myldap.c: add StartTLS support by Ralf Haferkamp + + * [r633] nslcd/myldap.c: pass URI to do_bind() to make it work with + do_rebind() and use that URI (thanks Ralf Haferkamp + ) + * [r632] tests/test_myldap.c: add tests for myldap_get_rdn_value() + and myldap_cpy_rdn_value() + +2008-02-12 arthur + + * [r631] configure.ac: make using implicit function definitions an + error + * [r630] common/tio.c, common/tio.h, nslcd/nslcd.c, nss/common.c, + tests/test_tio.c: implement resizable I/O buffers and tune buffer + sizes to normal requests + * [r629] common/tio.c: always allocate the read and write buffers + and make the struct tio_buffer inline in struct tio_fileinfo + +2008-02-10 arthur + + * [r628] nslcd/myldap.c: replace the calls to ldap_explode_dn() and + ldap_explode_rdn() with a call to ldap_str2dn() resulting in much + simpler code + +2008-02-08 arthur + + * [r627] nslcd/cfg.c: only support "dns" and "domain" values on + platforms with the necessary functions available + * [r626] nslcd/ether.c: don't define struct ether_addr here, it was + moved to compat/ether.h + +2008-02-04 arthur + + * [r625] nslcd/myldap.c: make some changes to allow it to compile + on more platforms + * [r624] compat/Makefile.am, compat/ether.c, compat/ether.h, + configure.ac, nslcd/ether.c: provide replacements for + ether_aton_r() and ether_ntoa_r() for platforms that don't have + them + * [r623] configure.ac, nslcd/nslcd.c: only call + __nss_configure_lookup() if it is available, if it isn't the + platform is out of luck + * [r622] nslcd/myldap.h: defined LDAP_SCOPE_DEFAULT it's not + defined elsewhere + * [r621] nslcd/nslcd.c: fix missing casts + * [r620] nslcd/nslcd.c: actually include the compat header files + when needed + +2008-02-03 arthur + + * [r618] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6 release + * [r617] configure.ac: also check for sasl2 library + * [r616] tests/test_myldap.c, tests/test_nsscmds.sh: add tests for + new LDAP lookups + * [r615] nslcd/attmap.c, nslcd/attmap.h, nslcd/group.c: support the + uniqueMember LDAP attribute that holds DN values (they are + translated with dn2uid() from passwd.c) + * [r614] debian/libnss-ldapd.postinst, debian/libnss-ldapd.postrm, + debian/rules: don't use dh_makeshlibs any more because we don't + need the shlibs file; call ldconfig from maintainer scripts + ourselves + * [r613] debian/rules: install the NSS library under /lib instead + of /usr/lib to make it easyer to unmount /usr if it's on a + separate filesystem + +2008-02-02 arthur + + * [r612] debian/rules: don't pass options to configure which are + not used + * [r611] configure.ac: remove --with-ngroups option because it + isn't used + * [r610] nslcd/common.h, nslcd/passwd.c: implement a dn2uid() + function to transform a DN into a username (looking inside the DN + or doing an LDAP lookup if neede) + * [r609] nslcd/myldap.c, nslcd/myldap.h: implement + myldap_cpy_rdn_value() function to copy rdn value into a buffer + (functionality like myldap_get_rdn_value()) + * [r608] nslcd/myldap.c: log and otherwise ignore errors in + ldap_parse_page_control() + * [r607] nslcd/myldap.c: fix copy-pasto + * [r606] nslcd/myldap.c: don't request paging when doing a search + with scope base and ignore errors of ldap_create_page_control() + * [r605] nslcd/myldap.c: reset LDAP error flag if ldap_get_values() + returned an error because some LDAP functions don't do this + correctly + +2008-02-01 arthur + + * [r604] nslcd/myldap.c: have proper checks and logs of all ldap + operations + * [r603] tests/test_group.c: enable _nss_ldap_initgroups_dyn() test + because it's working now + * [r602] nslcd-common.h: fix buffer size debug message + * [r601] nss/common.h, nss/hosts.c, nss/netgroup.c, nss/networks.c: + do not set errno (and h_errno) if we got the last entry from + get*ent() (this apparently is needed by coreutils' id and groups + commands) + * [r600] tests/Makefile.am: pagectrl module has moved + * [r599] tests/test_nsscmds.sh: test for hugegroup + * [r598] tests/test_nsscmds.sh: the groups command no longer lists + the username + * [r597] nss/common.c, nss/common.h, nss/group.c, nss/hosts.c, + nss/netgroup.c, nss/networks.c: remove the nslcd2nss() function + because it's not needed with the current protocol + * [r596] nss/common.h: fail with a permanent error if resetting the + stream failed to prevent indefinite retries + +2008-01-31 arthur + + * [r595] nslcd/myldap.c: defined LDAP_DEPRECATED to also have + definitions for deprecated functions + * [r594] compat/attrs.h: only define MUST_USE attribute if gcc + version is more recent than 3.4 + * [r593] debian/copyright: update copyright information + * [r592] compat/Makefile.am, compat/pagectrl.c, compat/pagectrl.h, + configure.ac, debian/copyright, nslcd/Makefile.am, + nslcd/myldap.c, nslcd/pagectrl.c, nslcd/pagectrl.h: move pagectrl + code into compat directory + * [r591] configure.ac: make comments lowercase for consistency + * [r590] tests/test_myldap.c: re-add test URIs that accidentally + got commented out in the last commit + * [r589] tests/Makefile.am, tests/test_cfg.c, tests/test_myldap.c, + tests/test_nsscmds.sh: pass the correct pthread flags for all + calls to compiler and linker and link in compat code, handle + other assert.h setups and avoid some ! in if statements in shell + scripts + * [r588] configure.ac: improve LDAP library autodetection and make + if statements consistent + * [r587] configure.ac: move finding of replacement functions to a + more logical place + * [r586] configure.ac: define extra macros to import system + extensions from system header files and remove duplicate check + for ldap_set_rebind_proc() + * [r585] configure.ac: test to see if the compiler supports certain + -W flags before using them + +2008-01-30 arthur + + * [r584] nslcd/ether.c: include stdint.h + * [r583] nslcd.h, nslcd/ether.c, nss/ethers.c: use uint8_t instead + of u_int8_t because the former seems to be available on more + platforms + * [r582] INSTALL, depcomp, install-sh: update some files from + recent automake + * [r581] compat/Makefile.am, compat/daemon.c, compat/daemon.h, + compat/getopt_long.c, compat/getopt_long.h, configure.ac: provide + replacement functions for daemon() and getopt_long() when they + are not available on the system + * [r580] configure.ac: remove duplicate warning flags + * [r579] compat/attrs.h: define __STRING() if it's not defined by + the system + * [r578] tests/test_tio.c: include errno in assertion statement + * [r577] compat/getpeercred.c: some fixes for LOCAL_PEERCRED (still + untested) + +2008-01-27 arthur + + * [r576] AUTHORS, debian/po/de.po: updated German (de) translation + of debconf templates by Erik Schanze + * [r575] compat/ldap.h, nslcd/Makefile.am, nslcd/myldap.c: + integrate some compatibility code into myldap.c, the only place + it's used + * [r573] nslcd/myldap.c: work around some LDAP libraries not having + all options + * [r572] configure.ac, nslcd/myldap.h: on some systems lber.h needs + to be included before ldap.h + * [r571] common/tio.c, nslcd-common.h, nslcd/nslcd.c, nss/common.c, + tests/test_tio.c: when including stdint.h check if we actually + have it + * [r570] nslcd/pagectrl.c, nslcd/pagectrl.h: correct #endif comment + +2008-01-26 arthur + + * [r569] nslcd/cfg.c: have a fallback value for HOST_NAME_MAX if it + is not defined + * [r568] tests/test_nsscmds.sh: handle the case where + /etc/nss-ldapd.conf does not exist a little more graceful + * [r567] nslcd/nslcd.c: log error when getpeercred() returned + nothing + * [r566] compat/getpeercred.c, compat/getpeercred.h, configure.ac: + add (untested) support for the Solaris getpeerucred() function + * [r565] Makefile.am, compat, compat/Makefile.am, + compat/getpeercred.c, compat/getpeercred.h, configure.ac, + nslcd/Makefile.am, nslcd/nslcd.c: move code to get information + from socket peer to the compat directory because it is very + platform specific + * [r564] tests/test_myldap.c, tests/test_nsscmds.sh, + tests/test_tio.c: somewhat improve the output from the tests + * [r563] nslcd/cfg.c: fix marsing of map statement + * [r562] tests/test_cfg.c: also test map filter and scope + configuration options + +2008-01-16 arthur + + * [r561] nslcd/cfg.c: fix problem in map statement end-of-line + handling + * [r560] tests/test_cfg.c: add a test for the map statement + +2008-01-03 arthur + + * [r559] nslcd/nslcd.c: close connections in worker threads at + program termination + * [r558] nslcd/nslcd.c: make code a little more compact, don't + include debug twice in the log message and remove the + capabilities code because it will probably never be used + * [r557] tests/test_nsscmds.sh: support the case where + is in + /etc/group + * [r556] nss/aliases.c, nss/common.h, nss/ethers.c, nss/group.c, + nss/hosts.c, nss/netgroup.c, nss/networks.c, nss/passwd.c, + nss/protocols.c, nss/rpc.c, nss/services.c, nss/shadow.c: only + start the NSLCD_ACTION_*_ALL requests with the first call to + getent() instead of with setent() to avoid unneeded requests if + compat is used (except with netgroups) + * [r555] nslcd/passwd.c, nss/prototypes.h: update copyright year + * [r554] tests/test_nsscmds.sh: get the number of groups and + services from files in /etc for comparison + * [r553] nslcd/passwd.c: do not warn about missing loginShell + attribute because it is not mandatory + * [r552] nss/group.c: increment value that is pointed to, not the + pointer (fixes segfault) + +2008-01-02 arthur + + * [r551] nslcd/common.h: immediatly bail out if write entity + function failed (prevents numerous "error writing to client" + messages from filling up the logs) + +2008-01-01 arthur + + * [r550] tests/test_nsscmds.sh: check to see if nslcd is running + and add test for a large group (100 members) + * [r549] nss/exports.linux, nss/group.c, nss/prototypes.h: enable + the _nss_ldap_initgroups_dyn() function that is now implemented + in nslcd + * [r548] nss/common.h: use the new tio_mark()/tio_reset() functions + to support retries of the getent() functions when + NSS_STATUS_TRYAGAIN would be returned + * [r547] common/tio.c, common/tio.h, tests/test_tio.c: add limited + implementation of tio_mark() and tio_reset() functions to do + limited seeks in the read stream, clean up header file comments + and write tests for new code + diff --git a/ChangeLog-2009 b/ChangeLog-2009 new file mode 100644 index 0000000..8c39f22 --- /dev/null +++ b/ChangeLog-2009 @@ -0,0 +1,711 @@ +2009-12-29 arthur + + * [r1046] nslcd/cfg.h, nslcd/myldap.c: some small simplifcations + and clarifications + +2009-12-28 arthur + + * [r1044] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.2 release + * [r1043] debian/nslcd.postrm: fix removal of old configuration + file (thanks piuparts) + * [r1042] debian/control: fix Conflicts relationship + * [r1041] common/Makefile.am, common/expr.c, common/expr.h, + man/nslcd.conf.5.xml, nslcd.conf, nslcd/Makefile.am, + nslcd/attmap.c, nslcd/attmap.h, nslcd/cfg.c, nslcd/passwd.c, + nslcd/shadow.c, tests, tests/Makefile.am, tests/test_cfg.c, + tests/test_common.c, tests/test_expr.c, tests/test_myldap.c: + implement attribute mapping using shell-like expressions + * [r1040] nss/networks.c: fix missing argument (problem in r1039) + * [r1039] nss/networks.c: Glibc changed the addr parameter of + getnetbyaddr_r() from network-byte-order to host-byte-order + * [r1038] tests/test_nsscmds.sh: preload our own NSS module for + tests + * [r1037] common/nslcd-prot.h: WRITE_STRINGLIST(): properly handle + the case where the list is null (result of change in r1028) + +2009-12-27 arthur + + * [r1036] nslcd/shadow.c: fix log message + * [r1035] nslcd/group.c: fix comment + * [r1034] debian/po/it.po: updated Italian (it) translation of + debconf templates by Vincenzo Campanella + +2009-12-21 arthur + + * [r1033] configure.ac: remove -Wunreachable-code because it was + turning up too many false positives (our use of macros, system + string functions, etc) + * [r1032] nss/prototypes.h: also use compat/ether.h for nss + functions + * [r1031] configure.ac: include the same headers in configure as in + compat/ether.h + +2009-12-13 arthur + + * [r1028] common/dict.c, common/dict.h, common/set.c, common/set.h, + nslcd/group.c, nslcd/myldap.c, tests/test_dict.c, + tests/test_set.c: change dict and set API to perform loops with a + list of strings instead of loop_first() and loop_next() functions + +2009-12-06 arthur + + * [r1027] debian/control: recommend libpam-krb5 als an alternative + to libpam-ldapd for Kerberos environments + +2009-11-14 arthur + + * [r1024] debian/po/it.po: updated Italian (it) translation of + debconf templates by Vincenzo Campanella + +2009-11-13 arthur + + * [r1023] configure.ac: fix lber library check for function we + actually use and another small reorganisation + +2009-11-11 arthur + + * [r1022] configure.ac: simplify structure of configure script and + see if -llber is needed + +2009-11-02 arthur + + * [r1017] configure.ac: fix PAM library check for systems without + pam_get_authtok() + +2009-11-01 arthur + + * [r1016] configure.ac: fail in configure if PAM functionality is + missing + * [r1015] tests/test.ldif.gz, tests/test_nsscmds.sh: add test case + for comma in DN attribute value + * [r1014] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + give search filter escaping buffers more logical names + * [r1013] nslcd/group.c: also do proper escaping in + mkfilter_group_bymember() + * [r1012] nslcd/myldap.c: also log uri when ldap_start_tls_s() + fails + * [r1011] configure.ac: make --disable-* configure options default + values clearer + +2009-10-20 arthur + + * [r1009] ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.1 release + +2009-10-17 arthur + + * [r1008] compat/Makefile.am, compat/pam_compat.h, + compat/pam_get_authtok.c, configure.ac, pam/Makefile.am, + pam/pam.c: provide a replacement for the pam_get_authtok() + functions for systems without it + * [r1007] compat/Makefile.am, compat/ldap_compat.h, + compat/ldap_initialize.c, compat/ldap_passwd_s.c, + compat/pagectrl.c, compat/pagectrl.h, configure.ac, + nslcd/myldap.c: provide replacement functions for + ldap_initialize() and ldap_passwd_s() and centralise LDAP + compatibility hacks into ldap_compat.h + * [r1006] compat/ether.c: also provide some function definitions + for ether_ntoa() and ether_aton() because definitions seem to be + missing on some platforms + +2009-10-11 arthur + + * [r1005] nslcd/common.h: make NSLCD_HANDLE_PARAMS() macro simpler + and not have empty argument + * [r1004] configure.ac, pam/pam.c: only include security/pam_ext.h + for systems that have it + +2009-10-08 arthur + + * [r1003] configure.ac, nslcd/myldap.c: fix some header checks in + configure and fix ldap_set_rebind_proc() return type check + * [r1002] nss/common.h: don't pass an empty parameter to a macro + * [r1001] configure.ac, nss/Makefile.am: re-organise configure + script and only run tests for parts that are enabled + +2009-10-07 arthur + + * [r1000] debian/libpam-ldapd.pam-auth-update, man/pam_ldap.8.xml, + nslcd/myldap.c, nslcd/myldap.h, nslcd/nslcd.c, nslcd/pam.c, + pam/pam.c: implement password changing in the PAM module by + performing an LDAP password modify EXOP request + * [r999] common/nslcd-prot.h: fix the case where the string passed + to WRITE_STRING() is an expression + +2009-10-05 arthur + + * [r998] configure.ac, nslcd/cfg.c, nslcd/cfg.h, nslcd/myldap.c, + pam/pam.c: some compatibility improvements + +2009-09-29 arthur + + * [r997] pam/pam.c: fix return of authorisation check (patch by + Howard Chu ) + +2009-09-27 arthur + + * [r996] debian/po/vi.po: updated Vietnamese (vi) translation of + debconf templates by Clytie Siddall + * [r995] nslcd/common.h: log reading and writing errors with errno + message + +2009-09-24 arthur + + * [r994] debian/po/vi.po: partially updated Vietnamese (vi) + translation of debconf templates by Clytie Siddall + + * [r993] pam/pam.c: general code cleanup and add missing casts and + includes + * [r992] nslcd/pam.c: fix for problem when authenticating to LDAP + entries without a uid attribute + +2009-09-13 arthur + + * [r991] debian/po/de.po: updated German (de) translation of + debconf templates by Erik Schanze + +2009-09-08 arthur + + * [r990] configure.ac: add the possibility to specify + --disable-maintainer-mode + * [r989] debian/nslcd.config: fix "Use StartTLS?" debconf question + when no ssl option is defined in the config + +2009-09-04 arthur + + * [r987] ChangeLog, Makefile.am, NEWS, configure.ac, debian/NEWS, + debian/changelog, man/nslcd.8.xml, man/nslcd.conf.5.xml, + man/pam_ldap.8.xml: get files ready for 0.7.0 release + * [r986] configure.ac, nslcd/cfg.c, nslcd/common.c, + nss/prototypes.h: some simple changes in includes to make FreeBSD + diff smaller + +2009-09-01 arthur + + * [r985] configure.ac, nslcd/cfg.c: add a + --disable-configfile-checking option to configure to cause + unknown options to be ignored from the configuration + * [r984] configure.ac: fix help message to indicate that PAM module + is built by default + * [r983] man/nslcd.conf.5.xml, nslcd/cfg.c: lower the default + values for bind_timelimit and reconnect_maxsleeptime from 30 to + 10 seconds + * [r982] Makefile.am: fix generation of ChangeLog + * [r981] .: rename trunk to nss-pam-ldapd + +2009-08-31 arthur + + * [r980] Makefile.am, README, configure.ac, + debian/libnss-ldapd.config, debian/nslcd.config, + debian/nslcd.examples, debian/nslcd.init, debian/nslcd.postinst, + debian/nslcd.postrm, debian/nslcd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fi.po, debian/po/fr.po, + debian/po/gl.po, debian/po/it.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po, debian/po/zh_CN.po, debian/rules, man, + man/Makefile.am, man/nslcd.8.xml, man/nslcd.conf.5.xml, + man/nss-ldapd.conf.5.xml, man/pam_ldap.8.xml, nslcd.conf, + nslcd/nslcd.c, nss-ldapd.conf, tests/Makefile.am, tests/README, + tests/nslcd-test.conf, tests/nss-ldapd-test.conf, + tests/test_myldap.c, tests/test_myldap.sh, + tests/test_nslcd_group.c, tests/test_nsscmds.sh: rename + configfile to /etc/nslcd.conf and make debian packaging copy the + file to the new name on upgrade + * [r979] INSTALL, autogen.sh, compile, depcomp, install-sh, + missing, mkinstalldirs: upgrade to using automake 1.11 + * [r978] ., HACKING, README, common/dict.c, common/dict.h, + common/set.c, common/set.h, common/tio.c, common/tio.h, + compat/getpeercred.c, compat/getpeercred.h, compat/pagectrl.c, + compat/pagectrl.h, configure.ac, debian/control, + debian/copyright, debian/nslcd.config, debian/nslcd.init, + debian/nslcd.postinst, debian/nslcd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fi.po, debian/po/fr.po, + debian/po/gl.po, debian/po/it.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po, debian/po/zh_CN.po, nslcd.h, nslcd/alias.c, + nslcd/attmap.c, nslcd/attmap.h, nslcd/cfg.c, nslcd/cfg.h, + nslcd/common.c, nslcd/common.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/myldap.c, nslcd/myldap.h, nslcd/netgroup.c, + nslcd/network.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, tests/README, tests/test_cfg.c, + tests/test_common.c, tests/test_dict.c, tests/test_getpeercred.c, + tests/test_myldap.c, tests/test_nsscmds.sh, tests/test_set.c, + tests/test_tio.c: rename software to nss-pam-ldapd + * [r977] debian/control: upgrade to standards-version 3.8.3 (no + changes needed) + * [r975] Makefile.am, debian/control, debian/libnss-ldapd.config, + debian/libnss-ldapd.docs, debian/libnss-ldapd.examples, + debian/libnss-ldapd.install, debian/libnss-ldapd.nslcd.init, + debian/libnss-ldapd.postinst, debian/libnss-ldapd.postrm, + debian/libnss-ldapd.templates, debian/libpam-ldapd.install, + debian/libpam-ldapd.pam-auth-update, + debian/libpam-ldapd.postinst, debian/libpam-ldapd.prerm, + debian/nslcd.config, debian/nslcd.docs, debian/nslcd.examples, + debian/nslcd.init, debian/nslcd.install, debian/nslcd.postinst, + debian/nslcd.postrm, debian/nslcd.templates, + debian/po/POTFILES.in, debian/po/ca.po, debian/po/cs.po, + debian/po/da.po, debian/po/de.po, debian/po/es.po, + debian/po/fi.po, debian/po/fr.po, debian/po/gl.po, + debian/po/it.po, debian/po/ja.po, debian/po/nl.po, + debian/po/pt.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po, + debian/po/zh_CN.po, debian/rules: split into binary packages + libnss-ldapd, libpam-ldapd and nslcd packages, using a patch for + libpam-ldap by Steve Langasek for the + libpam-ldapd package + * [r974] debian/libnss-ldapd.nslcd.init: patch by Petter + Reinholdtsen to fix init script to start before + autofs + +2009-08-16 arthur + + * [r973] config.guess, config.sub: include updated files + * [r972] Makefile.am, configure.ac: enable building PAM module by + default + * [r971] nslcd.h: remove development warning + * [r970] man, man/Makefile.am, man/pam_ldap.8.xml: add basic + pam_ldap manual page + +2009-08-12 arthur + + * [r969] nslcd/common.h, nslcd/nslcd.c, nslcd/passwd.c: don't + return password hashes at all for non-root users, based on a + patch by Alexander V. Chernikov + +2009-07-18 arthur + + * [r968] debian/po/gl.po: updated Galician (gl) translation of + debconf ates by Marce Villarino + +2009-07-12 arthur + + * [r966] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.11 release + * [r965] debian/po/fr.po: updated French (fr) translation of + debconf templates by Christian Perrier + +2009-07-10 arthur + + * [r962] debian/po/cs.po: updated Czech (cs) translation of debconf + templates by Miroslav Kure + +2009-07-04 arthur + + * [r961] debian/po/cs.po: unfuzzy translations that were due to + fixes in the English template + * [r960] debian/po/cs.po: updated Czech (cs) translation of debconf + templates by Miroslav Kure + * [r959] debian/po/pt.po: updated Portuguese (pt) translation of + debconf templates by Américo Monteiro + +2009-07-02 arthur + + * [r958] debian/po/es.po: updated Spanish (es) translation of + debconf templates by Francisco Javier Cuadrado + + +2009-06-29 arthur + + * [r957] nslcd/group.c: fix off by one error in the maximum number + of gidNumber attributes in an LDAP group entry + * [r956] nslcd/passwd.c: fix off by one error in the maximum number + of uidNumber attributes in an LDAP entry (thanks to David + Binderman for finding this) + +2009-06-27 arthur + + * [r955] debian/po/sv.po: updated Swedish (sv) translation of + debconf templates by Martin Ågren + * [r954] debian/control: upgrade to standards-version 3.8.2 (no + changes needed) + * [r953] debian/po/ru.po: updated Russian (ru) translation of + debconf templates by Yuri Kozlov + +2009-06-26 arthur + + * [r951] debian/control: add missing slash to homepage + +2009-06-24 arthur + + * [r950] debian/po/ja.po: updated Japanese (ja) translation of + debconf templates by Kenshi Muto + * [r949] debian/po/fi.po: updated Finnish (fi) translation of + debconf templates by Esko Arajärvi + +2009-06-23 arthur + + * [r948] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fi.po, debian/po/fr.po, + debian/po/gl.po, debian/po/it.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po, debian/po/zh_CN.po: change reqcert choice + description and make choices translatable + * [r947] debian/po/zh_CN.po: added Simplified Chinese (zh_CN) + translation of debconf templates by zym + +2009-06-22 arthur + + * [r946] debian/po/fi.po: fix non-ascii characters that got lost + when importing the file + +2009-06-21 arthur + + * [r945] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fi.po, debian/po/fr.po, + debian/po/gl.po, debian/po/it.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: improvements to debconf templates (English + language review by Justin B Rye + +2009-06-20 arthur + + * [r944] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fi.po, + debian/po/fr.po, debian/po/gl.po, debian/po/it.po, + debian/po/ja.po, debian/po/nl.po, debian/po/pt.po, + debian/po/pt_BR.po, debian/po/ru.po, debian/po/sv.po, + debian/po/templates.pot, debian/po/vi.po: update debconf + translation files + * [r943] debian/libnss-ldapd.config, debian/libnss-ldapd.postinst, + debian/libnss-ldapd.templates: make configuring SSL/TLS possible + with debconf + * [r942] nslcd/cfg.c: also support starttls as value for the ssl + option + +2009-06-19 arthur + + * [r941] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fi.po, debian/po/fr.po, + debian/po/gl.po, debian/po/it.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: rephrase LDAP server URI question based on + pam_ldap's new debconf templates + * [r940] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fi.po, debian/po/fr.po, + debian/po/gl.po, debian/po/it.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: fix wrapping, use of double spaces and unfuzzy + translations + +2009-06-14 arthur + + * [r939] debian/control: fix Vcs-Browser link + +2009-06-12 arthur + + * [r938] AUTHORS, HACKING, README, configure.ac, debian/control, + debian/copyright, man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: + replace references to ch.tudelft.nl with arthurdejong.org + * [r937] nslcd/nslcd.c: make error message a little clearer + +2009-06-06 arthur + + * [r934] README, nslcd/alias.c, nslcd/ether.c, nslcd/group.c, + nslcd/netgroup.c, nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, + nslcd/service.c, nslcd/shadow.c, tests/test_nsscmds.sh: implement + case-sensitive filtering for group, netgroup, passwd, protocols, + rpc, services and shadow lookups + * [r933] tests/README: fix wrapping + * [r932] HACKING, tests/README, tests/test.ldif.gz, + tests/test_nsscmds.sh: update and document test suite + * [r931] nss/group.c: fix buffer check for user to groups mapping + function + * [r930] configure.ac: add --disable-sasl and --disable-kerberos + configure options + +2009-06-04 arthur + + * [r929] nslcd/myldap.c: also compile correctly if + HAVE_LDAP_SASL_INTERACTIVE_BIND_S is not set + * [r928] configure.ac: let configure --help show the correct + behaviour + +2009-06-03 arthur + + * [r926] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.10 release + * [r925] nslcd/cfg.c: remove SSL/TLS warning messages during + startup + * [r924] README: add note about creating a user to run nslcd + * [r923] nslcd/Makefile.am, nslcd/common.h, nslcd/nslcd.c, + nslcd/pam.c: import preliminary version of PAM functionality into + nslcd + * [r922] nslcd/common.h, nslcd/passwd.c: make lookup_dn2uid() + available to other modules and split uid2dn() into uid2entry() + and uid2dn() (from nss-pam-ldapd branch) + * [r921] nslcd/myldap.c, nslcd/myldap.h: implement + myldap_set_credentials() and myldap_cpy_dn() which will be used + in the PAM lookups (from nss-pam-ldapd branch) + * [r920] pam/pam.c: remove trailing spaces + * [r919] nslcd.h, pam/pam.c: change PAM authorisation request to + also include ruser, rhost and tty (based on OpenLDAP cvs, r916 in + nss-pam-ldapd branch) + * [r917] debian/control: add Richard A Nelson (Rick) + to uploaders + +2009-06-01 arthur + + * [r914] HACKING, README, man/nss-ldapd.conf.5.xml, nss-ldapd.conf: + clean up documentation + +2009-05-30 arthur + + * [r910] nslcd/cfg.c: don't look inside the passed variable + get_strdup() because it could point to uninitialized memory + +2009-05-29 arthur + + * [r908] pam/common.h, pam/pam.c: partially refactor to follow + local coding convention and introduce READ_PAM_CODE macro (r896 + from nss-pam-ldapd) + * [r907] pam/pam.c: tabs to spaces (r889 from nss-pam-ldapd) + * [r906] pam/common.h, pam/pam.c: make request-response functions + simpler (r888 from nss-pam-ldapd) + * [r905] common/Makefile.am: remove unneeded EXTRA_DIST + * [r904] Makefile.am, common/Makefile.am, common/nslcd-prot.c, + common/nslcd-prot.h, nslcd-common.h, nslcd/Makefile.am, + nslcd/alias.c, nslcd/common.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c, + nss/Makefile.am, nss/aliases.c, nss/common.c, nss/common.h, + nss/ethers.c, nss/group.c, nss/hosts.c, nss/netgroup.c, + nss/networks.c, nss/passwd.c, nss/protocols.c, nss/rpc.c, + nss/services.c, nss/shadow.c, pam/Makefile.am, pam/common.h, + pam/pam.c, tests/Makefile.am: refactor protocol reading and + writing macros to the common directory, use more logical names + and in the PAM module no longer use NSS status codes (import of + r887 from nss-pam-ldapd) + * [r903] tests/Makefile.am: add missing objects to test programs + +2009-05-24 arthur + + * [r895] man/nss-ldapd.conf.5.xml: document that you can specify + base option multiple times + * [r894] Makefile.am: also build PAM module for make distcheck + * [r893] nslcd/alias.c, nslcd/cfg.c, nslcd/common.h, nslcd/ether.c, + nslcd/group.c, nslcd/host.c, nslcd/netgroup.c, nslcd/network.c, + nslcd/passwd.c, nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, + nslcd/shadow.c: initialise database modules only once after + parsing config + * [r892] AUTHORS, nslcd/alias.c, nslcd/attmap.c, nslcd/cfg.c, + nslcd/cfg.h, nslcd/common.h, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c, + tests/test_cfg.c, tests/test_myldap.c: support multiple search + bases, partially based on a patch by Leigh Wedding + + * [r891] AUTHORS: don't mention Howard Chu twice + +2009-05-23 arthur + + * [r890] debian/po/fi.po: added Finnish (fi) translation of debconf + templates by Esko Arajärvi + +2009-05-16 arthur + + * [r885] nss/common.h, pam/pam.c: quick fix for building PAM module + +2009-05-09 arthur + + * [r881] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.9 release + * [r880] debian/libnss-ldapd.postinst: if base is blank disable the + base option to let nslcd attempt search base autodiscovery + * [r879] nss/common.h: also close any open stream on buffer error + * [r878] nss/common.h, nss/group.c: check the buffer passed by + Glibc for validity + * [r877] nslcd-common.h: make sure that when writing a list of + strings the number of strings is always checked when excluding an + entry + * [r876] ., AUTHORS, Makefile.am, configure.ac, debian, + debian/copyright, nslcd.h, pam: import the PAM module from the + nss-ldapd branch (r875) based on the OpenLDAP nssov tree and + allow configuring which modules should be built (PAM module + disabled by default) + * [r872] configure.ac, nslcd/nslcd.c: according to autoupdate + RETSIGTYPE can be considered void always + +2009-05-08 arthur + + * [r868] debian/copyright: aggregate years + +2009-05-07 arthur + + * [r867] INSTALL, config.guess, config.sub: include updated files + * [r864] nslcd.h, nslcd/netgroup.c, nss/netgroup.c: prefix + NETGROUP_TYPE macros with NSLCD_ + * [r861] debian/po/gl.po: added Galician (gl) translation of + debconf templates by Marce Villarino + +2009-05-06 arthur + + * [r860] debian/po/es.po: updated Spanish (es) translation of + debconf templates by Francisco Javier Cuadrado + + +2009-05-05 arthur + + * [r859] debian/po/ru.po: updated Russian (ru) translation of + debconf templates by Yuri Kozlov + * [r858] debian/po/ru.po: convert translation to UTF-8 + +2009-05-03 arthur + + * [r857] debian/po/sv.po: updated Swedish (sv) translation of + debconf templates by Martin Ågren + +2009-05-02 arthur + + * [r856] debian/po/fr.po: updated French (fr) translation of + debconf templates by Guillaume Delacour + +2009-05-01 arthur + + * [r855] debian/po/it.po: fix incorrect references to nss-ldap + (without the d at the end) + * [r854] man/nslcd.8.xml: document that you can specify -d multiple + times + * [r853] nslcd/cfg.c, nslcd/cfg.h, nslcd/myldap.c: set most SSL/TLS + related options globally instead of per connection + +2009-04-30 arthur + + * [r852] nslcd/cfg.c, nslcd/cfg.h, nslcd/myldap.c, nslcd/myldap.h, + nslcd/nslcd.c: move debugging initialisation to + myldap_set_debuglevel() function + +2009-04-27 arthur + + * [r851] debian/po/it.po: added Italian (it) translation of debconf + templates by Vincenzo Campanella + +2009-04-25 arthur + + * [r850] nslcd/myldap.c: produce more logging and get OpenLDAP + logging working by logging to stderr (and implement temporary + workaround for reqcert problems) + * [r849] nslcd/cfg.h: include ldap.h to ensure that struct + ldap_config will be the same in every file + * [r848] nslcd/myldap.c: clear errno before ldap calls to get + usable returned errno + * [r847] debian/po/pt.po: updated Portuguese (pt) translation of + debconf templates by Américo Monteiro + +2009-04-22 arthur + + * [r846] debian/libnss-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fr.po, debian/po/ja.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po: fix spelling in English debconf template (thanks + Vincenzo Campanella) + * [r845] debian/po/ja.po: updated Japanese (ja) translation of + debconf templates by Kenshi Muto + * [r844] debian/po/da.po: updated Danish (da) translation of + debconf templates by Jonas Smedegaard + +2009-04-21 arthur + + * [r843] debian/libnss-ldapd.postrm, debian/libnss-ldapd.templates, + debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fr.po, + debian/po/ja.po, debian/po/nl.po, debian/po/pt.po, + debian/po/pt_BR.po, debian/po/ru.po, debian/po/sv.po, + debian/po/templates.pot, debian/po/vi.po: ask on removal and on + purge whether to edit /etc/nsswitch.conf and remove ldap entries + +2009-04-19 arthur + + * [r834] nslcd.h, nslcd/alias.c, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c, + nss/common.h, nss/group.c: clear up protocol description in + nslcd.h, renaming NSLCD_RESULT_SUCCESS to NSLCD_RESULT_BEGIN + +2009-04-17 arthur + + * [r830] nslcd.h: include definitions of PAM-related actions from + current OpenLDAP work in nssov + * [r829] debian/libnss-ldapd.postrm: fix spelling in comment + +2009-04-04 arthur + + * [r828] debian/libnss-ldapd.postrm: remove /var/run/nslcd on + package removal + +2009-03-31 arthur + + * [r827] debian/changelog: add CVE identifier + +2009-03-22 arthur + + * [r825] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nss-ldapd.conf.5.xml: get files ready for + 0.6.8 release + * [r824] README, debian/copyright: update copyright year + * [r823] nslcd/nslcd.c: update copyright year + * [r822] debian/compat, debian/control, debian/rules: upgrade to + debhelper compatibility level 7 + * [r821] debian/control: upgrade to standards-version 3.8.1 (no + changes needed) + * [r820] Makefile.am, debian/libnss-ldapd.lintian-overrides, + debian/rules: add lintian override for missing shlibs and symbols + control files (we are a shared library that should not be + directly linked to) + +2009-03-21 arthur + + * [r818] NEWS: fix version numbers in NEWS file + * [r817] nss-ldapd.conf: add a note about permissions of + nss-ldapd.conf when using the bindpw option + * [r816] debian/libnss-ldapd.postinst: instead of bindpw check + always create config file with proper permissions and fix + permissions once on upgrade + +2009-03-20 arthur + + * [r814] debian/libnss-ldapd.postinst: add bindpw-related warning + message to default installed config file + * [r813] debian/libnss-ldapd.postinst: fix permissions of + configfile if passwords are stored + +2009-03-15 arthur + + * [r812] debian/control: follow change in override file + +2009-02-27 arthur + + * [r811] debian/control: use misc:Depends to generate debconf + dependency + * [r810] nslcd/common.c: check user and group names against + LOGIN_NAME_MAX if it is defined + * [r809] man/Makefile.am: generate utf-8 encoded manual page (no + non-ascii characters used at the moment) + * [r808] nslcd/passwd.c: add some more documentation + +2009-01-30 arthur + + * [r807] compat/getpeercred.c: fix for getpeercred() on Solaris by + David Bartley + diff --git a/ChangeLog-2010 b/ChangeLog-2010 new file mode 100644 index 0000000..3adbb47 --- /dev/null +++ b/ChangeLog-2010 @@ -0,0 +1,934 @@ +2010-12-30 arthur + + * [r1358] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.8.0 release + * [r1357] README, debian/copyright: update copyright information + * [r1356] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fi.po, + debian/po/fr.po, debian/po/gl.po, debian/po/it.po, + debian/po/ja.po, debian/po/nb.po, debian/po/nl.po, + debian/po/pt.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po, + debian/po/zh_CN.po: run debconf-updatepo (new and updated + templates) + * [r1355] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fi.po, + debian/po/fr.po, debian/po/gl.po, debian/po/it.po, + debian/po/ja.po, debian/po/nb.po, debian/po/nl.po, + debian/po/pt.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/vi.po, debian/po/zh_CN.po: put headers + of .po files in a consistent format + * [r1354] ., AUTHORS, HACKING, README, configure.ac, + debian/copyright, nss/Makefile.am, nss/common.h, nss/ethers.c, + nss/exports.solaris, nss/group.c, nss/hosts.c, nss/netgroup.c, + nss/networks.c, nss/passwd.c, nss/protocols.c, nss/prototypes.h, + nss/rpc.c, nss/services.c, nss/shadow.c, nss/solnss.c: integrate + Solaris support developed by Ted C. Cheng of Symas Corporation + that was developed on the -solaris branch + +2010-12-29 arthur + + * [r1348] Makefile.am, pam/Makefile.am: fix distcheck by passing + --with-pam-seclib-dir to configure and remove unneeded slashes + * [r1347] Makefile.am, configure.ac, py-compile, pynslcd, + pynslcd/Makefile.am, pynslcd/alias.py, pynslcd/cfg.py, + pynslcd/common.py, pynslcd/config.py.in, pynslcd/debugio.py, + pynslcd/ether.py, pynslcd/group.py, pynslcd/mypidfile.py, + pynslcd/pam.py, pynslcd/passwd.py, pynslcd/pynslcd.py, + pynslcd/shadow.py, pynslcd/tio.py: add an experimental (currently + partial) Python implementation of nslcd to see if we can get the + same features with easier to maintain code + +2010-12-28 arthur + + * [r1346] man/nslcd.conf.5.xml, nslcd/attmap.c, nslcd/common.c, + nslcd/common.h, nslcd/group.c, nslcd/passwd.c, nslcd/shadow.c: + allow attribute mapping with an expression for the userPassword + attribute for passwd, group and shadow entries and by default map + it to the unmatchable password ("*") to avoid accidentally + leaking password information + +2010-12-26 arthur + + * [r1345] nslcd/common.h, nslcd/myldap.c, nslcd/myldap.h, + nslcd/pam.c, nslcd/shadow.c: try to update the shadowLastChange + attribute of a user on password change (the update is only tried + if the attribute is present to begin with) + * [r1344] common/tio.c: return connection reset when connection was + closed by the other end + * [r1343] tests/nslcd-test.conf: paging isn't supported by OpenLDAP + when chasing referrals + * [r1342] nslcd/cfg.c: also support the tls_cacert option as an + alias for tls_cacertfile + * [r1341] man/nslcd.conf.5.xml: add notes on ignored options when + using GnuTLS (based on #513270 which was reported against the + openldap package by Peter Palfrader) + +2010-12-24 arthur + + * [r1340] nslcd/common.c: also support tilde (~) in user and group + names, except as first character + * [r1339] nslcd/common.c: make logic of character tests easier to + read + +2010-12-20 arthur + + * [r1338] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/group.c, nslcd/passwd.c: implement a nss_min_uid option to + filter user entries returned by LDAP + +2010-12-18 arthur + + * [r1337] tests/test_nsscmds.sh: sort group members by alphabet to + not be dependant on the order of attributes returned and the + internal softing of the set + * [r1336] tests/README, tests/test.ldif.gz, tests/test_nsscmds.sh: + update tests with current test set-up (with chasing a referral + and some other minor changes) + +2010-12-12 arthur + + * [r1328] nslcd/myldap.c: pass the ld to do_bind() instead of the + session to use the correct ld from do_rebind() + * [r1327] nslcd/pam.c: always return a positive authorisation + result during authentication because we don't do any + authorisation checks during authentication and this may confuse + the PAM module if it's only used for authorisation + * [r1326] pam/pam.c: fallback to standard PAM error message if one + wasn't returned by nslcd + * [r1325] nslcd/myldap.c: fix comment + +2010-12-11 arthur + + * [r1322] tests/test_myldap.c: include extra assertion checks + +2010-12-08 arthur + + * [r1319] nslcd/myldap.c, nslcd/myldap.h, nslcd/nslcd.c: in each + worker wake up once in a while to check whether any existing LDAP + connections should be closed + +2010-12-03 arthur + + * [r1318] nslcd/pam.c: in try_bind(), perform the search ourselves + instead of using lookup_dn2uid() to also be able to match + administrator DNs (thanks to Thaddeus J. Kollar for spotting + this) + * [r1317] nslcd/pam.c: fix handling of try_bind() result code in + nslcd_pam_authc() (patch by Thaddeus J. Kollar) + +2010-11-26 arthur + + * [r1316] nslcd/nslcd.c: close all open file descriptors on start + +2010-11-17 arthur + + * [r1315] nslcd/common.h, nslcd/pam.c, nslcd/passwd.c: return + correct PAM status code for when LDAP server is unavailable + (based on a patch by Pierre Gambarotto) + * [r1314] nslcd/pam.c: switch all internal functions to return an + LDAP status code + * [r1313] nslcd/pam.c: return correct kind of error code from + try_pwmod() (bug) + +2010-11-10 arthur + + * [r1312] debian/nslcd.config, debian/nslcd.postinst, + debian/nslcd.templates: implement configuring SASL authentication + using Debconf, based on a patch by Daniel Dehennin + * [r1311] debian/nslcd.config: fix for problem with undefined + values in read_config() function + +2010-11-07 arthur + + * [r1310] debian/nslcd.config: split reading values from a + configfile into a separate function and also ensure that + tls_reqcert is correctly read + * [r1309] debian/nslcd.postinst: add comment describing function + * [r1308] debian/nslcd.postinst: split updating configuration file + based on debconf value to separate function and make config + option renaming consistent + * [r1307] pam/Makefile.am: fix installation directory for PAM + module (was broken in r1239) + * [r1306] debian/nslcd.postinst: move special casing of handling + bindpw removal to cfg_disable() function + * [r1305] debian/nslcd.config, debian/nslcd.postinst: handle + tls_reqcert option consistently with other options + * [r1304] debian/nslcd.config: remove extra slash character + * [r1303] configure.ac: guess NSS SONAME on freebsd + * [r1302] configure.ac: use NSS flavour to determine which exports + file to use + * [r1301] nslcd/alias.c, nslcd/common.h, nslcd/ether.c, + nslcd/group.c, nslcd/host.c, nslcd/log.c, nslcd/log.h, + nslcd/netgroup.c, nslcd/network.c, nslcd/pam.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + log the request with any logged messages + * [r1300] compat/ldap_compat.h: SASL compatibility definition + +2010-11-04 arthur + + * [r1298] nslcd/nslcd.c: move acceptconnection() function body + inside the worker() so we can more easily break out of the + connection handling thread, close the server socket inside the + signal handler to cause all threads waiting on accept() to fail + and ensure that signals are handled in the main thread by + blocking them in the worker threads (r1290 from -solaris branch) + * [r1297] nslcd/common.h, nslcd/pam.c, nslcd/passwd.c: avoid + unneeded strdup()s by using a passed buffer to lookup_dn2uid() + and using strcmp() in dn2uid() to see if the existing cached + value is ok + * [r1296] nslcd/passwd.c: fix race condition that could cause a + memory leak + * [r1295] common/nslcd-prot.c, nslcd/nslcd.c: pass the actual size + of the address family and the path length to bind() and connect() + for named sockets + +2010-11-03 arthur + + * [r1294] nslcd/myldap.c: call myldap_session_check() before adding + a new search to the session so the connection actually gets + closed on timeout (the connection isn't closed when there are + active searches) + +2010-10-16 arthur + + * [r1288] configure.ac: chage test for compiling with gcc to be + simpler and not use deprecated ac_cv_prog_gcc + * [r1287] nslcd/nslcd.c: fix log message + * [r1286] nslcd/cfg.h: remove obsolete note + +2010-10-15 arthur + + * [r1279] common/dict.c, common/dict.h, common/set.c, common/set.h, + tests/test_set.c: implement dict_getany() and set_pop() functions + to be able to pick and remove entries + * [r1278] common/dict.c, common/dict.h, common/set.h, + tests/test_dict.c, tests/test_set.c: make DICTs and SETs + case-sensitive + * [r1277] nss/common.h: split out checking of NSS module + availability and buffer correctness to separate macros (taken + from the -solaris branch) + * [r1276] nslcd/myldap.c: set a longer socket timout for the normal + connection (just in case mostly) and a short one to use when + shutting down the connection (also see + http://www.openldap.org/its/index.cgi?selectid=6673) + +2010-10-14 arthur + + * [r1274] configure.ac: set {nss,pam}_ldap_so_LINK from configure + to allow custom linker properties for Solaris (r1261 and r1263 + from -solaris branch) + * [r1273] configure.ac: also include sys/types.h for + ethernet-related tests (same as in compat/ether.h) (r1259 from + -solaris branch) + * [r1272] nss/group.c: move _nss_ldap_initgroups_dyn() definition + to the end to have more logical order + * [r1271] nslcd/myldap.c: simplify SASL includes + +2010-10-13 arthur + + * [r1270] nss/Makefile.am: link local modules before .a files from + common directory to pick symbols up in correct order + * [r1269] configure.ac: move ethernet function checks outside + nslcd-specific tests to also compile without warnings when only + compiling NSS module + * [r1267] nslcd/pam.c: make buffer sizes for PAM requests + consistent (and large enough for most situations) + * [r1266] configure.ac: rename --with-nss-ldap-maps to + --with-nss-maps + * [r1265] compat/ldap_passwd_s.c: small fix + +2010-10-12 arthur + + * [r1264] nslcd/myldap.c: set timeout options on LDAP socket to + avoid problems when the LDAP library hangs on a read() (e.g. at + ldap_unbind()) + +2010-10-10 arthur + + * [r1256] nslcd/myldap.c, nss/netgroup.c, pam/pam.c: make use of + UNUSED() consistent throughout the code + * [r1255] nss/rpc.c: correctly name shared file handle + * [r1254] ChangeLog: undo changes to ChangeLog accidentally checked + in in r1253) + * [r1253] ChangeLog, configure.ac, nss/Makefile.am, + nss/exports.glibc, nss/exports.solaris, nss/nss_ldap.map, + pam/Makefile.am: put all logic on how to run linker for NSS and + PAM components in configure script (remove stuff from + Makefile.ams) and add Solaris version script (renaming version + scripts as needed) (r1250 from -solaris branch) + * [r1252] compat/ether.c, compat/ether.h: move missing declarations + of ether_ntoa() and ether_aton() to header file so they are + available for other sources also (r1243 from -solaris branch) + * [r1251] configure.ac: fix test of returnlen struct member check + (r1244 from -solaris branch) + +2010-10-08 arthur + + * [r1245] nss/services.c: correctly name shared file handle + +2010-10-04 arthur + + * [r1240] nss/Makefile.am, nss/aliases.c, nss/ethers.c, + nss/group.c, nss/hosts.c, nss/netgroup.c, nss/networks.c, + nss/passwd.c, nss/protocols.c, nss/rpc.c, nss/services.c, + nss/shadow.c, pam/Makefile.am: improve consistency of code layout + * [r1239] compat/nss_compat.h, configure.ac, nss/Makefile.am, + nss/common.h, nss/hosts.c, nss/networks.c, nss/prototypes.h, + pam/Makefile.am: merge some of the changes for Solaris + portability to ease merging, adding --with-pam-seclib-dir, + --with-pam-ldap-soname and --with-nss-flavour options and having + some auto-detection for SONAMEs and NSS flavour + +2010-10-02 arthur + + * [r1235] .: ignore configure.lineno + +2010-10-01 arthur + + * [r1233] compat/ether.c, compat/ldap_passwd_s.c, configure.ac: use + AC_CHECK_DECLS to check for definitions of functions we provide a + replacement definition for + +2010-09-30 arthur + + * [r1229] debian/po/vi.po: updated Vietnamese (vi) translation of + debconf templates by Clytie Siddall + * [r1228] configure.ac: fix test quoting + +2010-09-29 arthur + + * [r1227] compat/ether.c, configure.ac: only provide definitions + for ether_aton() and ether_ntoa() for platforms missing a + definition + * [r1226] compat/ether.c: fix definitions of ether_aton() and + ether_ntoa() + +2010-09-28 arthur + + * [r1225] compat/nss_compat.h, compat/pam_get_authtok.c, + configure.ac: begin merging some of the compatibility + improvements from Ted C. Cheng of Symas Corporation + * [r1224] compat/nss_compat.h: no need to provide a enum nss_status + replacement because we don't use it + * [r1223] tests/test_aliases.c, tests/test_ethers.c, + tests/test_group.c, tests/test_hosts.c, tests/test_netgroup.c, + tests/test_networks.c, tests/test_passwd.c, + tests/test_protocols.c, tests/test_rpc.c, tests/test_services.c, + tests/test_shadow.c: also switch to nss_status_t for test code + * [r1222] configure.ac: simplify appending OBJEXT sed expression + +2010-09-27 arthur + + * [r1221] nslcd/myldap.c: remove variables which are no longer + necessary due to r1220 + * [r1220] nslcd/myldap.c: remove disabling keepalives since we + handle SIGPIPE anyway + +2010-09-26 arthur + + * [r1219] nslcd/myldap.c: remove ugly empty line + * [r1218] configure.ac: properly define PACKAGE_URL + * [r1217] nslcd/group.c: update description of group schema + supported + * [r1216] Makefile.am: switch to nicer mechanism to specify + subdirectories to build + +2010-09-25 arthur + + * [r1215] configure.ac, nss/Makefile.am: have a way to limit which + NSS maps should be built + +2010-09-24 arthur + + * [r1214] compat/nss_compat.h, nss/aliases.c, nss/common.h, + nss/ethers.c, nss/group.c, nss/hosts.c, nss/netgroup.c, + nss/networks.c, nss/passwd.c, nss/protocols.c, nss/prototypes.h, + nss/rpc.c, nss/services.c, nss/shadow.c: switch to using + nss_status_t throughout the code and provide compatibility code + to use whatever nss_status type is used on the system + +2010-09-23 arthur + + * [r1208] nslcd/myldap.c: add some more error cases which should + trigger a disconnect + +2010-09-20 arthur + + * [r1207] nslcd/myldap.c: handle errors from ldap_result() + consistently and also retry in case it times out + +2010-09-05 arthur + + * [r1206] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/common.h, nslcd/nslcd.c, nslcd/pam.c, pam/pam.c: implement + a rootpwmodpw option that allows root users to change user + passwords without a password prompt + +2010-08-28 arthur + + * [r1204] ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.9 release + * [r1203] debian/po/nl.po: unfuzzy a few Dutch translations and + improve some others + * [r1202] debian/po/it.po: fix package name + * [r1201] debian/po/es.po: updated Spanish (es) translation of + debconf templates by Francisco Javier Cuadrado + * [r1200] debian/libpam-ldapd.templates, debian/po/ca.po, + debian/po/cs.po, debian/po/da.po, debian/po/de.po, + debian/po/es.po, debian/po/fi.po, debian/po/fr.po, + debian/po/gl.po, debian/po/it.po, debian/po/ja.po, + debian/po/nb.po, debian/po/nl.po, debian/po/pt.po, + debian/po/pt_BR.po, debian/po/ru.po, debian/po/sv.po, + debian/po/templates.pot, debian/po/vi.po, debian/po/zh_CN.po: fix + incorrect reference from /etc/nsswitch to /etc/nsswitch.conf + * [r1199] debian/po/da.po, debian/po/de.po, debian/po/it.po, + debian/po/ja.po, debian/po/nb.po, debian/po/ru.po, + debian/po/sv.po: fix wrapping of po files + * [r1198] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/fr.po, debian/po/it.po, + debian/po/ja.po, debian/po/nb.po, debian/po/pt.po, + debian/po/ru.po, debian/po/sv.po, debian/po/zh_CN.po: correct + references to package name for up-to-date translations + * [r1197] debian/po/es.po, debian/po/fr.po, debian/po/gl.po, + debian/po/ja.po: fix translations that had a reference to the old + location of the configuration file + * [r1196] debian/po/sv.po: updated Swedish (sv) translation of + debconf templates by Martin Ågren + * [r1195] debian/po/ca.po: unfuzzy translated string (confirmed OK + by Agustí Grau) + +2010-08-27 arthur + + * [r1194] debian/po/ca.po: updated Catalan (ca) translation of + debconf templates by Agusti Grau + +2010-08-26 arthur + + * [r1193] debian/po/de.po: updated German (de) translation of + debconf templates by Chris Leick + +2010-08-25 arthur + + * [r1192] debian/po/fr.po: updated French (fr) translation of + debconf templates by Christian Perrier + +2010-08-24 arthur + + * [r1191] debian/po/da.po: updated Danish (da) translation of + debconf templates by Joe Hansen + +2010-08-20 arthur + + * [r1190] debian/po/ja.po: updated Japanese (ja) translation of + debconf templates by Kenshi Muto + +2010-08-19 arthur + + * [r1189] debian/nslcd.templates, debian/po/ca.po, debian/po/cs.po, + debian/po/da.po, debian/po/de.po, debian/po/es.po, + debian/po/fi.po, debian/po/fr.po, debian/po/gl.po, + debian/po/it.po, debian/po/ja.po, debian/po/nb.po, + debian/po/nl.po, debian/po/pt.po, debian/po/pt_BR.po, + debian/po/ru.po, debian/po/sv.po, debian/po/templates.pot, + debian/po/vi.po, debian/po/zh_CN.po: fix double "be" in English + template thanks to Christian PERRIER + * [r1188] debian/po/it.po: updated Italian (it) translation of + debconf templates by Vincenzo Campanella + * [r1187] debian/po/zh_CN.po: updated Simplified Chinese (zh_CN) + translation of debconf templates by zym + * [r1186] debian/po/cs.po: updated Czech (cs) translation of + debconf templates by Miroslav Kure + * [r1185] configure.ac: fix for --with-nss-ldap-soname option by + Julien Cristau + +2010-08-18 arthur + + * [r1183] ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.8 release + * [r1182] debian/po/nb.po: added Norwegian Bokmål (nb) translation + of debconf templates by Bjørn Steensrud + * [r1181] debian/po/ru.po: updated Russian (ru) translation of + debconf templates by Yuri Kozlov + * [r1180] debian/po/pt.po: updated Portuguese (pt) translation of + debconf templates by Américo Monteir + +2010-08-17 arthur + + * [r1179] debian/po/da.po, debian/po/vi.po, debian/po/zh_CN.po: + remove invalid and bouncing addresses + * [r1178] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fi.po, + debian/po/fr.po, debian/po/gl.po, debian/po/it.po, + debian/po/ja.po, debian/po/nl.po, debian/po/pt.po, + debian/po/pt_BR.po, debian/po/ru.po, debian/po/sv.po, + debian/po/templates.pot, debian/po/vi.po, debian/po/zh_CN.po: + update debian/po files with modified template + * [r1177] debian/libpam-ldapd.postinst: only offer to fix + nsswitch.conf if PAM has been converted with pam-auth-update + * [r1176] debian/libpam-ldapd.templates: updated debconf template + thanks to Justin B Rye + +2010-08-15 arthur + + * [r1175] debian/po/POTFILES.in, debian/po/ca.po, debian/po/cs.po, + debian/po/da.po, debian/po/de.po, debian/po/es.po, + debian/po/fi.po, debian/po/fr.po, debian/po/gl.po, + debian/po/it.po, debian/po/ja.po, debian/po/nl.po, + debian/po/pt.po, debian/po/pt_BR.po, debian/po/ru.po, + debian/po/sv.po, debian/po/templates.pot, debian/po/vi.po, + debian/po/zh_CN.po: update debian/po files with added template + +2010-08-14 arthur + + * [r1174] debian/control: upgrade to standards-version 3.9.1 + * [r1173] debian/control: add libpam-sss as an alternative to + libpam-ldapd + * [r1172] debian/control: merge the recommends from libnss-ldapd + and libpam-ldapd into those of nslcd so we can track all the PAM + alternatives in one place + * [r1171] Makefile.am, debian/libnss-ldapd.postinst, + debian/libnss-ldapd.postrm, + debian/libpam-ldapd.lintian-overrides, + debian/libpam-ldapd.postinst, debian/libpam-ldapd.templates: + offer to add ldap to shadow in nsswitch.conf if a potential + broken configuration is found + * [r1170] ChangeLog, ChangeLog-2006, ChangeLog-2007, + ChangeLog-2008, Makefile.am: archive older ChangeLog entries in + year files + * [r1169] common/expr.c: also don't expand variables in rest of + ${var:+rest} expressions if var is not set or empty + * [r1168] common/expr.c: do not expand variables in rest of + ${var:-rest} expressions if var is not blank or empty + +2010-07-27 arthur + + * [r1167] nss/services.c: use htons() instead of ntohs() (thanks + Ted C. Cheng) + +2010-07-18 arthur + + * [r1166] compat/nss_compat.h, configure.ac: compatibility + improvement: also check for nss_common.h and see if enum + nss_status exists + * [r1165] nslcd/pam.c: fix comment + * [r1164] nss/Makefile.am: use -h linker flag instead of -soname + which seems more portable + * [r1163] compat/pam_compat.h: define pam_info(), pam_error() and + pam_syslog() compatibility macros to allow no arguments for + format + +2010-07-17 arthur + + * [r1162] debian/nslcd.config: only go back one step on Debconf + back + +2010-07-07 arthur + + * [r1161] configure.ac, nslcd/nslcd.c, nss/Makefile.am: allow + configuring NSS module's SONAME from configure and use this in + nslcd to dlopen() the correct library (thanks to Alexander V. + Chernikov for the idea) + +2010-07-03 arthur + + * [r1159] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.7 release + * [r1158] debian/control: upgrade to standards-version 3.9.0 + * [r1157] debian/libnss-ldapd.config, debian/nslcd.config: don't + use dh_title to set the Debconf title, the default should be fine + * [r1156] debian/control: use Replaces/Breaks instead of Conflicts + for introduction of nslcd package (as per policy 3.9.0) + +2010-06-25 arthur + + * [r1155] Makefile.am, debian/libpam-ldapd.manpages, + debian/nslcd.install, debian/nslcd.manpages: make sure the + pam_ldap manual page is in the libpam-ldapd package + +2010-06-19 arthur + + * [r1154] nslcd/myldap.c: add logging to SASL interaction function + * [r1153] nslcd/myldap.c: improve debug logging of SASL bind calls + * [r1152] debian/nslcd.default: updated based on comments by Daniel + Dehennin + +2010-06-18 arthur + + * [r1151] AUTHORS, Makefile.am, debian/control, + debian/nslcd.conffile, debian/nslcd.default, debian/nslcd.init: + start k5start from the init script to keep the Kerberos ticket + active if nslcd is configured for SASL GSSAPI kerberos + authentication, based on a patch by Daniel Dehennin + + * [r1150] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h: remove + warning messages from parsing the sasl_* options and document + them in the nslcd.conf(5) manual page (they should be functional) + * [r1149] nslcd/myldap.c: make SASL binding code a little earier to + read + * [r1148] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/myldap.c: remove the use_sasl option and instead rely on + sasl_mech being specified + * [r1147] debian/nslcd.init: group options more + +2010-06-17 arthur + + * [r1146] compat/Makefile.am, compat/nss_compat.h, configure.ac, + nss/common.h, nss/prototypes.h: have more compatibility code for + NSS module and move compatibility code to compat directory + +2010-06-16 arthur + + * [r1145] debian/nslcd.init: ensure that nslcd is started after + hostname lookups are available so getting to the LDAP server via + DNS lookups will work (patch by Petter Reinholdtsen) + * [r1144] nslcd/nslcd.c: use RTLD_NODELETE during dlopen() instead + of not using dlclose() + +2010-06-15 arthur + + * [r1143] configure.ac, nss/Makefile.am, nss/exports.linux, + nss/nss_ldap.map, pam/Makefile.am, pam/exports.linux, + pam/pam_ldap.map: rename symbol map files and check for the + linker option to specify the file with + * [r1142] configure.ac, nslcd/Makefile.am: pass pthread flags + correctly to nslcd Makefile and rename save_ vars to not conflict + with AX_PTHREAD test + +2010-06-14 arthur + + * [r1141] configure.ac, nslcd/nslcd.c, nss/Makefile.am, + nss/common.c, nss/common.h, nss/exports.linux, nss/netgroup.c, + nss/prototypes.h, tests/Makefile.am: implement a global symbol + inside the NSS module to allow applications to disable NSS + lookups over LDAP and use it in nslcd to avoid deadlocks + * [r1140] common/dict.h, common/expr.h, common/nslcd-prot.h, + common/set.h, common/tio.h, compat/attrs.h, compat/daemon.h, + compat/ether.h, compat/getopt_long.h, compat/getpeercred.h, + compat/ldap_compat.h, compat/pam_compat.h, nslcd/attmap.h, + nslcd/cfg.h, nslcd/common.h, nslcd/log.h, nslcd/myldap.h, + nss/common.h, nss/prototypes.h, pam/common.h: make include guard + names consistent throughout the source and avoid conflicts with + system headers + * [r1139] nss/aliases.c, nss/ethers.c, nss/group.c, nss/hosts.c, + nss/netgroup.c, nss/networks.c, nss/passwd.c, nss/protocols.c, + nss/rpc.c, nss/services.c, nss/shadow.c: remove some unused + include statements + +2010-06-12 arthur + + * [r1138] README, common/tio.c, nslcd/attmap.c, nslcd/attmap.h, + nslcd/group.c, nslcd/network.c: remove commented out memberOf and + ipNetmaskNumber attributes and small cleanups + * [r1137] debian/po/ca.po, debian/po/cs.po, debian/po/da.po, + debian/po/de.po, debian/po/es.po, debian/po/fi.po, + debian/po/fr.po, debian/po/gl.po, debian/po/it.po, + debian/po/ja.po, debian/po/nl.po, debian/po/pt.po, + debian/po/pt_BR.po, debian/po/ru.po, debian/po/sv.po, + debian/po/vi.po, debian/po/zh_CN.po: run translations through + debconf-updatepo -v + +2010-06-11 arthur + + * [r1136] nslcd/nslcd.c: fix and remove source code comments + +2010-06-04 arthur + + * [r1135] ChangeLog, debian/changelog: revert part of r1134 that + was accidentally commited + * [r1134] ChangeLog, debian/changelog, pam/pam.c: fix nullok test + for password modification + +2010-06-03 arthur + + * [r1133] debian/libpam-ldapd.pam-auth-update: also ignore other + ignorable PAM return codes + +2010-06-02 arthur + + * [r1132] compat/pam_get_authtok.c: add a warning to the limitation + of our pam_get_authtok() implementation + * [r1131] pam/pam.c: simplify PAM module splitting remapping for + ignore_* options to a separate function, parsing of + try_first_pass and use_first_pass is done by pam_get_authtok(), + don't report session errors to the user and make error handling + consistent + +2010-06-01 arthur + + * [r1130] nslcd/pam.c: fix bug in test (r1127) + * [r1129] man/pam_ldap.8.xml, pam/pam.c: implement an nullok PAM + option and disable empty passwords by default + * [r1128] pam/pam.c: don't log failure to do nslcd request to user + and log authentication errors during password change + * [r1127] nslcd/pam.c: add a debug log message when user + authentication was successful + * [r1126] debian/libpam-ldapd.pam-auth-update: don't use + use_authtok for password modification by default + +2010-05-31 arthur + + * [r1125] pam/pam.c: fix typo + +2010-05-27 arthur + + * [r1123] AUTHORS, ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.6 release + +2010-05-26 arthur + + * [r1122] debian/control: drop extra parts of package descriptions + that should no longer be really relevant and update libpam-ldapd + description + +2010-05-24 arthur + + * [r1121] debian/libpam-ldapd.pam-auth-update: update + pam-auth-update configuration to always perform LDAP + autorisation, also pass use_authtok on password modification and + spell out session result handling + * [r1120] pam/pam.c: make code more consistent + * [r1119] man/pam_ldap.8.xml: fix typo + * [r1118] pam/pam.c: don't store use_authtok because + pam_get_authtok() looks at the arguments itself + +2010-05-23 arthur + + * [r1117] HACKING, README, man/nslcd.8.xml, man/nslcd.conf.5.xml: + update documentation + * [r1116] nslcd.conf: include uid and gid options in default + configuration file + * [r1115] configure.ac, m4/acx_pthread.m4, m4/ax_pthread.m4: update + AC?X_PTHREAD macro and update configure script to be simpler and + add some more checks + * [r1114] debian/nslcd.init: use nslcd --check in init script's + status command + +2010-05-22 arthur + + * [r1113] nslcd/pam.c: make debug logging for pam_authz_search + option a little more readable + +2010-05-20 arthur + + * [r1112] debian/control: add libpam-heimdal as an alternative + recommends for libnss-ldapd + +2010-05-15 arthur + + * [r1111] nslcd/attmap.c, nslcd/attmap.h: always clear returned + buffer when performing attribute mapping (based on a patch by + Nalin Dahyabhai ) + +2010-05-14 arthur + + * [r1109] ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.5 release + * [r1108] Makefile.am, debian/source, debian/source/format: switch + to source format 3.0 (native) + * [r1107] pam/pam.c: print uid as a long + * [r1106] compat/pam_compat.h, configure.ac, man/pam_ldap.8.xml, + pam/common.h, pam/pam.c: perform logging from PAM module to + syslog and support the debug option to log debugging information + +2010-05-13 arthur + + * [r1105] pam/pam.c: centralise initialising functions needed for + every PAM call into one function + * [r1104] common/nslcd-prot.h, nslcd/common.h: make logging of + buffer checks consistent + * [r1103] pam/pam.c: also use PAM username instead of one from + context for session open and close + * [r1102] pam/pam.c: replace my_pam_get_authtok() with standard + pam_get_authtok() function, get rid of get_old_password() and + general cleanups and simplifications + +2010-05-12 arthur + + * [r1101] pam/pam.c: make parsing configuration options global, + reorganise a bit and make code more consistent and easier to read + * [r1100] compat/pam_compat.h, nslcd/pam.c: small compatibility + improvements + +2010-05-10 arthur + + * [r1099] pam/pam.c: only log "LDAP session failed" if we actually + tried + * [r1098] compat/Makefile.am, compat/pam_compat.h, + compat/pam_get_authtok.c, compat/pam_prompt.c, configure.ac, + pam/pam.c: replace my_pam_warn() with pam_info() and pam_error() + and provide replacement for pam_prompt() also using it in our + pam_get_authtok() replacement + +2010-05-09 arthur + + * [r1096] ChangeLog, NEWS, TODO, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.4 release + * [r1095] nslcd/myldap.c: only log "connected to LDAP server" if + the previous connect failed or we are failing over to a different + server + * [r1094] debian/nslcd.postinst, man/nslcd.conf.5.xml, nslcd/cfg.c, + nslcd/cfg.h, nslcd/myldap.c, tests/README, tests/nslcd-test.conf: + rename reconnect_maxsleeptime option to reconnect_retrytime + * [r1093] nslcd/myldap.c: don't log errno if it is not set (make + error less confusing) + * [r1092] nslcd/myldap.c: handle authentication searches a little + differently (only try once if an authentication error is + returned) + * [r1091] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/myldap.c: refactor retry timing mechanism to use time + between first and last error to determin when to rerty and only + try once (and don't sleep) when we have been failing for a long + time + +2010-05-08 arthur + + * [r1090] man/nslcd.conf.5.xml: fix wrapping of long line (thanks + lintian) + * [r1089] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/pam.c: rename authz_search option to pam_authz_search + +2010-05-07 arthur + + * [r1088] man/nslcd.conf.5.xml, man/pam_ldap.8.xml, nslcd/cfg.c, + nslcd/cfg.h, nslcd/pam.c: implement an authz_search option to + test whether the user is authorised + * [r1087] nslcd/alias.c, nslcd/ether.c, nslcd/group.c, + nslcd/host.c, nslcd/netgroup.c, nslcd/network.c, nslcd/passwd.c, + nslcd/protocol.c, nslcd/rpc.c, nslcd/service.c, nslcd/shadow.c: + tune some buffer sizes and small cleanups + * [r1086] tests/test_myldap.c: implement test for buffer overflow + * [r1085] nslcd/myldap.c: fix buffer overflow + * [r1084] man, man/Makefile.am: have the possibility to generate + HTML for manual pages (not done by default) + * [r1083] man/nslcd.conf.5.xml, man/pam_ldap.8.xml: use docbook + elements where possible + +2010-05-06 arthur + + * [r1082] compat/pam_compat.h, configure.ac, + debian/libpam-ldapd.pam-auth-update, man/pam_ldap.8.xml, + pam/pam.c: implement a minimum_uid option for the PAM module to + ignore users that have a lower numeric user id + +2010-05-05 arthur + + * [r1081] config.guess, config.sub: include updated files + +2010-05-03 arthur + + * [r1080] debian/nslcd.config: also parse /etc/ldap.conf for + systems that use that for NSS and PAM configuration + +2010-04-13 arthur + + * [r1079] nslcd/myldap.c, nslcd/myldap.h, nslcd/pam.c: don't have + myldap_set_credentials() try to open a connection but have the + PAM code perform a search with the new credentials so we re-use + the fail-over mechanism in myldap_search() + * [r1078] nslcd/cfg.c, nslcd/common.h, nslcd/myldap.c, + nslcd/myldap.h, nslcd/passwd.c, tests/test_myldap.c: also have + myldap_search() return an LDAP status code + +2010-04-01 arthur + + * [r1077] tests/README, tests/test.ldif.gz, tests/test_nsscmds.sh: + small improvements to the test setup + +2010-03-20 arthur + + * [r1076] man/nslcd.conf.5.xml, nslcd/cfg.c, nslcd/cfg.h, + nslcd/group.c: add an nss_initgroups_ignoreusers option to ignore + username to group lookups for the specified users + +2010-03-13 arthur + + * [r1075] man/nslcd.conf.5.xml: remove commented-oud default option + because it is not implemented and we have a better mechanism now + +2010-02-28 arthur + + * [r1074] nslcd/myldap.c: have less warnings when LDAP_OPT_X_TLS + isn't defined + * [r1073] man/nslcd.conf.5.xml: document which attributes may be + mapped with an expression + +2010-02-27 arthur + + * [r1071] ChangeLog, NEWS, configure.ac, debian/changelog, + man/nslcd.8.xml, man/nslcd.conf.5.xml, man/pam_ldap.8.xml: get + files ready for 0.7.3 release + * [r1070] debian/NEWS: add blank line for apt-listchanges + * [r1069] debian/control: upgrade to standards-version 3.8.4 (no + changes needed) + * [r1068] common/dict.h: fix typo + * [r1067] debian/nslcd.postinst, man/nslcd.conf.5.xml, nslcd.conf, + nslcd.h, nslcd/cfg.c, nslcd/cfg.h, nslcd/pam.c: rename admindn + option to rootpwmoddn + * [r1066] INSTALL, compile: update from latest automake + * [r1065] HACKING, tests/README: small updates to documentation + +2010-02-17 arthur + + * [r1064] nslcd/myldap.c: first try password modification without + the old password and if that fails with the old password + * [r1063] compat/ldap_passwd_s.c: add pointer to RFC 3062 + +2010-01-28 arthur + + * [r1062] man/nslcd.8.xml, nslcd/nslcd.c: patch by Jan Schampera to + implement a --check option + +2010-01-25 arthur + + * [r1061] nslcd/myldap.c: fix for type mismatch (thanks to Jan + Schampera) + +2010-01-24 arthur + + * [r1060] configure.ac, nslcd/cfg.c: add --with-bindpw-file + configure option to enable reading the bindpw option from a file + * [r1059] debian/nslcd.postinst, man/nslcd.conf.5.xml, nslcd.conf, + nslcd.h, nslcd/cfg.c, nslcd/cfg.h, nslcd/pam.c, pam/pam.c: add + admindn configuration file option that is used when modifying + another user's password + * [r1058] man/nslcd.conf.5.xml: fix example + * [r1057] nslcd/myldap.c: make logging of passwords consistent and + support a NULL oldpassword value in myldap_passwd() + * [r1056] nslcd/myldap.c: free data returned from ldap_passwd_s() + call if needed and add missing casts + * [r1055] HACKING: general updates and add PAM module information + +2010-01-23 arthur + + * [r1054] nss/prototypes.h: simple improvement for FreeBSD + * [r1053] nslcd/nslcd.c: lock the pidfile at start-up to ensure + only one nslcd process is running (based on a patch by Jan + Schampera ) + +2010-01-21 arthur + + * [r1052] debian/nslcd.init: start nslcd before apache for systems + that use LDAP users to run virtual hosts + * [r1051] HACKING, README, configure.ac: set contact address to + mailing list + * [r1050] debian/NEWS: change format of NEWS entry based on + Developer's Reference + * [r1049] debian/rules: install lintian overrides with dh_lintian + +2010-01-08 arthur + + * [r1048] nslcd/cfg.c: improve getting of domain name by also + checking hostname aliases (based on patch by Jan Schampera + ) + * [r1047] AUTHORS: improve getting of domain name by also checking + hostname aliases (based on patch by Jan Schampera + ) + diff --git a/HACKING b/HACKING new file mode 100644 index 0000000..d9d8e16 --- /dev/null +++ b/HACKING @@ -0,0 +1,241 @@ + +This document tries to describe the software layout and design of +nss-pam-ldapd. It should provide some help for contributing code to this +package. + +CONTRIBUTING TO NSS-PAM-LDAPD +============================= + +Contributions to nss-pam-ldapd are most welcome. Integrating contributions +will be done on a best-effort basis and can be made easier if the following +are considered: + +* for large changes it is a good idea to send an email first +* send your patches in unified diff (diff -u) format +* try to use the svn version of the software to develop the patch +* clearly state which problem you're trying to solve and how this is + accomplished +* please follow the existing coding conventions +* please test the patch and include information on testing with the patch + (platforms tested, etc) +* contributions will be acknowledged in the AUTHORS file +* include a copyright statement in the patched code if you feel the + contribution is significant enough (e.g. more than a few lines) +* when including third-party code, retain copyright information (copyright + holder and license) and ensure that the license is LGPL compatible + +Please email nss-pam-ldapd-users@lists.arthurdejong.org if you want to +contribute. + + +BUILD DEPENDENCIES +================== + +For building svn snapshots the following tools are needed: + +* autoconf (2.65 is used but 2.61 is minimal) +* automake (1.11 is used) + +and of course the usual build tools (gcc/make/etc). Also see debian/control +(Build-Depends field) for libraries you may need. + +To build the svn snapshot run the autogen.sh shell script to build the +configure script. When developing patches please use --enable-warnings with +configure and don't introduce too many new warnings. For building the manual +pages docbook2x is used. + + +RELEASE VERSIONING +================== + +A new versioning scheme was chosen over the nss_ldap release scheme. The +scheme is a simple major.minor.micro numbering. Until a 1.0 release is made +the code will be considered work in progress. The interfaces may change and +features may be added or removed. + + +GENERAL DESIGN +============== + +The basic design splits the functionality in three parts. The NSS part +interfaces with libc and translates the NSS requests into simple generic +requests (e.g. "get user with name test", "get group with gid 101" or "get all +shadow entries"). + +Another part is the PAM module which handles authentication requests from the +system. + +Both these parts translate the queries in a higher-level simple protocol used +to communicate with the nslcd daemon. This daemon translates the requests into +LDAP searches. As a result, the NSS and PAM modules don't need to known +anything about LDAP (in fact replacing it with another lookup method should be +very simple) and don't have to link with the LDAP libraries. + + libc NSS -> libnss_ldap.so + \ + |-> nslcd -> OpenLDAP -> LDAP server + / + PAM stack -> pam_ldap.so + +design goals +------------ +* make it as simple as possible +* simpler configuration and semantics +* simpler, clearer and completer documentation +* split source code into manageable parts +* get rid of unneeded code and complexity +* have a stable, easily maintainable piece of quality software + + +NSS MODULE +========== + +The NSS module is implemented in the nss directory. The functions are split +into files according to the database they support. The files support multiple +NSS implementations. + +The NSS interface is specific to the C library that is used. The original +implementation was for the GNU C Library but now also includes an +implementation for Solaris' C Library and has some support for FreeBSD. + +GNU C Library notes +------------------- + +Function definitions for glibc look like: + +_nss_ldap_FUNCTION_r(...) + This function opens the connection to the nslcd (with a time-out), builds + the correct data structures and does a request (write()) to the nslcd + waiting for an answer (again with a time-out) + +The complete list of exported functions can be found in exports.linux and +prototypes.h. + +Currently a number of macros are used to build most of the function bodies for +these functions. Part of this is defined in the common/nslcd-prot.h file and +the NSS-specific stuff is in nss/common.h. + +For memory management, the general mechanism that is expected to be used is +to return NSS_STATUS_TRYAGAIN and set errno to ERANGE. This causes glibc to +retry the request with a larger buffer. + +Some useful links: +http://www.gnu.org/software/libc/manual/html_node/index.html + +Solaris C Library notes +----------------------- + +The Solaris C library uses a different mechanism. For each map a back-end +object is allocated per thread which is used to do queries. The object is +created with a constructor (e.g. _nss_ldap_passwd_constr()) that returns a +back-end that contains a list of function pointer to lookup methods and a +destructor. + +A buffer is passed with every request but a local buffer that is stored in the +back-end can presumably also be created. + +Earlier versions of Solaris expected the NSS functions to return the binary +representation of the lookups (e.g. struct passwd) but later versions expect a +string representation of the data to be returned (just like a single line out +of /etc/passwd was read). + +Source and documentation pointers for Solaris NSS: +http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/nsswitch/ +http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/head/nss_common.h +http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/head/nss_dbdefs.h + +FreeBSD C Libarary notes +------------------------ + +The FreeBSD C library seems to have support for exposing GNU C Library NSS +module functions through a wrapper function. This makes it very easy to +implement NSS support on FreeBSD. + +Pointers for more documentation on this is welcome. Some information is +available here: +http://nixdoc.net/man-pages/FreeBSD/man3/nsdispatch.3.html +ftp://ftp8.tw.freebsd.org/pub/branches/-current/src/include/nss.h + + +PAM MODULE +========== + +The PAM module is implemented in the pam directory. Implementation is fairly +straight-forward. The PAM module stores some state between PAM calls in a +struct. The calls to nslcd are however stateless. The PAM module may supply +some information that help lookups (most notably DNs of user entries). + +Care must be taken with the communication because the nslcd requests are not +authenticated (e.g. changing passwords requests should include all +credentials). The PAM requests may result in state changes on the LDAP server +and this is where they are most notably different from the NSS requests. + +Some useful links: +http://www.kernel.org/pub/linux/libs/pam/ +http://www.opengroup.org/tech/rfc/rfc86.0.html + + +THE COMMUNICATIONS PROTOCOL +=========================== + +The protocol used for communicating between the NSS library and PAM module on +one end and the nslcd daemon on the other is very simple and almost fully +described in the nslcd.h header file. The common/nslcd-prot.h header file +defines some macros that are used for reading and writing protocol entities +(strings, 32-bit integers, etc). + +Every NSS database has a corresponding source file in the nss and the nslcd +directory. The PAM module is built up of a single file in both the pam and +nslcd directories. + +If the protocol is changed in an incompatible way the protocol version should +be incremented in nslcd.h. There is currently no versioning scheme available +for this. + +A special module (common/tio.c) was made so we can define simpler semantics +for time-out values and buffer sizes. All components use this module which +means that it includes functionality that is needed for both (e.g. large write +buffers for the server part and large resettable read buffers for the NSS +part). Maybe building two modules from the same source with different features +in them is an option (e.g. the NSS part needs the read buffers and handling of +SIGPIPE and the nslcd part needs the write buffers and possibly flushing in +the background). + +The common directory also contains some other generally useful modules that +are used in some components. + + +SERVER PART +=========== + +At the server end a dispatcher picks up the request and delegates it to one of +the database specific functions. + +nslcd_FUNCION(...) + This functions fills in the correct parameters from the request. This + function should write responses to the stream. + + +SECURITY NOTES +============== + +This design does open up the system to more potential security issues because +there is now a local interface to a daemon with privileges. Before (with +nss_ldap) processes could only potentially exploit bugs in the library and +gain the privileges of the process that was doing the name lookups. In this +case the privileges of the daemon are potentially exposed. + +Extra care should be taken with processes that normally require extra +privileges (getting shadow entries, authentication, updating session +information, etc). + +Any user on the system can perform nslcd queries so either the nslcd daemon +needs to check the userid of the caller or the request needs to contain the +needed credentials itself. + + +TEST SET-UP +=========== + +In the test directory there are a number of tests available. See the file +README in the test directory for more details. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..7d1c323 --- /dev/null +++ b/INSTALL @@ -0,0 +1,365 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + 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, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + 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 you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' 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. + + Running `configure' might take 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, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. 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. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +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 can use 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 `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer 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. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + 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'. + + 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. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + 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 machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +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. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5d63171 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,125 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2006 Luke Howard +# Copyright (C) 2006 West Consulting +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +SUBDIRS = compat common +if ENABLE_NSS + SUBDIRS += nss +endif +if ENABLE_PAM + SUBDIRS += pam +endif +if ENABLE_NSLCD + SUBDIRS += nslcd +endif +if ENABLE_PYNSLCD + SUBDIRS += pynslcd +endif +SUBDIRS += man tests + +DEBIAN_FILES = debian/changelog debian/compat debian/control \ + debian/copyright debian/rules debian/NEWS \ + debian/source/format debian/source/lintian-overrides \ + debian/nslcd.conffile \ + debian/nslcd.config \ + debian/nslcd.default \ + debian/nslcd.docs \ + debian/nslcd.examples \ + debian/nslcd.init \ + debian/nslcd.install \ + debian/nslcd.manpages \ + debian/nslcd.postinst \ + debian/nslcd.postrm \ + debian/nslcd.templates \ + debian/libnss-ldapd.config \ + debian/libnss-ldapd.install \ + debian/libnss-ldapd.lintian-overrides \ + debian/libnss-ldapd.postinst \ + debian/libnss-ldapd.postrm \ + debian/libnss-ldapd.templates \ + debian/libpam-ldapd.install \ + debian/libpam-ldapd.lintian-overrides \ + debian/libpam-ldapd.manpages \ + debian/libpam-ldapd.postinst \ + debian/libpam-ldapd.prerm \ + debian/libpam-ldapd.templates \ + debian/pam-configs/ldap \ + debian/po/POTFILES.in debian/po/templates.pot \ + $(wildcard debian/po/*.po) + +EXTRA_DIST = nslcd.conf nslcd.h $(wildcard ChangeLog-20??) \ + $(wildcard m4/*.m4) HACKING $(DEBIAN_FILES) + +DISTCHECK_CONFIGURE_FLAGS = --enable-warnings --with-pam-seclib-dir="\$${libdir}/security" \ + --enable-pynslcd + +ACLOCAL_AMFLAGS = -I m4 + +NSLCD_CONF_PATH = @NSLCD_CONF_PATH@ + +install-data-local: install-nslcd_conf +uninstall-local: uninstall-nslcd_conf + +# install a default configuration file if it is not already there +install-nslcd_conf: + @if [ -f $(DESTDIR)$(NSLCD_CONF_PATH) ]; then \ + echo "$(DESTDIR)$(NSLCD_CONF_PATH) already exists, install will not overwrite"; \ + else \ + $(mkinstalldirs) `dirname $(DESTDIR)$(NSLCD_CONF_PATH)`; \ + $(INSTALL_DATA) $(srcdir)/nslcd.conf $(DESTDIR)$(NSLCD_CONF_PATH); \ + fi +uninstall-nslcd_conf: + -rm -f $(DESTDIR)$(NSLCD_CONF_PATH) + +# fix permissions before distributing +dist-hook: + chmod -R a+rX $(distdir) + +# target for easily creating a Debian package +# the find is an ugly hack to fix a bug if being built on an nfs filesystem +deb: distdir + find $(distdir) -type d | xargs touch + cd $(distdir) && \ + debuild + rm -rf $(distdir) + +# target for generating the ChangeLog file +changelog: + svn2cl -i -r HEAD:1359 + +flawfinder.html: + flawfinder --quiet --html --context --followdotdir . > $@ + +rats.html: + rats --quiet --html --context . > $@ + +splint.txt: + -env LARCH_PATH=/usr/share/splint/lib/ \ + LCLIMPORTDIR=/usr/share/splint/imports/ \ + splint -checks -mustfreefresh \ + -warnposix +showsummary +showalluses +hints -namechecks \ + -globstate -predboolint -mustfreeonly -temptrans -kepttrans \ + -I. -I$(srcdir) -I$(top_builddir) $(DEFS) -D_REENTRANT -DDEBUG \ + -D__signed__=signed -D__thread= -D__gnuc_va_list=__ptr_t \ + -Dkrb5_int32=int32_t -Dkrb5_ui_4=uint32_t \ + -D__u16=uint16_t -D__u32=uint32_t \ + *.[ch] nss/*.[ch] nslcd/*.[ch] common/*.[ch] compat/*.[ch] > $@ 2>&1 + +.PHONY: flawfinder.html rats.html splint.txt diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e6fa736 --- /dev/null +++ b/NEWS @@ -0,0 +1,2415 @@ +changes from 0.8.3 to 0.8.4 +--------------------------- + +* switch to using the member attribute by default instead of + uniqueMember (backwards incompatible change) +* only return "x" as a password hash when the object has the shadowAccount + objectClass and nsswitch.conf is configured to do shadow lookups using + LDAP (this avoids some problems with pam_unix) +* fix problem with partial attribute name matches in DN (thanks Timothy + White) +* fix a problem with objectSid mappings with recent versions of OpenLDAP + (patch by Wesley Mason) +* set the socket timeout in a connection callback to avoid timeout + issues during the SSL handshake (patch by Stefan Völkel) +* check for unknown variables in pam_authz_search +* only check password expiration when authenticating, only check account + expiration when doing authorisation +* make buffer sizes consistent and grow all buffers holding string + representations of numbers to be able to hold 64-bit numbers +* update AX_PTHREAD from autoconf-archive +* support querying DNS SRV records from a different domain than the current + one (based on a patch by James M. Leddy) +* fix a problem with uninitialised memory while parsing the tls_ciphers + option +* implement bounds checking of numeric values read from LDAP (patch by + Jakub Hrozek) +* correctly support large uid and gid values from LDAP (patch by Jakub + Hrozek) +* improvements to the configure script (patch by Jakub Hrozek) +* Debian packaging improvements + + +changes from 0.8.2 to 0.8.3 +--------------------------- + +* support using the objectSid attribute to provide numeric user and group + ids, based on a patch by Wesley Mason +* check shadow account and password expiry properties (similarly to what + pam_unix does) in the PAM handling code +* implement attribute mapping functionality in pynslcd +* relax default for validnames option to allow user names of only two + characters +* make user and group name validation errors a little more informative +* small portability improvements +* general code improvements and refactoring in pynslcd +* some simplifications in the protocol between the PAM module and nslcd + (without actual protocol changes so far) +* Debian packaging improvements + + +changes from 0.8.1 to 0.8.2 +--------------------------- + +* fix problem with endless loop on incorrect password +* fix a communication problem between nslcd and the NSS and PAM modules when + running on Solaris 10 +* fix a compilation issue on systems without HOST_NAME_MAX +* link to the resolv library for hstrerror() on platforms that need it +* ignore password change requests for users not in LDAP +* many clean-ups to the tests and added some new tests including some + integration tests for the PAM functionality +* some smaller code clean-ups and improvements +* improvements to pynslcd, including implementations for service, protocol and + rpc lookups +* implement a validnames option that can be used to filter valid user and + group names using a regular expression +* improvements to the way nslcd shuts down with hanging worker threads + + +changes from 0.8.0 to 0.8.1 +--------------------------- + +* SECURITY FIX: the PAM module will allow authentication for users that do not + exist in LDAP, this allows login to local users with an + incorrect password (CVE-2011-0438) + the exploitability of the problem depends on the details of + the PAM stack and the use of the minimum_uid PAM option +* include a file that was missing for Solaris support +* add FreeBSD support, partially imported from the FreeBSD port (thanks to + Jacques Vidrine, Artem Kazakov and Alexander V. Chernikov) +* document how to replace name pam_check_service_attr and pam_check_host_attr + options in PADL's pam_ldap with with pam_authz_search in nss-pam-ldapd +* implement a fqdn variable that can be used in pam_authz_search filters +* create the directory to hold the socket and pidfile on startup +* implement host, network and netgroup support in pynslcd + + +changes from 0.7.13 to 0.8.0 +---------------------------- + +* include Solaris support developed by Ted C. Cheng of Symas Corporation +* include an experimental partial implementation of nslcd in Python (disabled + by default, see --enable-pynslcd configure option) +* implement a nss_min_uid option to filter user entries returned by LDAP +* implement a rootpwmodpw option that allows the root user to change a user's + password without a password prompt +* try to update the shadowLastChange attribute on password change +* all log messages now include a description of the request to more easily + track problems when not running in debug mode +* allow attribute mapping expressions for the userPassword attribute for + passwd, group and shadow entries and by default map it to the unmatchable + password ("*") to avoid accidentally leaking password information +* numerous compatibility improvements +* add --with-pam-seclib-dir and --with-pam-ldap-soname configure options to + allow more control of hot to install the PAM module +* add --with-nss-flavour and --with-nss-maps configure options to support + other C libraries and limit which NSS modules to install +* allow tilde (~) in user and group names +* improvements to the timeout mechanism (connections are now actively timed + out using the idle_timelimit option) +* set socket timeouts on the LDAP connection to disconnect regardless of LDAP + and possibly TLS handling of connection +* better disconnect/reconnect handling of error conditions +* some code improvements and cleanups and several smaller bug fixes +* all internal string comparisons are now also case sensitive (e.g. for + providing DN to username lookups, etc) +* signal handling in the daemon was changed to behave more reliable across + different threading implementations +* nslcd will now always return a positive authorisation result during + authentication to avoid confusing the PAM module when it is only used for + authorisation +* Debian packaging improvement: implement configuring SASL authentication + using Debconf, based on a patch by Daniel Dehennin + + +changes from 0.7.12 to 0.7.13 +----------------------------- + +* fix handling of idle_timelimit option +* fix error code for problem while doing password modification + + +changes from 0.7.11 to 0.7.12 +----------------------------- + +* set a short socket timeout when shutting down the connection to the LDAP + server to avoid disconnect problems when using TLS + + +changes from 0.7.10 to 0.7.11 +----------------------------- + +* grow the buffer for the PAM ruser to not reject logins for users with + a ruser including a domain part +* Debian packaging improvements + + +changes from 0.7.9 to 0.7.10 +---------------------------- + +* handle errors from ldap_result() better and disconnect (and reconnect) + in more cases + + +changes from 0.7.8 to 0.7.9 +--------------------------- + +* fix for --with-nss-ldap-soname configure option by Julien Cristau +* Debian packaging improvements + + +changes from 0.7.7 to 0.7.8 +--------------------------- + +* minor portability improvements and clean-ups (thanks Alexander V. + Chernikov and Ted C. Cheng) +* don't expand variables in rest of ${var:-rest} and ${var:+rest} + expressions if it is not needed +* Debian packaging improvements + + +changes from 0.7.6 to 0.7.7 +--------------------------- + +* refactoring and simplification of PAM module which also improves logging +* implement a nullok PAM option and disable empty passwords by default +* portability improvements and other minor code improvements +* the mechanism to disable name lookups through LDAP from within the nslcd + process has been improved +* the undocumented use_sasl option has been removed (specifying sasl_mech now + implies use_sasl) +* the sasl_mech, sasl_realm, sasl_authcid, sasl_authzid and sasl_secprops + configuration options are now documented +* Debian packaging improvements + + +changes from 0.7.5 to 0.7.6 +--------------------------- + +* fix a problem with empty attributes if expression-based attribute + mapping is used (patch by Nalin Dahyabhai) +* make debug logging for pam_authz_search option a little more informative +* documentation improvements +* Debian packaging improvements + + +changes from 0.7.4 to 0.7.5 +--------------------------- + +* fix a problem in the session handling of the PAM module if the minimum_uid + option was used +* refactor the PAM module code to be simpler and better maintainable +* perform logging from PAM module to syslog and support the debug option to + log more information + + +changes from 0.7.3 to 0.7.4 +--------------------------- + +* fix a buffer overflow that should have no security consequences +* perform proper fail-over when authenticating in the PAM module +* add an nss_initgroups_ignoreusers option to ignore user name to group + lookups for the specified users +* add an pam_authz_search option to perform a flexible authorisation check on + login (e.g. to restrict which users can login to which hosts, etc) +* implement a minimum_uid option for the PAM module to ignore users that have + a lower numeric user id +* change the way retries are done to error out quicker if the LDAP server is + down for some time (this should make the system more responsive when the + LDAP server is unavailable) and rename the reconnect_maxsleeptime option to + reconnect_retrytime to better describe the behaviour +* only log "connected to LDAP server" if the previous connection failed +* documentation improvements + + +changes from 0.7.2 to 0.7.3 +--------------------------- + +* allow password modification by root using the rootpwmoddn configuration file + option (the user will be prompted for the password for rootpwmoddn instead + of the user's password) +* the LDAP password modify EXOP is first tried without the old password and if + that fails retried with the old password +* when determining the domain name (used for some value of the base and uri + options) also try to use the hostname aliases to build the domain name + (patch by Jan Schampera) +* perform locking on the pidfile on start-up to ensure that only one nslcd + process is running and implement a --check option (patch by Jan Schampera) +* documentation improvements + + +changes from 0.7.1 to 0.7.2 +--------------------------- + +* some attributes may be mapped to a shell-like expression that expand + attributes from LDAP entries; this allows attributes overrides, defaults and + much more (as a result the passwd cn attribute mapping has been removed + because the gecos mapping is now "${gecos:-$cn}" by default) +* update the NSS module to follow the change in Glibc where the addr + parameter of getnetbyaddr_r() was changed from network-byte-order to + host-byte-order +* properly escape searches for uniqueMember attributes for DN with a comma in + an attribute value +* miscellaneous improvements to the configure script implementing better (and + simpler) library detection +* some general refactoring and other miscellaneous improvements + + +changes from 0.7.0 to 0.7.1 +--------------------------- + +* implement password changing by performing an LDAP password modify EXOP + request +* fix return of authorisation check in PAM module (patch by Howard Chu) +* fix for problem when authenticating to LDAP entries without a uid attribute + in the DN +* general code clean-up and portability improvements +* provide more information with communication error messages + + +changes from 0.6.11 to 0.7.0 +---------------------------- + +* rename software to nss-pam-ldapd to indicate that PAM module is now a + standard part of the software +* the PAM module is now built by default (the configure script can be + instructed whether or not to build certain parts) +* the default configuration file name has been changed to /etc/nslcd.conf +* the default values for bind_timelimit and reconnect_maxsleeptime were + lowered from 30 to 10 seconds +* password hashes are no longer returned to non-root users (based on a patch + by Alexander V. Chernikov) +* a pam_ldap(8) manual page was added +* unknown options in the configuration file can now be ignored with a new + --disable-configfile-checking configure option + + +changes from 0.6.10 to 0.6.11 +----------------------------- + +* fix user name to groups mapping (a bug in buffer checking in initgroups() + that was introduced in 0.6.9) +* fix a possible buffer overflow with too many uidNumber or gidNumber + attributes (thanks to David Binderman for finding this) +* lookups for group, netgroup, passwd, protocols, rpc, services and shadow + maps are now case-sensitive +* test suite is now minimally documented +* added --disable-sasl and --disable-kerberos configure options +* changed references to home page and contact email addresses to use + arthurdejong.org +* Debian packaging improvements + + +changes from 0.6.9 to 0.6.10 +---------------------------- + +* implement searching through multiple search bases, based on a patch by Leigh + Wedding +* fix a segmentation fault that could occur when using any of the tls_* + options with a string parameter +* miscellaneous improvements to the experimental PAM module +* implement PAM authentication function in the nslcd daemon +* the code for reading and writing protocol entries between the NSS module and + the daemon was improved +* documentation updates +* removed SSL/TLS related warnings during startup +* Debian packaging improvements + + +changes from 0.6.8 to 0.6.9 +--------------------------- + +* produce more detailed logging in debug mode and allow multiple -d options to + be specified to also include logging from the LDAP library +* some LDAP configuration options are now initialized globally instead of per + connection which should fix problems with the tls_reqcert option +* documentation improvements for the NSLCD protocol used between the NSS + module and the nslcd server +* imported the new PAM module from the OpenLDAP nssov tree by Howard Chu (note + that the PAM-related NSLCD protocol is not yet finalised and this module is + not built by default) +* in configure script allow disabling of building certain components +* fix a bug with writing alternate service names and add checks for + validity of passed buffer in NSS module +* Debian packaging improvements + + +changes from 0.6.7 to 0.6.8 +--------------------------- + +* SECURITY FIX: the nss-ldapd.conf file that is installed by the Debian + package was created world-readable which could cause problems + if the bindpw option is used (CVE-2009-1073) + this has been fixed in the Debian package but other users + should check the permissions of the nss-ldapd.conf file when + the bindpw option is used (warnings have been added to the + manual page and sample nss-ldapd.conf) +* clean the environment and set LDAPNOINIT to disable parsing of LDAP + configuration files (.ldaprc, /etc/ldap/ldap.conf, etc) +* remove sslpath option because it wasn't used +* correctly set SSL/TLS options when using StartTLS +* rename the tls_checkpeer option to tls_reqcert, deprecating the old name and + supporting all values that OpenLDAP supports +* allow backslashes in user and group names except as first or last character +* check user and group names against LOGIN_NAME_MAX if it is defined +* fix for getpeercred() on Solaris by David Bartley +* Debian packaging improvements + + +changes form 0.6.6 to 0.6.7 +--------------------------- + +* a fix for a problem in the Debian packaging that would cause user-configured + options be ignored + + +changes form 0.6.5 to 0.6.6 +--------------------------- + +* Debian packaging improvements +* allow spaces in user and group names because it was causing problems in + some environments +* if ldap_set_option() fails log the option name instead of number +* retry connecting to LDAP server in more cases + + +changes form 0.6.4 to 0.6.5 +--------------------------- + +* Debian package configuration translation updates + + +changes form 0.6.3 to 0.6.4 +--------------------------- + +* fix for the tls_checkpeer option +* fix incorrect test for ssl option in combination with ldaps:// URIs +* improvements to Active Directory sample configuration +* implement looking up search base in rootDSE of LDAP server + + +changes form 0.6.2 to 0.6.3 +--------------------------- + +* retry connection and search if getting results failed with connection + problems (some errors only occur when getting the results, not when starting + the search) +* add support for groups with up to around 150000 members (assuming user names + on average are a little under 10 characters) +* problem with possible SIGPIPE race condition was fixed by using send() + instead of write() +* add uid and gid configuration keywords that set the user and group of the + nslcd daemon +* add some documentation on supported group to member mappings +* add sanity checking to code for when clock moves backward +* log messages now include a session id that makes it easier to track errors + to requests (especially useful in debugging mode) +* miscellaneous portability improvements +* increase buffers and time-outs to handle large lookups more gracefully +* implement SASL authentication based on a patch by Dan White +* allow more characters in user and group names + + +changes form 0.6.1 to 0.6.2 +--------------------------- + +* all user and group names are now checked for validity are specified in the + POSIX Portable Filename Character Set +* support retrieval of ranged attribute values as sometimes returned by Active + Directory +* added the threads keyword to configure the number of threads that should be + started in nslcd +* handle empty netgroups properly +* change the time-out and retry mechanism for connecting to the LDAP server to + return an error quickly if the LDAP server is known to be unavailable for a + long time (this removed the reconnect_tries option and changes the meaning + of the reconnect_sleeptime and reconnect_maxsleeptime options) +* increased the time-out values between the NSS module and nslcd because of + new retry mechanism +* implement new dict and set modules that use a hashtable to map keys + efficiently +* use the new set to store group membership to simplify memory management and + eliminate duplicate members +* the uniqueMember attribute now only supports DN values +* implement a cache for DN to user name lookups (15 minute timeout) used for + the uniqueMember attribute to save on doing LDAP searches for groups with a + lot of members, based on a patch by Petter Reinholdtsen +* improvements to the tests +* if any of the ldap calls return LDAP_UNAVAILABLE or LDAP_SERVER_DOWN the + connection is closed +* improve dependencies in LSB init script header to improve dependency based + booting + + +changes from 0.6 to 0.6.1 +------------------------- + +* numerous small fixes and compatibility improvements +* the I/O buffers between nslcd and NSS module are now dynamically sized and + tuned for common requests +* correctly follow referrals +* add StartTLS support by Ralf Haferkamp of SuSE +* miscellaneous documentation improvements +* remove code for handling rootbinddn/pw because it is unlikely to be + supported any time soon +* fix a problem with realloc()ed memory that was not referenced +* fix for a crash in group membership buffer growing code thanks to Petter + Reinholdtsen +* some improvements to the Active Directory sample configuration +* fix init script exit code with stop while not running +* fixes to the _nss_ldap_initgroups_dyn() function to properly handle the + buffer and limits passed by Glibc +* fixes to the member to groups search functions to correctly handle + uniqueMember attributes +* only return shadow entries to root users +* miscellaneous Debian packaging improvements + + +changes from 0.5 to 0.6 +----------------------- + +* fix parsing of map option in nss-ldapd.conf +* fix bug in handling of userPassword values +* remove warning about missing loginShell attribute +* support the uniqueMember LDAP attribute that holds DN values +* support ldap as a compat service in /etc/nsswitch.conf +* implement _nss_ldap_initgroups_dyn() to allow username->groups searches +* fix retry mechanism with get*ent() functions where a too small buffer was + passed by libc (to support groups with a lot of members) +* fix a bug in reporting of communications problems between nslcd and the NSS + library +* test and log failures of all LDAP library calls +* improved tests +* miscellaneous compatibility improvements to try to support more LDAP + libraries and platforms +* support compilation with OpenLDAP 2.4 and newer +* some configure script improvements +* Debian packaging improvements + + +changes from 0.4.1 to 0.5 +------------------------- + +* major structural changes in the LDAP lookup code using a newly implemented + module that does memory management, session handling, paging and all other + painful things with a simple interface +* rewritten LDAP query and result handling code, now generating warnings + about incorrect entries in the LDAP directory +* IPv6 addresses in host lookups are now supported +* added Kerberos ccname support (with the krb5_ccname option) thanks to + Andreas Schneider and Ralf Haferkamp from SuSE and remove --with-gssapi-dir, + --enable-configurable-krb5-ccname-gssapi and + --enable-configurable-krb5-ccname-env configure options and having automatic + detection instead +* added support for DNS SRV record lookups by specifying DNS as uri thanks to + Ralf Haferkamp and Michael Calmer from SuSE +* added support for DOMAIN as base DN which uses the host's domain to + construct a DN +* removed nss_connect_policy, bind_policy and sizelimit options +* cleaned up and documented reconnect logic with reconnect_tries, + reconnect_sleeptime and reconnect_maxsleeptime options +* configuration values with spaces in them (e.g. distinguished names) are now + handled properly +* fix a small memory leak in the I/O module +* miscellaneous code improvements (better source code comments, more + consistent logging, portability improvements, more tests, etc) +* improvements to documentation + + +changes from 0.4 to 0.4.1 +------------------------- + +* added French debconf translation by Cyril Brulebois +* added Japanese debconf translation by Kenshi Muto +* fix a problem with network name lookups where the lookup would result + in the wrong call to nslcd +* fix wrong default filter for rpc lookups +* fix a number of memory leaks (thanks valgrind) + (all memory leaks during normal operation should be fixed now) + + +changes from 0.3 to 0.4 +----------------------- + +* remove nss_schema configfile option +* temporary remove support for uniqueMember group membership attributes (will + be re-added in a later release) +* removed support for nested groups, if this is really needed (please ask or + file a bug if you want it) it can be re-added later on +* added missing docbook sources for manual pages to tarball +* major cleanups and simplifications in the core LDAP query code (we don't + need to worry about SIGPIPE because nslcd does that globally, locking + because a connection is only used by one thread) and more simplifications in + the the LDAP connection and query state +* get base, scope, filter and map configfile directives properly working +* simplifications in LDAP reconnect logic (some work remains to be done in + this area) +* issue warnings or errors for untested or unsupported configuration options +* properly handle multiple URIs in Debian configuration +* documentation improvements + + +changes from 0.2.1 to 0.3 +------------------------- + +* a bug in the communication buffer handling code was fixed +* a bug in the dictionary code was fixed (code not yet in use) +* a fix for the init script that used a wrong pidfile +* configuration file handling code was rewritten to be better maintainable +* some configuration file options have changed which means that compatibility + with the nss_ldap configuration file is lost +* configuration syntax is now documented in the nss-ldapd.conf(5) manual page +* support for dnsconfig was removed +* the configuration file no longer supports using multiple search bases +* removed nss_initgroups and nss_initgroups_ignoreusers options +* removed --enable-paged-results configure option and use pagesize + configuration file option to specify usage of paging at runtime +* added Portuguese debconf translation by Américo Monteiro +* Debian package configuration improvements and simplifications +* use docbook2x-man for generating manual pages +* miscellaneous documentation improvements including improved manual pages +* general code reorganisation and clean-ups to achieve another 9% code + reduction relative to 0.2.1 release (more than 40% relative to nss_ldap) +* SASL, Kerberos and SSL/TLS support remain untested + + +changes from 0.2 to 0.2.1 +------------------------- + +* fix permissions of server socket (this fixes a problem where non-root users + were unable to do lookups) +* fix configure script to properly check for pthread support +* small code improvements +* general build system cleanups + + +changes from 0.1 to 0.2 +----------------------- + +* fixes to the netgroup lookup code +* more simplifications and improvements in the code almost 5% code reduction + (compared to release 0.1) and 37% reduction in gcc warnings (from 443 in 251 + to 389 in 0.1 and 244 in 0.2) +* a lot of code improvements thanks to flawfinder, more gcc warnings, splint + and rats +* license change from GNU Library General Public License to GNU Lesser General + Public License (with the permission of Luke Howard) +* fix logging code to be cleaner and always use our own logging module +* a start has been made to make the code more testable and initial work to set + up a testing framework has been done +* implemented a timeout mechanism in the communication between the NSS part + and the nslcd server part + + +changes from nss_ldap 251 to nss-ldapd 0.1 +------------------------------------------ + +* initial release of nss-ldapd (should be functional but not yet stable enough + for production use) +* fork from the nss_ldap which was originally written by Luke Howard of PADL + Software Pty Ltd. changing package name to nss-ldapd and versioning scheme +* the functionality was split into a thin NSS library and a simple daemon + proxying the requests to the LDAP server (see README for rationale) +* a lot of dead and old compatibility code was removed (about 25% of the code + was removed) (more simplifications to come) +* the test code was rewritten +* build script simplifications +* default configuration file has been changed to /etc/nss-ldapd.conf +* most documentation has been updated and rewritten +* dropped support for non-glibc NSS interfaces and assumed OpenLDAP compatible + library + + +changes from 250 to 251 +----------------------- + +* remove doc/rfc2307.txt, it is available from + http://www.ietf.org/rfc/rfc2307.txt +* make objectClass a mappable attribute + + +changes from 249 to 250 +----------------------- + +* don't use static _nss_ldap_no_members buffer, causes crash when nss_ldap is + unloaded and memory is still referenced +* fix for BUG#249: tcsh closes file descriptors, confuses nss_ldap and hangs + (from David Houlder) +* fix for BUG#257: initgroups() broken in RFC2307bis support disabled +* fix for BUG#261: sslpath example wrong +* fix for BUG#263: compile do_triple_permutations() when IRS enabled + + +changes from 248 to 249 +----------------------- + +* fix for BUG#253: build broken on AIX +* fix for BUG#255: deadlock in initgroups + + +changes from 247 to 248 +----------------------- + +* fix regression in per-objectclass attribute mapping introduced in + nss_ldap-246 + + +changes from 246 to 247 +----------------------- + +* double-check *ld != NULL even if mapped eror return from ldap_initialize() + returns NSS_SUCCESS + + +changes from 245 to 246 +----------------------- + +* paged results and RFC2307bis support are now always compiled in; they are by + default disabled unless you configured with --enable-paged-results and + --enable-rfc2307bis, respectively. See nss_ldap(5) for configuration + options. +* fix for BUG#219: paged results delivers wrong results +* fix for BUG#222: use asynchronous start TLS if available, using bind_timeout + value +* fix for BUG#235: make DNS SRV lookup domain configurable (nss_srv_domain) +* fix for BUG#240: return "*" rather than "x" for userPassword if not present +* fix for BUG#245: paged results broken since nss_ldap-241 +* patch from Ralf Haferkamp : compile fix for IPv6 +* compile for Solaris +* schema mapping is always enabled, cleanup schema mapping code +* allow for map-specific objectclass mapping +* partial implementation of Solaris Simplified LDAP API, allows automountd + support on Solaris via nss_ldap +* for Linux automounter, always close connection after endautomntent() to + avoid persistent connection +* add nss_connect_policy argument to ldap.conf + + +changes from 244 to 245 +----------------------- + +* don't leak LDAP connection if do_bind() failed or descriptor owner had + changed. If do_bind() failed the underlying descriptor would also be leaked, + causing a large number of sockets to be consumed during failover +* add nss_initgroups_ignoreusers parameter to ldap.conf, returns NOTFOUND if + nss_ldap's initgroups() is called for users (comma separated) +* try to deal with systems that have headers for both versions of the SASL + library installed +* better logging of failed connections and reconnections +* patch from Dean Michaels : build with Netscape 5 + library on Solaris +* patch from Ralf Haferkamp : manual page fix to bind_policy + + +changes from 243 to 244 +----------------------- + +* patch from Ralf Haferkamp : enusre bytesleft macro does not + return values < 0 +* include in ldap-nss.c + + +changes from 242 to 243 +----------------------- + +* fix for BUG#225: invalid pointer dereferencing when reading rootpw + + +changes from 241 to 242 +----------------------- + +* fixes for compiling on Solaris 10 + + +changes from 240 to 241 +----------------------- + +* new, more robust reconnection logic +* both "host" and "uri" directives can be used in ldap.conf +* new (undocumented) nss_reconnect_tries, nss_reconnect_sleeptime, + nss_reconnect_maxsleeptime, nss_reconnect_maxconntries directives +* reload configuration file if changed + + +changes from 239 to 240 +----------------------- + +* new API for resolving automounts (requires custom autofs plugin for Linux at + present): _nss_ldap_setautomntent(), _nss_ldap_getautomntent(), + _nss_ldap_endautomntent(), _nss_ldap_getautomntbyname_r() +* fix for BUG#200: rename SOCKLEN_T as it conflicts on AIX +* fix for BUG#205: accept line feeds in ldap.conf +* fix for BUG#211: nss_ldap fails to start TLS on referred connections +* fix for BUG#213: initgroups crash if RFC2307bis undefined +* turn down reconnection logging volume + + +changes from 238 to 239 +----------------------- + +* support for initgroups using backlinks (selectable at runtime if RFC2307bis + support is enabled, using the nss_initgroups backlink configuration + directive) +* support for dynamically expanding filter sizes +* from Peter Marschall : revert the deletion of blanks/tabs in + ldap.conf that happened between 235 and 238 +* from Peter Marschall : This patch changes configure.in and + Makefile.am so that ldap.conf gets installed in the place and with the name + that is given to the configure option --with-ldap-conf-file. In addition to + that it fixes a long standing bug in Makefile.am that tries to install a + file before the destination directory is guaranteed to be created (hunk #3), + and uses $(mkinstalldirs) for AIX (hunk #2). + + +changes from 237 to 238 +----------------------- + +* more manual page updates + + +changes from 236 to 237 +----------------------- + +* more manual page updates + + +changes from 235 to 236 +----------------------- + +* fix for BUG#201: typo in ldap-schema.c causing build to fail +* add manual page for nss_ldap + + +changes from 234 to 235 +----------------------- + +* fix for BUG#198: make pagesize configurable +* fix for BUG#199: correct fix for BUG#138 (blind last char remove in + ldap.secret) + + +changes from 233 to 234 +----------------------- + +* don't reacquire global lock in do_next_page() +* restore old "bind_policy hard" behaviour (don't try to reconnect if + initialization failed). The behaviour introduced in nss_ldap-227 can be + enabled with "bind_policy hard_init". + + +changes from 232 to 233 +----------------------- + +* if do_open() returns NSS_UNAVAIL, don't try to do server reconnect; only do + it if NSS_TRYAGAIN is returned This should fix the problems introduced by + the fixes in nss_ldap-227 (delayed binding) + + +changes from 231 to 232 +----------------------- + +* fix for BUG#138 (blind last char remove in ldap.secret) + + +changes from 229 to 230 +----------------------- + +* don't free gss_krb5_ccache_name() output (Heimdal) + + +changes from 228 to 229 +----------------------- + +* more debugging in initgroups and _nss_ldap_getentry() +* fix _nss_ldap_getentry() enumeration behaviour, and optimize by not + searching if the requested attribute cannot be mapped + + +changes from 227 to 228 +----------------------- + +* fix for BUG#188: better documentation for OpenLDAP SSL options +* fix for BUG#189: do not configure tls_checkpeer unless it is explicitly + specifier in ldap.conf +* fix for BUG#190: set ls_state to LS_UNINITIALIZED after fork + + +changes from 226 to 227 +----------------------- + +* separate initializing LDAP session with actually connecting to the DSA, so + that we don't try to bind until we actually need to search (which allows the + retry logic in the search function to also apply to binding). NB: this will + only provide improved behavior for LDAP client libraries that support + ldap_init() or ldap_initialize() rather than ldap_open +* fix for BUG#183: support pw_change and pw_expire on BSD +* fix for BUG#187: NSS_BUFLEN_DEFAULT causing problems on IRS platforms +* fix for glibc 2.1 from Alexander Spannagel + + +changes from 225 to 226 +----------------------- + +* make LDAP_NSS_NGROUPS configurable with --with-ngroups (experts only) option + + +changes from 224 to 225 +----------------------- + +* make LDAP_NSS_NGROUPS 64 - better choice for small directories + + +changes from 223 to 224 +----------------------- + +* don't double-free on realloc() failure in do_parse_group_members() +* don't pass LDAP session as an argument, as it may refer to a stale LDAP + handle. If this does not work we will need to replace LDAPMessage pointers + with pointers to a structure that contains a reference-counted LDAP handle + as well as the message +* fix crasher when internal group membership buffer was reallocated + (introduced with nested group expansion code) +* immediately return NSS_TRYAGAIN and errno=ERANGE if there is not enough + buffer space to handle LDAP_NSS_NGROUPS groups; this prevents getgrXXX() + from expensive repeated directory searches when there is a priori knowledge + that group memberships are large + + +changes from 222 to 223 +----------------------- + +* allow empty lines in /etc/ldap.conf +* do loop detection in nested groups +* fixes for building with IRS on FreeBSD 4.10 + + +changes from 221 to 222 +----------------------- + +* fix deadlock in _nss_ldap_getentry() +* support more AIX usersec attributes +* more AIX porting fixes +* support Heimdal as well as MIT Kerberos + + +changes from 220 to 221 +----------------------- + +* AIX fix from Recall #169033 +* support for expansion of nested RFC2307bis groups +* support for searching using range retrieval +* fix memory leak with private contexts +* fix memory leak in do_result() +* implement _nss_ldap_getentry for AIX enumeration +* implement netgroups for IRS/AIX +* remove dependency on Berkeley DB - schema mapping and RFC2307bis no longer + requires DB +* remove old NeXT cruft in resolve.c + + +changes from 218 to 220 +----------------------- + +* fix for BUG#169: getntohost() on Solaris +* fix for BUG#170: _nss_ldap_getgroupsbymember_r fails to return all groups + when NSCD is running and attribute mapping is enabled on Solaris +* fix for BUG#173: reinstate use of sigaction() (XXX what is the correct fix + here?) +* fix for BUG#174: innetgr() depth checking + + +changes from 217 to 218 +----------------------- + +* fix for BUG#168: set errnop to ENOENT if not found +* check for -lgssapi before -lgssapi_krb5 + + +changes from 216 to 217 +----------------------- + +* fix for BUG#167: compilation fails on Solaris + + +changes from 215 to 216 +----------------------- + +* patch from Thorsten Kukuk to avoid overwriting sockaddr storage for IPv6; + use struct sockaddr_storage if available +* fix for BUG#153: use asynchronous search API in initgroups() +* fix for BUG#157: check for __pthread_once rather than __pthread_atfork on + glibc, as the latter is no longer exported +* fix for BUG#158: escape netgroup search filters correctly +* fix for BUG#161: remove redundant lock in _nss_ldap_innetgr() +* fix for BUG#164: set schema element array size to LM_NONE + 1 not LM_NONE +* fix for BUG#165: make _nss_ldap_result() private +* fix for BUG#166: chase all nested netgroups in innetgr() +* fix deadlock if getXXXent() called without first calling setXXXent() +* only request gidNumber attribute when initgroups() (avoids sending back rest + of a group's entry) +* don't request any attributes when mapping a user to a DN (we want the DN + only) + + +changes from 214 to 215 +----------------------- + +* choose between using native GSS-API and putenv() for setting ccache path +* per-map attribute mapping for attributes that appear in multiple maps + + +changes from 213 to 214 +----------------------- + +* define LDAP_DEPRECATED for compiling against OpenLDAP 2.2 + + +changes from 212 to 213 +----------------------- + +* fix netgroup compilation error when debugging is enabled +* support GSS-API for setting ccache name +* initgroups() should require user to be a POSIX account +* define LOGNAME_MAX for HP-UX +* do not use sigprocmask() - this blocks rather than disabling signals +* SASL version check fix from Howard Chu + + +changes from 211 to 212 +----------------------- + +* Solaris netgroup support test release +* fix crasher in do_sasl_interact() +* do_sasl_interact() needs to strdup() result for Cyrus SASL 1.x but not 2.x +* merge in LDAP debug patch from Howard Chu +* try alternate search descriptors on NSS_NOTFOUND as well as NSS_SUCCESS + + +changes from 210 to 211 +----------------------- + +* do AT_OC_MAP cache initialization at config init +* BSD build fixes +* replace [h]errno2nssstat lookup tables with switch statement; should help + building on AIX! + + +changes from 209 to 210 +----------------------- + +* initialize DBT structures +* fix SASL crasher + + +changes from 208 to 209 +----------------------- + +* fix SASL breakage + + +changes from 207 to 208 +----------------------- + +* use socklen_t not int +* remove OpenLDAP SASL code +* incorporated patches from (see below) Geert Jansen +* add the "sasl_secprops" option to configure SASL security layers (usage as + for OpenLDAP ldap.conf) +* add the "krb5_ccname" option to specify the location of the Kerberos ticket + cache (requires --enable-configurable-krb5-ccname for now as it is a fairly + coarse solution to a lack of appropriate API in the Kerberos libraries) +* add support for native Active Directory password policy attributes (enabled + if shadowLastChange is mapped to pwdLastSet) +* add "nss_override_attribute_value" and "nss_default_attribute_value" + keywords for over- riding and setting default attribute values, respectively + + +changes from 205 to 207 +----------------------- + +* work without LDAP_OPT_X_TLS_RANDOM_FILE +* fix schema mapping regression from nss_ldap-205; attribute mapping now works + again + + +changes from 204 to 205 +----------------------- + +* build with Sleepycat DB without db185 compat layer (tested with 4.x; needs + testing on 3.x) + + +changes from 203 to 204 +----------------------- + +* Linux netgroup implementation from Larry Lile +* Multiple service search descriptor support from Symas +* IPv6 patch from Thorsten Kukuk at SuSE + + +changes from 202 to 203 +----------------------- + +* fix for BUG#115 +* fix for BUG#121 + + +changes from 201 to 202 +----------------------- + +* getsockname() fixes from Howard Chu +* configuration parser crasher fix + + +changes from 200 to 201 +----------------------- + +* Berkeley DB fixes from Howard Chu +* Netscape client library build fix + + +changes from 199 to 200 +----------------------- + +* use sigprocmask() if available to block SIGPIPE +* fix build breakage with OpenLDAP HEAD + + +changes from 198 to 199 +----------------------- + +* HP-UX port +* BUG#111: incorrect debugging statement in _nss_ldap_enter() +* export required symbols only on Linux +* corrected symbol names for glibc alias enumeration functions +* the DNS response parser doesn't stop after parsing the right number of + records, and doesn't handle long responses (Nalin at RedHat) + + +changes from 197 to 198 +----------------------- + +* BUG#108: fix potential buffer overflow in dnsconfig.c (could be triggered if + no flat file configuration for nss_ldap and large DNS SRV data for domain; + because nss_ldap in SRV mode trusts DNS we do not believe this to be + exploitable to elevate privilege in the default configuration) +* do not malloc() configuration structure; use buffer + + +changes from 196 to 197 +----------------------- + +* improved AIX documentation from Dejan Muhamedagic +* define LDAP_OPT_SSL for Solaris 9 + + +changes from 195 to 196 +----------------------- + +* return NSS_TRYAGAIN not NSS_NOTFOUND for insufficient buffer space in + dn2uid_cache_get() +* support automake 1.5 and friends +* out of box build on AIX 4.3.3 +* fixed BUG#104: do_ssl_options() return code ignored + + +changes from 194 to 195 +----------------------- + +* fixed BUG#98: large groups cause buffer length wraparound with rfc2307bis + + +changes from 193 to 194 +----------------------- + +* bugfix for Debian Bug report #147553: lack of global mutex use in + initgroups() + + +changes from 192 to 193 +----------------------- + +* support for PADL GSS-SASL client library + + +changes from 191 to 192 +----------------------- + +* more carefully compare cached socket and peer addresses + + +changes from 190 to 191 +----------------------- + +* added configurable [hard|soft] reconnect, see the bind_policy parameter in + ldap.conf. + + +changes from 189 to 190 +----------------------- + +* check for Netscape 4 SDK without SSL; don't require pthreads for these + + +changes from 188 to 189 +----------------------- + +* patch for building on OpenLDAP 1.x from Nalin at RedHat + + +changes from 187 to 188 +----------------------- + +* specify runtime path for LDAP library correctly to native Solaris linker +* check for gcc correctly +* use native linker on Solaris and AIX + + +changes from 186 to 187 +----------------------- + +* make bogusSd in ldap-nss.c conditional on !HAVE_LDAP_LD_FREE +* merge in paged result support from Max Caines +* bugfixes for Debian Bug report #140854 + + +changes from 185 to 186 +----------------------- + +* incorporated patch for Debian Bug report #140854, where nss_ldap could in + some cases close a descriptor it did not own. Patch was provided by Luca + Filipozzi. + + +changes from 184 to 185 +----------------------- + +* updated copyrights +* fix for BUG#82: set close on exec (Debian bug 136953) + + +changes from 183 to 184 +----------------------- + +* return NSS_TRYAGAIN if no buffer space in ldap-grp.c + + +changes from 181 to 183 +----------------------- + +* return error strings in AIX authentication routine +* initialize schema in getgroupsbymember() +* fix for tls_checkpeer; pass NULL session in to set global option +* BUG#77: configurable config file locations + + +changes from 181 to 181 +----------------------- + +* ignore SIGPIPE whilst inside nss_ldap library routines to prevent crashing + on down LDAP server; possible fix for Debian bug 130006 +* removed --enable-no-so-keepalive; always try to disable SO_KEEPALIVE on + underlying socket to LDAP server +* include local copy of irs.h under AIX +* general cleanup of locking code +* _nss_ldap_no_members appears to only need defining for when RFC2307bis is + enabled + + +changes from 179 to 180 +----------------------- + +* pull in libpthreads on AIX + + +changes from 178 to 179 +----------------------- + +* a couple more patches for AIX + + +changes from 177 to 178 +----------------------- + +* patch from Gabor Gombas for AIX support +* Makefile.am: sasl.o needed by NSS_LDAP +* aix_authmeth.c: method_passwordexpired is really method_passwdexpired; but + since the struct was bzero()ed no need to set it to NULL +* configure.in: support both gcc and xlc_r +* exports.aix: sv_byport was not exported +* ldap-grp.c: getgrset() returned group names instead of gid numbers + + +changes from 176 to 177 +----------------------- + +* patch for building on AIX from IBM +* added simple authentication support for AIX +* cleaned up SASL patch to not break if Cyrus SASL is not installed + + +changes from 175 to 176 +----------------------- + +* fixed bug in SASL patch which had required OpenLDAP headers + + +changes from 174 to 175 +----------------------- + +* incorporated GSS-API SASL patches +* rebind to server on LDAP_LOCAL_ERROR + + +changes from 173 to 174 +----------------------- + +* added patches from Maxim Batourine for compiling with Sun workshop compiler +* added notes re: 64-bit compile on Solaris from above source + + +changes from 172 to 173 +----------------------- + +* notes on IRS in doc/README.IRS +* added irs.h for AIX compat +* patch from Bob Guo for stripping trailing spaces in ldap.conf. + + +changes from 171 to 172 +----------------------- + +* fixed schema mapping bug by storing a copy of the mapped schema in the + Berkeley DB rather than the element itself. Because the DB library returns + static storage, this was causing problems where the schema mapping calls + were used to build the attribute table in ldap-schema.c. This bugfix was + sponsored by n2h2.com; thanks! + + +changes from 170 to 171 +----------------------- + +* added ldap.conf stanza for AIX +* workaround for schema mapping bug. + + +changes from 169 to 170 +----------------------- + +* use _nss_ldap_getrdnvalue() for determining canonical group name + + +changes from 168 to 169 +----------------------- + +* fixed typo in ldap-service.c; prefix filters now with _nss_ldap + + +changes from 167 to 168 +----------------------- + +* initialize old_handler to SIG_DFL +* incorporate Stephan Cremer's mapping patches, a big thanks to Stephan for + these! +* use LDAP_OPT_NETWORK_TIMEOUT if available for network connect timeout +* removed hard-coded schema mapping for authPassword, NDS and MSSFU + + +changes from 166 to 167 +----------------------- + +* support for new OpenLDAP rebind proc prototype +* in rebind function, respect timeout +* fix for PADL Release Control + + +changes from 165 to 166 +----------------------- + +* corrected small typos + + +changes from 164 to 165 +----------------------- + +* posixMember is a distinguished name, don't pretend it is a login name +* cleaned up code referencing different member syntaxes + + +changes from 163 to 164 +----------------------- + +* removed IDS_UID code, never worked properly + + +changes from 162 to 163 +----------------------- + +* removed context_free function, usage confusing + + +changes from 161 to 162 +----------------------- + +* in reconnect harness, do not treat entry not found errors as requiring a + reconnect + + +changes from 160 to 161 +----------------------- + +* hopefully fixed use of synchronous searches in _nss_ldap_getbyname() + + +changes from 159 to 160 +----------------------- + +* patch from RedHat to check for DB3, override install user/group optionally +* use synchronous searches for _nss_ldap_getbyname() +* only set SSL options if we have values for those options + + +changes from 158 to 159 +----------------------- + +* make do_ssl_options() take a config parameter; avoid segfault with SSL? + + +changes from 157 to 158 +----------------------- + +* in the distinguished name to login cache (dn2uid) make sure we use the + AT(uid) macro for the uid attribute rather than the hard-coded value of + "uid" This should enable the cache for MSSFU support. + + +changes from 156 to 157 +----------------------- + +* for MSSFU, use posixMember for group memberships rather than member + (reported by Andy Rechenberg) +* ignore SIGPIPE before calling do_close() for idle_timeout + + +changes from 155 to 156 +----------------------- + +* logic was around the wrong way in do_search(), all searches were broken! +* --disable-ssl option for configure +* removed "Obsoletes: pam_ldap" from spec file + + +changes from 154 to 155 +----------------------- + +* do not use private API when setting OpenLDAP TLS options (do_ssl_options()) + + +changes from 153 to 154 +----------------------- + +* notes from Scott M. Stone +* idle timeout patch from Steve Barrus + + +changes from 152 to 153 +----------------------- + +* SSL fix + + +changes from 151 to 152 +----------------------- + +* further patch from Jarkko for TLS/SSL auth: support for LDAPS/cipher suite + selection/ client key/cert authentication + + +changes from 150 to 151 +----------------------- + +* patch from Andrew Rechenberg for Active Directory schema support +* patch from Jarkko Turkulainen for peer certificate support + with OpenLDAP + + +changes from 149 to 150 +----------------------- + +* patch from Anselm Kruis for URI support + + +changes from 148 to 149 +----------------------- + +* fixed compile on Solaris, broken in 145 by malformed Linux patch + + +changes from 147 to 148 +----------------------- + +* check for HAVE_LDAP_SET_OPTION always + + +changes from 146 to 147 +----------------------- + +* check for ldap_set_option(), as LDAP_OPT_REFERRALS is defined for OpenLDAP + 1.x but without the ldap_set_option() function + + +changes from 145 to 146 +----------------------- + +* mass re-indentation, GNU style +* patch from Simon Wilkinson for compatibility with old + initgroups entry point +* request authPassword attribute if --enable-authpassword +* authPassword support in ldap-spwd.c (shadow) + + +changes from 144 to 145 +----------------------- + +* preliminary support for authPassword attribute +* updated COPYING +* patch from Szymon Juraszczyk to suppot _nss_ldap_initgroups_dyn prototype + + +changes from 143 to 144 +----------------------- + +* when specifying filters with nss_base_XXX, only escape the filter argument + not the entire filter + + +changes from 142 to 143 +----------------------- + +* patch from nalin@redhat.com to avoid corrupting the heap when the + configuration file exists but has no host and base values. + _nss_ldap_readconfigfromdns() will write to the region which was already + freed. + + +changes from 141 to 142 +----------------------- + +* patch from Simon Wilkinson for memory leak in + ldap-service.c + + +changes from 140 to 141 +----------------------- + +* fix for BUG#54 (AIX detection broken) +* use -rpath on all platforms except Solaris, + not just Linux + + +changes from 139 to 140 +----------------------- + +* fix configure bug for DISABLE_SO_KEEPALIVE +* fix alignment bug in util.c; this was causing Solaris to crash whenever + per-map search descriptors were specified in ldap.conf + + +changes from 138 to 139 +----------------------- + +* updated INSTALL file with boilerplate +* fixed pointer error in ldap-nss.c + + +changes from 137.1 to 138 +------------------------- + +* close config file FILE * if out of buffer space for parsing search + descriptor +* fixed bug where non-recognized directives in ldap.conf would cause the + configuration file to not be parsed at all, if they were the last entries in + the config file. + + +changes from 137 to 137.1 +------------------------- + +* patch from nalin@redhat.com; return { NULL } not NULL for no group members +* cleaned up usage of libc-lock.h weak aliases to pthreads API; use in ltf.c + also +* use __libc_atfork() or pthread_atfork() to close off connection on fork, + rather than checking PIDs; this is expensive and breaks on Linux where each + thread may have a different PID. + + +changes from 136 to 137 +----------------------- + +* build nss_ldap as a loadable module on AIX +* doco on AIX + + +changes from 135 to 136 +----------------------- + +* define -DPIC for FreeBSD +* link with -shared not --shared +* fixes for AIX + + +changes from 134 to 135 +----------------------- + +* merged ldap.conf +* fixed bug in concatenating relative search bases in ldap-nss.c (profile + support) + + +changes from 133 to 134 +----------------------- + +* fixed Makefile.am +* reordered DB search order in util.c + + +changes from 132 to 133 +----------------------- + +* make /usr/lib directory in Makefile.am +* new spec file from Joe Little + + +changes from 131 to 132 +----------------------- + +* fixed rebind preprocessor logic + + +changes from 130 to 131 +----------------------- + +* created files for automake happiness + + +changes from 129 to 130 +----------------------- + +* fixed typo preventing build with Netscape client library + + +changes from 128 to 129 +----------------------- + +* updated version number +* fixed build bug on Solaris + + +changes from 127 to 128 +----------------------- + +* fixed logic bug in util.c introduced in nss_ldap-127 + + +changes from 126 to 127 +----------------------- + +* updating copyright notices +* autoconf support; IRIX and OSF/1 support has been dropped (dl-*.[ch]) as no + one really used this, the implementation was a hack, and these operating + systems have their own LDAP implementations now +* added support for "referrals" and "restart" options to ldap.conf +* use OpenLDAP 2.x rebind proc with correct arguments +* added "timelimit" and "bind_timelimit" directives to ldap.conf +* fixed bug with dereferencing aliases +* preliminary support for profiles; recognise profile semantics in + ldap-nss.c/util.c +* parity with pam_ldap; "ssl" directive in ldap.conf can now specify "yes" or + "start_tls" for Start TLS +* hopefully fixed Berkeley DB include mess in util.c +* fixed potential buffer overflow in util.c +* default to LDAP protocol version 3 +* fixed leaks in util.c, dnsconfig.c +* accept on/yes/true for boolean configuration values +* tested building on FreeBSD, Solaris 8, Linux +* tested functionality on RedHat 6.2 + + +changes from 124 to 126 +----------------------- + +* fixed up Linux Makefiles to build libnss_ldap + + +changes from 123 to 124 +----------------------- + +* patch from nalin@redhat.com for StartTLS +* fixed up indenting + + +changes from 122.BZ52.2 to 123 +------------------------------ + +* rolled in BUG#52 branch with fixes for AIX + + +changes from 122.BZ52.1 to 122.BZ52.2 +------------------------------------- + +* included ldap-schema.c; omitted from previous checkpoint + + +changes from 122 to 122.BZ52.1 +------------------------------ + +* preliminary fix for BUG#52 (support for different naming contexts for each + map) +* fixed bug in enumerating services map + + +changes from 121 to 122 +----------------------- + +* fixed BUG#50 (check return value of ldap_simple_bind()) + + +changes from 120 to 121 +----------------------- + +* fixed BUG#49 (fix acknowledged race condition) + + +changes from 119 to 120 +----------------------- + +* added Makefile.aix and exports.aix (forgot) + + +changes from 118 to 119 +----------------------- + +* patch from Gabor Gombas to support AIX implementation + of BIND IRS + + +changes from 117 to 118 +----------------------- + +* Makefile.RPM.openldap2 from Joe Little + + +changes from 116 to 117 +----------------------- + +* permanently ignore SIGPIPE when using SSL. This bug should be fixed + properly. + + +changes from 115 to 116 +----------------------- + +* added irs-nss.diff and README.IRS from Emile Heitor + + +changes from 113 to 115 +----------------------- + +* fixed filter escaping +* call ldapssl_client_init() once only +* include db_185.h not db.h for dn2uid cache +* fixes for FreeBSD (IRS) support from Emile Heitor + + +changes from 110 to 113 +----------------------- + +* patch from Ben Collins to escape '*' in filters + + +changes from 109 to 110 +----------------------- + +* patch from Phlilip Liu for async binds + + +changes from 108 to 109 +----------------------- + +* omit socket check for -DSSL; it doesn't work +* updated CONTRIBUTORS +* updated README re HAVE_LDAP_LD_FREE + + +changes from 107 to 108 +----------------------- + +* included "deref" option in /etc/ldap.conf, compatible with OpenLDAP syntax. + Patch from Michael Mattice. + + +changes from 106.2 to 107 +------------------------- + +* fixed argument to _nss_ldap_getent() in ldap-ethers.c + + +changes from 106.1 to 106.2 +--------------------------- + +* if root, use rootbinddn/rootbindpw in rebind proc +* include objectClass in pwd required attributes + + +changes from 105 to 106.1 +------------------------- + +* if user is a shadowAccount, then don't return password in getpwent(), + getpwuid() or getpwnam() +* incorporated patch (from Doug Nazar): +* allow getgrent() to be called without setgrent(); note arguments to + _nss_ldap_getent() have changed. +* return NSS_NOTFOUND instead of NSS_UNAVAIL at the end of a search +* initialize len for getpeername() + + +changes from 104 to 105 +----------------------- + +* incorporated patch for deadlock under Solaris (from Dave Begley) + + +changes from 103 to 104 +----------------------- + +* new spec file + + +changes from 102 to 103 +----------------------- + +* don't call ldap_parse_result() with V2 API + + +changes from 101 to 102 +----------------------- + +* added defines for LDAP_MSG_ONE et al if not in ldap.h +* removed LDAP_MORE_RESULTS_TO_RETURN test + + +changes from 100 to 101 +----------------------- + +* fixed spec file + + +changes from 99 to 100 +---------------------- + +* support for asynchronous search API! +* added some contributors +* notes about ldap_ld_free() +* merged in ChangeLog + + +changes from 98 to 99 +--------------------- + +* added some netgroup implementation tips +* do_close_no_unbind() cleanup + + +changes from 97 to 98 +--------------------- + +* /etc/nss_ldap.secret -> /etc/ldap.secret (sorry, Doug!) +* deleted crypt-mechanism code. Junk. +* fixed call to _nss_ldap_read() after changing prototypes in nss_ldap-88 + + +changes from 96 to 97 +--------------------- + +* #ifndef HAVE_LDAP_LD_FREE, still call ldap_unbind(), but having closed the + descriptor. + + +changes from 95 to 96 +--------------------- + +* re-orged + + +changes from 94 to 95 +--------------------- + +* disable SO_KEEPALIVE on socket rather than blocking SIGPIPE. Need to figure + out the right way to do this. + + +changes from 93 to 94 +--------------------- + +* committed some changes for the parent/child close problem. It relies on + internal libldap APIs so it may be non-portable but should work with + OpenLDAP and Netscape client libraries, and perhaps most UMich- derived + client libraries. There's a possible workaround for client libraries without + this; undefine HAVE_LDAP_LD_FREE to test this. + + +changes from 92 to 93 +--------------------- + +* important fix: make sure return status is reset after do_open() == + NSS_SUCCESS, just in case no entries are returned. This bug was introduced + in nss_ldap-88 and could potentially cause a security hole. + + +changes from 91 to 92 +--------------------- + +* signal handling fix: don't restore handler unnecessarily. +* don't open nss_ldap.secret unless a root pw is specified in ldap.conf + + +changes from 90 to 91 +--------------------- + +* reorganized SIGPIPE blocking code +* added SSL support + + +changes from 89 to 90 +--------------------- + +* only reconnect if we've changed to/from root + + +changes from 88 to 89 +--------------------- + +* cleaned up a few things + + +changes from 87 to 88 +--------------------- + +* added breaks to switch in _nss_ldap_lookup (thanks to Nathan.Hawkins@FMR.COM + for pointing this out) +* save signal handler and ignore SIGPIPE for appropriate sections of do_open() + and confirm connection is still active (patch from rpatel@globix.com) +* allow root users to bind as a different user, to provide quasi-shadow + password support (patch from nazard@dragoninc.on.ca) +* under Linux, make Makefile look at last libc version (patch from + nazard@dragoninc.on.ca) +* never clobber nsswitch.ldap/ldap.conf when making install (patch from + nazard@dragoninc.on.ca) +* change do_open() to not unbind the parent ldap connection when the pid + changes but simply open a new connection (patch from nazard@dragoninc.on.ca) +* changed _nss_ldap_lookup() and _nss_ldap_read() prototypes to return + NSS_STATUS error codes, so that NSS_UNAVAIL percolates as appropriate. + + +changes from 86 to 87 +--------------------- + +* fixed looking up DN-membered groups by member. Thanks to Jeff Mandel for + spotting this hard to find bug. + + +changes from 85 to 86 +--------------------- + +* member for NDS vs uniqueMember (needs further investigation; -DNDS) + + +changes from 84 to 85 +--------------------- + +* check non-NULLity of userdn before freeing +* use AT(uid) for groupsbymember filter + + +changes from 81 to 84 +--------------------- + +* implemented _nss_ldap_initgroups() + + +changes from 80 to 81 +--------------------- + +* removed extraneous do_sleep() code +* updated spec file + + +changes from 2.79 to 80 +----------------------- + +* (really 2.80) changed version number a la Solaris 7! +* cleaned up schema stuff into ldap-schema.h + + +changes from 2.78 to 2.79 +------------------------- + +* implemented exponential backoff reconnect logic + + +changes from 2.76 to 2.78 +------------------------- + +* removed ldap.conf.ragenet from lineup +* removed spurious do_close() + + +changes from 2.75 to 2.76 +------------------------- + +* added -lresolv to Solaris makefiles + + +changes from 2.72 to 2.75 +------------------------- + +* incorporated RPM patches from stein@terminator.net + + +changes from 2.71 to 2.72 +------------------------- + +* implemented getgroupsbymember() for Solaris. Supplementary groups should be + initialized now. (NB: doesn't appear to be quite working for RFC2307bis + yet.) +* GNU indent-ified + + +changes from 2.70 to 2.71 +------------------------- + +* removed -DDEBUG as default build flag + + +changes from 2.69 to 2.70 +------------------------- + +* put /usr/ucblib back into linker search path for Solaris. + + +changes from 2.68 to 2.69 +------------------------- + +* added timeout, unavailable, and server busy conditions to rebind logic +* indent -gnu all source files + + +changes from 2.65 to 2.68 +------------------------- + +* mods for glibc 2.1 (__set_errno is obselete it seems) + + +changes from 2.64 to 2.65 +------------------------- + +* mods to compile with OpenLDAP 2 + + +changes from 2.63 to 2.64 +------------------------- + +* changed alias schema to Sun SDS nisMailAlias schema +* updated TODO list to reflect Bugzilla entries +* restored capitalization of attributes for "niceness" + + +changes from 2.62 to 2.63 +------------------------- + +* added patch from gero@faveve.uni-stuttgart.de for parsing of ldap.conf with + tabs +* some fixes for BSDI BSD/OS IRS + + +changes from 2.61 to 2.62 +------------------------- + +* added experimental support for DN-membered groups; to enable, define + RFC2307BIS +* fixed align bug (where buflen wasn't being decremented after pointer + alignment) + + +changes from 2.60 to 2.61 +------------------------- + +* added warning about compiling with DS 4.1 LDAP SDK + + +changes from 2.59 to 2.60 +------------------------- + +* fixed missing close brace + + +changes from 2.56 to 2.59 +------------------------- + +* pw_comment field defaults to pw_gecos (Solaris only) + + +changes from 2.55 to 2.56 +------------------------- + +* fixed Makefile.linux.mozilla NSSLIBVER + + +changes from 2.54.6 to 2.55 +--------------------------- + +* merged in glibc-2.1 branch + + +changes from 2.54.5 to 2.54.6 +----------------------------- + +* misc fixes. + + +changes from 2.54.4 to 2.54.5 +----------------------------- + +* misc fixes. + + +changes from 2.54.3 to 2.54.4 +----------------------------- + +* glibc-2.1 patches from bcollins@debian.org + + +changes from 2.51 to 2.54.3 +--------------------------- + +* glibc-2.1 support. (Recall #93) +* set erange correctly on Solaris (related to above) +* added rebind function + + +changes from 2.49 to 2.51 +------------------------- + +* added stuff for RC + + +changes from 2.47 to 2.49 +------------------------- + +* configuration file is now case insensitive + + +changes from 2.45 to 2.47 +------------------------- + +* RFC2052BIS (_ldap._tcp) support + + +changes from 2.44 to 2.45 +------------------------- + +* added #include to globals.c + + +changes from 2.42 to 2.44 +------------------------- + +* NULL search base allowed (omit basedn from config file) + + +changes from 2.39 to 2.42 +------------------------- + +* fixed potential crasher in dnsconfig.c +* LDAP session is now persistent for performance reasons. Removed references + to the session anywhere outside ldap-nss.c. The process ID is cached and the + session reopened after a fork(). + + +changes from 2.38 to 2.39 +------------------------- + +* fixed warning in ldap-ethers.c (removed const from struct ether) +* added ldap_version keyword to ldap.conf for parity with pam_ldap + + +changes from 2.37 to 2.38 +------------------------- + +* debugged ldap_explode_rdn() code +* added support for Mozilla LDAP client library; see Makefile.linux.mozilla + and ltf.c for more information. Thanks to Netscape for making their library + available. + + +changes from 2.36 to 2.37 +------------------------- + +* moved to CVS repository and Linux as development environment +* incorporated ldap-service.c fix from Greg + + +changes from 2.35 to 2.36 +------------------------- + +* util.c: will use ldap_explode_rdn() if it exists + + +changes from 2.34 to 2.35 +------------------------- + +* made util.c compile again. Silly me. + + +changes from 2.33 to 2.34 +------------------------- + +* fixed #endif in testpw.c +* fixed another DN freeing leak in util.c +* added RFC 2307 to distribution (fixed the two typos in it: +* fixed bug in ...getrdnvalue() (thanks, Greg) +* diff rfc2307.txt ~/rfc2307.txt +480c480 +< MUST ( cn $ ipProtocolNumber ) +--- +> MUST ( cn $ ipProtocolNumber $ description ) +1038c1038 +< lester:X5/DBrWPOQQaI:10:10:Lester:/home/lester:/bin/csh +--- +> lester:X5/DBrWPOQQaI:10:10:Lester:/home/lester:/bin/sh + + +changes from 2.32 to 2.33 +------------------------- + +* rolled in more patches from greg@rage.net: +* removed _r from setXXXent and endXXXent functions for GNU_NSS +* cleaned up testpw.c to use pthreads and protos +* fixed prototype for gethostbyaddr_r on GNU_NSS +* braced conditional in getservbyname_r +* merged in Makefile.linux and README.LINUX diffs +* added htons(port) in getservbyport_r +* added nsswitch.test +* added ldaptest.pl +* added ldap.conf.ragenet + + +changes from 2.31 to 2.32 +------------------------- + +* moved Makefile to Makefile.solaris +* cleaned up mutex code for Linux, hopefully + + +changes from 2.30 to 2.31 +------------------------- + +* fixed leak in util.c (need to free dn) +* rolled in patches from greg@rage.net: +* fixed ldap-ethers.c to use struct ether +* fixed bracing in ldap-hosts.c (?) +* added SSLEAY patch to ldap-nss.h +* fixed locking in ldap-nss.h +* Makefile changes incorporated into Makefile.linux + + +changes from 2.29e to 2.30 +-------------------------- + +* synced into DevMan repository again +* RFC 2307 is the one! + + +changes from 2.29d to 2.29e +--------------------------- + +* util.c: fixed memory leak (call to ldap_value_free()) + + +changes from 2.29c to 2.29d +--------------------------- + +* ldap-ethers.c: fixed to use HOSTNAME attribute + + +changes from 2.29b to 2.29c +--------------------------- + +* ieee8022Device -> ieee802Device + + +changes from 2.29a to 2.29b +--------------------------- + +* added ieee8022Device and bootableDevice classes, + at Sun's request. + + +changes from 2.29 to 2.29a +-------------------------- + +* dc -> cn + + +changes from 2.28 to 2.29 +------------------------- + +* changed host/network/ethers naming schema see the -02 draft revision for + more info + + +changes from 2.27 to 2.28 +------------------------- + +* ldap-pwd.c, ldap-spwd.c: fixed tmpbuf stuff. Yuck. + + +changes from 2.26 to 2.27 +------------------------- + +* ANNOUNCE: reflected draft-howard-nis-schema-01.txt +* ldap-spwd.c: default for shadow integer values is -1, not 0 and fixed + crasher (thanks to dj@gregor.com) + + +changes from 2.25 to 2.26 +------------------------- + +* globals.c: added offset stuff back for mapping errnumbers. Weird: this stuff + *was* in an earlier version of the work area. I have no idea where it went. + Scary. + + +changes from 2.24 to 2.25 +------------------------- + +* irs-nss.h: added prototype for irs_ldap_acc() +* ldap-*.[ch]: removed redundent PARSER macro +* unbroke for GNU NSS (context_key_t changed to context_handle_t) + + +changes from 2.23 to 2.24 +------------------------- + +* irs-nss.c: added dispatch table for IRS library +* testpw5.c: added additional test program +* ldap-nss.c: removed spurious debug statement +* ldap-nss.c, util.c, dnsconfig.c: cleaned up memory allocation for config. + (This could be improved, but there is no longer a static ldap_config_t + structure.) +* Makefile: general cleanup + + +changes from 2.22 to 2.23 +------------------------- + +* default destructor is now simply wrapped around by individual backend + destructors +* __EXTENSIONS__ defined for Solaris 2.6 to import strncasecmp() +* getbyname: fixed crasher in ldap-nss.c due to uninitialized variable +* ldap-parse.h, assorted others: tidied up resolver calls to use NSS_ARGS() + macro and not to interfere with the previous backend's status (bad thing!) +* ldap-service.c: cleaned up potential uninitialized var in parser +* ldap-nss.c: no valued arrays are now { NULL } instead of NULL. + + +changes from 2.21 to 2.22 +------------------------- + +* testpw.c: XXX problem. dies with segfault, but gdb doesn't give me enough + information; it's definitely within nss_ldap.so though. I just can't see the + symbols. (Maybe dbx would be better...) However, testpw doesn't work at + *all* under 2.5.1, and technically it shouldn't as it's not linked against + liblthread. I haven't been able to duplicate this with testpw2, which is the + same code linked with the thread library. +* backported to NeXT + + +changes from 2.20 to 2.21 +------------------------- + +* resolve.h: renamed functions so as to keep namespace clean +* snprintf.h: tidied up for systems which already have snprintf() and renamed + anyway to keep namespace clean (_nss_ldap_snprintf) +* ldap-*.h: made character constants const to avoid nasty warnings +* globals.[ch]: as above +* README, TODO, ANNOUNCE: general documentation updates +* ldap-nss.c, et al: general work on Solaris 2.6 port, to get nscd working. + Lots of fiddling with the locking. +* Major architectural changes to Solaris NSS implementation. Thread specific + data is now stored in the backend, where it should be: just like it is in + IRS. Locking is a little more coarse now, but it will do for the moment. +* Paul Henson's DCE module gave me the inspiration to do the backend stuff the + "right" way -- thanks, Paul! +* As a result, a lot of the bugs listed in TODO have mysteriously fixed + themselves. :-) + + +changes from 2.19 to 2.20 +------------------------- + +* Makefile.*: ensured resolve.[ch] and dnsconfig.[ch] were there. +* Makefile: should link now with gcc -shared instead of requiring cc. + + +changes from 2.18 to 2.19 +------------------------- + +* testpw4.c: added irs hostbyname() test +* Makefile: added correct flags to build position indepdenent code with Sun's + compiler (thanks, Bill). Added SRV sources. +* testpw.c: works under NeXT, cleaned up a bit. +* ldap.conf: documented what this file does +* util.c: ignore blank lines in ldap.conf properly +* resolve.h: fixed up for Solaris + + +changes from 2.17 to 2.18 +------------------------- + +* ldap-network.c: fixed infinite loop in getnetbyname() +* util.c: goto out causes a compiler warning under Solaris. Documented this. + Should fix this, I suppose, but we need to break out of two blocks. (We + could remove the code that handles multivalued DNs, as it's fairly unlikely + that someone will use a DN of o=Xedoc+dc=xedoc,c=US+dc=com, but who knows?) +* ldap-ethers.c: line 215, result was not assigned to an lvalue (should have + been args->status, not args). Fixed. + + +changes from 2.16 to 2.17 +------------------------- + +* Cleaned up documentation and testpw4.c +* dnsconfig.c: Fixed strtok() bug which was clobbering domain + + +changes from 2.15 to 2.16 +------------------------- + +* util.c (_nss_ldap_readconfig) fixed strtok() typo + + +changes from 2.2 to 2.15 +------------------------ + +* dnsconfig.c: got DNS SRV support working under NEXTSTEP +* util.c: (_nss_ldap_getdomainname) made host and network DN parsing compliant + with current draft + + +changes from 2.1 to 2.2 +----------------------- + +* I'll get around to merging in the RCS log here one day. Nothing very + exciting happened, I just backported the code to NEXTSTEP and compiled it. diff --git a/README b/README new file mode 100644 index 0000000..6e223ea --- /dev/null +++ b/README @@ -0,0 +1,403 @@ + nss-pam-ldapd - NSS and PAM library for name lookups and authentication + using LDAP + + nss-pam-ldapd started as nss-ldapd which was a fork from nss_ldap which was + originally written by Luke Howard of PADL Software Pty Ltd. + + http://www.padl.com/OSS/nss_ldap.html + + In 2006 Arthur de Jong of West Consuling forked the library to split it + into a thin NSS part and a server part. Most of the code was rewritten. + + The software was renamed to nss-pam-ldapd when PAM code contributed by + Howard Chu for the OpenLDAP nssov module was integrated. Solaris + compatibility was developed by Ted C. Cheng of Symas Corporation. + + http://arthurdejong.org/nss-pam-ldapd/ + + Copyright (C) 1997-2006 Luke Howard + Copyright (C) 2006-2007 West Consulting + Copyright (C) 2006-2010 Arthur de Jong + Copyright (C) 2009 Howard Chu + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + +INTRODUCTION +============ + +This is the nss-pam-ldapd library which consists of an NSS module to do name +lookups to an LDAP directory server and a PAM module to do authentication to +an LDAP server. The NSS part of this library was forked from nss_ldap as +provided by Luke Howard of PADL Software Pty Ltd. The PAM module was mostly +provided by Howard Chu of the OpenLDAP project. + +The NSS library allows distributing account, group, host and other +configuration information from a central LDAP server throughout an +organisation. Because LDAP is a hierarchical directory service, you can +distribute the information in a manner which reflects an organisational +structure. This contrasts with the flat, single domain policy of NIS. LDAP has +many of the advantages of NIS+ (security and scalability) without the +complexity. The system will work alongside your existing NIS, NIS+, DNS and +flat file name services. + +The PAM library (module) can be used to perform authentication based on +information inside the LDAP directory. + +Both libraries consist of a thin NSS or PAM part that communicates with a +local daemon (nslcd) that handles the LDAP lookups. This simplifies the +architecture and fixes some scalability and locking problems in the original +design of nss_ldap. + +Also it is possible to use the thin NSS and PAM parts together with the nssov +overlay in the OpenLDAP server (slapd). + +The three parts (NSS module, PAM module, and nslcd server) can be build +separately and are not tied together. This means that for instance you can +still use pam_ldap and use the NSS module from nss-pam-ldapd. + +improvements over nss_ldap +-------------------------- + +The fork from nss_ldap was done to implement some major design changes to fix +some structural problems in the library. + +The biggest of those problems were host name lookups through LDAP which could +cause deadlocks in most cases and some general name lookup problems during +booting (when the LDAP server was not started or not yet reachable). + +A number of refactoring steps were done to simplify the code and improve +maintainability. Legacy code was removed and support for non-Linux operating +systems was initially removed to make the code more readable. Portability will +be re-added once the architecture stabilises. + +The most practical improvements over nss_ldap are: +- the LDAP library is not loaded for every process doing LDAP lookups +- the number of connections to the LDAP server is limited, because not every + process will open it's own connection (this problem is also mitigated by + using nscd) +- hostname lookups should now be deadlock-free because the LDAP server name is + no longer looked up using the ldap method +- the setup is easier to debug because logging on the server component can be + enabled without affecting "normal" processes + +This package runs a local daemon that will be enabled during the boot process. +This daemon will handle connections to the LDAP server and accept requests +through a named socket (/var/run/nslcd/socket). The thin NSS library will +proxy requests to the daemon. + +Note that the package currently cannot be used on the same system alongside +nss_ldap. + +comparison to pam_ldap +---------------------- + +The PAM module that is currently implemented contains functionality for +authentication, account management, password management and session +management. The nslcd daemon currently implements authentication, +authorisation and password modification. The OpenLDAP nssov overlay also +implements session functionality. + +supported C libraries (for NSS module) +-------------------------------------- + +This library currently only supports the GNU C Library. Support for other C +libraries has been removed in a refactoring step. Compatibility code and +support for other C libraries will be added upon request. + +supported name databases +------------------------ + +Currently the following name databases are supported: + + aliases, ethers, group, hosts, netgroup, networks, passwd, protocols, rpc, + services and shadow + +Note that for when using IPv6 hosts entries, the addresses in the LDAP +directory must be in their preferred form. The same is true for mac addresses +for the ethers database. Otherwise the address to entry lookups will not work. +For more details on the preferred form see + http://ldap.akbkhome.com/index.php/attribute/ipHostNumber.html +and + http://ldap.akbkhome.com/index.php/attribute/macAddress.html + +automounter map lookups (which are also defined in /etc/nsswitch.conf) are not +supported because the NSS interface is not used for these. The common autofs +implementation (on GNU/Linux) currently uses it's own method for getting the +maps from LDAP. + +Although aliases are exposed through NSS, most mail servers parse /etc/aliases +by themselves and getting aliases from LDAP requires some configuration in the +mail server. + +The publickey, bootparams and netmasks are currently unsupported. Some +investigation should be done if these are needed for anything, which +interfaces should be exported and how the LDAP schema part should look like. + +supported PAM implementation +---------------------------- + +The PAM module is currently only regularly tested on Linux PAM but other PAM +implementations should also work. + +supported LDAP libraries +------------------------ + +The current version of nss-pam-ldapd has been developed with OpenLDAP 2.4 but +other LDAP libraries and older versions of OpenLDAP may also work. + +unsupported features +-------------------- + +Since nss-pam-ldapd was forked from nss_ldap most of the features that came +with nss_ldap are available. The most important differences: +- the configuration file formats are not fully compatible +- nested groups are currently unsupported +- rootbinddn/rootbindpw support is removed and is not likely to return + +For the PAM module some functionality is missing. Comparing it to pam_ldap: +- only BIND authentication is supported +- only LDAP password modify EXOP is supported as password changing mechanism + +Some things work a little different in nss-pam-ldapd. For instance the +attribute defaults and overrides of nss_ldap are implemented with mapping +expressions and pam_ldap's pam_check_*_attr options can be implemented with +the pam_authz_search option. + + +INSTALLATION +============ + +The nss-pam-ldapd library uses autoconf and automake for building. Installing +nss-pam-ldapd should be as simple as: + + % ./configure + % make + % make install + +That said, it is a good idea to go first through the options of configure by +running: + + % ./configure --help + +The last step (make install) should install the libnss_ldap.so.* and +pam_ldap.so files and the daemon (nslcd). The boot process needs to be +manually modified to start the daemon at the right time. + +Also, it is recommended to create a dedicated user for the nslcd daemon. +Configure this user in /etc/nslcd.conf using the uid and gid options. + + +CONFIGURATION +============= + +After installation the name service switch configuration file +(/etc/nsswitch.conf) needs to be modified to do name lookups using the new +module. This consist mostly of adding ldap in the list of lookup methods in +the right place. See the nsswitch.conf(5) manual page for details on the +format. As an example the file could look a little like this: + + # the following contain normal unix user and group information + passwd: files ldap + group: files ldap + shadow: files ldap + + # hostname lookups through ldap before dns should work now + hosts: files ldap dns + networks: files ldap + + # normal flat-file definitions + protocols: files ldap + services: files ldap + ethers: files ldap + rpc: files ldap + netgroup: ldap + + # whether alias lookups really use NSS depends on the mail server + aliases: files ldap + +Configuring PAM differs a little from platform to platform but this is a basic +set-up for files under /etc/pam.d: + +auth sufficient pam_unix.so +auth sufficient pam_ldap.so use_first_pass +auth required pam_deny.so + +account required pam_unix.so +account sufficient pam_ldap.so +account required pam_permit.so + +session required pam_unix.so +session optional pam_ldap.so + +password sufficient pam_unix.so nullok md5 shadow use_authtok +password sufficient pam_ldap.so try_first_pass +password required pam_deny.so + +Lastly, a configuration file for nslcd (by default /etc/nslcd.conf) needs to +be made. See the shipped manual page for details on the format and options. It +should at the very least contain something like: + + # the location of LDAP server + uri ldap://localhost/ + + # search base for all queries. + base dc=example,dc=net + +service discovery through DNS +----------------------------- + +nss-pam-ldapd supports looking up LDAP server names through DNS SRV records as +specified in RFC 2782. However, Priority and Weight are not considered +separately and a single list of servers in added as if they had been specified +with uri options in the configuration file. + +To use this feature specify DNS as an uri in the configuration file and +include something like the following in your zone: + + _ldap._tcp SRV 10 0 389 ldapserver + + +LDAP SCHEMA +=========== + +nss-pam-ldapd supports a wide range of possible LDAP schema configurations and +it can be customized heavily. The LDAP schema used is described in RFC 2307. +Groups with distinguished name members (instead of login names) (RFC 2307bis) +are also supported, although use of memberUid has much better performance (see +below for details). + +default attributes +------------------ + +This paragraph describes the mapping between the NSS lookups and the LDAP +database. The mapping may be modified by changing the nslcd.conf configuration +file. See the nslcd.conf(5) manual page for details. + +aliases (objectClass=nisMailAlias) + cn - alias name + rfc822MailMember - members of the alias (recipients) +ethers (objectClass=ieee802Device) + cn - host name + macAddress - ethernet address +group (objectClass=posixGroup) + cn - group name + userPassword - password + gidNumber - gid + memberUid - members (user names) + member - members (DN values) +hosts (objectClass=ipHost) + cn - host name (and aliases) + ipHostNumber - addresses +netgroup (objectClass=nisNetgroup) + cn - netgroup name + nisNetgroupTriple - triplets describing netgroup entries + memberNisNetgroup - reference to other netgroup +networks (objectClass=ipNetwork) + cn - network name + ipNetworkNumber - network address +passwd (objectClass=posixAccount) + uid - account name + userPassword - password + uidNumber - uid + gidNumber - gid + gecos - gecos + homeDirectory - home directory + loginShell - shell +protocols (objectClass=ipProtocol) + cn - protocol name + ipProtocolNumber - protocol number +rpc (oncRpc) + cn - rpc name + oncRpcNumber - rpc number +services (objectClass=ipService) + cn - service name + ipServicePort - service port + ipServiceProtocol - service protocol +shadow (objectClass=shadowAccount) + uid - use name + userPassword - password + shadowLastChange - last change of password + shadowMax - days before password may be changed + shadowMin - days after which password must be changed + shadowWarning - expiry warning + shadowInactive - account is disabled if no password is changed + shadowExpire - account expiration + shadowFlag - reserved field + +using Microsoft Active Directory +-------------------------------- + +When using Microsoft Active Directory server (typically on Microsoft Windows +2000) some changes need to be made to the nslcd.conf configuration file. The +included sample configuration file has some commented out attribute mappings +for such a set-up. + +group membership +---------------- + +Currently, two ways of specifying group membership are supported. The first, +by using the memberUid attribute, is the simplest and by far the fastest +(takes the least number of lookups). This attribute maps to user names with +the same values as the uid attribute would hold for posixAccount entries. + +The second method is to use DN values in the member attribute (attribute +names can be changed by using the attribute mapping options as described in +the manual page). This is potentially a lot slower because in the worst case +every DN has to be looked up in the LDAP server to find the proper value for +the uid attribute. + +If the DN value already contains a uid value (e.g. uid=arthur, dc=example, +dc=com) the lookup is skipped and the value from the DN is used. A cache is +maintained that saves the DN to uid translations for 15 minutes. + +In all cases, users that are specified as member multiple times are returned +only once. + +Currently, having nested groups by member values pointing to other groups, +as well as the memberOf attribute in posixAccount entries are unsupported. + +case sensitivity +---------------- + +Most values in the NSS databases are considered case-sensitive (e.g. the user +"Foo" is a different user from the user "foo"). Most values in an LDAP +database are however considered case-insensitive. nss-pam-ldapd tries to solve +this problem by adding an extra filtering layer to ensure that e.g. when +looking for the user "foo" it will not return a user "Foo" that is found in +LDAP. + +For the group, netgroup, passwd, protocols, rpc, services and shadow maps the +matches will be checked case-sensitively and for aliases, ethers, hosts and +networks matches will be case-insensitive (this seems to be what Glibc is +doing currently with flat files). Only searching for groups by user is done +case-insensitive. In all cases the case-use in the LDAP directory is returned. + +Note that having entries that only differ in case is a bad idea and will +likely get you in trouble. One example of such a problem is that the DN +uid=test,dc=example,dc=com is the same as uid=TEST,dc=example,dc=com. + + +REPORTING BUGS +============== + +If you find any bugs or missing features please send email to + nss-pam-ldapd-users@lists.arthurdejong.org +If you are using the Debian package you are encouraged to use the BTS. Please +include as much information as needed (platform, output of configure if +compilation fails, output of the failure, etc). Patches are more than welcome +(also see the file HACKING). diff --git a/TODO b/TODO new file mode 100644 index 0000000..fb0d1c0 --- /dev/null +++ b/TODO @@ -0,0 +1,31 @@ +* write more unit tests +* add sanity checking code (e.g. not too large buffer allocation and checking + that host, user, etc do not contain funky characters) in all server modules +* log some statistics: "passwd=100 shadow=10 host=20 rpc=10" (10 req/minute) +* add an option to create an extra socket somewhere (so it may be used in + chroot jails) +* make I/O timeout between NSS lib and daemon configurable with configure +* protocols/rpc: the description attribute should be used as an alias? +* review changes in nss_ldap and merge any useful changes +* maybe rate-limit LDAP entry warnings +* setnetgrent() may need to return an error if the netgroup is undefined +* handle repeated calls to getent() better + (see http://bugzilla.padl.com/show_bug.cgi?id=376) +* make it possible to start nslcd real early in the boot process and have + it become available when it determines it can (other timeout/retry mechanism + on startup) +* implement requesting and handling password policy information when binding + as a user +* implement nested groups +* implement other services in nslcd: sudo and autofs are candidates +* restart unscd on postinst, just like nscd (or perhaps do nscd -i ) +* instead of library symbol, use environment variable to disable NSS module +* properly test Solaris support +* fix buffer handling in read_**string() functions (Solaris support) +* complete pynslcd implementation +* implement chsh and chfn in nslcd PAM code and make chsh.ldap and chfn.ldap + binaries +* have nslcd flush the nscd caches when reconnecting to the LDAP server after + an error +* have PAM code support password policy of server (see pam_ldap) +* also add a max uid option for PAM module diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..9c1f67d --- /dev/null +++ b/autogen.sh @@ -0,0 +1,31 @@ +#! /bin/sh + +# run this to generate all initial .in files etc + +# copy some files from automake/autoconf into place +[ -r /usr/share/misc/config.sub ] && \ + cp -f /usr/share/misc/config.sub config.sub +[ -r /usr/share/misc/config.guess ] && \ + cp -f /usr/share/misc/config.guess config.guess +[ -r /usr/share/automake-1.11/mkinstalldirs ] && \ + cp -f /usr/share/automake-1.11/mkinstalldirs mkinstalldirs +[ -r /usr/share/automake-1.11/missing ] && \ + cp -f /usr/share/automake-1.11/missing missing +[ -r /usr/share/automake-1.11/install-sh ] && \ + cp -f /usr/share/automake-1.11/install-sh install-sh +[ -r /usr/share/automake-1.11/depcomp ] && \ + cp -f /usr/share/automake-1.11/depcomp depcomp +[ -r /usr/share/automake-1.11/INSTALL ] && \ + cp -f /usr/share/automake-1.11/INSTALL INSTALL + +# generate aclocal.m4 from configure.ac +aclocal-1.11 -I m4 + +# generate config.h.in from configure.ac +autoheader --warnings=all --force + +# generate Makefile.in from Makefile.am and configure.ac +automake-1.11 --warnings=all --add-missing --copy --force-missing + +# generate configure from configure.ac +autoconf --warnings=all --force diff --git a/common/Makefile.am b/common/Makefile.am new file mode 100644 index 0000000..df90b8e --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,32 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2007, 2008, 2009 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LIBRARIES = libtio.a libprot.a libdict.a libexpr.a + +AM_CPPFLAGS=-I$(top_srcdir) +AM_CFLAGS = -fPIC + +libtio_a_SOURCES = tio.c tio.h + +libprot_a_SOURCES = nslcd-prot.c nslcd-prot.h + +libdict_a_SOURCES = dict.c dict.h \ + set.c set.h + +libexpr_a_SOURCES = expr.c expr.h diff --git a/common/dict.c b/common/dict.c new file mode 100644 index 0000000..c42b8b4 --- /dev/null +++ b/common/dict.c @@ -0,0 +1,294 @@ +/* + dict.c - dictionary functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ + +#include "dict.h" + +/* + This module uses a hashtable to store it's key to value mappings. The + structure is basically as follows: + + [struct dictionary] + \- holds an array of pointers to a linked list of [struct dict_entry] + \- each entry has a key/value mapping + + The hashmap can be resized when the total number of elements in the hashmap + exceeds a certain load factor. + + All the keys are copied in a separate linked list of buffers where each new + buffer that is allocated is larger than the previous one. The first buffer + in the linked list is always the current one. +*/ + +/* an entry stores one key/value pair */ +struct dict_entry { + uint32_t hash; /* used for quick matching and rehashing */ + const char *key; /* a reference to a copy of the key */ + void *value; /* the stored value */ + struct dict_entry *next; +}; + +/* the initial size of the hashtable */ +#define DICT_INITSIZE 7 + +/* load factor at which point to grow hashtable */ +#define DICT_LOADPERCENTAGE 400 + +/* the dictionary is a hashtable */ +struct dictionary { + int size; /* size of the hashtable */ + int num; /* total number of keys stored */ + struct dict_entry **table; /* the hashtable */ +}; + +/* Simple hash function that computes the hash value of a string. */ +static uint32_t stringhash(const char *str) +{ + uint32_t hash=0; + while (*str!='\0') + hash=3*hash+*str++; + return hash; +} + +/* Grow the hashtable. */ +static void growhashtable(DICT *dict) +{ + int i; + int newsize; + struct dict_entry **newtable; + struct dict_entry *entry,*tmp; + newsize=dict->size*3+1; + /* allocate room for new hashtable */ + newtable=(struct dict_entry **)malloc(newsize*sizeof(struct dict_entry *)); + if (newtable==NULL) + return; /* allocating memory failed continue to fill the existing table */ + /* clear new table */ + for (i=0;isize;i++) + { + /* go over elements in linked list */ + entry=dict->table[i]; + while (entry!=NULL) + { + tmp=entry; + entry=entry->next; + /* put in new position */ + tmp->next=newtable[tmp->hash%newsize]; + newtable[tmp->hash%newsize]=tmp; + } + } + /* free the old hashtable */ + free(dict->table); + /* put new hashtable in place */ + dict->size=newsize; + dict->table=newtable; +} + +DICT *dict_new(void) +{ + struct dictionary *dict; + int i; + /* allocate room for dictionary information */ + dict=(struct dictionary *)malloc(sizeof(struct dictionary)); + if (dict==NULL) + return NULL; + dict->size=DICT_INITSIZE; + dict->num=0; + /* allocate initial hashtable */ + dict->table=(struct dict_entry **)malloc(DICT_INITSIZE*sizeof(struct dict_entry *)); + if (dict->table==NULL) + { + free(dict); + return NULL; + } + /* clear the hashtable */ + for (i=0;itable[i]=NULL; + /* we're done */ + return dict; +} + +void dict_free(DICT *dict) +{ + struct dict_entry *entry,*etmp; + int i; + /* free hashtable entries */ + for (i=0;isize;i++) + { + entry=dict->table[i]; + while (entry!=NULL) + { + etmp=entry; + entry=entry->next; + free(etmp); + } + } + /* free the hashtable */ + free(dict->table); + /* free dictionary struct itself */ + free(dict); +} + +void *dict_get(DICT *dict,const char *key) +{ + uint32_t hash; + struct dict_entry *entry; + /* calculate the hash */ + hash=stringhash(key); + /* loop over the linked list in the hashtable */ + for (entry=dict->table[hash%dict->size];entry!=NULL;entry=entry->next) + { + if ( (entry->hash==hash) && + (strcmp(entry->key,key)==0) ) + return entry->value; + } + /* no matches found */ + return NULL; +} + +const char *dict_getany(DICT *dict) +{ + int i; + /* loop over the linked list in the hashtable */ + for (i=0;isize;i++) + if (dict->table[i]) + return dict->table[i]->key; + /* no matches found */ + return NULL; +} + +int dict_put(DICT *dict,const char *key,void *value) +{ + uint32_t hash; + int l; + char *buf; + int idx; + struct dict_entry *entry,*prev; + /* check if we should grow the hashtable */ + if ( dict->num >= ((dict->size*DICT_LOADPERCENTAGE)/100) ) + growhashtable(dict); + /* calculate the hash and position in the hashtable */ + hash=stringhash(key); + idx=hash%dict->size; + /* check if the entry is already present */ + for (entry=dict->table[idx],prev=NULL; + entry!=NULL; + prev=entry,entry=entry->next) + { + if ( (entry->hash==hash) && + (strcmp(entry->key,key)==0) ) + { + /* check if we should unset the entry */ + if (value==NULL) + { + /* remove from linked list */ + if (prev==NULL) + dict->table[idx]=entry->next; + else + prev->next=entry->next; + /* free entry memory and register removal */ + free(entry); + dict->num--; + return 0; + } + /* just set the new value */ + entry->value=value; + return 0; + } + } + /* if entry should be unset we're done */ + if (value==NULL) + return 0; + /* entry is not present, make new entry */ + l=strlen(key)+1; + buf=(char *)malloc(sizeof(struct dict_entry)+l); + if (buf==NULL) + return -1; + entry=(struct dict_entry *)(void *)buf; + buf+=sizeof(struct dict_entry); + strcpy(buf,key); + entry->hash=hash; + entry->key=buf; + entry->value=value; + /* insert into hashtable/linked list */ + entry->next=dict->table[idx]; + dict->table[idx]=entry; + /* increment number of stored items */ + dict->num++; + return 0; +} + +const char **dict_keys(DICT *dict) +{ + int i; + struct dict_entry *entry; + char *buf; + const char **values; + size_t sz; + int num; + /* figure out how much memory to allocate */ + num=0; + sz=0; + for (i=0;isize;i++) + { + entry=dict->table[i]; + while (entry!=NULL) + { + num++; + sz+=strlen(entry->key)+1; + entry=entry->next; + } + } + /* allocate the needed memory */ + buf=(char *)malloc((num+1)*sizeof(char *)+sz); + if (buf==NULL) + return NULL; + values=(const char **)(void *)buf; + buf+=(num+1)*sizeof(char *); + /* fill the array with the keys */ + num=0; + for (i=0;isize;i++) + { + entry=dict->table[i]; + while (entry!=NULL) + { + strcpy(buf,entry->key); + values[num++]=buf; + buf+=strlen(buf)+1; + entry=entry->next; + } + } + values[num]=NULL; + /* done */ + return values; +} diff --git a/common/dict.h b/common/dict.h new file mode 100644 index 0000000..bb244f0 --- /dev/null +++ b/common/dict.h @@ -0,0 +1,71 @@ +/* + dict.h - dictionary functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMMON__DICT_H +#define COMMON__DICT_H + +#include "compat/attrs.h" + +/* + These functions provide a mapping between a string and a pointer. +*/ +typedef struct dictionary DICT; + +/* Create a new instance of a dictionary. Returns NULL + in case of memory allocation errors. */ +DICT *dict_new(void) + LIKE_MALLOC MUST_USE; + +/* Add a relation in the dictionary. The key is duplicated + and can be reused by the caller. The pointer is just stored. + This function returns non-0 in case of memory allocation + errors. If the key was previously in use the value + is replaced. All key comparisons are case sensitive. */ +int dict_put(DICT *dict,const char *key,void *value); + +/* Look up a key in the dictionary and return the associated + value. NULL is returned if the key is not found in the dictionary. + All key comparisons are case sensitive. */ +void *dict_get(DICT *dict,const char *key) + MUST_USE; + +/* Get a key from the dictionary that has a value set. The caller does + not need to free the returned value (it is freed when dict_free() + is called). */ +const char *dict_getany(DICT *dict); + +/* Delete a key-value association from the dictionary. + All key comparisons are case sensitive. */ +/*void dict_del(DICT *dict,const char *key);*/ + +/* Remove the dictionary from memory. All allocated storage + for the dictionary and the keys is freed. + Note that values are not freed. This is the responsibility + of the caller. */ +void dict_free(DICT *dict); + +/* Return the keys of the dict as a list of strings. + The caller should free the memory with a single call to free(). */ +const char **dict_keys(DICT *dict) + MUST_USE; + +#endif /* COMMON__DICT_H */ diff --git a/common/expr.c b/common/expr.c new file mode 100644 index 0000000..7fa4f84 --- /dev/null +++ b/common/expr.c @@ -0,0 +1,234 @@ +/* + expr.c - limited shell-like expression parsing functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "expr.h" +#include "compat/attrs.h" + +/* the maximum length of a variable name */ +#define MAXVARLENGTH 30 + +static inline int my_isalpha(const char c) +{ + return ((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z')); +} + +static inline int my_isalphanum(const char c) +{ + return my_isalpha(c)||((c>='0')&&(c<='9')); +} + +/* return the part of the string that is a valid name */ +MUST_USE static const char *parse_name(const char *str,int *ptr,char *buffer,size_t buflen) +{ + int i=0; + /* clear the buffer */ + buffer[i]='\0'; + /* look for an alpha+alphanumeric* string */ + if (!my_isalpha(str[*ptr])) + return NULL; + while (my_isalphanum(str[*ptr])) + { + if ((size_t)i>=buflen) + return NULL; + buffer[i++]=str[(*ptr)++]; + } + /* NULL-terminate the string */ + if ((size_t)i>=buflen) + return NULL; + buffer[i++]='\0'; + return buffer; +} + +/* dummy expander function to always return an empty string */ +static const char *empty_expander(const char UNUSED(*name),void UNUSED(*expander_arg)) +{ + return ""; +} + +/* definition of the parse functions (they call eachother) */ +MUST_USE static const char *parse_dollar_expression( + const char *str,int *ptr,char *buffer,size_t buflen, + expr_expander_func expander,void *expander_arg); +MUST_USE static const char *parse_expression( + const char *str,int *ptr,int endat,char *buffer,size_t buflen, + expr_expander_func expander,void *expander_arg); + +MUST_USE static const char *parse_dollar_expression( + const char *str,int *ptr,char *buffer,size_t buflen, + expr_expander_func expander,void *expander_arg) +{ + char varname[MAXVARLENGTH]; + const char *varvalue; + if ((buflen<=0)||(buffer==NULL)||(str==NULL)||(ptr==NULL)) + return NULL; + if (str[*ptr]=='{') + { + (*ptr)++; + /* the first part is always a variable name */ + if (parse_name(str,ptr,varname,sizeof(varname))==NULL) + return NULL; + varvalue=expander(varname,expander_arg); + if (varvalue==NULL) + varvalue=""; + if (str[*ptr]=='}') + { + /* simple substitute */ + if (strlen(varvalue)>=buflen) + return NULL; + strcpy(buffer,varvalue); + } + else if (strncmp(str+*ptr,":-",2)==0) + { + /* if variable is not set or empty, substitute remainder */ + (*ptr)+=2; + if ((varvalue!=NULL)&&(*varvalue!='\0')) + { + /* value is set, skip rest of expression and use value */ + if (parse_expression(str,ptr,'}',buffer,buflen,empty_expander,NULL)==NULL) + return NULL; + if (strlen(varvalue)>=buflen) + return NULL; + strcpy(buffer,varvalue); + } + else + { + /* value is not set, evaluate rest of expression */ + if (parse_expression(str,ptr,'}',buffer,buflen,expander,expander_arg)==NULL) + return NULL; + } + } + else if (strncmp(str+*ptr,":+",2)==0) + { + /* if variable is set, substitute remainer */ + (*ptr)+=2; + if ((varvalue!=NULL)&&(*varvalue!='\0')) + { + /* value is set, evaluate rest of expression */ + if (parse_expression(str,ptr,'}',buffer,buflen,expander,expander_arg)==NULL) + return NULL; + } + else + { + /* value is not set, skip rest of expression and blank */ + if (parse_expression(str,ptr,'}',buffer,buflen,empty_expander,NULL)==NULL) + return NULL; + buffer[0]='\0'; + } + } + else + return NULL; + (*ptr)++; /* skip closing } */ + } + else + { + /* it is a simple reference to a variable, like $uidNumber */ + if (parse_name(str,ptr,varname,sizeof(varname))==NULL) + return NULL; + varvalue=expander(varname,expander_arg); + if (varvalue==NULL) + varvalue=""; + if (strlen(varvalue)>=buflen) + return NULL; + strcpy(buffer,varvalue); + } + return buffer; +} + +MUST_USE static const char *parse_expression( + const char *str,int *ptr,int endat,char *buffer,size_t buflen, + expr_expander_func expander,void *expander_arg) +{ + int j=0; + /* go over string */ + while ((str[*ptr]!=endat)&&(str[*ptr]!='\0')) + { + switch (str[*ptr]) + { + case '$': /* beginning of an expression */ + (*ptr)++; + if ((size_t)j>=buflen) + return NULL; + if (parse_dollar_expression(str,ptr,buffer+j,buflen-j,expander,expander_arg)==NULL) + return NULL; + j=strlen(buffer); + break; + case '\\': /* escaped character, unescape */ + (*ptr)++; + default: /* just copy the text */ + if ((size_t)j>=buflen) + return NULL; + buffer[j++]=str[*ptr]; + (*ptr)++; + } + } + /* NULL-terminate buffer */ + if ((size_t)j>=buflen) + return NULL; + buffer[j++]='\0'; + return buffer; +} + +MUST_USE const char *expr_parse(const char *str,char *buffer,size_t buflen, + expr_expander_func expander,void *expander_arg) + +{ + int i=0; + return parse_expression(str,&i,'\0',buffer,buflen,expander,expander_arg); +} + +SET *expr_vars(const char *str,SET *set) +{ + char varname[MAXVARLENGTH]; + int i=0; + /* allocate set if needed */ + if (set==NULL) + set=set_new(); + if (set==NULL) + return NULL; + /* go over string */ + while (str[i]!='\0') + { + switch (str[i]) + { + case '$': /* beginning of a $-expression */ + i++; + if (str[i]=='{') + i++; + /* the rest should start with a variable name */ + if (parse_name(str,&i,varname,sizeof(varname))!=NULL) + set_add(set,varname); + break; + case '\\': /* escaped character, unescape */ + i++; + /* no break needed here */ + default: /* just skip */ + i++; + } + } + return set; +} diff --git a/common/expr.h b/common/expr.h new file mode 100644 index 0000000..0ff2c28 --- /dev/null +++ b/common/expr.h @@ -0,0 +1,41 @@ +/* + expr.h - limited shell-like expression parsing functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2009 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMMON__EXPR_H +#define COMMON__EXPR_H 1 + +#include "compat/attrs.h" +#include "common/set.h" + +typedef const char *(*expr_expander_func)(const char *name,void *expander_arg); + +/* Parse the expression and store the result in buffer, using the + expander function to expand variable names to values. If the expression + is invalid or the result didn't fit in the buffer NULL is returned. */ +MUST_USE const char *expr_parse(const char *expr,char *buffer,size_t buflen, + expr_expander_func expander,void *expander_arg); + +/* Return the variable names that are used in expr. If set is NULL a new one + is allocated, otherwise the passed set is added to. */ +SET *expr_vars(const char *expr,SET *set); + +#endif /* not _COMMON__ */ diff --git a/common/nslcd-prot.c b/common/nslcd-prot.c new file mode 100644 index 0000000..f2d6adf --- /dev/null +++ b/common/nslcd-prot.c @@ -0,0 +1,89 @@ +/* + nslcd-prot.c - common functions for NSLCD lookups + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nslcd.h" +#include "nslcd-prot.h" + +/* buffer sizes for I/O */ +#define READBUFFER_MINSIZE 1024 +#define READBUFFER_MAXSIZE 2*1024*1024 +#define WRITEBUFFER_MINSIZE 32 +#define WRITEBUFFER_MAXSIZE 32 + +/* Note that the READBUFFER_MAXSIZE should be large enough to hold any single + result entity as defined in nslcd.h because the get*ent() functions expect + to be able to tio_reset() the stream to re-read the current entity. + Since group entities can grow arbitrarily large, this setting limits the + number of users that can be put in a group. */ + +/* returns a socket to the server or NULL on error (see errno), + socket should be closed with fclose() */ +TFILE *nslcd_client_open() +{ + int sock; + struct sockaddr_un addr; + struct timeval readtimeout,writetimeout; + TFILE *fp; + /* create a socket */ + if ( (sock=socket(PF_UNIX,SOCK_STREAM,0))<0 ) + return NULL; + /* create socket address structure */ + memset(&addr,0,sizeof(struct sockaddr_un)); + addr.sun_family=AF_UNIX; + strncpy(addr.sun_path,NSLCD_SOCKET,sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path)-1]='\0'; + /* connect to the socket */ + if (connect(sock,(struct sockaddr *)&addr,(socklen_t)(sizeof(addr.sun_family)+strlen(addr.sun_path)))<0) + { + (void)close(sock); + return NULL; + } + /* set the timeouts */ + readtimeout.tv_sec=60; /* looking up stuff may take some time */ + readtimeout.tv_usec=0; + writetimeout.tv_sec=10; /* nslcd could be loaded with requests */ + writetimeout.tv_usec=0; + /* create a stream object */ + if ((fp=tio_fdopen(sock,&readtimeout,&writetimeout, + READBUFFER_MINSIZE,READBUFFER_MAXSIZE, + WRITEBUFFER_MINSIZE,WRITEBUFFER_MAXSIZE))==NULL) + { + (void)close(sock); + return NULL; + } + /* return the stream */ + return fp; +} diff --git a/common/nslcd-prot.h b/common/nslcd-prot.h new file mode 100644 index 0000000..1252158 --- /dev/null +++ b/common/nslcd-prot.h @@ -0,0 +1,358 @@ +/* + nslcd-prot.h - helper macros for reading and writing in protocol streams + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMMON__NSLCD_PROT_H +#define COMMON__NSLCD_PROT_H 1 + +#include "tio.h" + +/* If you use these macros you should define the following macros to + handle error conditions (these marcos should clean up and return from the + function): + ERROR_OUT_WRITEERROR(fp) + ERROR_OUT_READERROR(fp) + ERROR_OUT_BUFERROR(fp) + ERROR_OUT_NOSUCCESS(fp) */ + + +/* Debugging marcos that can be used to enable detailed protocol logging, + pass -DDEBUG_PROT to do overall protocol debugging, and -DDEBUG_PROT_DUMP + to dump the actual bytestream. */ + +#ifdef DEBUG_PROT +/* define a debugging macro to output logging */ +#include +#include +#define DEBUG_PRINT(fmt,arg) \ + fprintf(stderr,"%s:%d:%s: " fmt "\n",__FILE__,__LINE__,__PRETTY_FUNCTION__,arg); +#else /* DEBUG_PROT */ +/* define an empty debug macro to disable logging */ +#define DEBUG_PRINT(fmt,arg) +#endif /* not DEBUG_PROT */ + +#ifdef DEBUG_PROT_DUMP +/* define a debugging macro to output detailed logging */ +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ +static void debug_dump(const void *ptr,size_t size) +{ + int i; + for (i=0;i0) \ + { WRITE(fp,(str),tmpint32); } \ + } + +#define WRITE_STRINGLIST(fp,arr) \ + if ((arr)==NULL) \ + { \ + DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d",0); \ + WRITE_INT32(fp,0); \ + } \ + else \ + { \ + /* first determin length of array */ \ + for (tmp3int32=0;(arr)[tmp3int32]!=NULL;tmp3int32++) \ + /*noting*/ ; \ + /* write number of strings */ \ + DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d",(int)tmp3int32); \ + WRITE_TYPE(fp,tmp3int32,int32_t); \ + /* write strings */ \ + for (tmp2int32=0;tmp2int32=sizeof(buffer)) \ + { \ + /* will not fit */ \ + tmpint32=(tmpint32-sizeof(buffer))+1; \ + DEBUG_PRINT("READ : buffer %d bytes too small",tmpint32); \ + ERROR_OUT_BUFERROR(fp); \ + } \ + /* read string from the stream */ \ + if (tmpint32>0) \ + { READ(fp,buffer,(size_t)tmpint32); } \ + /* null-terminate string in buffer */ \ + buffer[tmpint32]='\0'; \ + DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" string=\"%s\"",buffer); + + +/* READ BUF macros that read data into a pre-allocated buffer. + these macros may require the availability of the following + variables: + int32_t tmpint32; - temporary variable + char *buffer; - pointer to a buffer for reading strings + size_t buflen; - the size of the buffer + size_t bufptr; - the current position in the buffer + */ + +/* current position in the buffer */ +#define BUF_CUR \ + (buffer+bufptr) + +/* check that the buffer has sz bytes left in it */ +#define BUF_CHECK(fp,sz) \ + if ((bufptr+(size_t)(sz))>buflen) \ + { \ + /* will not fit */ \ + tmpint32=bufptr+(sz)-(buflen); \ + DEBUG_PRINT("READ : buffer %d bytes too small",tmpint32); \ + ERROR_OUT_BUFERROR(fp); \ + } + +/* move the buffer pointer */ +#define BUF_SKIP(sz) \ + bufptr+=(size_t)(sz); + +/* move BUF_CUR foreward so that it is aligned to the specified + type width */ +#define BUF_ALIGN(fp,type) \ + /* figure out number of bytes to skip foreward */ \ + tmp2int32=(sizeof(type)-((BUF_CUR-(char *)NULL)%sizeof(type)))%sizeof(type); \ + /* check and skip */ \ + BUF_CHECK(fp,tmp2int32); \ + BUF_SKIP(tmp2int32); + +/* allocate a piece of the buffer to store an array in */ +#define BUF_ALLOC(fp,ptr,type,num) \ + /* align to the specified type width */ \ + BUF_ALIGN(fp,type); \ + /* check that we have enough room */ \ + BUF_CHECK(fp,(size_t)(num)*sizeof(type)); \ + /* store the pointer */ \ + (ptr)=(type *)BUF_CUR; \ + /* reserve the space */ \ + BUF_SKIP((size_t)(num)*sizeof(type)); + +/* read a binary blob into the buffer */ +#define READ_BUF(fp,ptr,sz) \ + /* check that there is enough room and read */ \ + BUF_CHECK(fp,sz); \ + READ(fp,BUF_CUR,(size_t)sz); \ + /* store pointer and skip */ \ + (ptr)=BUF_CUR; \ + BUF_SKIP(sz); + +/* read string in the buffer (using buffer, buflen and bufptr) + and store the actual location of the string in field */ +#define READ_BUF_STRING(fp,field) \ + /* read the size of the string */ \ + READ_TYPE(fp,tmpint32,int32_t); \ + DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" strlen=%d",tmpint32); \ + /* check if read would fit */ \ + BUF_CHECK(fp,tmpint32+1); \ + /* read string from the stream */ \ + if (tmpint32>0) \ + { READ(fp,BUF_CUR,(size_t)tmpint32); } \ + /* null-terminate string in buffer */ \ + BUF_CUR[tmpint32]='\0'; \ + DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" string=\"%s\"",BUF_CUR); \ + /* prepare result */ \ + (field)=BUF_CUR; \ + BUF_SKIP(tmpint32+1); + +/* read an array from a stram and store it as a null-terminated + array list (size for the array is allocated) */ +#define READ_BUF_STRINGLIST(fp,arr) \ + /* read the number of entries */ \ + READ_TYPE(fp,tmp3int32,int32_t); \ + DEBUG_PRINT("READ_STRLST: var="__STRING(arr)" num=%d",(int)tmp3int32); \ + /* allocate room for *char[num+1] */ \ + BUF_ALLOC(fp,arr,char *,tmp3int32+1); \ + /* read all entries */ \ + for (tmp2int32=0;tmp2int32 +#include +#include +#include + +#include "set.h" +#include "dict.h" + +/* + The SET object is just a DICT which is passed around. The value + for each entry in the dict is just the pointer to the dict. + Another API is provided to give it a more set-like interface. +*/ + +SET *set_new(void) +{ + return (SET *)dict_new(); +} + +int set_add(SET *set,const char *value) +{ + return dict_put((DICT *)set,value,set); +} + +char *set_pop(SET *set) +{ + const char *key; + char *value; + key=dict_getany((DICT *)set); + if (key==NULL) + return NULL; /* no more entries in set */ + /* remove the entry from the dict and return a copy */ + value=strdup(key); + dict_put((DICT *)set,key,NULL); + return value; +} + +int set_contains(SET *set,const char *value) +{ + return dict_get((DICT *)set,value)!=NULL; +} + +void set_free(SET *set) +{ + dict_free((DICT *)set); +} + +const char **set_tolist(SET *set) +{ + return dict_keys((DICT *)set); +} diff --git a/common/set.h b/common/set.h new file mode 100644 index 0000000..d57c3db --- /dev/null +++ b/common/set.h @@ -0,0 +1,64 @@ +/* + set.h - set functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMMON__SET_H +#define COMMON__SET_H + +#include "compat/attrs.h" + +/* + These functions provide a set of strings in an unordered + collection. +*/ +typedef struct set SET; + +/* Create a new instance of a set. Returns NULL + in case of memory allocation errors. */ +SET *set_new(void) + LIKE_MALLOC MUST_USE; + +/* Add a string in the set. The value is duplicated + and can be reused by the caller. + This function returns non-0 in case of memory allocation + errors. All value comparisons are case sensitive. */ +int set_add(SET *set,const char *value); + +/* Return non-zero if the value is in the set. + All value comparisons are case sensitive. */ +int set_contains(SET *set,const char *value) + MUST_USE; + +/* Get an element from the set and removes it from the set. + Returns NULL on an empty set. A copy of the string in the set + is returned, the caller should use free() to free it. */ +char *set_pop(SET *set); + +/* Remove the set from memory. All allocated storage + for the set and the values is freed. */ +void set_free(SET *set); + +/* Return the content of the set as a list of strings. + The caller should free the memory with a single call to free(). */ +const char **set_tolist(SET *set) + MUST_USE; + +#endif /* COMMON__SET_H */ diff --git a/common/tio.c b/common/tio.c new file mode 100644 index 0000000..e323e1e --- /dev/null +++ b/common/tio.c @@ -0,0 +1,511 @@ +/* + tio.c - timed io functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tio.h" + +/* for platforms that don't have ETIME use ETIMEDOUT */ +#ifndef ETIME +#define ETIME ETIMEDOUT +#endif /* ETIME */ + +/* structure that holds a buffer + the buffer contains the data that is between the application and the + file descriptor that is used for efficient transfer + the buffer is built up as follows: + |.....********......| + ^start ^size + ^--len--^ */ +struct tio_buffer { + uint8_t *buffer; + size_t size; /* the size of the buffer */ + size_t maxsize; /* the maximum size of the buffer */ + size_t start; /* the start of the data (before start is unused) */ + size_t len; /* size of the data (from the start) */ +}; + +/* structure that holds all the state for files */ +struct tio_fileinfo { + int fd; + struct tio_buffer readbuffer; + struct tio_buffer writebuffer; + struct timeval readtimeout; + struct timeval writetimeout; + int read_resettable; /* whether the tio_reset() function can be called */ +#ifdef DEBUG_TIO_STATS + /* this is used to collect statistics on the use of the streams + and can be used to tune the buffer sizes */ + size_t byteswritten; + size_t bytesread; +#endif /* DEBUG_TIO_STATS */ +}; + +/* add the second timeval to the first modifing the first */ +static inline void tio_tv_add(struct timeval *tv1, const struct timeval *tv2) +{ + /* BUG: we hope that this does not overflow */ + tv1->tv_usec+=tv2->tv_usec; + if (tv1->tv_usec>=1000000) + { + tv1->tv_usec-=1000000; + tv1->tv_sec+=1; + } + tv1->tv_sec+=tv2->tv_sec; +} + +/* build a timeval for comparison to when the operation should be finished */ +static inline void tio_tv_prepare(struct timeval *deadline, const struct timeval *timeout) +{ + if (gettimeofday(deadline,NULL)) + { + /* just blank it in case of errors */ + deadline->tv_sec=0; + deadline->tv_usec=0; + return; + } + tio_tv_add(deadline,timeout); +} + +/* update the timeval to the value that is remaining before deadline + returns non-zero if there is no more time before the deadline */ +static inline int tio_tv_remaining(struct timeval *tv, const struct timeval *deadline) +{ + /* get the current time */ + if (gettimeofday(tv,NULL)) + { + /* 1 second default if gettimeofday() is broken */ + tv->tv_sec=1; + tv->tv_usec=0; + return 0; + } + /* check if we're too late */ + if ( (tv->tv_sec>deadline->tv_sec) || + ( (tv->tv_sec==deadline->tv_sec) && (tv->tv_usec>deadline->tv_usec) ) ) + return -1; + /* update tv */ + tv->tv_sec=deadline->tv_sec-tv->tv_sec; + if (tv->tv_usec<=deadline->tv_usec) + tv->tv_usec=deadline->tv_usec-tv->tv_usec; + else + { + tv->tv_sec--; + tv->tv_usec=1000000+deadline->tv_usec-tv->tv_usec; + } + return 0; +} + +/* open a new TFILE based on the file descriptor */ +TFILE *tio_fdopen(int fd,struct timeval *readtimeout,struct timeval *writetimeout, + size_t initreadsize,size_t maxreadsize, + size_t initwritesize,size_t maxwritesize) +{ + struct tio_fileinfo *fp; + fp=(struct tio_fileinfo *)malloc(sizeof(struct tio_fileinfo)); + if (fp==NULL) + return NULL; + fp->fd=fd; + /* initialize read buffer */ + fp->readbuffer.buffer=(uint8_t *)malloc(initreadsize); + if (fp->readbuffer.buffer==NULL) + { + free(fp); + return NULL; + } + fp->readbuffer.size=initreadsize; + fp->readbuffer.maxsize=maxreadsize; + fp->readbuffer.start=0; + fp->readbuffer.len=0; + /* initialize write buffer */ + fp->writebuffer.buffer=(uint8_t *)malloc(initwritesize); + if (fp->writebuffer.buffer==NULL) + { + free(fp->readbuffer.buffer); + free(fp); + return NULL; + } + fp->writebuffer.size=initwritesize; + fp->writebuffer.maxsize=maxwritesize; + fp->writebuffer.start=0; + fp->writebuffer.len=0; + /* initialize other attributes */ + fp->readtimeout.tv_sec=readtimeout->tv_sec; + fp->readtimeout.tv_usec=readtimeout->tv_usec; + fp->writetimeout.tv_sec=writetimeout->tv_sec; + fp->writetimeout.tv_usec=writetimeout->tv_usec; + fp->read_resettable=0; +#ifdef DEBUG_TIO_STATS + fp->byteswritten=0; + fp->bytesread=0; +#endif /* DEBUG_TIO_STATS */ + return fp; +} + +/* wait for any activity on the specified file descriptor using + the specified deadline */ +static int tio_select(TFILE *fp, int readfd, const struct timeval *deadline) +{ + struct timeval tv; + fd_set fdset; + int rv; + while (1) + { + /* prepare our filedescriptorset */ + FD_ZERO(&fdset); + FD_SET(fp->fd,&fdset); + /* figure out the time we need to wait */ + if (tio_tv_remaining(&tv,deadline)) + { + errno=ETIME; + return -1; + } + /* wait for activity */ + if (readfd) + { + /* santiy check for moving clock */ + if (tv.tv_sec>fp->readtimeout.tv_sec) + tv.tv_sec=fp->readtimeout.tv_sec; + rv=select(FD_SETSIZE,&fdset,NULL,NULL,&tv); + } + else + { + /* santiy check for moving clock */ + if (tv.tv_sec>fp->writetimeout.tv_sec) + tv.tv_sec=fp->writetimeout.tv_sec; + rv=select(FD_SETSIZE,NULL,&fdset,NULL,&tv); + } + if (rv>0) + return 0; /* we have activity */ + else if (rv==0) + { + /* no file descriptors were available within the specified time */ + errno=ETIME; + return -1; + } + else if (errno!=EINTR) + /* some error ocurred */ + return -1; + /* we just try again on EINTR */ + } +} + +/* do a read on the file descriptor, returning the data in the buffer + if no data was read in the specified time an error is returned */ +int tio_read(TFILE *fp, void *buf, size_t count) +{ + struct timeval deadline; + int rv; + uint8_t *tmp; + size_t newsz; + /* have a more convenient storage type for the buffer */ + uint8_t *ptr=(uint8_t *)buf; + /* build a time by which we should be finished */ + tio_tv_prepare(&deadline,&(fp->readtimeout)); + /* loop until we have returned all the needed data */ + while (1) + { + /* check if we have enough data in the buffer */ + if (fp->readbuffer.len >= count) + { + if (count>0) + { + if (ptr!=NULL) + memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,count); + /* adjust buffer position */ + fp->readbuffer.start+=count; + fp->readbuffer.len-=count; + } + return 0; + } + /* empty what we have and continue from there */ + if (fp->readbuffer.len>0) + { + if (ptr!=NULL) + { + memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.len); + ptr+=fp->readbuffer.len; + } + count-=fp->readbuffer.len; + fp->readbuffer.start+=fp->readbuffer.len; + fp->readbuffer.len=0; + } + /* after this point until the read fp->readbuffer.len is 0 */ + if (!fp->read_resettable) + { + /* the stream is not resettable, re-use the buffer */ + fp->readbuffer.start=0; + } + else if (fp->readbuffer.start>=(fp->readbuffer.size-4)) + { + /* buffer is running empty, try to grow buffer */ + if (fp->readbuffer.sizereadbuffer.maxsize) + { + newsz=fp->readbuffer.size*2; + if (newsz>fp->readbuffer.maxsize) + newsz=fp->readbuffer.maxsize; + tmp=realloc(fp->readbuffer.buffer,newsz); + if (tmp!=NULL) + { + fp->readbuffer.buffer=tmp; + fp->readbuffer.size=newsz; + } + } + /* if buffer still does not contain enough room, clear resettable */ + if (fp->readbuffer.start>=(fp->readbuffer.size-4)) + { + fp->readbuffer.start=0; + fp->read_resettable=0; + } + } + /* wait until we have input */ + if (tio_select(fp,1,&deadline)) + return -1; + /* read the input in the buffer */ + rv=read(fp->fd,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.size-fp->readbuffer.start); + /* check for errors */ + if (rv==0) + { + errno=ECONNRESET; + return -1; + } + else if ((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN)) + return -1; /* something went wrong with the read */ + /* skip the read part in the buffer */ + fp->readbuffer.len=rv; +#ifdef DEBUG_TIO_STATS + fp->bytesread+=rv; +#endif /* DEBUG_TIO_STATS */ + } +} + +/* Read and discard the specified number of bytes from the stream. */ +int tio_skip(TFILE *fp, size_t count) +{ + return tio_read(fp,NULL,count); +} + +/* the caller has assured us that we can write to the file descriptor + and we give it a shot */ +static int tio_writebuf(TFILE *fp) +{ + int rv; + /* write the buffer */ +#ifdef MSG_NOSIGNAL + rv=send(fp->fd,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len,MSG_NOSIGNAL); +#else /* not MSG_NOSIGNAL */ + /* on platforms that cannot use send() with masked signals, we change the + signal mask and change it back after the write (note that there is a + race condition here) */ + struct sigaction act,oldact; + /* set up sigaction */ + memset(&act,0,sizeof(struct sigaction)); + act.sa_sigaction=NULL; + act.sa_handler=SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags=SA_RESTART; + /* ignore SIGPIPE */ + if (sigaction(SIGPIPE,&act,&oldact)!=0) + return -1; /* error setting signal handler */ + /* write the buffer */ + rv=write(fp->fd,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len); + /* restore the old handler for SIGPIPE */ + if (sigaction(SIGPIPE,&oldact,NULL)!=0) + return -1; /* error restoring signal handler */ +#endif + /* check for errors */ + if ((rv==0)||((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN))) + return -1; /* something went wrong with the write */ + /* skip the written part in the buffer */ + if (rv>0) + { + fp->writebuffer.start+=rv; + fp->writebuffer.len-=rv; +#ifdef DEBUG_TIO_STATS + fp->byteswritten+=rv; +#endif /* DEBUG_TIO_STATS */ + /* reset start if len is 0 */ + if (fp->writebuffer.len==0) + fp->writebuffer.start=0; + /* move contents of the buffer to the front if it will save enough room */ + if (fp->writebuffer.start>=(fp->writebuffer.size/4)) + { + memmove(fp->writebuffer.buffer,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len); + fp->writebuffer.start=0; + } + } + return 0; +} + +/* write all the data in the buffer to the stream */ +int tio_flush(TFILE *fp) +{ + struct timeval deadline; + /* build a time by which we should be finished */ + tio_tv_prepare(&deadline,&(fp->writetimeout)); + /* loop until we have written our buffer */ + while (fp->writebuffer.len > 0) + { + /* wait until we can write */ + if (tio_select(fp,0,&deadline)) + return -1; + /* write one block */ + if (tio_writebuf(fp)) + return -1; + } + return 0; +} + +/* try a single write of data in the buffer if the file descriptor + will accept data */ +static int tio_flush_nonblock(TFILE *fp) +{ + struct timeval tv; + fd_set fdset; + int rv; + /* prepare our filedescriptorset */ + FD_ZERO(&fdset); + FD_SET(fp->fd,&fdset); + /* set the timeout to 0 to poll */ + tv.tv_sec=0; + tv.tv_usec=0; + /* wait for activity */ + rv=select(FD_SETSIZE,NULL,&fdset,NULL,&tv); + /* check if any file descriptors were ready (timeout) or we were + interrupted */ + if ((rv==0)||((rv<0)&&(errno==EINTR))) + return 0; + /* any other errors? */ + if (rv<0) + return -1; + /* so file descriptor will accept writes */ + return tio_writebuf(fp); +} + +int tio_write(TFILE *fp, const void *buf, size_t count) +{ + size_t fr; + uint8_t *tmp; + size_t newsz; + const uint8_t *ptr=(const uint8_t *)buf; + /* keep filling the buffer until we have bufferred everything */ + while (count>0) + { + /* figure out free size in buffer */ + fr=fp->writebuffer.size-(fp->writebuffer.start+fp->writebuffer.len); + if (count <= fr) + { + /* the data fits in the buffer */ + memcpy(fp->writebuffer.buffer+fp->writebuffer.start+fp->writebuffer.len,ptr,count); + fp->writebuffer.len+=count; + return 0; + } + else if (fr > 0) + { + /* fill the buffer with data that will fit */ + memcpy(fp->writebuffer.buffer+fp->writebuffer.start+fp->writebuffer.len,ptr,fr); + fp->writebuffer.len+=fr; + ptr+=fr; + count-=fr; + } + /* try to flush some of the data that is in the buffer */ + if (tio_flush_nonblock(fp)) + return -1; + /* if we have room now, try again */ + if (fp->writebuffer.size>(fp->writebuffer.start+fp->writebuffer.len)) + continue; + /* try to grow the buffer */ + if (fp->writebuffer.sizewritebuffer.maxsize) + { + newsz=fp->writebuffer.size*2; + if (newsz>fp->writebuffer.maxsize) + newsz=fp->writebuffer.maxsize; + tmp=realloc(fp->writebuffer.buffer,newsz); + if (tmp!=NULL) + { + fp->writebuffer.buffer=tmp; + fp->writebuffer.size=newsz; + continue; /* try again */ + } + } + /* write the buffer to the stream */ + if (tio_flush(fp)) + return -1; + } + return 0; +} + +int tio_close(TFILE *fp) +{ + int retv; + /* write any buffered data */ + retv=tio_flush(fp); +#ifdef DEBUG_TIO_STATS + /* dump statistics to stderr */ + fprintf(stderr,"DEBUG_TIO_STATS READ=%d WRITTEN=%d\n",fp->bytesread,fp->byteswritten); +#endif /* DEBUG_TIO_STATS */ + /* close file descriptor */ + if (close(fp->fd)) + retv=-1; + /* free any allocated buffers */ + free(fp->readbuffer.buffer); + free(fp->writebuffer.buffer); + /* free the tio struct itself */ + free(fp); + /* return the result of the earlier operations */ + return retv; +} + +void tio_mark(TFILE *fp) +{ + /* move any data in the buffer to the start of the buffer */ + if ((fp->readbuffer.start>0)&&(fp->readbuffer.len>0)) + { + memmove(fp->readbuffer.buffer,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.len); + fp->readbuffer.start=0; + } + /* mark the stream as resettable */ + fp->read_resettable=1; +} + +int tio_reset(TFILE *fp) +{ + /* check if the stream is (still) resettable */ + if (!fp->read_resettable) + return -1; + /* reset the buffer */ + fp->readbuffer.len+=fp->readbuffer.start; + fp->readbuffer.start=0; + return 0; +} diff --git a/common/tio.h b/common/tio.h new file mode 100644 index 0000000..22c099c --- /dev/null +++ b/common/tio.h @@ -0,0 +1,81 @@ +/* + tio.h - timed io functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +/* + + TODO: Add some documentation here. + + the SIGPIPE signal should be ignored (is ignored in this code) + + This library is not thread safe. You cannot share TFILE objects between + threads and expect to be able to read and write from them in different + threads. All the state is in the TFILE object so calls to this library on + different objects can be done in parallel. + +*/ + +#ifndef COMMON__TIO_H +#define COMMON__TIO_H + +#include +#include + +#include "compat/attrs.h" + +/* This is a generic file handle used for reading and writing + (something like FILE from stdio.h). */ +typedef struct tio_fileinfo TFILE; + +/* Open a new TFILE based on the file descriptor. The timeout is set for any + operation. The timeout value is copied so may be dereferenced after the + call. */ +TFILE *tio_fdopen(int fd,struct timeval *readtimeout,struct timeval *writetimeout, + size_t initreadsize,size_t maxreadsize, + size_t initwritesize,size_t maxwritesize) + LIKE_MALLOC MUST_USE; + +/* Read the specified number of bytes from the stream. */ +int tio_read(TFILE *fp,void *buf,size_t count); + +/* Read and discard the specified number of bytes from the stream. */ +int tio_skip(TFILE *fp,size_t count); + +/* Write the specified buffer to the stream. */ +int tio_write(TFILE *fp,const void *buf,size_t count); + +/* Write out all buffered data to the stream. */ +int tio_flush(TFILE *fp); + +/* Flush the streams and closes the underlying file descriptor. */ +int tio_close(TFILE *fp); + +/* Store the current position in the stream so that we can jump back to it + with the tio_reset() function. */ +void tio_mark(TFILE *fp); + +/* Rewinds the stream to the point set by tio_mark(). Note that this only + resets the read stream and not the write stream. This function returns + whether the reset was successful (this function may fail if the buffers + were full). */ +int tio_reset(TFILE *fp); + +#endif /* COMMON__TIO_H */ diff --git a/compat/Makefile.am b/compat/Makefile.am new file mode 100644 index 0000000..9ff1204 --- /dev/null +++ b/compat/Makefile.am @@ -0,0 +1,34 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2008, 2009, 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LIBRARIES = libcompat.a + +AM_CPPFLAGS=-I$(top_srcdir) +AM_CFLAGS = -fPIC + +EXTRA_DIST = getopt_long.c getopt_long.h \ + daemon.c daemon.h \ + ether.c ether.h \ + strndup.c strndup.h \ + nss_compat.h \ + ldap_compat.h pagectrl.c ldap_passwd_s.c ldap_initialize.c \ + pam_compat.h pam_get_authtok.c pam_prompt.c + +libcompat_a_SOURCES = getpeercred.c getpeercred.h +libcompat_a_LIBADD = @LIBOBJS@ diff --git a/compat/attrs.h b/compat/attrs.h new file mode 100644 index 0000000..0bc0f30 --- /dev/null +++ b/compat/attrs.h @@ -0,0 +1,91 @@ +/* + attrs.h - wrapper macros for the gcc __attribute__(()) directive + + Copyright (C) 2007, 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__ATTRS_H +#define COMPAT__ATTRS_H 1 + +/* macro for testing the version of GCC */ +#define GCC_VERSION(major,minor) \ + ((__GNUC__ > (major)) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) + +/* These are macros to use some gcc-specific flags in case the're available + and otherwise define them to empty strings. This allows us to give + the compiler some extra information. + See http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html + for a list of attributes supported by gcc */ + +/* this is used to flag function parameters that are not used in the function + body. */ +#if GCC_VERSION(3,0) +#define UNUSED(x) x __attribute__((__unused__)) +#else +#define UNUSED(x) x +#endif + +/* this is used to add extra format checking to the function calls as if this + was a printf()-like function */ +#if GCC_VERSION(3,0) +#define LIKE_PRINTF(format_idx,arg_idx) \ + __attribute__((__format__(__printf__,format_idx,arg_idx))) +#else +#define LIKE_PRINTF(format_idx,arg_idx) /* no attribute */ +#endif + +/* indicates that the function is "pure": it's result is purely based on + the parameters and has no side effects or used static data */ +#if GCC_VERSION(3,0) +#define PURE __attribute__((__pure__)) +#else +#define PURE /* no attribute */ +#endif + +/* the function returns a new data structure that has been freshly + allocated */ +#if GCC_VERSION(3,0) +#define LIKE_MALLOC __attribute__((__malloc__)) +#else +#define LIKE_MALLOC /* no attribute */ +#endif + +/* the function's return value should be used by the caller */ +#if GCC_VERSION(3,4) +#define MUST_USE __attribute__((__warn_unused_result__)) +#else +#define MUST_USE /* no attribute */ +#endif + +/* the function's return value should be used by the caller */ +#if GCC_VERSION(2,5) +#define NORETURN __attribute__((__noreturn__)) +#else +#define NORETURN /* no attribute */ +#endif + +/* define __STRING if it's not yet defined */ +#ifndef __STRING +#ifdef __STDC__ +#define __STRING(x) #x +#else /* __STDC__ */ +#define __STRING(x) "x" +#endif /* not __STDC__ */ +#endif /* not __STRING */ + +#endif /* not COMPAT__ATTRS_H */ diff --git a/compat/daemon.c b/compat/daemon.c new file mode 100644 index 0000000..cd8e0f3 --- /dev/null +++ b/compat/daemon.c @@ -0,0 +1,71 @@ +/* + daemon.c - implementation of daemon() for systems that lack it + + Copyright (C) 2002, 2003, 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "daemon.h" + +#include +#include +#include +#include + +int daemon(int nochdir,int noclose) +{ + /* change directory */ + if (!nochdir) + if (chdir("/")!=0) + return -1; + /* fork() and exit() to detach from the parent process */ + switch (fork()) + { + case 0: /* we are the child */ + break; + case -1: /* we are the parent, but have an error */ + return -1; + default: /* we are the parent and we're done*/ + _exit(0); + } + /* become process leader */ + if (setsid()<0) + { + return -1; + } + /* fork again so we cannot allocate a pty */ + switch (fork()) + { + case 0: /* we are the child */ + break; + case -1: /* we are the parent, but have an error */ + return -1; + default: /* we are the parent and we're done*/ + _exit(0); + } + /* close stdin, stdout and stderr and reconnect to /dev/null */ + if (!noclose) + { + close(0); /* stdin */ + close(1); /* stdout */ + close(2); /* stderr */ + open("/dev/null",O_RDWR); /* stdin, fd=0 */ + dup(0); /* stdout, fd=1 */ + dup(0); /* stderr, fd=2 */ + } + return 0; +} diff --git a/compat/daemon.h b/compat/daemon.h new file mode 100644 index 0000000..5a2b02a --- /dev/null +++ b/compat/daemon.h @@ -0,0 +1,34 @@ +/* + daemon.h - definition of daemon() for systems that lack it + + Copyright (C) 2002, 2003, 2008, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__DAEMON_H +#define COMPAT__DAEMON_H 1 + +#include + +#if !HAVE_DECL_DAEMON +/* we define daemon() here because on some platforms the function is + undefined: deamonize process, optionally chdir to / and optionally + close stdin, strdout and stderr and redirect them to /dev/null */ +int daemon(int nochdir,int noclose); +#endif /* not HAVE_DECL_DAEMON */ + +#endif /* not COMPAT__DAEMON_H */ diff --git a/compat/ether.c b/compat/ether.c new file mode 100644 index 0000000..ec42909 --- /dev/null +++ b/compat/ether.c @@ -0,0 +1,60 @@ +/* + ether.c - useful ethernet functions for systems lacking those + + Copyright (C) 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_NETINET_ETHER_H +#include +#endif + +#include "ether.h" + +/* these functions are not really reentrant */ + +#ifndef HAVE_ETHER_NTOA_R +char *ether_ntoa_r(const struct ether_addr *addr,char *buf) +{ + char *tmp; + tmp=ether_ntoa(addr); + if (tmp==NULL) + return NULL; + strcpy(buf,tmp); + return buf; +} +#endif /* not HAVE_ETHER_NTOA_R */ + +#ifndef HAVE_ETHER_ATON_R +struct ether_addr *ether_aton_r(const char *asc,struct ether_addr *addr) +{ + struct ether_addr *tmp; + tmp=ether_aton(asc); + if (tmp==NULL) + return NULL; + memcpy(addr,tmp,sizeof(struct ether_addr)); + return addr; +} +#endif /* not HAVE_ETHER_ATON_R */ diff --git a/compat/ether.h b/compat/ether.h new file mode 100644 index 0000000..ac328da --- /dev/null +++ b/compat/ether.h @@ -0,0 +1,64 @@ +/* + ether.h - ethernet definitions for systems lacking those + + Copyright (C) 2008, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__ETHER_H +#define COMPAT__ETHER_H 1 + +#include +#include +#include +#include +#include +#ifdef HAVE_NETINET_ETHER_H +#include +#endif + +#ifndef HAVE_STRUCT_ETHER_ADDR +struct ether_addr { + uint8_t ether_addr_octet[6]; +}; +#endif /* not HAVE_STRUCT_ETHER_ADDR */ + +#ifndef HAVE_ETHER_NTOA_R +char *ether_ntoa_r(const struct ether_addr *addr,char *buf); +#endif /* not HAVE_ETHER_NTOA_R */ + +#ifndef HAVE_ETHER_ATON_R +struct ether_addr *ether_aton_r(const char *asc,struct ether_addr *addr); +#endif /* not HAVE_ETHER_ATON_R */ + +#ifdef HAVE_ETHER_NTOA +#if !HAVE_DECL_ETHER_NTOA +/* we define ether_ntoa() here because on some platforms the function is + undefined */ +extern char *ether_ntoa(const struct ether_addr *e); +#endif /* not HAVE_DECL_ETHER_NTOA */ +#endif /* HAVE_ETHER_NTOA */ + +#ifdef HAVE_ETHER_ATON +#if !HAVE_DECL_ETHER_ATON +/* we define ether_aton() here because on some platforms the function is + undefined */ +extern struct ether_addr *ether_aton(const char *s); +#endif /* not HAVE_DECL_ETHER_ATON */ +#endif /* HAVE_ETHER_ATON */ + +#endif /* not COMPAT__ETHER_H */ diff --git a/compat/getopt_long.c b/compat/getopt_long.c new file mode 100644 index 0000000..a276dd5 --- /dev/null +++ b/compat/getopt_long.c @@ -0,0 +1,92 @@ +/* + getopt_long.c - implementation of getopt_long() for systems that lack it + + Copyright (C) 2001, 2002, 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include +#include +#include + +#include "getopt_long.h" + +/* this is a (poor) getopt_long() replacement for systems that don't have it + (getopt_long() is generaly a GNU extention) + this implementation is by no meens flawless, especialy the optional arguments + to options and options following filenames is not quite right, allso + minimal error checking is provided + */ +int getopt_long(int argc,char * const argv[], + const char *optstring, + const struct option *longopts,int *longindex) +{ + int i; /* for looping through options */ + int l; /* for length */ + + /* first check if there realy is a -- option */ + if ( (optind>0)&&(optind +#include +#include +#include +#ifdef HAVE_SYS_UCRED_H +#include +#endif /* HAVE SYS_UCRED_H */ +#include +#ifdef HAVE_UCRED_H +#include +#endif /* HAVE_UCRED_H */ + +#include "getpeercred.h" + +/* Note: most of this code is untested, except for the first + implementation (it may even fail to compile) */ + +int getpeercred(int sock,uid_t *uid,gid_t *gid,pid_t *pid) +{ +#if defined(SO_PEERCRED) + socklen_t l; + struct ucred cred; + /* initialize client information (in case getsockopt() breaks) */ + cred.pid=(pid_t)0; + cred.uid=(uid_t)-1; + cred.gid=(gid_t)-1; + /* look up process information from peer */ + l=(socklen_t)sizeof(struct ucred); + if (getsockopt(sock,SOL_SOCKET,SO_PEERCRED,&cred,&l) < 0) + return -1; /* errno already set */ + /* return the data */ + if (uid!=NULL) *uid=cred.uid; + if (gid!=NULL) *gid=cred.gid; + if (pid!=NULL) *pid=cred.pid; + return 0; +#elif defined(LOCAL_PEERCRED) + socklen_t l; + struct xucred cred; + /* look up process information from peer */ + l=(socklen_t)sizeof(struct xucred); + if (getsockopt(sock,0,LOCAL_PEERCRED,&cred,&l) < 0) + return -1; /* errno already set */ + if (cred.cr_version!=XUCRED_VERSION) + { + errno=EINVAL; + return -1; + } + /* return the data */ + if (uid!=NULL) *uid=cred.cr_uid; + if (gid!=NULL) *gid=cred.cr_gid; + if (pid!=NULL) *pid=(pid_t)-1; + return 0; +#elif defined(HAVE_GETPEERUCRED) + ucred_t *cred=NULL; + if (getpeerucred(sock,&cred)) + return -1; + /* save the data */ + if (uid!=NULL) *uid=ucred_geteuid(cred); + if (gid!=NULL) *gid=ucred_getegid(cred); + if (pid!=NULL) *pid=ucred_getpid(cred); + /* free cred and return */ + ucred_free(cred); + return 0; +#elif defined(HAVE_GETPEEREID) + uid_t tuid; + gid_t tgid; + if (uid==NULL) uid=&tuid; + if (gid==NULL) gid=&tguid; + if (getpeereid(sock,uid,gid)) + return -1; + /* return the data */ + if (uid!=NULL) *uid=cred.uid; + if (gid!=NULL) *gid=cred.gid; + if (pid!=NULL) *pid=-1; /* we return a -1 pid because we have no usable pid */ + return 0; +#else + /* nothing found that is supported */ + errno=ENOSYS; + return -1; +#endif +} diff --git a/compat/getpeercred.h b/compat/getpeercred.h new file mode 100644 index 0000000..afa049f --- /dev/null +++ b/compat/getpeercred.h @@ -0,0 +1,35 @@ +/* + getpeercred.h - function for determining information about the + other end of a unix socket + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__GETPEERCRED_H +#define COMPAT__GETPEERCRED_H 1 + +/* This function tries to determine the (effective) user id, group id + and process id of the other end of the specified socket. + Any of the uid, gid and pid paramaters may be NULL to not update + that information. + On success, zero is returned. On error, -1 is returned, and errno + is set appropriately. */ +int getpeercred(int sock,uid_t *uid,gid_t *gid,pid_t *pid); + +#endif /* not COMPAT__GETPEERCRED_H */ diff --git a/compat/ldap_compat.h b/compat/ldap_compat.h new file mode 100644 index 0000000..322e232 --- /dev/null +++ b/compat/ldap_compat.h @@ -0,0 +1,65 @@ +/* + ldap_compat.h - provide a replacement definitions for some ldap functions + + Copyright (C) 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__LDAP_COMPAT_H +#define COMPAT__LDAP_COMPAT_H 1 + +#include +#include + +/* compatibility macros */ +#ifndef LDAP_CONST +#define LDAP_CONST const +#endif /* not LDAP_CONST */ +#ifndef LDAP_MSG_ONE +#define LDAP_MSG_ONE 0x00 +#endif /* not LDAP_MSG_ONE */ + +#ifndef HAVE_LDAP_INITIALIZE +/* provide a wrapper around ldap_init() if the system doesn't have + ldap_initialize() */ +int ldap_initialize(LDAP **ldp,const char *url); +#endif /* not HAVE_LDAP_INITIALIZE */ + +#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL +int ldap_create_page_control(LDAP *ld,unsigned long pagesize, + struct berval *cookiep,int iscritical, + LDAPControl **ctrlp); +#endif /* not HAVE_LDAP_CREATE_PAGE_CONTROL */ + +#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL +int ldap_parse_page_control(LDAP *ld,LDAPControl **ctrls, + unsigned long *list_countp, + struct berval **cookiep); +#endif /* not HAVE_LDAP_PARSE_PAGE_CONTROL */ + +#ifndef HAVE_LDAP_PASSWD_S +int ldap_passwd_s(LDAP *ld,struct berval *user,struct berval *oldpw, + struct berval *newpw,struct berval *newpasswd, + LDAPControl **sctrls,LDAPControl **cctrls); +#endif /* not HAVE_LDAP_PASSWD_S */ + +/* compatibility definition */ +#ifndef LDAP_SASL_QUIET +#define LDAP_SASL_QUIET 2U +#endif /* not LDAP_SASL_QUIET */ + +#endif /* COMPAT__LDAP_COMPAT_H */ diff --git a/compat/ldap_initialize.c b/compat/ldap_initialize.c new file mode 100644 index 0000000..d397784 --- /dev/null +++ b/compat/ldap_initialize.c @@ -0,0 +1,64 @@ +/* + ldap_initialize.c - replacement function for ldap_initialize() + + Copyright (C) 2009 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +/* also include deprecated LDAP functions for now */ +#define LDAP_DEPRECATED 1 + +#include +#include +#include +#include +#include + +#include "compat/ldap_compat.h" +#include "nslcd/log.h" + + +/* provide a wrapper around ldap_init() if the system doesn't have + ldap_initialize() */ +int ldap_initialize(LDAP **ldp,const char *url) +{ + char host[80]; + /* check schema part */ + if (strncasecmp(url,"ldap://",7)==0) + { + strncpy(host,url+7,sizeof(host)); + host[sizeof(host)-1]='\0'; + } + else if (strncasecmp(url,"ldaps://",8)==0) + { + strncpy(host,url+8,sizeof(host)); + host[sizeof(host)-1]='\0'; + } + else + { + log_log(LOG_ERR,"ldap_initialize(): schema not supported: %s",url); + exit(EXIT_FAILURE); + } + /* strip trailing slash */ + if ((strlen(host)>0)&&(host[strlen(host)-1]=='/')) + host[strlen(host)-1]='\0'; + /* call ldap_init() */ + *ldp=ldap_init(host,LDAP_PORT); + return (*ldp==NULL)?LDAP_OPERATIONS_ERROR:LDAP_SUCCESS; +} diff --git a/compat/ldap_passwd_s.c b/compat/ldap_passwd_s.c new file mode 100644 index 0000000..6fc5cff --- /dev/null +++ b/compat/ldap_passwd_s.c @@ -0,0 +1,107 @@ +/* + ldap_passwd_s.c - replacement function for ldap_passwd_s() + Parts of this file were based on parts of the pam_ldap library + (taken from _update_authtok() in pam_ldap.c). + + Copyright (C) 1998-2004 Luke Howard + Copyright (C) 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "compat/ldap_compat.h" +#include "compat/attrs.h" + +#ifndef LDAP_EXOP_MODIFY_PASSWD +#ifdef LDAP_EXOP_X_MODIFY_PASSWD +#define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD +#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID +#define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD LDAP_TAG_EXOP_X_MODIFY_PASSWD_OLD +#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW +#else /* not LDAP_EXOP_X_MODIFY_PASSWD */ +#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1" +#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U) +#define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U) +#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U) +#endif /* not LDAP_EXOP_X_MODIFY_PASSWD */ +#endif /* not LDAP_EXOP_MODIFY_PASSWD */ + +#ifndef LBER_USE_DER +#define LBER_USE_DER 1 +#endif /* not LBER_USE_DER */ + +#ifndef HAVE_BER_MEMFREE +#define ber_memfree free +#endif /* not HAVE_BER_MEMFREE */ + +#if !HAVE_DECL_LDAP_EXTENDED_OPERATION_S +/* we define this ourselves here because some LDAP header versions don't + seem to define this */ +extern int ldap_extended_operation_s(LDAP *ld,LDAP_CONST char *reqoid, + struct berval *reqdata,LDAPControl **serverctrls,LDAPControl **clientctrls, + char **retoidp,struct berval **retdatap); +#endif /* not HAVE_DECL_LDAP_EXTENDED_OPERATION_S */ + +/* Replacement for password modification. user is the DN of the entry to + change, oldpw is the old password (may not always be needed?), newpw is + the new password to set and newpasswd is sometimes returned (though not + by us). See RFC 3062 for details.*/ +int ldap_passwd_s(LDAP *ld,struct berval *user,struct berval *oldpw, + struct berval *newpw,struct berval UNUSED(*newpasswd), + LDAPControl **sctrls,LDAPControl **cctrls) +{ +#ifndef HAVE_LDAP_EXTENDED_OPERATION_S + return LDAP_OPERATIONS_ERROR; +#else /* HAVE_LDAP_EXTENDED_OPERATION_S */ + int rc; + BerElement *ber; + struct berval *bv; + char *retoid; + struct berval *retdata; + /* set up request data */ + ber=ber_alloc_t(LBER_USE_DER); + if (ber==NULL) + return LDAP_NO_MEMORY; + ber_printf(ber,"{"); + ber_printf(ber,"tO",LDAP_TAG_EXOP_MODIFY_PASSWD_ID,user); + if (oldpw!=NULL) + ber_printf(ber,"tO",LDAP_TAG_EXOP_MODIFY_PASSWD_OLD,oldpw); + ber_printf(ber,"tO",LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,newpw); + ber_printf(ber,"N}"); + rc=ber_flatten(ber,&bv); + ber_free(ber,1); + if (rc<0) + return LDAP_NO_MEMORY; + /* perform the operation */ + rc=ldap_extended_operation_s(ld,LDAP_EXOP_MODIFY_PASSWD,bv,sctrls,cctrls, + &retoid,&retdata); + /* free data */ + ber_bvfree(bv); + if (rc==LDAP_SUCCESS) + { + ber_bvfree(retdata); + ber_memfree(retoid); + } + /* return result code */ + return rc; +#endif /* HAVE_LDAP_EXTENDED_OPERATION_S */ +} diff --git a/compat/nss_compat.h b/compat/nss_compat.h new file mode 100644 index 0000000..232519e --- /dev/null +++ b/compat/nss_compat.h @@ -0,0 +1,151 @@ +/* + nss_compat.h - compatibility definitions for NSS functions + + Copyright (C) 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__NSS_H +#define COMPAT__NSS_H + +#ifdef HAVE_NSS_H +#include +#endif /* HAVE_NSS_H */ +#ifdef HAVE_NSS_COMMON_H +#include +#endif /* HAVE_NSS_COMMON_H */ +#ifdef HAVE_ALIASES_H +#include +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_SHADOW_H +#include +#endif /* HAVE_SHADOW_H */ +#ifdef HAVE_RPC_RPCENT_H +#include +#endif /* HAVE_RPC_RPCENT_H */ +#ifdef HAVE_NSS_DBDEFS_H +#include +#endif /* HAVE_NSS_DBDEFS_H */ +#ifdef HAVE_NSSWITCH_H +#include +#endif /* HAVE_NSSWITCH_H */ +#ifdef HAVE_IRS_NSS_H +#include "irs-nss.h" +#endif /* HAVE_IRS_NSS_H */ + +#include "compat/ether.h" + +/* define missing status codes */ +#ifndef HAVE_ENUM_NSS_STATUS +#ifndef NSS_STATUS_SUCCESS +#define NSS_STATUS_SUCCESS NSS_SUCCESS +#endif +#ifndef NSS_STATUS_NOTFOUND +#define NSS_STATUS_NOTFOUND NSS_NOTFOUND +#endif +#ifndef NSS_STATUS_UNAVAIL +#define NSS_STATUS_UNAVAIL NSS_UNAVAIL +#endif +#ifndef NSS_STATUS_TRYAGAIN +#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN +#endif +#ifndef NSS_STATUS_RETURN +#define NSS_STATUS_RETURN NSS_NOTFOUND +#endif +#endif /* not HAVE_ENUM_NSS_STATUS */ + +/* define nss_status_t */ +#ifdef HAVE_ENUM_NSS_STATUS +typedef enum nss_status nss_status_t; +#endif + +/* Define an aliasent if it was not found on the system. */ +#ifndef HAVE_STRUCT_ALIASENT +struct aliasent +{ + char *alias_name; + size_t alias_members_len; + char **alias_members; + int alias_local; +}; +#endif /* not HAVE_STRUCT_ALIASENT */ + +/* Define an rpcent if it was not found on the system */ +#ifndef HAVE_STRUCT_RPCENT +struct rpcent +{ + char *r_name; + char **r_aliases; + int r_number; +}; +#endif /* not HAVE_STRUCT_RPCENT */ + +/* We define struct etherent here because it does not seem to + be defined in any publicly available header file exposed + by glibc. This is taken from include/netinet/ether.h + of the glibc (2.3.6) source tarball. */ +#ifndef HAVE_STRUCT_ETHERENT +struct etherent +{ + const char *e_name; + struct ether_addr e_addr; +}; +#endif /* not HAVE_STRUCT_ETHERENT */ + +/* We also define struct __netgrent because it's definition is + not publically available. This is taken from inet/netgroup.h + of the glibc (2.3.6) source tarball. + The first part of the struct is the only part that is modified + by our getnetgrent() function, all the other fields are not + touched at all. */ +struct __netgrent +{ + enum { triple_val, group_val } type; + union + { + struct + { + const char *host; + const char *user; + const char *domain; + } triple; + const char *group; + } val; + /* the following stuff is used by some NSS services + but not by ours (it's not completely clear how these + are shared between different services) or is used + by our caller */ + char *data; + size_t data_size; + union + { + char *cursor; + unsigned long int position; + } insertedname; /* added name to union to avoid warning */ + int first; + struct name_list *known_groups; + struct name_list *needed_groups; + void *nip; /* changed from `service_user *nip' */ +}; + +#endif /* not COMPAT__NSS_H */ diff --git a/compat/pagectrl.c b/compat/pagectrl.c new file mode 100644 index 0000000..d846623 --- /dev/null +++ b/compat/pagectrl.c @@ -0,0 +1,217 @@ +/* + pagectrl.c - provide a replacement ldap_create_page_control() function. + This file was part of the nss_ldap library which has been + forked into the nss-pam-ldapd library. + + Copyright (C) 2002 Max Caines + This software is not subject to any license of the University + of Wolverhampton. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "compat/ldap_compat.h" + +#ifndef LDAP_CONTROL_PAGE_OID +#define LDAP_CONTROL_PAGE_OID "1.2.840.113556.1.4.319" +#endif + +#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL +/*--- + ldap_create_page_control + + Create and encode the Paged Results control. + + ld (IN) An LDAP session handle, as obtained from a call to + ldap_init(). + + pagesize (IN) The number of entries to return in each page + + cookiep (IN) Pointer to a berVal structure that the server uses to + determine the current location in the + result set (opaque). Set to NULL the + first time. + + iscritical (IN) Is this control critical to the search? + + ctrlp (OUT) A result parameter that will be assigned the address + of an LDAPControl structure that contains the + PagedResult control created by this function. + The memory occupied by the LDAPControl structure + SHOULD be freed when it is no longer in use by + calling ldap_control_free(). + + + Ber encoding + + PageResult ::= SEQUENCE { + pageSize INTEGER + cookie OCTET STRING } + + + Note: The first time the Page control is created, the cookie + should be set to a zero-length string. The cookie obtained + from calling ldap_parse_page_control() should be used as + the cookie in the next ldap_create_page_control call. + + ---*/ + +int +ldap_create_page_control (LDAP * ld, + unsigned long pagesize, + struct berval *cookiep, + int iscritical, LDAPControl ** ctrlp) +{ + ber_tag_t tag; + BerElement *ber; + BerElement *ldap_alloc_ber_with_options (LDAP * ld); + int rc; + + if ((ld == NULL) || (ctrlp == NULL)) + { + return (LDAP_PARAM_ERROR); + } + + if ((ber = ldap_alloc_ber_with_options (ld)) == NULL) + { + return (LDAP_NO_MEMORY); + } + + tag = ber_printf (ber, "{i", pagesize); + if (tag == LBER_ERROR) + goto exit; + + if (cookiep == NULL) + tag = ber_printf (ber, "o", "", 0); + else + tag = ber_printf (ber, "O", cookiep); + if (tag == LBER_ERROR) + goto exit; + + tag = ber_printf (ber, /*{ */ "N}"); + if (tag == LBER_ERROR) + goto exit; + + rc = ldap_create_control (LDAP_CONTROL_PAGE_OID, ber, iscritical, ctrlp); + + ber_free (ber, 1); + return (rc); + +exit: + ber_free (ber, 1); + return (LDAP_ENCODING_ERROR); +} +#endif /* not HAVE_LDAP_CREATE_PAGE_CONTROL */ + +#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL +/*--- + ldap_parse_page_control + + Decode the Virtual List View control return information. + + ld (IN) An LDAP session handle. + + ctrls (IN) The address of a NULL-terminated array of + LDAPControl structures, typically obtained + by a call to ldap_parse_result(). + + list_countp (OUT) This result parameter is filled in with the number + of entries returned in this page + + cookiep (OUT) This result parameter is filled in with the address + of a struct berval that contains the server- + generated cookie. + The returned cookie SHOULD be used in the next call + to create a Page sort control. The struct berval + returned SHOULD be disposed of by calling ber_bvfree() + when it is no longer needed. + +---*/ +int +ldap_parse_page_control (LDAP * ld, + LDAPControl ** ctrls, + unsigned long *list_countp, struct berval **cookiep) +{ + BerElement *ber; + LDAPControl *pControl; + int i; + unsigned long count; + ber_tag_t tag; + + if (cookiep) + { + *cookiep = NULL; /* Make sure we return a NULL if error occurs. */ + } + + if (ld == NULL) + { + return (LDAP_PARAM_ERROR); + } + + if (ctrls == NULL) + { + return (LDAP_CONTROL_NOT_FOUND); + } + + /* Search the list of control responses for a Page control. */ + for (i = 0; ctrls[i]; i++) + { + pControl = ctrls[i]; + if (!strcmp (LDAP_CONTROL_PAGE_OID, pControl->ldctl_oid)) + goto foundPageControl; + } + + /* No page control was found. */ + return (LDAP_CONTROL_NOT_FOUND); + +foundPageControl: + /* Create a BerElement from the berval returned in the control. */ + ber = ber_init (&pControl->ldctl_value); + + if (ber == NULL) + { + return (LDAP_NO_MEMORY); + } + + /* Extract the data returned in the control. */ + tag = ber_scanf (ber, "{iO" /*} */ , &count, cookiep); + + if (tag == LBER_ERROR) + { + ber_free (ber, 1); + return (LDAP_DECODING_ERROR); + } + + ber_free (ber, 1); + + /* Return data to the caller for items that were requested. */ + if (list_countp) + { + *list_countp = count; + } + + return (LDAP_SUCCESS); +} +#endif /* not HAVE_LDAP_PARSE_PAGE_CONTROL */ diff --git a/compat/pam_compat.h b/compat/pam_compat.h new file mode 100644 index 0000000..b4923f6 --- /dev/null +++ b/compat/pam_compat.h @@ -0,0 +1,87 @@ +/* + pam_compat.h - provide a replacement definitions for some pam functions + + Copyright (C) 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__PAM_COMPAT_H +#define COMPAT__PAM_COMPAT_H 1 + +#ifdef HAVE_SECURITY_PAM_APPL_H +#include +#endif /* HAVE_SECURITY_PAM_APPL_H */ +#ifndef HAVE_PAM_PAM_MODULES_H +#include +#ifdef HAVE_SECURITY_PAM_EXT_H +#include +#endif /* HAVE_SECURITY_PAM_EXT_H */ +#else /* not HAVE_PAM_PAM_MODULES_H */ +#include +#endif /* not HAVE_PAM_PAM_MODULES_H */ +#ifdef HAVE_SECURITY_PAM_MODUTIL_H +#include +#endif /* HAVE_SECURITY_PAM_MODUTIL_H */ + +/* some systems define PAM_AUTHTOK_RECOVER_ERR but not + PAM_AUTHTOK_RECOVERY_ERR */ +#ifndef PAM_AUTHTOK_RECOVERY_ERR +#ifdef PAM_AUTHTOK_RECOVER_ERR +#define PAM_AUTHTOK_RECOVERY_ERR PAM_AUTHTOK_RECOVER_ERR +#endif /* PAM_AUTHTOK_RECOVER_ERR */ +#endif /* not PAM_AUTHTOK_RECOVERY_ERR */ + +/* define our own replacement pam_get_authtok() if it wasn't found */ +#ifndef HAVE_PAM_GET_AUTHTOK +int pam_get_authtok(pam_handle_t *pamh,int item,const char **authtok,const char *prompt); +#endif /* not HAVE_PAM_GET_AUTHTOK */ + +/* replace pam_prompt() if needed */ +#ifndef HAVE_PAM_PROMPT +int pam_prompt(pam_handle_t *pamh,int style,char **response,const char *format,...) + LIKE_PRINTF(4,5); +#endif /* not HAVE_PAM_PROMPT */ + +/* provide pam_info() if needed */ +#ifndef pam_info +#define pam_info(pamh,format...) \ + pam_prompt(pamh,PAM_TEXT_INFO,NULL,##format) +#endif /* not pam_info */ + +/* provide pam_error() if needed */ +#ifndef pam_error +#define pam_error(pamh,format...) \ + pam_prompt(pamh,PAM_ERROR_MSG,NULL,##format) +#endif /* not pam_error */ + +/* fall back to using getpwnam() if pam_modutil_getpwnam() isn't defined */ +#ifndef HAVE_PAM_MODUTIL_GETGWNAM +#include +#include +#define pam_modutil_getpwnam(pamh,user) getpwnam(user) +#endif /* not HAVE_PAM_MODUTIL_GETGWNAM */ + +/* fall back to using syslog() if pam_syslog() doesn't exist */ +#ifndef HAVE_PAM_SYSLOG +#ifndef LOG_AUTHPRIV +#define LOG_AUTHPRIV LOG_AUTH +#endif /* not LOG_AUTHPRIV */ +#define pam_syslog(pamh,priority,format...) \ + syslog(LOG_AUTHPRIV|(priority),##format) +#endif /* not HAVE_PAM_SYSLOG */ + +#endif /* _COMPAT_LDAP_COMPAT_H */ diff --git a/compat/pam_get_authtok.c b/compat/pam_get_authtok.c new file mode 100644 index 0000000..a2f3b9a --- /dev/null +++ b/compat/pam_get_authtok.c @@ -0,0 +1,101 @@ +/* + pam_get_authtok.c - replacement function for pam_get_authtok() + + Copyright (C) 2009, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "compat/attrs.h" +#include "compat/pam_compat.h" + +/* warning: this version assumes that try_first_pass is specified */ + +/* find value of PAM_AUTHTOK_RECOVERY_ERR */ +#ifndef PAM_AUTHTOK_RECOVERY_ERR +#ifdef PAM_AUTHTOK_RECOVER_ERR +#define PAM_AUTHTOK_RECOVERY_ERR PAM_AUTHTOK_RECOVER_ERR +#else +#define PAM_AUTHTOK_RECOVERY_ERR 21 /* not defined anywhere */ +#endif +#endif + +int pam_get_authtok(pam_handle_t *pamh,int item,const char **authtok,const char *prompt) +{ + int rc; + char *passwd=NULL,*retype_passwd=NULL; + const void *oldauthtok; + char retype_prompt[80]; + /* first try to see if the value is already on the stack */ + *authtok=NULL; + rc=pam_get_item(pamh,item,(const void **)authtok); + if ((rc==PAM_SUCCESS)&&(*authtok!=NULL)) + return PAM_SUCCESS; + /* check what to prompt for and provide default prompt */ + *retype_prompt='\0'; + if (item==PAM_OLDAUTHTOK) + prompt=(prompt!=NULL)?prompt:"Old Password: "; + else + { + rc=pam_get_item(pamh,PAM_OLDAUTHTOK,&oldauthtok); + if ((rc==PAM_SUCCESS)&&(oldauthtok!=NULL)) + { + prompt=(prompt!=NULL)?prompt:"New Password: "; + snprintf(retype_prompt,sizeof(retype_prompt),"Retype %s",prompt); + retype_prompt[sizeof(retype_prompt)-1]='\0'; + } + else + prompt=(prompt!=NULL)?prompt:"Password: "; + } + /* prepare prompt and get password */ + rc=pam_prompt(pamh,PAM_PROMPT_ECHO_OFF,&passwd,"%s",prompt); + if (rc!=PAM_SUCCESS) + return rc; + /* if a second prompt should be presented, do it */ + if (*retype_prompt) + { + rc=pam_prompt(pamh,PAM_PROMPT_ECHO_OFF,&retype_passwd,"%s",retype_prompt); + /* check passwords */ + if ((rc==PAM_SUCCESS)&&(strcmp(retype_passwd,passwd)!=0)) + rc=PAM_AUTHTOK_RECOVERY_ERR; + } + /* store the password if everything went ok */ + if (rc==PAM_SUCCESS) + rc=pam_set_item(pamh,item,passwd); + /* clear and free any password information */ + memset(passwd,0,strlen(passwd)); + free(passwd); + if (retype_passwd!=NULL) + { + memset(retype_passwd,0,strlen(retype_passwd)); + free(retype_passwd); + } + if (rc!=PAM_SUCCESS) + return rc; + /* return token from the stack */ + return pam_get_item(pamh,item,(const void **)authtok); +} diff --git a/compat/pam_prompt.c b/compat/pam_prompt.c new file mode 100644 index 0000000..6e1b779 --- /dev/null +++ b/compat/pam_prompt.c @@ -0,0 +1,72 @@ +/* + pam_prompt.c - replacement function for pam_prompt() + + Copyright (C) 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "compat/attrs.h" +#include "compat/pam_compat.h" + +int pam_prompt(pam_handle_t *pamh,int style,char **response,const char *format,...) +{ + int rc; + struct pam_conv *aconv; + char buffer[200]; + va_list ap; + struct pam_message msg, *pmsg; + struct pam_response *resp; + /* the the conversion function */ + rc=pam_get_item(pamh,PAM_CONV,(const void **)&aconv); + if (rc!=PAM_SUCCESS) + return rc; + /* make the message string */ + va_start(ap,format); + vsnprintf(buffer,sizeof(buffer),format,ap); + buffer[sizeof(buffer)-1]='\0'; + va_end(ap); + /* build the message */ + msg.msg_style=style; + msg.msg=buffer; + pmsg=&msg; + resp=NULL; + rc=aconv->conv(1,(const struct pam_message **)&pmsg,&resp,aconv->appdata_ptr); + if (rc!=PAM_SUCCESS) + return rc; + /* assign response if it is set */ + if (response!=NULL) + { + if (resp==NULL) + return PAM_CONV_ERR; + if (resp[0].resp==NULL) + { + free(resp); + return PAM_CONV_ERR; + } + *response=resp[0].resp; + } + else + free(resp[0].resp); + free(resp); + return PAM_SUCCESS; +} diff --git a/compat/strndup.c b/compat/strndup.c new file mode 100644 index 0000000..9eb38a0 --- /dev/null +++ b/compat/strndup.c @@ -0,0 +1,41 @@ +/* + strndup.c - implementation of strndup() for systems that lack it + + Copyright (C) 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "strndup.h" + +/* this is a strndup() replacement for systems that don't have it + (strndup() is in POSIX 2008 now) */ +char *strndup(const char *s,size_t size) +{ + char *result; + result=(char *)malloc(size+1); + if (result!=NULL) + { + strncpy(result,s,size); + result[size]='\0'; + } + return result; +} diff --git a/compat/strndup.h b/compat/strndup.h new file mode 100644 index 0000000..abedd22 --- /dev/null +++ b/compat/strndup.h @@ -0,0 +1,33 @@ +/* + strndup.h - definition of strndup() for systems that lack it + + Copyright (C) 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef COMPAT__STRNDUP_H +#define COMPAT__STRNDUP_H 1 + +#ifndef HAVE_STRNDUP + +/* this is a strndup() replacement for systems that don't have it + (strndup() is in POSIX 2008 now) */ +char *strndup(const char *s,size_t size); + +#endif /* not HAVE_STRNDUP */ + +#endif /* COMPAT__STRNDUP_H */ diff --git a/compile b/compile new file mode 100755 index 0000000..c0096a7 --- /dev/null +++ b/compile @@ -0,0 +1,143 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2009-10-06.20; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software +# Foundation, Inc. +# Written by Tom Tromey . +# +# 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, see . + +# 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. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; +esac + +ofile= +cfile= +eat= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..40eaed4 --- /dev/null +++ b/config.guess @@ -0,0 +1,1517 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-05-11' + +# 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, 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. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# 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. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +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 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # 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. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + 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 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + 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 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + 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 ;; + 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 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # 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 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + 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 -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${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 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + 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 ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${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=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #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 + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + 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 -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + 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 i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-tilera-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # 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. + echo i386-sequent-sysv4 + exit ;; + 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 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + 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|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + 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 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*: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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *: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 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + 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 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +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\n"); 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) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# 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 -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# 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 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..30fdca8 --- /dev/null +++ b/config.sub @@ -0,0 +1,1760 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-03-23' + +# 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, 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. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# 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. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# 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. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +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 + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + 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 | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -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/'` + ;; + -sco5v6*) + # 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 + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +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. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # 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*86 | x86_64) + 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. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile-* | tilegx-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # 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 + ;; + abacus) + basic_machine=abacus-unknown + ;; + 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 + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + 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 | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + 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 + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + 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 + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*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 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + 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 + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + 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 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + 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 + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + 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/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-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 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + 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 + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-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 + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + 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 + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + 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. + -auroraux) + os=-auroraux + ;; + -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* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -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|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -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[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -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 + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + 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 + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-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 + ;; + f30[01]-fujitsu | f700-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 + ;; + -cnk*|-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* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..8847cf5 --- /dev/null +++ b/configure.ac @@ -0,0 +1,762 @@ +# configure.ac - process this file with autoconf to produce configure +# +# Copyright (C) 2006 Luke Howard +# Copyright (C) 2006 West Consulting +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +AC_PREREQ(2.61) +AC_COPYRIGHT( +[Copyright (C) 2006 Luke Howard +Copyright (C) 2006 West Consulting +Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + +This configure script is derived from configure.ac which is free software; +you can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. See the +configure.ac file for more details.]) + +# initialize and set version and bugreport address +AC_INIT([nss-pam-ldapd], + [0.8.4], + [nss-pam-ldapd-users@lists.arthurdejong.org],, + [http://arthurdejong.org/nss-pam-ldapd/]) +RELEASE_MONTH="Sep 2011" +AC_SUBST(RELEASE_MONTH) +AC_CONFIG_SRCDIR([nslcd.h]) + +# define package URL (remove when switching to 2.64) +m4_ifndef([AC_PACKAGE_URL], + PACKAGE_URL="http://arthurdejong.org/nss-pam-ldapd/" + [AC_DEFINE_UNQUOTED([PACKAGE_URL],"$PACKAGE_URL",[Define to the home page for this package.]) + AC_SUBST(PACKAGE_URL)]) + +# some initialisation +AC_CANONICAL_TARGET +AC_PREFIX_DEFAULT() +AC_CONFIG_LIBOBJ_DIR([compat]) + +# display notice and initialize automake +AC_MSG_NOTICE([configuring AC_PACKAGE_TARNAME AC_PACKAGE_VERSION]) +AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME,AC_PACKAGE_VERSION) + +# create a config.h file (Automake will add -DHAVE_CONFIG_H) +AC_CONFIG_HEADERS([config.h]) + +# check for programs +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_RANLIB +AM_PROG_CC_C_O +AC_USE_SYSTEM_EXTENSIONS +AC_PROG_LN_S + +# checks for tool to convert docbook to man +AC_PATH_PROGS(DOCBOOK2X_MAN, docbook2x-man) +if test "x${DOCBOOK2X_MAN}" = x +then + AC_MSG_WARN([docbook2x-man not found: not generating man pages]) +fi +AM_CONDITIONAL([GENMAN], [test "x${DOCBOOK2X_MAN}" != x]) + +# check for debugging options +AC_ARG_ENABLE(debug, + AS_HELP_STRING([--enable-debug], + [enable extensive debugging and logging]), + [if test "x$enableval" != "xno" ; then CFLAGS="-g -DDEBUG $CFLAGS" ; fi]) + +DESIRED_CFLAGS="" + +# check for extra compiler warnings +AC_ARG_ENABLE(warnings, + AS_HELP_STRING([--enable-warnings], + [enable extra compiler warnings (gcc)]), + [if test "x$enableval" != "no" + then + CFLAGS="$CFLAGS -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Waggregate-return -Wmissing-declarations -Wunused -Wformat=2 -Wswitch-default -Wswitch-enum -Wfloat-equal -Wbad-function-cast -Wredundant-decls" + DESIRED_CFLAGS="$DESIRED_CFLAGS -Wextra -Wdeclaration-after-statement -Werror-implicit-function-declaration" + fi]) +test_gcc_flag() { + AC_LANG_CONFTEST([AC_LANG_PROGRAM([int main() {}])]) + $CC -c conftest.c $CFLAGS $@ > /dev/null 2> /dev/null + ret=$? + rm -f conftest.o + return $ret +} +for flag in $DESIRED_CFLAGS +do + AC_MSG_CHECKING([whether $CC accepts $flag]) + if test_gcc_flag $flag + then + CFLAGS="$CFLAGS $flag" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi +done + +# add --disable-maintainer-mode option +AM_MAINTAINER_MODE([enable]) + +# check whether the NSS module should be built +AC_MSG_CHECKING([whether to build the NSS module]) +AC_ARG_ENABLE(nss, + AS_HELP_STRING([--disable-nss], + [build the NSS module [[default=enabled]]]),, + [enable_nss="yes"]) +AC_MSG_RESULT($enable_nss) +AM_CONDITIONAL([ENABLE_NSS], [test "x$enable_nss" = "xyes"]) + +# check whether the PAM module should be built +AC_MSG_CHECKING([whether to build the PAM module]) +AC_ARG_ENABLE(pam, + AS_HELP_STRING([--disable-pam], + [build the PAM module [[default=enabled]]]),, + [enable_pam="yes"]) +AC_MSG_RESULT($enable_pam) +AM_CONDITIONAL([ENABLE_PAM], [test "x$enable_pam" = "xyes"]) + +# check whether the nslcd daemon should be built +AC_MSG_CHECKING([whether to build the nslcd daemon]) +AC_ARG_ENABLE(nslcd, + AS_HELP_STRING([--disable-nslcd], + [build the nslcd daemon [[default=enabled]]]),, + [enable_nslcd="yes"]) +AC_MSG_RESULT($enable_nslcd) +AM_CONDITIONAL([ENABLE_NSLCD], [test "x$enable_nslcd" = "xyes"]) + +# check whether the Python version of the nslcd daemon should be built +AC_MSG_CHECKING([whether to build the pynslcd daemon]) +AC_ARG_ENABLE(pynslcd, + AS_HELP_STRING([--enable-pynslcd], + [build the pynslcd daemon [[default=disabled]]]),, + [enable_pynslcd="no"]) +AC_MSG_RESULT($enable_pynslcd) +AM_CONDITIONAL([ENABLE_PYNSLCD], [test "x$enable_pynslcd" = "xyes"]) +if test "x$enable_pynslcd" = "xyes" +then + AC_MSG_WARN([the pynslcd daemon is experimental]) +fi + +# check whether SASL support should be enabled +AC_MSG_CHECKING([whether to enable SASL support]) +AC_ARG_ENABLE(sasl, + AS_HELP_STRING([--disable-sasl], + [disable SASL support [[default=enabled]]]), + [enable_sasl=$enableval], + [enable_sasl="yes"]) +AC_MSG_RESULT($enable_sasl) + +# check whether Kerberos support should be enabled +AC_MSG_CHECKING([whether to enable Kerberos support]) +AC_ARG_ENABLE(kerberos, + AS_HELP_STRING([--disable-kerberos], + [disable Kerberos support [[default=enabled]]]), + [enable_kerberos=$enableval], + [enable_kerberos="yes"]) +AC_MSG_RESULT($enable_kerberos) + +# check whether configfile options should be checked +AC_MSG_CHECKING([whether to check configfile options]) +AC_ARG_ENABLE(configfile_checking, + AS_HELP_STRING([--disable-configfile-checking], + [check configfile options [[default=enabled]]]), + [configfile_checking=$enableval], + [configfile_checking="yes"]) +AC_MSG_RESULT($configfile_checking) +if test "x$configfile_checking" = "xyes" +then + AC_DEFINE(ENABLE_CONFIGFILE_CHECKING,1,[Whether to check configfile options.]) + AC_SUBST(ENABLE_CONFIGFILE_CHECKING,1) +fi + +# check the name of the configuration file +AC_ARG_WITH(ldap-conf-file, + AS_HELP_STRING([--with-ldap-conf-file=PATH], + [path to nslcd configuration file @<:@/etc/nslcd.conf@:>@]), + [ NSLCD_CONF_PATH="$with_ldap_conf_file" ], + [ NSLCD_CONF_PATH="/etc/nslcd.conf" ]) +AC_DEFINE_UNQUOTED(NSLCD_CONF_PATH,"$NSLCD_CONF_PATH",[Path to nslcd configuration file.]) +AC_SUBST(NSLCD_CONF_PATH) + +# check the name of the file with a bindpw value +AC_ARG_WITH(bindpw-file, + AS_HELP_STRING([--with-bindpw-file=PATH], + [path to file with value for bindpw @<:@disabled@:>@]), + [ NSLCD_BINDPW_PATH="$with_bindpw_file" + AC_DEFINE_UNQUOTED(NSLCD_BINDPW_PATH,"$NSLCD_BINDPW_PATH",[Path to bindpw value.]) + AC_SUBST(NSLCD_BINDPW_PATH) + ]) + +# where should the pidfile be written +AC_ARG_WITH(nslcd-pidfile, + AS_HELP_STRING([--with-nslcd-pidfile=PATH], + [path to pidfile @<:@/var/run/nslcd/nslcd.pid@:>@]), + [ NSLCD_PIDFILE="$with_nslcd_pidfile" ], + [ NSLCD_PIDFILE="/var/run/nslcd/nslcd.pid" ]) +AC_DEFINE_UNQUOTED(NSLCD_PIDFILE,"$NSLCD_PIDFILE",[The location of the pidfile used for checking availability of the nslcd.]) +AC_SUBST(NSLCD_PIDFILE) + +# where is the socket used for communication +AC_ARG_WITH(nslcd-socket, + AS_HELP_STRING([--with-nslcd-socket=PATH], + [path to socket @<:@/var/run/nslcd/socket@:>@]), + [ NSLCD_SOCKET="$with_nslcd_socket" ], + [ NSLCD_SOCKET="/var/run/nslcd/socket" ]) +AC_DEFINE_UNQUOTED(NSLCD_SOCKET,"$NSLCD_SOCKET",[The location of the socket used for communicating.]) +AC_SUBST(NSLCD_SOCKET) + +# the directory PAM librabries are expected to be placed into +AC_ARG_WITH(pam-seclib-dir, + AS_HELP_STRING([--with-pam-seclib-dir=PAM_SECLIB_DIR], + [path to PAM security library @<:@/lib/security@:>@]), + [ PAM_SECLIB_DIR="$with_pam_seclib_dir" ], + [ PAM_SECLIB_DIR="/lib/security" ]) +AC_DEFINE_UNQUOTED(PAM_SECLIB_DIR,"$PAM_SECLIB_DIR",[path to PAM security library]) +AC_SUBST(PAM_SECLIB_DIR) + +# the SONAME to use for the NSS module +AC_MSG_CHECKING([name of NSS module]) +AC_ARG_WITH(nss-ldap-soname, + AS_HELP_STRING([--with-nss-ldap-soname=SONAME], + [name of NSS module @<:@auto@:>@]), + [ NSS_LDAP_SONAME="$with_nss_ldap_soname" ], + [ NSS_LDAP_SONAME="auto" ]) +if test "x$NSS_LDAP_SONAME" = "xauto" +then + case "$target_os" in + solaris*) NSS_LDAP_SONAME="nss_ldap.so.1" ;; + freebsd*) NSS_LDAP_SONAME="nss_ldap.so.1" ;; + *) NSS_LDAP_SONAME="libnss_ldap.so.2" ;; + esac +fi +AC_MSG_RESULT($NSS_LDAP_SONAME) +AC_DEFINE_UNQUOTED(NSS_LDAP_SONAME,"$NSS_LDAP_SONAME",[The SONAME of the NSS library module.]) +AC_SUBST(NSS_LDAP_SONAME) + +# the SONAME to use for the PAM module +AC_MSG_CHECKING([name of PAM module]) +AC_ARG_WITH(pam-ldap-soname, + AS_HELP_STRING([--with-pam-ldap-soname=SONAME], + [name of PAM module @<:@auto@:>@]), + [ PAM_LDAP_SONAME="$with_pam_ldap_soname" ], + [ PAM_LDAP_SONAME="auto" ]) +if test "x$PAM_LDAP_SONAME" = "xauto" +then + case "$target_os" in + solaris*) PAM_LDAP_SONAME="pam_ldap.so.1" ;; + *) PAM_LDAP_SONAME="pam_ldap.so" ;; + esac +fi +AC_MSG_RESULT($PAM_LDAP_SONAME) +AC_SUBST(PAM_LDAP_SONAME) + +# check which modules should be build +AC_ARG_WITH(nss-maps, + AS_HELP_STRING([--with-nss-maps=MAP LIST], + [comma separated list of NSS maps to build @<:@all@:>@]), + ,[ with_nss_maps="all" ]) + +# checks for availability of header files +AC_CHECK_HEADERS([ctype.h strings.h pthread.h fcntl.h limits.h]) +AC_CHECK_HEADERS([nss.h nss_common.h grp.h shadow.h aliases.h netdb.h rpc/rpcent.h]) +AC_CHECK_HEADERS([netinet/ether.h arpa/inet.h netinet/in.h]) +AC_CHECK_HEADERS([nsswitch.h nss_dbdefs.h]) +AC_CHECK_HEADERS([sys/socket.h sys/un.h sys/ucred.h ucred.h sys/param.h sys/time.h]) +AC_CHECK_HEADERS([getopt.h syslog.h]) + +# other general checks +AC_C_INLINE +AC_C_CONST + +# checks for availability of common functions +AC_CHECK_FUNCS([sigaction snprintf]) +AC_CHECK_FUNCS(gethostbyname) +AC_SEARCH_LIBS(socket,socket) +AC_CHECK_FUNCS([strcasecmp strncasecmp strchr strcspn strspn strtol strtoul strtoull]) +AC_CHECK_FUNCS([malloc realloc]) +AC_FUNC_FORK +AC_CHECK_FUNCS(__assert_fail) + +# checks for types +AC_TYPE_MODE_T +AC_TYPE_SIZE_T +AC_TYPE_UID_T +AC_TYPE_PID_T +AC_TYPE_INT32_T +AC_TYPE_UINT8_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_CHECK_SIZEOF(unsigned int) +AC_CHECK_SIZEOF(unsigned long int) +AC_CHECK_SIZEOF(unsigned long long int) +AC_CHECK_SIZEOF(uid_t) +AC_CHECK_SIZEOF(gid_t) + +# check for support for the __thread keyword +AC_CACHE_CHECK([whether $CC supports '__thread'], [mn_cv_c___thread_supported], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[static __thread i;]], [])], + [mn_cv_c___thread_supported=yes], + [mn_cv_c___thread_supported=no])]) +if test $mn_cv_c___thread_supported != yes +then + AC_MSG_WARN([$CC does not support '__thread' keyword]) + AC_DEFINE(__thread,,[Define to empty if compiler does not support `__thread' keyword.]) +fi + +# check for support for the struct ether_addr structure +AC_CHECK_TYPES(struct ether_addr,,,[ + #include + #include + #include + #include + #include + #ifdef HAVE_NETINET_ETHER_H + #include + #endif]) + +# check for ether_aton and ether_ntoa functions +AC_CHECK_FUNCS(ether_aton ether_ntoa ether_aton_r ether_ntoa_r) +AC_CHECK_DECLS([ether_aton,ether_ntoa],,,[ + #include + #include + #include + #include + #include + #ifdef HAVE_NETINET_ETHER_H + #include + #endif]) + +# check to see if socklen_t is defined +AC_CHECK_TYPE(socklen_t,, + AC_DEFINE(socklen_t,size_t,[Define to `size_t' if not defined elswhere.]),[ + #include + #include ]) + +# NSS module-specific tests +if test "x$enable_nss" = "xyes" +then + # save CFLAGS and LIBS to restore later + nss_save_CFLAGS="$CFLAGS" + nss_save_LIBS="$LIBS" + + # check for a definition of struct aliasent + AC_CHECK_TYPES(struct aliasent,,,[ + #ifdef HAVE_ALIASES_H + #include + #endif]) + + # check for a definition of struct etherent + AC_CHECK_TYPES(struct etherent,,,[ + #include + #include + #include + #include + #ifdef HAVE_NETINET_ETHER_H + #include + #endif]) + + # check for a definition of struct rpcent + AC_CHECK_TYPES(struct rpcent,,,[ + #include + #ifdef HAVE_RPC_RPCENT_H + #include + #endif]) + + # check for a definition of enum nss_status and nss_backend_t + AC_CHECK_TYPES([enum nss_status,nss_backend_t],,,[ + #ifdef HAVE_NSS_H + #include + #endif + #ifdef HAVE_NSS_COMMON_H + #include + #endif + #ifdef HAVE_NSS_DBDEFS_H + #include + #endif + #ifdef HAVE_NSSWITCH_H + #include + #endif + #ifdef HAVE_IRS_NSS_H + #include "irs-nss.h" + #endif]) + + # check if struct nss_XbyY_args has a returnlen attribute + AC_CHECK_MEMBERS([struct nss_XbyY_args.returnlen],,,[[ + #ifdef HAVE_NSS_H + #include + #endif + #ifdef HAVE_NSS_COMMON_H + #include + #endif + #ifdef HAVE_NSS_DBDEFS_H + #include + #endif + #ifdef HAVE_NSSWITCH_H + #include + #endif + #ifdef HAVE_IRS_NSS_H + #include "irs-nss.h" + #endif]]) + + # check which NSS flavour to build + AC_MSG_CHECKING([which NSS flavour to build]) + AC_ARG_WITH(nss-flavour, + AS_HELP_STRING([--with-nss-flavour=auto|glibc|solaris|freebsd], + [the libc flavour to build our NSS module for @<:@auto@:>@]),, + with_nss_flavour=auto) + if test "x$with_nss_flavour" = "xauto" + then + # do the guessing game + case "$target_os" in + solaris*) with_nss_flavour=solaris ;; + freebsd*) with_nss_flavour=freebsd ;; + *) with_nss_flavour=glibc ;; + esac + fi + AC_MSG_RESULT($with_nss_flavour) + case "$with_nss_flavour" in + glibc) AC_DEFINE(NSS_FLAVOUR_GLIBC,1,[Whether to use the Glibc NSS interface flavour.]) ;; + solaris) AC_DEFINE(NSS_FLAVOUR_SOLARIS,1,[Whether to use the Solaris NSS interface flavour.]) ;; + freebsd) AC_DEFINE(NSS_FLAVOUR_FREEBSD,1,[Whether to use the FreeBSD NSS interface flavour.]) ;; + esac + + # check which module source files to use + AC_MSG_CHECKING([which NSS maps to build]) + if test "x$with_nss_maps" = "xall" + then + case "$with_nss_flavour" in + glibc) with_nss_maps="aliases,ethers,group,hosts,netgroup,networks,passwd,protocols,rpc,services,shadow" ;; + solaris) with_nss_maps="ethers,group,hosts,netgroup,networks,passwd,protocols,rpc,services,shadow" ;; + freebsd) with_nss_maps="group,hosts,passwd" ;; + esac + fi + AC_MSG_RESULT($with_nss_maps) + NSS_MODULE_OBJS="$(echo "$with_nss_maps " | sed 's/,/ /g;s/ */.$(OBJEXT) /g')" + AC_SUBST(NSS_MODULE_OBJS) + + # find out how to link the library + nss_ldap_so_LINK="\$(CCLD) \$(AM_CFLAGS) \$(CFLAGS) \$(nss_ldap_so_LDFLAGS) \$(LDFLAGS) -o \$@" + case "$target_os" in + solaris*) + if test "x$GCC" = xyes + then + nss_ldap_so_LINK="/usr/ccs/bin/ld -Bdirect -z nodelete -Bdynamic -M \$(srcdir)/exports.solaris -G -o \$@" + else + nss_ldap_so_LDFLAGS="-Wl,-Bdirect -Wl,-z,nodelete -Wl,-Bdynamic -Wl,-M,\$(srcdir)/exports.solaris -Wl,-G" + fi + ;; + *) + nss_ldap_so_LDFLAGS="-shared -Wl,-h,\$(NSS_LDAP_SONAME) -Wl,--version-script,\$(srcdir)/exports.$with_nss_flavour" + ;; + esac + AC_SUBST(nss_ldap_so_LDFLAGS) + AC_SUBST(nss_ldap_so_LINK) + + # restore CFLAGS and LIBS + CFLAGS="$nss_save_CFLAGS" + LIBS="$nss_save_LIBS" +fi + +# PAM module-specific tests +if test "x$enable_pam" = "xyes" +then + # save CFLAGS and LIBS to restore later + pam_save_CFLAGS="$CFLAGS" + pam_save_LIBS="$LIBS" + + # check for headers + AC_CHECK_HEADERS(security/pam_appl.h) + AC_CHECK_HEADERS(security/pam_modules.h,,,[ + #ifdef HAVE_SECURITY_PAM_APPL_H + #include + #endif + ]) + AC_CHECK_HEADERS(pam/pam_modules.h) + AC_CHECK_HEADERS(security/pam_ext.h) + AC_CHECK_HEADERS(security/pam_modutil.h) + + # at least one of security/pam_modules.h or pam/pam_modules.h is required + if test "x$ac_cv_header_security_pam_modules_h" != "xyes" && \ + test "x$ac_cv_header_pam_pam_modules_h" != "xyes" + then + AC_MSG_ERROR(PAM header files are missing) + fi + + # find pam library + AC_SEARCH_LIBS(pam_get_data,pam,,AC_MSG_ERROR(no PAM library available)) + + # replace some PAM functions if they are unavailable + AC_REPLACE_FUNCS(pam_get_authtok pam_prompt) + AC_CHECK_FUNCS(pam_modutil_getpwnam pam_syslog) + + # find out how to link the library + pam_ldap_so_LINK="\$(CCLD) \$(AM_CFLAGS) \$(CFLAGS) \$(pam_ldap_so_LDFLAGS) \$(LDFLAGS) -o \$@" + case "$target_os" in + solaris*) + if test "x$GCC" = xyes + then + pam_ldap_so_LINK="/usr/ccs/bin/ld -Bdirect -z nodelete -Bdynamic -M \$(srcdir)/pam_ldap.map -G -o \$@" + else + pam_ldap_so_LDFLAGS="-shared -Wl,-Bdirect -Wl,-z,nodelete -Wl,-Bdynamic -Wl,-M,\$(srcdir)/pam_ldap.map -Wl,-G" + fi + ;; + *) + pam_ldap_so_LDFLAGS="-shared -Wl,--version-script,\$(srcdir)/pam_ldap.map" + ;; + esac + AC_SUBST(pam_ldap_so_LDFLAGS) + AC_SUBST(pam_ldap_so_LINK) + + # restore CFLAGS and LIBS + CFLAGS="$pam_save_CFLAGS" + LIBS="$pam_save_LIBS" +fi + +# nslcd daemon-specific tests +if test "x$enable_nslcd" = "xyes" +then + # save CFLAGS and LIBS to restore later + nslcd_save_CFLAGS="$CFLAGS" + nslcd_save_LIBS="$LIBS" + + # check header files + AC_CHECK_HEADERS(lber.h) + AC_CHECK_HEADERS(ldap.h,, test "x$enable_nslcd" = "xyes" && AC_MSG_ERROR([could not locate ]),[ + #if HAVE_LBER_H + #include + #endif + ]) + AC_CHECK_HEADERS(ldap_ssl.h) + AC_CHECK_HEADERS(gssldap.h) + if test "x$enable_sasl" = "xyes" + then + AC_CHECK_HEADERS(sasl.h sasl/sasl.h) + AC_CHECK_HEADERS(gsssasl.h) + fi + if test "x$enable_kerberos" = "xyes" + then + AC_CHECK_HEADERS(gssapi/gssapi.h gssapi/gssapi_generic.h gssapi/gssapi_krb5.h gssapi.h) + fi + AC_CHECK_HEADERS(regex.h) + + # checks for availability of system libraries for nslcd + AC_SEARCH_LIBS(gethostbyname,nsl socket) + AC_SEARCH_LIBS(hstrerror,resolv) + AC_SEARCH_LIBS(socket,socket) + AC_SEARCH_LIBS(dlopen,dl) + + # check for availability of functions + AC_CHECK_FUNCS(setgroups) + AC_CHECK_FUNCS(getpeereid) + AC_CHECK_FUNCS(getpeerucred) + AC_CHECK_FUNCS(__nss_configure_lookup) + AC_CHECK_FUNCS(getenv putenv clearenv) + AC_CHECK_FUNCS(dlopen dlsym dlerror) + AC_CHECK_FUNCS(regcomp regexec regerror) + + # replace some functions if they are not on the system + AC_REPLACE_FUNCS(getopt_long) + AC_REPLACE_FUNCS(strndup) + + # replace daemon() function if it is not on the system + AC_SEARCH_LIBS(daemon,bsd) + AC_REPLACE_FUNCS(daemon) + AC_CHECK_DECLS([daemon],,,[#include ]) + + # replace ether_aton_r() and ether_ntoa_r() if they are not found + AC_CHECK_FUNCS(ether_aton_r ether_ntoa_r,,[AC_LIBOBJ(ether)]) + + # check to see if struct sockaddr_storage is defined + AC_CHECK_TYPE(struct sockaddr_storage,, + AC_DEFINE(sockaddr_storage,sockaddr_in,[Define to `sockaddr_in' if not defined elsewhere.]),[ + #include + #include ]) + + # check for support for the struct ucred structure + AC_CHECK_TYPE(struct ucred, + AC_DEFINE(HAVE_STRUCT_UCRED,1,[Define to 1 if you have a `struct ucred' definition.]),,[ + #include + #include + #include ]) + + # check threading stuff + AX_PTHREAD(,AC_MSG_ERROR([no support for pthreads])) + pthread_save_CFLAGS="$CFLAGS" + pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$LIBS $PTHREAD_LIBS" + AC_CHECK_FUNCS([pthread_mutex_lock pthread_join pthread_timedjoin_np]) + CFLAGS="$pthread_save_CFLAGS" + LIBS="$pthread_save_LIBS" + + # also use deprecated LDAP functions + AC_DEFINE(LDAP_DEPRECATED, 1, Define to activate deprecated features in OpenLDAP) + # for compatibility on Solaris + AC_DEFINE(LDAP_REFERRALS, 1, Define to get some functions on Solaris) + + # search for an LDAP library (only OpenLDAP is tested) + AC_ARG_WITH(ldap-lib, + AS_HELP_STRING([--with-ldap-lib=TYPE], + [select ldap library (auto|netscape5|netscape4|netscape3|umich|openldap) @<:@auto@:>@])) + if test -z "$with_ldap_lib" + then + with_ldap_lib=auto + fi + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \) + then + AC_SEARCH_LIBS(ldap_search_ext,[ldap_r ldap],found_ldap_lib=yes,,) + fi + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \) + then + AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes,, -lpthread) + fi + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \) + then + AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes,, -lpthread) + if test -z "$found_ldap_lib" + then + AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes,, -lpthread) + fi + if test -z "$found_ldap_lib" + then + AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes,,) + fi + if test -z "$found_ldap_lib" + then + AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes,,) + fi + fi + if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \) + then + AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes,, -lpthread) + fi + AC_CHECK_FUNCS(ldap_search_ext,,AC_MSG_ERROR([could not locate a valid LDAP library])) + + # see if we need a BER library + AC_SEARCH_LIBS(ber_bvfree,lber) + + # check for extra SASL libraries + if test "$enable_sasl" = "yes" + then + AC_CHECK_TYPE(sasl_interact_t, + AC_DEFINE(HAVE_SASL_INTERACT_T,1,[Define to 1 if you have a `sasl_interact_t' definition.]),,[ + #ifdef HAVE_SASL_SASL_H + #include + #elif defined(HAVE_SASL_H) + #include + #endif]) + AC_SEARCH_LIBS(ldap_sasl_interactive_bind_s,sasl2) + AC_CHECK_FUNCS(ldap_sasl_interactive_bind_s) + fi + + # check for extra Kerberos libraries + if test "$enable_kerberos" = "yes" + then + AC_SEARCH_LIBS(gss_krb5_ccache_name,gssapi gssapi_krb5) + AC_CHECK_FUNCS(gss_krb5_ccache_name) + fi + + # check for ldap function availability + AC_CHECK_FUNCS(ldap_parse_result ldap_memfree ldap_controls_free ldap_control_free) + AC_CHECK_FUNCS(ldap_explode_dn ldap_explode_rdn ldap_set_option ldap_get_option) + AC_CHECK_FUNCS(ldap_abandon ldap_simple_bind_s ldap_unbind ldap_set_rebind_proc) + AC_CHECK_FUNCS(ldap_initialize ldap_search_ext) + AC_CHECK_FUNCS(ldap_create_control ldap_extended_operation_s) + AC_CHECK_FUNCS(ldap_domain2hostlist ldap_domain2dn) + AC_CHECK_FUNCS(ldap_get_values ldap_value_free ldap_get_dn) + AC_CHECK_FUNCS(ldap_err2string ldap_msgfree ldap_result) + AC_CHECK_FUNCS(ber_bvfree ber_free ber_set_option) + + # replace ldap_create_page_control() and ldap_parse_page_control() + AC_CHECK_FUNCS(ldap_create_page_control ldap_parse_page_control,,[AC_LIBOBJ(pagectrl)]) + AC_CHECK_DECLS(ldap_extended_operation_s,,,[ + #if HAVE_LBER_H + #include + #endif + #include ]) + + # replace other ldap functions + AC_REPLACE_FUNCS(ldap_passwd_s) + AC_REPLACE_FUNCS(ldap_initialize) + + # check the number of arguments that ldap_set_rebind_proc() uses + AC_CACHE_CHECK( + [number of arguments to ldap_set_rebind_proc], + nss_ldapd_cv_ldap_set_rebind_proc_args, + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + ldap_set_rebind_proc(0,0,0); + ]])], + [nss_ldapd_cv_ldap_set_rebind_proc_args=3], + [nss_ldapd_cv_ldap_set_rebind_proc_args=2]) ]) + AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS,$nss_ldapd_cv_ldap_set_rebind_proc_args, + [Define to the number of arguments to ldap_set_rebindproc.]) + + # check the return type of ldap_set_rebind_proc() + AC_CACHE_CHECK( + [return type of ldap_set_rebind_proc], + nss_ldapd_cv_ldap_set_rebind_proc_type, + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + #if LDAP_SET_REBIND_PROC_ARGS == 3 + return ldap_set_rebind_proc(0,0,0); + #else + return ldap_set_rebind_proc(0,0); + #endif + ]])], + [nss_ldapd_cv_ldap_set_rebind_proc_type=int], + [nss_ldapd_cv_ldap_set_rebind_proc_type=void]) ]) + if test "x$nss_ldapd_cv_ldap_set_rebind_proc_type" = "xvoid" + then + AC_DEFINE(LDAP_SET_REBIND_PROC_RETURNS_VOID,1, + [Define to 1 if ldap_set_rebind_proc() returns void.]) + fi + + # save nslcd LIBS and CFLAGS and restore originals + nslcd_CFLAGS="$CFLAGS" + nslcd_LIBS="$LIBS" + CFLAGS="$nslcd_save_CFLAGS" + LIBS="$nslcd_save_LIBS" + + AC_SUBST(nslcd_LIBS) +fi + +# pynslcd daemon-specific tests +if test "x$enable_pynslcd" = "xyes" +then + # check Python interpreter + AM_PATH_PYTHON(2.5) +fi + +AM_CONDITIONAL([NSS_FLAVOUR_GLIBC], [test "x${with_nss_flavour}" = xglibc]) +AM_CONDITIONAL([NSS_FLAVOUR_SOLARIS], [test "x${with_nss_flavour}" = xsolaris]) +AM_CONDITIONAL([NSS_FLAVOUR_FREEBSD], [test "x${with_nss_flavour}" = xfreebsd]) + +# generate files +AC_CONFIG_FILES([Makefile compat/Makefile common/Makefile nss/Makefile + pam/Makefile nslcd/Makefile pynslcd/Makefile pynslcd/config.py + man/Makefile tests/Makefile]) +AC_OUTPUT diff --git a/debian/NEWS b/debian/NEWS new file mode 100644 index 0000000..7404fcc --- /dev/null +++ b/debian/NEWS @@ -0,0 +1,12 @@ +nss-pam-ldapd (0.7.0) unstable; urgency=low + + The package has been split into libnss-ldapd which contains the the NSS + module, libpam-ldapd which contains the PAM module and nslcd which + includes the daemon that performs the LDAP operations. + + The configuration file has been changed to /etc/nslcd.conf to reflect this + new organisation of packages (upgrades should create this file based on + any existing /etc/nss-ldapd.conf file). + + -- Arthur de Jong Tue, 01 Sep 2009 17:00:00 +0200 + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..1e770b9 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,1383 @@ +nss-pam-ldapd (0.8.4) unstable; urgency=low + + * Upload to unstable + * switch to using the member attribute by default instead of + uniqueMember (backwards incompatible change) + * only return "x" as a password hash when the object has the shadowAccount + objectClass and nsswitch.conf is configured to do shadow lookups using + LDAP (this avoids some problems with pam_unix) + * fix problem with partial attribute name matches in DN (thanks Timothy + White) + * fix a problem with objectSid mappings with recent versions of OpenLDAP + (patch by Wesley Mason) + * set the socket timeout in a connection callback to avoid timeout + issues during the SSL handshake (patch by Stefan Völkel) + * check for unknown variables in pam_authz_search + * only check password expiration when authenticating, only check account + expiration when doing authorisation + * make buffer sizes consistent and grow all buffers holding string + representations of numbers to be able to hold 64-bit numbers + * update AX_PTHREAD from autoconf-archive + * support querying DNS SRV records from a different domain than the current + one (based on a patch by James M. Leddy) + * fix a problem with uninitialised memory while parsing the tls_ciphers + option (closes: #638872) (but doesn't work yet due to #640384) + * implement bounds checking of numeric values read from LDAP (patch by + Jakub Hrozek) + * correctly support large uid and gid values from LDAP (patch by Jakub + Hrozek) + * improvements to the configure script (patch by Jakub Hrozek) + * switch to dh for debian/rules and bump debhelper compatibility to 8 + * build Debian packages with multiarch support + * ship shlibs (but still no symbol files) for libnss-ldapd since that was + the easiest way to support multiarch + * fix output in init script when restarting nslcd (closes: #637132) + * correctly handle leading and trailing spaces in preseeded debconf uri + option (patch by Andreas B. Mundt) (closes: #637863) + * support spaces around database names in /etc/nsswitch.conf while + configuring package (closes: #640185) + * updated Russian debconf translation by Yuri Kozlov (closes: #637751) + * updated French debconf translation by Christian Perrier (closes: #637756) + * added Slovak debconf translation by Slavko (closes: #637759) + * updated Danish debconf translation by Joe Hansen (closes :#637763) + * updated Brazilian Portuguese debconf translation by Denis Doria + * updated Portuguese debconf translation by Américo Monteiro + * updated Japanese debconf translation by Kenshi Muto (closes: #638195) + * updated Czech debconf translation by Miroslav Kure (closes: #639026) + * updated German debconf translation by Chris Leick (closes: #639107) + * updated Spanish debconf translation by Francisco Javier Cuadrado + (closes: #639236) + * updated Dutch debconf translation by Arthur de Jong with help from Paul + Gevers and Jeroen Schot + + -- Arthur de Jong Sun, 04 Sep 2011 21:00:00 +0200 + +nss-pam-ldapd (0.8.3) experimental; urgency=low + + * support using the objectSid attribute to provide numeric user and group + ids, based on a patch by Wesley Mason + * check shadow account and password expiry properties (similarly to what + pam_unix does) in the PAM handling code + * implement attribute mapping functionality in pynslcd + * relax default for validnames option to allow user names of only two + characters (closes: #620235) + * make user and group name validation errors a little more informative + * small portability improvements + * general code improvements and refactoring in pynslcd + * some simplifications in the protocol between the PAM module and nslcd + (without actual protocol changes so far) + * fix debconf LDAP search base suggestion when domain has more than two + parts (patch by Per Carlson) (closes: #626571) + * search for LDAP server by looking for SRV _ldap._tcp DNS records and + try to query LDAP server for base DN during package configuration + (based on work by Petter Reinholdtsen for the sssd package) + * upgrade to standards-version 3.9.2 (no changes needed) + + -- Arthur de Jong Fri, 13 May 2011 15:00:00 +0200 + +nss-pam-ldapd (0.8.2) experimental; urgency=low + + * fix problem with endless loop on incorrect password + * fix definition of HOST_NAME_MAX (closes: #618795) and fall back to + _POSIX_HOST_NAME_MAX + * ignore password change requests for users not in LDAP (closes: #617452) + * many clean-ups to the tests and added some new tests including some + integration tests for the PAM functionality + * some smaller code clean-ups and improvements + * improvements to pynslcd, including implementations for service, protocol + and rpc lookups + * implement a validnames option that can be used to filter valid user and + group names using a regular expression + * integrate patch by Daniel Dehennin to not loose debconf values of + previously set options with dpkg-reconfigure (closes: #610117) + * improvements to the way nslcd shuts down with hanging worker threads + + -- Arthur de Jong Sat, 26 Mar 2011 19:00:00 +0100 + +nss-pam-ldapd (0.8.1) experimental; urgency=low + + * SECURITY FIX: the PAM module will allow authentication for users that do + not exist in LDAP, this allows login to local users with an + incorrect password (CVE-2011-0438) + the exploitability of the problem depends on the details of + the PAM stack and the use of the minimum_uid PAM option + * add FreeBSD support, partially imported from the FreeBSD port (thanks to + Jacques Vidrine, Artem Kazakov and Alexander V. Chernikov) + * document how to replace name pam_check_service_attr and + pam_check_host_attr options in PADL's pam_ldap with with pam_authz_search + in nss-pam-ldapd (closes: #610925) + * implement a fqdn variable that can be used in pam_authz_search filters + * create the directory to hold the socket and pidfile on startup + * implement host, network and netgroup support in pynslcd + + -- Arthur de Jong Thu, 10 Mar 2011 22:00:00 +0100 + +nss-pam-ldapd (0.8.0) experimental; urgency=low + + * include Solaris support developed by Ted C. Cheng of Symas Corporation + * include an experimental partial implementation of nslcd in Python + (disabled by default, see --enable-pynslcd configure option) + * implement a nss_min_uid option to filter user entries returned by LDAP + * implement a rootpwmodpw option that allows the root user to change a + user's password without a password prompt + * try to update the shadowLastChange attribute on password change + * all log messages now include a description of the request to more easily + track problems when not running in debug mode + * allow attribute mapping expressions for the userPassword attribute for + passwd, group and shadow entries and by default map it to the unmatchable + password ("*") to avoid accidentally leaking password information + * numerous compatibility improvements + * add --with-pam-seclib-dir and --with-pam-ldap-soname configure options to + allow more control of hot to install the PAM module + * add --with-nss-flavour and --with-nss-maps configure options to support + other C libraries and limit which NSS modules to install + * allow tilde (~) in user and group names (closes: #607640) + * improvements to the timeout mechanism (connections are now actively timed + out using the idle_timelimit option) + * set socket timeouts on the LDAP connection to disconnect regardless of + LDAP and possibly TLS handling of connection + * better disconnect/reconnect handling of error conditions + * some code improvements and cleanups and several smaller bug fixes + * all internal string comparisons are now also case sensitive (e.g. for + providing DN to username lookups, etc) + * signal handling in the daemon was changed to behave more reliable across + different threading implementations + * nslcd will now always return a positive authorisation result during + authentication to avoid confusing the PAM module when it is only used for + authorisation (closes: #604147) + * implement configuring SASL authentication using Debconf, based on a patch + by Daniel Dehennin (closes: #586532) (not called for translations yet + because the English text is likely to change) + + -- Arthur de Jong Thu, 30 Dec 2010 20:00:00 +0100 + +nss-pam-ldapd (0.7.13) unstable; urgency=low + + * fix handling of idle_timelimit option + * fix error code for problem while doing password modification + + -- Arthur de Jong Sat, 11 Dec 2010 22:00:00 +0100 + +nss-pam-ldapd (0.7.12) unstable; urgency=low + + * set a short socket timeout when shutting down the connection to the LDAP + server to avoid disconnect problems when using TLS + (addresses part of #596983) + + -- Arthur de Jong Fri, 29 Oct 2010 18:00:00 +0200 + +nss-pam-ldapd (0.7.11) unstable; urgency=low + + * updated Vietnamese debconf translation by Clytie Siddall (closes: #598500) + * grow the buffer for the PAM ruser to not reject logins for users with + a ruser including a domain part (closes: #600065) + + -- Arthur de Jong Fri, 15 Oct 2010 15:30:00 +0200 + +nss-pam-ldapd (0.7.10) unstable; urgency=low + + * handle errors from ldap_result() better and disconnect (and reconnect) + in more cases (closes: #596983) + + -- Arthur de Jong Fri, 24 Sep 2010 09:00:00 +0200 + +nss-pam-ldapd (0.7.9) unstable; urgency=low + + * fix for --with-nss-ldap-soname configure option by Julien Cristau + * fix double "be" in English template thanks to Christian Perrier + (closes: #593646) + * updated Czech debconf translation by Miroslav Kure (closes: #593510) + * updated Simplified Chinese debconf translation by zym + * updated Italian debconf translation by Vincenzo Campanella + * updated Japanese debconf translation by Kenshi Muto (closes: #593692) + * updated Danish debconf translation by Joe Hansen (closes: #594205) + * updated French debconf translation by Christian Perrier (closes: #594311) + * updated German debconf translation by Chris Leick (closes: #594456) + * updated Catalan debconf translation by Agusti Grau + * updated Swedish debconf translation by Martin Ågren (closes: #594679) + * updated Spanish debconf translation by Francisco Javier Cuadrado + (closes: #594723) + + -- Arthur de Jong Sat, 28 Aug 2010 20:45:00 +0200 + +nss-pam-ldapd (0.7.8) unstable; urgency=low + + * minor portability improvements and clean-ups (thanks Alexander V. + Chernikov and Ted C. Cheng) + * don't expand variables in rest of ${var:-rest} and ${var:+rest} + expressions if it is not needed (closes: #592320) + * libpam-ldapd.postinst: offer to add ldap to shadow in nsswitch.conf if + a potential broken configuration is found (closes: #592104) + (thanks to Justin B Rye for the template review) + * merge the suggests of libnss-ldapd and libpam-ldapd into those of the + nslcd package to have a single consistent list of PAM alternatives + (closes: #591773) + * add libpam-sss as an alternative to libpam-ldapd (closes: #591773) + * upgrade to standards-version 3.9.1 (no changes needed) + * updated Portuguese debconf translation by Américo Monteir + (closes: #593404) + * updated Russian debconf translation by Yuri Kozlov (closes: #593491) + * added Norwegian Bokmål debconf translation by Bjørn Steensrud + (closes: #593501) + + -- Arthur de Jong Wed, 18 Aug 2010 21:00:00 +0200 + +nss-pam-ldapd (0.7.7) unstable; urgency=low + + * don't use use_authtok for password modification by default + * fine-tune pam-auth-update configuration after discussion with Steve + Langasek (see: #583492) + Note that this currently requires that shadow information is also provided + by LDAP (in /etc/nsswitch.conf). + * ensure that nslcd is started after hostname lookups are available so + getting to the LDAP server via DNS will work (patch by Petter + Reinholdtsen) (closes: #585968) + * start k5start from the init script to keep the Kerberos ticket active if + nslcd is configured for SASL GSSAPI Kerberos authentication, based on a + patch by Daniel Dehennin (closes: #585639) + * upgrade to standards-version 3.9.0 (switch to Breaks/Replaces instead of + Conflicts) + * refactoring and simplification of PAM module which also improves logging + * implement a nullok PAM option and disable empty passwords by default + * portability improvements and other minor code improvements + * the mechanism to disable name lookups through LDAP from within the nslcd + process has been improved + * the undocumented use_sasl option has been removed (specifying sasl_mech + now implies use_sasl) + * the sasl_mech, sasl_realm, sasl_authcid, sasl_authzid and sasl_secprops + configuration options are now documented + + -- Arthur de Jong Sat, 03 Jul 2010 17:00:00 +0200 + +nss-pam-ldapd (0.7.6) unstable; urgency=low + + * include libpam-heimdal in libnss-ldapd recommends list of PAM + implementations (closes: #582407) + * fix a problem with empty attributes if expression-based attribute + mapping is used (patch by Nalin Dahyabhai) + * make debug logging for pam_authz_search option a little more informative + * documentation improvements + * update pam-auth-update configuration to always perform LDAP autorisation + for LDAP users + + -- Arthur de Jong Thu, 27 May 2010 21:00:00 +0200 + +nss-pam-ldapd (0.7.5) unstable; urgency=low + + * fix a problem in the session handling of the PAM module if the minimum_uid + option was used (Debian package default) + * refactor the PAM module code to be simpler and better maintainable + * perform logging from PAM module to syslog and support the debug option to + log more information + * Switch to "3.0 (native)" format. + + -- Arthur de Jong Thu, 13 May 2010 20:17:39 +0200 + +nss-pam-ldapd (0.7.4) unstable; urgency=low + + * fix a buffer overflow that should have no security consequences + * perform proper fail-over when authenticating in the PAM module + (closes: #577593) + * add an nss_initgroups_ignoreusers option to ignore user name to group + lookups for the specified users + * add an pam_authz_search option to perform a flexible authorisation check + on login (e.g. to restrict which users can login to which hosts, etc) + * implement a minimum_uid option for the PAM module to ignore users that + have a lower numeric user id and make 1000 the default value for Debian + (closes: #579574) + * change the way retries are done to error out quicker if the LDAP server + is down for some time (this should make the system more responsive when + the LDAP server is unavailable) and rename the reconnect_maxsleeptime + option to reconnect_retrytime to better describe the behaviour + * only log "connected to LDAP server" if the previous connection failed + (closes: #483795) + * documentation improvements + * debian/nslcd.config: also parse /etc/ldap.conf for systems that put NSS + and PAM configuration there + + -- Arthur de Jong Sat, 08 May 2010 12:00:00 +0200 + +nss-pam-ldapd (0.7.3) unstable; urgency=low + + * allow password modification by root using the rootpwmoddn configuration + file option (the user will be prompted for the password for rootpwmoddn + instead of the user's password) + * the LDAP password modify EXOP is first tried without the old password and + if that fails retried with the old password + * when determining the domain name (used for some value of the base and uri + options) also try to use the hostname aliases to build the domain name + (patch by Jan Schampera) + * perform locking on the pidfile on start-up to ensure that only one nslcd + process is running and implement a --check option (patch by Jan Schampera) + * documentation improvements + * upgrade to standards-version 3.8.4 (no changes needed) + * start nslcd before apache for systems that use LDAP users to run virtual + hosts (closes: #565971) + + -- Arthur de Jong Sat, 27 Feb 2010 16:00:00 +0100 + +nss-pam-ldapd (0.7.2) unstable; urgency=low + + * some attributes may be mapped to a shell-like expression that expand + attributes from LDAP entries; this allows attributes overrides, defaults + and much more (as a result the passwd cn attribute mapping has been + removed because the gecos mapping is now "${gecos:-$cn}" by default) + * update the NSS module to follow the change in Glibc where the addr + parameter of getnetbyaddr_r() was changed from network-byte-order to + host-byte-order + * properly escape searches for uniqueMember attributes for DN with a comma + in an attribute value + * miscellaneous improvements to the configure script implementing better + (and simpler) library detection + * some general refactoring and other miscellaneous improvements + * make configure check if we need to explicitly link to -llber + (closes: #555779) + * libnss-ldapd: recommend libpam-krb5 as an alternative to libpam-ldapd for + Kerberos environments + * updated Italian debconf translation by Vincenzo Campanella + (closes: #556107) + * fix nslcd postrm to remove old config file (thanks piuparts) + + -- Arthur de Jong Mon, 28 Dec 2009 13:30:00 +0100 + +nss-pam-ldapd (0.7.1) unstable; urgency=low + + * implement password changing by performing an LDAP password modify EXOP + request (closes: #550836) + * fix return of authorisation check in PAM module (patch by Howard Chu) + * fix "Use StartTLS?" debconf question when no ssl option is defined in the + config + * fix for problem when authenticating to LDAP entries without a uid + attribute in the DN + * general code clean-up and portability improvements and include all + needed header files (closes: #547206) + * provide more information with communication error messages + * updated German debconf translation by Erik Schanze (closes: #546244) + * updated Vietnamese debconf translation by Clytie Siddall (closes: #548037) + + -- Arthur de Jong Tue, 20 Oct 2009 12:00:00 +0200 + +nss-pam-ldapd (0.7.0) unstable; urgency=low + + * rename software to nss-pam-ldapd to indicate that PAM module is now a + standard part of the software + * split into the binary packages libnss-ldapd, libpam-ldapd and nslcd + (libpam-ldapd packaging used a patch for libpam-ldap by Steve Langasek) + (closes: #535505) + * the configuration file name has been changed to /etc/nslcd.conf (package + upgrade should migrate the configuration) + * updated Galician debconf translation by Marce Villarino (closes: #537424) + * patch by Petter Reinholdtsen to fix init script to start before autofs + (closes: #544093) + * the default values for bind_timelimit and reconnect_maxsleeptime were + lowered from 30 to 10 seconds (closes: #532874) + * upgrade to standards-version 3.8.3 (no changes needed) + * password hashes are no longer returned to non-root users (based on a patch + by Alexander V. Chernikov) + + -- Arthur de Jong Tue, 01 Sep 2009 17:00:00 +0200 + +nss-ldapd (0.6.11) unstable; urgency=low + + * fix user name to groups mapping (a bug in buffer checking in initgroups() + that was introduced in 0.6.9) + * fix a possible buffer overflow with too many uidNumber or gidNumber + attributes (thanks to David Binderman for finding this) + * lookups for group, netgroup, passwd, protocols, rpc, services and shadow + maps are now case-sensitive + * test suite is now minimally documented + * added --disable-sasl and --disable-kerberos configure options + * changed references to home page and contact email addresses to use + arthurdejong.org + * upgrade to standards-version 3.8.2 (no changes needed) + * make configuring SSL/TLS possible with debconf (closes: #529985) + * updated Finnish debconf translation by Esko Arajärvi (closes: #534343) + * updated Japanese debconf translation by Kenshi Muto (closes: #534399) + * updated Russian debconf translation by Yuri Kozlov (closes: #534780) + * updated Swedish debconf translation by Martin Ågren (closes: #534869) + * updated Spanish debconf translation by Francisco Javier Cuadrado + (closes: #535438) + * updated Portuguese debconf translation by Américo Monteiro + (closes: #535641) + * updated Czech debconf translation by Miroslav Kure (closes: #535678) + * updated French debconf translation by Christian Perrier (closes: #536717) + + -- Arthur de Jong Sun, 12 Jul 2009 22:30:00 +0200 + +nss-ldapd (0.6.10) unstable; urgency=low + + * implement searching through multiple search bases, based on a patch by + Leigh Wedding + * fix a segmentation fault that could occur when using any of the tls_* + options with a string parameter (closes: #531113) + * miscellaneous improvements to the experimental PAM module + * implement PAM authentication function in the nslcd daemon + * the code for reading and writing protocol entries between the NSS module + and the daemon was improved + * documentation updates + * removed SSL/TLS related warnings during startup + * added Finnish debconf translation by Esko Arajärvi (closes: #530284) + * added Richard A Nelson (Rick) to uploaders + + -- Arthur de Jong Wed, 03 Jun 2009 15:00:00 +0200 + +nss-ldapd (0.6.9) unstable; urgency=low + + * produce more detailed logging in debug mode and allow multiple -d options + to be specified to also include logging from the LDAP library + * some LDAP configuration options are now initialized globally instead of + per connection which should fix problems with the tls_reqcert option + (closes: #521617) + * documentation improvements for the NSLCD protocol used between the NSS + module and the nslcd server + * imported the new PAM module from the OpenLDAP nssov tree by Howard Chu + (note that the PAM-related NSLCD protocol is not yet finalised and this + module is not built by default) + * in configure script allow disabling of building certain components + * fix a problem with writing alternate service names and add checks for + validity of passed buffer in NSS module (closes: #527246) + * ask the user whether LDAP should be removed from /etc/nsswitch.conf at + package removal time (closes: #523483) + * remove /var/run/nslcd on package removal + * updated Danish debconf translation by Jonas Smedegaard (closes: #525075) + * updated Japanese debconf translation by Kenshi Muto (closes: #525085) + * updated Portugese debconf translation by Américo Monteiro + (closes: #525530) + * added Italian debconf translation by Vincenzo Campanella (closes: #525784) + * updated French debconf translation by Guillaume Delacour (closes: #526638) + * updated Swedish debconf translation by Martin Ågren (closes: #526757) + * updated Russian debconf translation by Yuri Kozlov (closes: #527102) + * updated Spanish debconf translation by Francisco Javier Cuadrado + (closes: #527242) + * added Galician debconf translation by Marce Villarino (closes: #527327) + + -- Arthur de Jong Sat, 09 May 2009 22:00:00 +0200 + +nss-ldapd (0.6.8) unstable; urgency=high + + * SECURITY FIX: the nss-ldapd.conf file that is installed was created + world-readable which could cause problems if the bindpw + option is used (CVE-2009-1073) + this has been fixed and warnings have been added to the + manual page and sample nss-ldapd.conf (closes: #520476) + * clean the environment and set LDAPNOINIT to disable parsing of LDAP + configuration files (.ldaprc, /etc/ldap/ldap.conf, etc) + * remove sslpath option because it wasn't used + * correctly set SSL/TLS options when using StartTLS + * rename the tls_checkpeer option to tls_reqcert, deprecating the old name + and supporting all values that OpenLDAP supports + * allow backslashes in user and group names execpt as first or last + character + * check user and group names against LOGIN_NAME_MAX if it is defined + * fix for getpeercred() on Solaris by David Bartley + * debian/control: change section to admin to follow change in override file + * add lintian override for missing shlibs and symbols control files (we are + a shared library that should not be directly linked to) + * upgrade to standards-version 3.8.1 (no changes needed) + * upgrade to debhelper compatibility level 7 + + -- Arthur de Jong Sat, 22 Mar 2009 22:00:00 +0100 + +nss-ldapd (0.6.7) unstable; urgency=low + + * a fix for a problem in debconf configuration that would ignore user input + and use automatically detected values instead (closes: #505384) + + -- Arthur de Jong Fri, 14 Nov 2008 16:30:00 +0100 + +nss-ldapd (0.6.6) unstable; urgency=low + + * clarify relationship to nss_ldap in package description (closes: #499892) + * fix test for nscd init script in postinst (closes: #504142) + * allow spaces in user and group names (closes: #488635) + * if ldap_set_option() fails log the option name instead of number + * retry connecting to LDAP server in more cases + + -- Arthur de Jong Tue, 04 Nov 2008 22:30:00 +0100 + +nss-ldapd (0.6.5) unstable; urgency=low + + * updated Swedish debconf translation by Martin Ågren (closes: #492910) + * updated Danish debconf translation by Jonas Smedegaard (closes: #493973) + + -- Arthur de Jong Fri, 22 Aug 2008 11:00:00 +0200 + +nss-ldapd (0.6.4) unstable; urgency=medium + + * set urgency medium in an attempt to get in before the freeze + (not much code changes) + * fix for the tls_checkpeer option + * fix incorrect test for ssl option in combination with ldaps:// URIs + * improvements to Active Directory sample configuration + * implement looking up search base in rootDSE of LDAP server + (closes: #489361) + + -- Arthur de Jong Sun, 20 Jul 2008 10:30:00 +0200 + +nss-ldapd (0.6.3) unstable; urgency=low + + * retry connection and search if getting results failed with connection + problems (some errors only occur when getting the results, not when + starting the search) (closes: #474178, #484798) + * add support for groups with up to around 150000 members (assuming user + names on average are a little under 10 characters) + (closes: #481077, #479552) + * problem with possible SIGPIPE race condition was fixed by using send() + instead of write() + * add uid and gid configuration keywords that set the user and group of the + nslcd daemon + * run nslcd as user nslcd and group nslcd by default (note that this can + affect access to SSL/TLS and/or SASL files) + * add some documentation on supported group to member mappings + * add sanity checking to code for when clock moves backward + (closes: #480197) + * log messages now include a session id that makes it easier to track errors + to requests (especially useful in debugging mode) + * miscellaneous portability improvements + * increase buffers and timeouts to handle large lookups more gracefully + (further addresses #474174) + * implement SASL authentication based on a patch by Dan White + * allow more characters in user and group names + * upgrade to standards-version 3.8.0 (no changes needed) + * removed lintian override (seems to be no longer necessary) + + -- Arthur de Jong Sun, 15 Jun 2008 15:00:00 +0200 + +nss-ldapd (0.6.2) unstable; urgency=low + + * all user and group names are now checked for validity are specified in the + POSIX Portable Filename Character Set + * support retrieval of ranged attribute values as sometimes returned by + Active Directory (closes: #476454) + * added the threads keyword to configure the number of threads that should + be started in nslcd + * handle empty netgroups properly (closes: #478764) + * change the time out and retry mechanism for connecting to the LDAP server + to return an error quickly if the LDAP server is known to be unavailable + for a long time (this removed the reconnect_tries option and changes the + meaning of the reconnect_sleeptime and reconnect_maxsleeptime options) + (closes: #474174) + * increased the time out values between the NSS module and nslcd because of + new retry mechanism + * implement new dict and set modules that use a hashtable to map keys + efficiently + * use the new set to store group membership to simplify memory management + and eliminate duplicate members (closes: #474218) + * the uniqueMember attribute now only supports DN values + * implement a cache for DN to user name lookups (15 minute timeout) used for + the uniqueMember attribute to save on doing LDAP searches for groups with + a lot of members, based on a patch by Petter Reinholdtsen + (closes: #478267) + * only guess default search base in package configuration if the value + doesn't seem to be preseeded (closes: #475830) + * improvements to the tests + * if any of the ldap calls return LDAP_UNAVAILABLE or LDAP_SERVER_DOWN the + connection is closed + * improve dependencies in LSB init script header to improve dependency based + booting (closes: #478807) + + -- Arthur de Jong Sun, 04 May 2008 14:30:00 +0200 + +nss-ldapd (0.6.1) unstable; urgency=low + + * new release (closes: #474232) + * numerous small fixes and compatibility improvements + * the I/O buffers between nslcd and NSS module are now dynamically sized and + tuned for common requests + * correctly follow referrals + * add StartTLS support by Ralf Haferkamp of SuSE + * miscellaneous documentation improvements + * remove code for handling rootbinddn/pw because it is unlikely to be + supported any time soon + * fix a problem with realloc()ed memory that was not referenced + (closes: #472814) + * fix for a crash in group membership buffer growing code thanks to Petter + Reinholdtsen + * some improvements to the Active Directory sample configuration + * remove warning for failing to retrieve objectClass (closes: #472872) + * fix init script exit code with stop while not running (closes: #473920) + * fixes to the _nss_ldap_initgroups_dyn() function to properly handle the + buffer and limits passed by Glibc + * fixes to the member to groups search functions to correctly handle + uniqueMember attributes + * only return shadow entries to root users + * make maintainer scripts more gracefully handle repeated options + (closes: #471131) + * fix a problem with rootbinddn being incorrectly copied from + /etc/libnss-ldap.conf on installation (closes: #471146) + * fix handling of spaces in values when using debconf (closes: #474371) + * updated Spanish debconf translation by Rudy Godoy Guillén + (closes: #463894) + * updated Dutch debconf translation by Bart Cornelis (closes: #469176) + + -- Arthur de Jong Sun, 06 Apr 2008 13:00:00 +0200 + +nss-ldapd (0.6) unstable; urgency=low + + * fix parsing of map option in nss-ldapd.conf + * fix bug in handling of userPassword values + * remove warning about missing loginShell attribute + * support the uniqueMember LDAP attribute that holds DN values + * support ldap as a compat service in /etc/nsswitch.conf + * implement _nss_ldap_initgroups_dyn() to allow username->groups searches + * fix retry mechanism with get*ent() functions where a too small buffer was + passed by libc (to support groups with a lot of members) (closes: #457936) + * fix a bug in reporting of communications problems between nslcd and the + NSS library + * test and log failures of all LDAP library calls + * improved tests + * miscellaneous compatibility improvements to try to support more LDAP + libraries and platforms + * support compilation with OpenLDAP 2.4 and newer + * define LDAP_DEPRECATED for now to have definitions for deprecated + functions (closes: #463421) + * some configure script improvements + * updated German debconf translation by Erik Schanze (closes: #462841) + * install the NSS library under /lib instead of /usr/lib to make it easier + to umount /usr if it's on a separate file system (closes: #439355) + * don't ship a shlibs file any more because we're not providing a normal + shared library + + -- Arthur de Jong Sun, 03 Feb 2008 22:00:00 +0100 + +nss-ldapd (0.5) unstable; urgency=low + + * major structural changes in the LDAP lookup code using a newly implemented + module that does memory management, session handling, paging and all other + painful things with a simple interface + * rewritten LDAP query and result handling code, now generating warnings + about incorrect entries in the LDAP directory + * IPv6 addresses in host lookups are now supported + * added Kerberos ccname support (with the krb5_ccname option) thanks to + Andreas Schneider and Ralf Haferkamp from SuSE and remove + --with-gssapi-dir, --enable-configurable-krb5-ccname-gssapi and + --enable-configurable-krb5-ccname-env configure options and having + automatic detection instead + * added support for DNS SRV record lookups by specifying DNS as uri thanks + to Ralf Haferkamp and Michael Calmer from SuSE + * added support for DOMAIN as base DN which uses the host's domain to + construct a DN + * removed nss_connect_policy, bind_policy and sizelimit options + * cleaned up and documented reconnect logic with reconnect_tries, + reconnect_sleeptime and reconnect_maxsleeptime options + * configuration values with spaces in them (e.g. distinguished names) are + now handled properly + * fix a small memory leak in the I/O module + * miscellaneous code improvements (better source code comments, more + consistent logging, portability improvements, more tests, etc) + * improvements to documentation + + -- Arthur de Jong Wed, 27 Dec 2007 11:00:00 +0100 + +nss-ldapd (0.4.1) unstable; urgency=low + + * updated French debconf translation by Cyril Brulebois (closes: #433248) + * updated Japanese debconf translation by Kenshi Muto (closes: #446580) + * remove S runlevel from Default-Stop in init script (closes: #447949) + * fix a problem with network name lookups where the lookup would result + in the wrong call to nslcd + * fix wrong default filter for rpc lookups + * fix a number of memory leaks (thanks valgrind) (closes: #447997) + (all memory leaks during normal operation should be fixed now) + + -- Arthur de Jong Thu, 26 Oct 2007 10:00:00 +0200 + +nss-ldapd (0.4) unstable; urgency=low + + * remove nss_schema configfile option + * temporary remove support for uniqueMember group membership attributes + (will be re-added in a later release) + * removed support for nested groups, if this is really needed (please ask or + file a bug if you want it) it can be re-added later on + * added missing docbook sources for manual pages to tarball (closes: #442688) + * major cleanups and simplifications in the core LDAP query code (we don't + need to worry about SIGPIPE because nslcd does that globally, locking + because a connection is only used by one thread) and more simplifications + in the the LDAP connection and query state + * get base, scope, filter and map configfile directives properly working + * simplifications in LDAP reconnect logic (some work remains to be done in + this area) + * issue warnings or errors for untested or unsupported configuration options + * properly handle multiple URIs in Debian configuration + * documentation improvements + + -- Arthur de Jong Fri, 05 Oct 2007 22:00:00 +0200 + +nss-ldapd (0.3) unstable; urgency=low + + * added XS-Vcs-Svn and XS-Vcs-Browser as specified in #391023 + * improved manual pages and use docbook2x-man for generating them + * a bug in the communication buffer handling code was fixed + * a bug in the dictionary code was fixed (code not yet in use) + * a fix for the init script that used a wrong pidfile + * configuration file handling code was rewritten to better maintainable + * some configuration file options have changed which means that + compatibility with the nss_ldap configuration file is lost + * configuration syntax is now documented in the nss-ldapd.conf(5) manual + page + * support for dnsconfig was removed + * the configuration file no longer supports using multiple search bases + * removed nss_initgroups and nss_initgroups_ignoreusers options + * removed --enable-paged-results configure option and use pagesize + configuration file option to specify usage of paging at runtime + * added Portuguese debconf translation by Américo Monteiro + (closes: #433039) + * Debian package configuration improvements and simplifications + * use docbook2x-man for generating manual pages + * miscellaneous documentation improvements including improved manual pages + * general code reorganisation and clean-ups to achieve another 9% code + reduction relative to 0.2.1 release (more than 40% relative to nss_ldap) + * SASL, Kerberos and SSL/TLS support remain untested + + -- Arthur de Jong Sun, 26 Aug 2007 19:00:00 +0200 + +nss-ldapd (0.2.1) unstable; urgency=low + + * fix permissions of server socket (this fixes a problem where non-root + users were unable to do lookups) + * fix configure script to properly check for pthread support + * small code improvements + * general build system cleanups + * add more information to debian/copyright + + -- Arthur de Jong Sun, 17 Jun 2007 18:30:00 +0200 + +nss-ldapd (0.2) unstable; urgency=low + + * fixes to the netgroup lookup code + * more simplifications and improvements in the code almost 5% code reduction + (compared to release 0.1) and 37% reduction in gcc warnings (from 443 in + 251 to 389 in 0.1 and 244 in 0.2) + * a lot of code improvements thanks to flawfinder, more gcc warnings, splint + and rats + * license change from GNU Library General Public License to GNU Lesser + General Public License (with the permission of Luke Howard) + * fix logging code to be cleaner and always use our own logging module + * a start has been made to make the code more testable and initial work to + set up a testing framework + * implemented a timeout mechanism in the communication between the NSS part + and the nslcd server part + * install NSS library files in /usr/lib instead of /lib (they won't work + without /usr anyway) + * fixed debian/copyright file to include information on all files + + -- Arthur de Jong Sun, 10 Jun 2007 01:27:52 +0200 + +nss-ldapd (0.1) unstable; urgency=low + + * initial release of nss-ldapd (should be functional but not yet stable + enough for production use) + * fork from the nss_ldap which was originally written by Luke Howard of PADL + Software Pty Ltd. changing package name to nss-ldapd and changing + versioning schema + * the functionality was split into a thin NSS library and a simple daemon + proxying the requests to the LDAP server (see README for rationale) + * a lot of dead and old compatibility code was removed (about 25% of the + code was removed) (more simplifications to come) + * the test code was rewritten + * build script simplifications + * default configuration file has been changed to /etc/nss-ldapd.conf + * most documentation has been updated and rewritten + * improved Debian packaging configuration with auto-detection of proper + default settings + * switched to native package (no deviation from "upstream") + + -- Arthur de Jong Fri, 22 Dec 2006 23:00:00 +0100 + +libnss-ldap (251-5.2) unstable; urgency=high + + * Non-maintainer upload. + * When doing substitutions in libnss-ldap.conf, pass the values to the Perl + program as environment variables instead of directly to the program; + should eliminate the problems with having to escape them. + (Closes: #376684, #386141) + * Change the init script policy. Instead of stopping libnss-ldap.init on + clean shutdown (touching a file) and starting it after networking (rm-ing + it), we touch the file in /lib/init/rw as soon as possible (right before + udev is started, touching a file) and stop it after initial system bootup. + This fixes both issues with /var being on a separate partition, and + unclean shutdown where the file would not be created. (To make sure we + don't get similar problems during shutdown, we create it in runlevels 0 + and 6 as before, but we don't assume it's still there when we boot, since + it's on a tmpfs now.) (Closes: #375077) + * Block SIGPIPE in do_atfork_child(), as some versions of libldap2 in some + circumstances (notably with TLS enabled) write data onto our dummy socket + during close, which raises a SIGPIPE that should not be delivered on to the + application. (Closes: #376426, #388574) + + -- Steinar H. Gunderson Fri, 29 Sep 2006 12:29:33 +0200 + +libnss-ldap (251-5.1) unstable; urgency=low + + * Fixed regexp in postinstall script as described by + Peter Buecker in the BTS (closes: #377895) + + -- Mathias Weyland Sat, 9 Sep 2006 18:28:54 +0200 + +libnss-ldap (251-5) unstable; urgency=low + + * Handle case when /var/lib is not yet available + (ie: very early in the boot process) + + -- Stephen Frost Mon, 26 Jun 2006 14:53:29 -0400 + +libnss-ldap (251-4) unstable; urgency=low + + * Added system which implicitly sets bind_policy to 'soft' + during system boot/shutdown. This is implemented by an + init script run at end of system boot and start of system + shutdown which creates/removes a file in /var/lib/libnss-ldap + called 'bind_policy_soft'. When this file exists the policy + is treated as 'soft' regardless of the configuration in + /etc/nss-ldap.conf. Note that soft doesn't mean 'always + fail' but rather only try to connect to each URI listed in + the configuration file once, with no sleeping. + Closes: #375077, #375215 + + -- Stephen Frost Mon, 26 Jun 2006 14:03:21 -0400 + +libnss-ldap (251-3) unstable; urgency=low + + * Handle both host and uri cases from debconf, Closes: #375097 + * Escape dashes in value handling, Closes: #375108 + + -- Stephen Frost Fri, 23 Jun 2006 23:11:24 -0400 + +libnss-ldap (251-2) unstable; urgency=low + + * Copy existing ldap.secret to new location, if it exists. + + -- Stephen Frost Thu, 22 Jun 2006 21:59:20 -0400 + +libnss-ldap (251-1) unstable; urgency=low + + * New upstream version, Closes: #332600 + * Upstream fixes, Closes: #323580, #302391, #308490 + * Maintainer upload, Closes: #316973, #335133 + * Changed debconf 'host' question to 'uri', Closes: #312284, #359341 + * Added additional commentary to the ldap.conf, Closes: #368191, #369192 + * Enabled configurable krb5 CCNAME, Closes: #352032 + * Included Swedish, Vietnamese and Czech translations, + Closes: #317672, #312435, #340633 + * Modified syslog() calls to use LOG_AUTHPRIV facility, Closes: #310421 + * Removed build-depend on libdb4.2-dev, Closes: #302541 + * Changed nscd restart to use invoke-rc.d, Closes: #367766 + * Changed depends to allow debconf-2.0, Closes: #332001 + * Ensure that libnss-ldap is compiled with libpthread, + Closes: #314461, #330911, #366540, #347477 + * Changed to using upstream manpage, Closes: #302396 + * Added escaping to password handling, Closes: #341539 + * Moved ldap.secret to libnss-ldap.secret, Closes: #302562 + * Upstream removed RFC from tarball, Closes: #199810 + * Cleaned up copyright file, Closes: #364051 + * Fixed possible overflow in uid/gid handling, Closes: #354093 + + -- Stephen Frost Thu, 22 Jun 2006 10:01:07 -0400 + +libnss-ldap (238-1) unstable; urgency=low + + * New upstream version, Closes: #292538 + * Appears to be fixed accorindg to upstream changelog, Closes: #282209 + * Added --enable-paged-results, Closes: #272793, #273793 + * Link against libldap_r instead of libldap, Closes: #277640 + * Updated Catalan translation, Closes: #279432 + * Updated German translation, Closes: #280996 + + -- Stephen Frost Tue, 29 Mar 2005 23:04:48 -0500 + +libnss-ldap (220-1) unstable; urgency=low + + * New upstream version, Closes: #254605, #259243 + (Apparently, anyway. I reproduced the problem with the old + version and then installed the new and it fixed it. I'm + not 100% sure that a malformed DB_CONFIG couldn't still + cause some problem though. It would seem more like a + problem w/ libdb in any case though...) + (Why was this sev:normal?) Closes: #254608, #258811 + * Updated Russian translation, Closes: #221658 + * Netgroups Description fixed, Closes: #222602, #222603 + * Updated French translation, Closes: #235163 + * Updated Danish translation, Closes: #235316 + * Added Catalan translation, Closes: #248721 + + -- Stephen Frost Sat, 7 Aug 2004 15:49:05 -0400 + +libnss-ldap (215-1) unstable; urgency=low + + * New upstream version. + + -- Stephen Frost Sun, 15 Feb 2004 22:08:50 -0500 + +libnss-ldap (211-4) unstable; urgency=low + + * Try again to fix the build problem on the buildds. Very odd. + + -- Stephen Frost Fri, 3 Oct 2003 09:33:06 -0400 + +libnss-ldap (211-3) unstable; urgency=low + + * Attempt to fix build problem with installing nss_ldap.so into debian/tmp + (It didn't create the directories for some reason.. Very odd.) + + -- Stephen Frost Thu, 2 Oct 2003 16:14:14 -0400 + +libnss-ldap (211-2) unstable; urgency=low + + * Add -fPIC for silly systems, Closes: #213513. + + -- Stephen Frost Wed, 1 Oct 2003 14:56:44 -0400 + +libnss-ldap (211-1) unstable; urgency=low + + * New upstream release, Closes: #207046. + * New maintainer + * Moved to CDBS + * Nuked the (pretty much) unnecessary/unused patches. + * Added nl.po and ja.po translations, Closes: #204758, #210973. + * Added minor patch to improve logging, Closes: #194044. + * Added in people.ldif/groups.ldif examples, Closes: #202629. + + -- Stephen Frost Wed, 10 Sep 2003 22:19:21 -0400 + +libnss-ldap (207-1) unstable; urgency=low + + * New upstream release (Closes: #192161) + * Updated standards-version to 3.5.9, no changes. + * Make the build scripts use -fPIC for the whole process. (Closes: #185937) + * Removed LdapNS-howto, it's outdated (Closes: #179359) + * Updated nsswitch.ldap to reflect the current state of libnss-ldap + (Closes: #192208) + + -- Sami Haahtinen Fri, 9 May 2003 13:35:31 +0300 + +libnss-ldap (204-3) unstable; urgency=low + + * Re-update the french Debconf translations from bug #183953.. bad DDTP! + BAD! (Closes: #185914) + * Regenerate automake and autoconf files (Closes: #185937) + + -- Sami Haahtinen Sun, 23 Mar 2003 11:16:48 +0200 + +libnss-ldap (204-2) unstable; urgency=low + + * Fixed the build problems, by adding automake1.6 to dependancies + (Closes: #184692) + * Added debconf translations from ddtp + + -- Sami Haahtinen Fri, 14 Mar 2003 22:44:55 +0200 + +libnss-ldap (204-1) unstable; urgency=low + + * New upstream release + * Switched to CBS. + * Disabled our IPv6 patch, the upstream has new additions to IPv6 + + -- Sami Haahtinen Sun, 9 Mar 2003 02:41:03 +0200 + +libnss-ldap (203-1) unstable; urgency=low + + * New upstream release + * Applied patch by Steve Langasek to read the debconf questions from the + configuration file instead of using the previously given (Closes: #156858) + * Bumped Standards-Version to 3.5.8.0 + + -- Sami Haahtinen Mon, 16 Dec 2002 21:39:44 +0200 + +libnss-ldap (202-0.1) unstable; urgency=low + + * Non-maintainer upload + * New upstream release + * partially fix IPv6 problems + + -- Bastian Blank Sun, 15 Dec 2002 17:51:06 +0100 + +libnss-ldap (199-1) unstable; urgency=low + + * New upstream release + * Upstream added new option bind_policy added documentation to manual + * Enabling SSL support again. (Closes: #147106) + * Added libdb-dev to build depends, schema mapping needs it. + * Changed config to use Debconf::Client::ConfModule now that woody is out. + * Fixed the ###DEBCONF### detection which caused a bit of problems for some + users. + + -- Sami Haahtinen Wed, 14 Aug 2002 19:43:57 +0300 + +libnss-ldap (188-1) unstable; urgency=low + + * New upstream release + * Upstream now includes the patch from Luca Filipozzi which improves the + socket handling in extreme cases. (Closes: #140854) + + -- Sami Haahtinen Tue, 7 May 2002 22:28:58 +0300 + +libnss-ldap (186-1) unstable; urgency=low + + * New upstream release + * Added french translation of debconf templates. + Thanks go to Philippe Batailler (Closes: #140827) + * Upstream included the patch from bug 140854, which adds better handling of + extreme filehandle usage, a big thanks to Luca Filipozzi for sorting this + out with the upstream (Closes: #140854) + * Added an extra note about ###DEBCONF### in configuration to README.Debian, + hopefully people will read it. there is a note about this when debconf is + run, but it's not critical so it's on medium priority. sigh... + (Closes: #139959) + * enabled schema mapping (Closes: #131280) + * Made postinst change the permission back from 0600 if it wasn't wanted, + interestin and ugly hack, but hey.. atleast it works.. =) + (Closes: #130871) + + -- Sami Haahtinen Thu, 4 Apr 2002 21:20:40 +0300 + +libnss-ldap (184-2) unstable; urgency=low + + * Setting FD_CLOEXEC to the socket. (Closes: #136953) + + -- Sami Haahtinen Sun, 24 Mar 2002 21:17:22 +0200 + +libnss-ldap (184-1) unstable; urgency=low + + * New upstream release + * Improved SIGPIPE handling (Closes: #130006,#92199) + * Rebuild fixes bug 133398 (Closes: #133398) + + -- Sami Haahtinen Sat, 16 Feb 2002 12:35:19 +0200 + +libnss-ldap (176-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Wed, 9 Jan 2002 10:05:30 +0200 + +libnss-ldap (174-1) unstable; urgency=medium + + * New upstream release + * Moved Configuration template to /usr/share/libnss-ldap + * Changed config to use the stubbed Debconf library (and raised the urgency + to medium, this needs to go to woody) (Closes: #121918) + * Applied the Grammar Patch by Branden Robinson (Closes: #121567) + * Fixed some major stupidity in Debconf configuration script. + + -- Sami Haahtinen Tue, 11 Dec 2001 15:32:03 +0200 + +libnss-ldap (173-1) unstable; urgency=low + + * New upstream release + * Added Brazilian translation, thanks to Andre Luis Lopes (Closes: #114007) + + -- Sami Haahtinen Sat, 17 Nov 2001 00:42:07 +0200 + +libnss-ldap (172-1) unstable; urgency=low + + * New upstream release + * Fixed priorities, related to bug #108864 + * Rewrote configuration script in perl, still the same is waiting for + postinst + + -- Sami Haahtinen Wed, 5 Sep 2001 22:00:48 +0300 + +libnss-ldap (163-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Wed, 11 Jul 2001 20:09:48 +0300 + +libnss-ldap (162-1) unstable; urgency=low + + * New upstream release + * This release fixes the syncronous lookups bug.. + + -- Sami Haahtinen Wed, 11 Jul 2001 16:54:41 +0300 + +libnss-ldap (161-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Tue, 10 Jul 2001 17:21:40 +0300 + +libnss-ldap (160-2) unstable; urgency=low + + * removed the _nss_ldap_getbyname synchronous patch (Closes: #103734) + + -- Sami Haahtinen Sat, 7 Jul 2001 00:51:45 +0300 + +libnss-ldap (160-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Thu, 5 Jul 2001 17:40:10 +0300 + +libnss-ldap (159-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Thu, 28 Jun 2001 09:47:59 +0300 + +libnss-ldap (156-1) unstable; urgency=low + + * New upstream release + * Finally a working version! + * --disable-ssl was applied upstream + + -- Sami Haahtinen Fri, 22 Jun 2001 08:26:41 +0300 + +libnss-ldap (155-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Wed, 20 Jun 2001 23:57:02 +0300 + +libnss-ldap (154-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Wed, 20 Jun 2001 10:02:31 +0300 + +libnss-ldap (153-1) unstable; urgency=low + + * New upstream release + * Added patch: --disable-ssl + + -- Sami Haahtinen Tue, 5 Jun 2001 23:06:14 +0300 + +libnss-ldap (150-4) unstable; urgency=low + + * Fixed bash-ism in postinst (Closes: #95275) + + -- Sami Haahtinen Thu, 26 Apr 2001 22:17:06 +0300 + +libnss-ldap (150-3) unstable; urgency=low + + * 'Not really my day' release. + * This time really fixed the one broken db_input (Closes: #94795) + * added Debconf question for LDAP version (Closes: #94789) + * cleaned up the example ldap.conf which is used as a base for a new install + + -- Sami Haahtinen Sun, 22 Apr 2001 11:03:04 +0300 + +libnss-ldap (150-2) unstable; urgency=low + + * missed one db_input when i was checking for '|| true's fixed now. + (Closes: #94710) + + -- Sami Haahtinen Sat, 21 Apr 2001 19:37:57 +0300 + +libnss-ldap (150-1) unstable; urgency=low + + * New upstream release + * Converted to debconf + * /etc/libnss-ldap.conf is no longer listed as a conffile + + -- Sami Haahtinen Mon, 16 Apr 2001 01:40:54 +0300 + +libnss-ldap (149-2) unstable; urgency=low + + * Removed reference to debconf from postinst (Closes: #93180) + + -- Sami Haahtinen Sat, 7 Apr 2001 14:42:09 +0300 + +libnss-ldap (149-1) unstable; urgency=low + + * New upstream release + + -- Sami Haahtinen Sun, 11 Mar 2001 18:50:15 +0200 + +libnss-ldap (140-3) unstable; urgency=low + + * Took over the package from evo + + -- Sami Haahtinen Wed, 28 Feb 2001 15:24:38 +0200 + +libnss-ldap (140-2) unstable; urgency=low + + * Fixed debian/rules to remove debug stuff (yes, upstream configure is + broken, already reported); closes: #85084. + + -- Davide Puricelli (evo) Tue, 6 Feb 2001 14:37:46 +0100 + +libnss-ldap (140-1) unstable; urgency=low + + * New upstream version. + * I've decided to remove all debconf support from /etc/libnss-ldap.conf + until I manage to find a better way to handle configuration modifications. + closes: #82102, #83766. + + -- Davide Puricelli (evo) Mon, 5 Feb 2001 17:25:35 +0100 + +libnss-ldap (123-2) unstable; urgency=low + + * "s/Suggests/Depends" debconf; debconf ask you if you want or not to use the + ldap version of /etc/nsswitch.conf; closes: #78110. + + -- Davide Puricelli (evo) Tue, 28 Nov 2000 19:56:37 +0100 + +libnss-ldap (123-1) unstable; urgency=low + + * New upstream version. + * Fixed a stupid typo into debian/templates. + + -- Davide Puricelli (evo) Fri, 24 Nov 2000 16:10:41 +0100 + +libnss-ldap (122-2) unstable; urgency=low + + * Compiled against libldap2 2.0.7-1; closes: #72118, #75325. + Thanks to Martijn van de Streek and Sami Haahtinen. + + * Added "Suggests: debconf" and removed some debug stuff from postinst; + closes: #76363. + + * debian/postinst: now we must restart nscd if it's running. + + -- Davide Puricelli (evo) Sat, 11 Nov 2000 19:15:41 +0100 + +libnss-ldap (122-1) unstable; urgency=HIGH + + * New upstream version that fixes an important security related bug. + For more info check http://bugzilla.padl.com/show_bug.cgi?id=49. + + -- Davide Puricelli (evo) Fri, 3 Nov 2000 21:28:45 +0100 + +libnss-ldap (120-1) unstable; urgency=low + + * New upstream version. + * Added debconf support, patch provided by Michael Vogt . + * Standard compliant to 3.2.1 + + -- Davide Puricelli (evo) Sun, 15 Oct 2000 13:37:11 +0200 + +libnss-ldap (118-1) unstable; urgency=low + + * New upstream version. + * This situation isn't reproducible by me or other people, probably + it's a local problem, so I'm closing it; if it occurs also with new + upstream version feel free to reopen the bug. closes: #72118. + * Now ssh doesn't segfault, here we go! :) + + -- Davide Puricelli (evo) Thu, 12 Oct 2000 17:33:27 +0200 + +libnss-ldap (116-2) unstable; urgency=low + + * Oops, previous version was broken, now it should work, + I hope :); closes: #71749. + + -- Davide Puricelli (evo) Mon, 18 Sep 2000 19:05:21 +0200 + +libnss-ldap (116-1) unstable; urgency=low + + * New upstream version. + * Compiled against libldap2. + + -- Davide Puricelli (evo) Thu, 14 Sep 2000 19:38:32 +0200 + +libnss-ldap (115-1) unstable; urgency=low + + * New upstream version. + + -- Davide Puricelli (evo) Thu, 31 Aug 2000 17:06:59 +0200 + +libnss-ldap (113-1) unstable; urgency=low + + * New maintainer. + * New upstream version. + * Fixed LdapNS-howto.txt; closes: #68430. + * ldapmigrate and ldapinit are into a different upstream + tarball; closes: #66194. + + -- Davide Puricelli (evo) Wed, 23 Aug 2000 21:51:06 +0200 + +libnss-ldap (110-2) frozen unstable; urgency=low + + * Fix minor (but important) thinko in previous patch + + -- Ben Collins Thu, 29 Jun 2000 22:48:41 -0400 + +libnss-ldap (110-1) frozen unstable; urgency=low + + * uptream patch merge with fixes, closes: #62695 + * After looking at this, I think it is better to let nss_ldap continue + to use only RFC compliant attributes and not support non-RFC compliant + ones, closes: #48953 + * Added patch to escape search filter from user input, closes: #66116 + + -- Ben Collins Thu, 29 Jun 2000 22:08:38 -0400 + +libnss-ldap (99-1) unstable; urgency=low + + * New upstream version. + + -- Ben Collins Thu, 16 Dec 1999 21:30:07 -0500 + +libnss-ldap (97-1) unstable; urgency=low + + * New upstream version, ChangeLog reports fix for..., closes: #48953 + + -- Ben Collins Thu, 25 Nov 1999 01:27:27 -0500 + +libnss-ldap (87-1) unstable; urgency=low + + * New upstream version + * Standard compliant to 3.0.1.1 + + -- Ben Collins Sun, 3 Oct 1999 14:40:59 -0400 + +libnss-ldap (2.65-1) unstable; urgency=low + + * New upstream source + * Reompiled against newest libopenldap1 + + -- Ben Collins Sat, 12 Jun 1999 14:35:49 -0400 + +libnss-ldap (2.64-1) unstable; urgency=low + + * New upstream release + * Removed nsswitch.ldap from /etc on install...it's still in /usr/doc + closed: #37186 + + -- Ben Collins Sat, 8 May 1999 20:11:04 -0400 + +libnss-ldap (2.60-1) unstable; urgency=low + + * New upstream version + + -- Ben Collins Fri, 16 Apr 1999 12:31:09 -0400 + +libnss-ldap (2.55-1) unstable; urgency=low + + * New upstream source with a lot of GLIBC 2.1 changes merged in + + -- Ben Collins Sun, 11 Apr 1999 12:37:44 -0400 + +libnss-ldap (2.54.4-1) unstable; urgency=low + + * New upstream release + * Lot's of glibc 2.1 related patches merged upstream + * Makefile changes merged upstream + + -- Ben Collins Tue, 23 Mar 1999 19:44:14 -0500 + +libnss-ldap (2.54-1) unstable; urgency=low + + * New upstream source + * Added manpage for libnss-ldap.conf from rage.net + * Redid make setup to be more glibc like in the library install (so name + is generated based on current installation as well as links) + * Added LdapNS-howto.txt from rage.net + * Cleaned up patch for glibc 2.1 (libc-lock.h) to allow compilation + under glibc 2.0 still + + -- Ben Collins Tue, 9 Mar 1999 00:43:31 -0500 + +libnss-ldap (2.49-2) unstable; urgency=low + + * Updated soname to match glibc 2.1 + * libc-lock.h is now in /usr/include/bits (glibc 2.1) + * Added recommend for nscd (improves performance) + + -- Ben Collins Sat, 6 Mar 1999 18:02:22 -0500 + +libnss-ldap (2.49-1) unstable; urgency=low + + * Initial Release. + + -- Ben Collins Thu, 11 Feb 1999 22:46:20 -0500 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..c2fdf4e --- /dev/null +++ b/debian/control @@ -0,0 +1,49 @@ +Source: nss-pam-ldapd +Section: admin +Priority: extra +Maintainer: Arthur de Jong +Uploaders: Richard A Nelson (Rick) +Standards-Version: 3.9.2 +Build-Depends: debhelper (>= 8.1.3), libkrb5-dev, libldap2-dev, libsasl2-dev, po-debconf (>= 0.5.0), docbook2x, docbook-xml, libpam0g-dev +Homepage: http://arthurdejong.org/nss-pam-ldapd/ +Vcs-Svn: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd/ +Vcs-Browser: http://arthurdejong.org/viewvc/nss-pam-ldapd/nss-pam-ldapd/ + +Package: nslcd +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends}, adduser +Recommends: nscd, libnss-ldapd | libnss-ldap, libpam-ldapd | libpam-ldap | libpam-krb5 | libpam-heimdal | libpam-sss, ldap-utils, bind9-host | host +Suggests: kstart +Replaces: libnss-ldapd (<< 0.7.0) +Breaks: libnss-ldapd (<< 0.7.0) +Description: Daemon for NSS and PAM lookups using LDAP + This package provides a daemon for retrieving user account, and other + system information from LDAP. + . + It is used by the libnss-ldapd and libpam-ldapd packages but by itself is + not very useful. + +Package: libnss-ldapd +Architecture: any +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends}, nslcd (>= 0.7.0) +Conflicts: libnss-ldap +Provides: libnss-ldap +Multi-Arch: same +Description: NSS module for using LDAP as a naming service + This package provides a Name Service Switch module that allows your LDAP + server to provide user account, group, host name, alias, netgroup, and + basically any other information that you would normally get from /etc flat + files or NIS. + +Package: libpam-ldapd +Architecture: any +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends}, nslcd, libpam-runtime (>= 1.0.1-6) +Conflicts: libpam-ldap +Provides: libpam-ldap +Multi-Arch: same +Description: PAM module for using LDAP as an authentication service + This package provides a Pluggable Authentication Module that allows + user authentication, authorisation and password management based on + credentials stored in an LDAP server. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..6898ca9 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,98 @@ +This is nss-pam-ldapd, a library for doging NSS and PAM lookups using an LDAP +server. + +nss-pam-ldapd started as nss-ldapd which was a fork from nss_ldap which was +originally written by Luke Howard of PADL Software Pty Ltd. +http://www.padl.com/OSS/nss_ldap.html + +In 2006 Arthur de Jong of West Consuling forked the library to split it into a +thin NSS part and a server part. Most of the code was rewritten. + +The software was renamed to nss-pam-ldapd when PAM code contributed by Howard +Chu for the OpenLDAP nssov module was integrated. Solaris compatibility was +developed by Ted C. Cheng of Symas Corporation. + +http://arthurdejong.org/nss-pam-ldapd/ + +Arthur de Jong is both the upstream and Debian package maintainer, so there +are no differences between the Debian package and the upstream version. + +The Debian package of nss-pam-ldapd was partially based on packaging of the +libnss-ldap package. The libnss-ldap package was maintained by Ben Collins, +Davide Puricelli (evo), Sami Haahtinen and Stephen Frost. + + Copyright (C) 1997-2006 Luke Howard + Copyright (C) 2006-2007 West Consulting + Copyright (C) 2006-2011 Arthur de Jong + Copyright (C) 2009 Howard Chu + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + On Debian GNU/Linux systems, the complete text of + the GNU Lesser General Public License can be found in + /usr/share/common-licenses/LGPL-2.1. + +The following files are also contain other copyright holders and are also +covered by the GNU Lesser General Public License: + +compat/pagectrl.c: Copyright (C) 2002 Max Caines +debian/po/ca.po: Copyright (C) 2004 Free Software Foundation, Inc. +debian/po/da.po: Copyright (C) 2008 Jonas Smedegaard +debian/po/da.po: Copyright (C) 2010, 2011 Joe Hansen +debian/po/de.po: Copyright (C) 2004 Erik Schanze +debian/po/es.po: Copyright (C) 2007 Rudy Godoy Guillén +debian/po/es.po: Copyright (C) 2009, 2010, 2011 Software in the Public Interest +debian/po/fi.po: Copyright (C) 2009 Esko Arajärvi +debian/po/fr.po: Copyright (C) 2007, 2009, 2010 Debian French l10n team +debian/po/vi.po: Copyright (C) 2010 Free Software Foundation, Inc. +nss/bsdnss.c: Copyright (C) 2003 Jacques Vidrine +nss/bsdnss.c: Copyright (C) 2006 Artem Kazakov +nss/bsdnss.c: Copyright (C) 2009 Alexander V. Chernikov + +The distribution includes code from the Autoconf and Automake suites. This +code is either licensed under the GNU General Public License with the extra +permission to use it in a configure script under the licensing terms of that +configure script or gives unlimited permission to copy and/or distribute it +with or without modifications. The code is + Copyright (C) 1996-2010 Free Software Foundation, Inc. +(years aggregated). + +The file m4/ax_pthread.m4 contains the following copyright statement: + + Copyright (c) 2008 Steven G. Johnson + Copyright (c) 2011 Daniel Richard G. + + 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 3 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, see . + + As a special exception, the respective Autoconf Macro's copyright owner + gives unlimited permission to copy, distribute and modify the configure + scripts that are the output of Autoconf when processing the Macro. You + need not follow the terms of the GNU General Public License when using + or distributing such scripts, even though portions of the text of the + Macro appear in them. The GNU General Public License (GPL) does govern + all other use of the material that constitutes the Autoconf Macro. + + This special exception to the GPL applies to versions of the Autoconf + Macro released by the Autoconf Archive. When you make and distribute a + modified version of the Autoconf Macro, you may extend this special + exception to the GPL to apply to your modified version as well. diff --git a/debian/libnss-ldapd.config b/debian/libnss-ldapd.config new file mode 100644 index 0000000..4f8e2e7 --- /dev/null +++ b/debian/libnss-ldapd.config @@ -0,0 +1,49 @@ +#!/bin/sh + +set -e + +# source debconf library. +. /usr/share/debconf/confmodule +db_version 2.0 + +# +# This is the fist part of the script. In this part an attempt +# is made to get or guess the current configuration. This information +# is used later on to prompt the user and to provide a sensible +# default. +# + +# find the names of services that are configured to use LDAP +# Note: this function is in libnss-ldapd.config and libnss-ldapd.postrm +nss_list_configured() +{ + sed -n \ + 's/^[[:space:]]*\([a-z]*\)[[:space:]]*:.*[[:space:]]ldap\([[:space:]].*\)\?/\1/p' \ + /etc/nsswitch.conf +} + +# parse /etc/nsswitch.conf and see which services have ldap specified +db_get libnss-ldapd/nsswitch +# find name services that currently use LDAP +configured=`nss_list_configured` +# separate by commas +configured=`echo $configured | sed 's/ /, /g'` +# store configured services either on first config or when ldap is already +# configured +if [ -z "$RET" ] || [ -n "$configured" ] +then + db_set libnss-ldapd/nsswitch "$configured" +fi + +# +# This is the second part of the script. In this part the configurable +# settings will be presented to the user for approval. The postinst +# will finaly perform the actual modifications. +# + +# ask for which nsswitch options to configure +db_capb multiselect +db_input high libnss-ldapd/nsswitch || true +db_go || true + +exit 0 diff --git a/debian/libnss-ldapd.install b/debian/libnss-ldapd.install new file mode 100644 index 0000000..67d96c3 --- /dev/null +++ b/debian/libnss-ldapd.install @@ -0,0 +1 @@ +lib/*/libnss_ldap.so* diff --git a/debian/libnss-ldapd.lintian-overrides b/debian/libnss-ldapd.lintian-overrides new file mode 100644 index 0000000..0346fe3 --- /dev/null +++ b/debian/libnss-ldapd.lintian-overrides @@ -0,0 +1,6 @@ +# we ship a shared library that is used for the NSS system but providing +# symbols files is no use because nobody should directly link to the library +libnss-ldapd: no-symbols-control-file lib/*/libnss_ldap.so.2 +# since the shared library shouldn't be publically used the SONAME is only +# used for internal purposes +libnss-ldapd: package-name-doesnt-match-sonames libnss-ldap2 diff --git a/debian/libnss-ldapd.postinst b/debian/libnss-ldapd.postinst new file mode 100644 index 0000000..dc59e16 --- /dev/null +++ b/debian/libnss-ldapd.postinst @@ -0,0 +1,91 @@ +#!/bin/sh + +set -e + +# editing nsswitch.conf seems to be ok +# http://lists.debian.org/debian-devel/2007/02/msg00076.html + +# check whether the name is configure to do lookups through +# LDAP +# Note: this function is in libnss-ldapd.postinst, libnss-ldapd.postrm +# and libpam-ldapd.postinst +nss_is_enabled() +{ + name="$1" + grep -q '^[[:space:]]*'$name'[[:space:]]*:.*ldap.*' /etc/nsswitch.conf +} + +# check to see if name is configured to do lookups through +# LDAP and enable if not +# Note: this function is in libnss-ldapd.postinst and libpam-ldapd.postinst +nss_enable() +{ + name="$1" + if ! nss_is_enabled "$name" + then + echo "/etc/nsswitch.conf: enable LDAP lookups for $name" >&2 + if grep -q '^[[:space:]]*'$name'[[:space:]]*:' /etc/nsswitch.conf + then + # modify an existing entry by just adding ldap to the end + sed -i 's/^\([[:space:]]*'$name'[[:space:]]*:.*[^[:space:]]\)[[:space:]]*$/\1 ldap/' /etc/nsswitch.conf + else + # append a new line + printf '%-15s ldap\n' $name':' >> /etc/nsswitch.conf + fi + # invalidate nscd cache + nscd -i "$name" > /dev/null 2>&1 || true + fi + # we're done + return 0 +} + +# remove NSS lookups though LDAP for the specified service +# Note: this function is in libnss-ldapd.postinst and libnss-ldapd.postrm +nss_disable() +{ + name="$1" + # these functions also remove the lookup result handling part + # of the ldap entry (see nsswitch.conf(5)) + if nss_is_enabled "$name" + then + echo "/etc/nsswitch.conf: disable LDAP lookups for $name" >&2 + if [ -n "`sed -n '/^[[:space:]]*'$name'[[:space:]]*:[[:space:]]*ldap[[:space:]]*\(\[[^]]*\]\)*[[:space:]]*$/p' /etc/nsswitch.conf`" ] + then + # the name service only maps to ldap, remove the whole line + sed -i '/^[[:space:]]*'$name'[[:space:]]*:[[:space:]]*ldap[[:space:]]*\(\[[^]]*\]\)*[[:space:]]*$/d' /etc/nsswitch.conf + else + # remove ldap part from existing line, keeping other methods intact + # TODO: remove trailing space + sed -i 's/^\([[:space:]]*'$name'[[:space:]]*:.*\)ldap[[:space:]]*\(\[[^]]*\]\)*[[:space:]]*\(.*\)$/\1\3/' /etc/nsswitch.conf + fi + # invalidate nscd cache + nscd -i "$name" > /dev/null 2>&1 || true + fi + # we're done + return 0 +} + +# real functions begin here +if [ "$1" = "configure" ] +then + # get configuration data from debconf + . /usr/share/debconf/confmodule + # modify /etc/nsswitch.conf + db_get libnss-ldapd/nsswitch + enablenss=`echo "$RET" | sed 's/,//g'` + for n in aliases ethers group hosts netgroup networks passwd protocols rpc services shadow + do + if echo ' '$enablenss' ' | grep -q ' '$n' ' + then + nss_enable $n + else + nss_disable $n + fi + done + # we're done + db_stop +fi + +#DEBHELPER# + +exit 0 diff --git a/debian/libnss-ldapd.postrm b/debian/libnss-ldapd.postrm new file mode 100644 index 0000000..cfa96ce --- /dev/null +++ b/debian/libnss-ldapd.postrm @@ -0,0 +1,94 @@ +#!/bin/sh + +set -e + +# find the names of services that are configured to use LDAP +# Note: this function is in libnss-ldapd.config and libnss-ldapd.postrm +nss_list_configured() +{ + sed -n \ + 's/^[[:space:]]*\([a-z]*\)[[:space:]]*:.*[[:space:]]ldap\([[:space:]].*\)\?/\1/p' \ + /etc/nsswitch.conf +} + +# check whether the name is configure to do lookups through +# LDAP +# Note: this function is in libnss-ldapd.postinst, libnss-ldapd.postrm +# and libpam-ldapd.postinst +nss_is_enabled() +{ + name="$1" + grep -q '^[[:space:]]*'$name'[[:space:]]*:.*ldap.*' /etc/nsswitch.conf +} + +# remove NSS lookups though LDAP for the specified service +# Note: this function is in libnss-ldapd.postinst and libnss-ldapd.postrm +nss_disable() +{ + name="$1" + # these functions also remove the lookup result handling part + # of the ldap entry (see nsswitch.conf(5)) + if nss_is_enabled "$name" + then + echo "/etc/nsswitch.conf: disable LDAP lookups for $name" >&2 + if [ -n "`sed -n '/^[[:space:]]*'$name'[[:space:]]*:[[:space:]]*ldap[[:space:]]*\(\[[^]]*\]\)*[[:space:]]*$/p' /etc/nsswitch.conf`" ] + then + # the name service only maps to ldap, remove the whole line + sed -i '/^[[:space:]]*'$name'[[:space:]]*:[[:space:]]*ldap[[:space:]]*\(\[[^]]*\]\)*[[:space:]]*$/d' /etc/nsswitch.conf + else + # remove ldap part from existing line, keeping other methods intact + # TODO: remove trailing space + sed -i 's/^\([[:space:]]*'$name'[[:space:]]*:.*\)ldap[[:space:]]*\(\[[^]]*\]\)*[[:space:]]*\(.*\)$/\1\3/' /etc/nsswitch.conf + fi + # invalidate nscd cache + nscd -i "$name" > /dev/null 2>&1 || true + fi + # we're done + return 0 +} + +# offer to remove ldap from nsswitch.conf +if ( [ "$1" = "remove" ] || [ "$1" = "purge" ] ) +then + # check which naming services are configured + configured=`nss_list_configured` + if [ -n "$configured" ] + then + # if we have debconf, use debconf to ask, otherwise just shout + if [ -e /usr/share/debconf/confmodule ] + then + # ask with debconf + . /usr/share/debconf/confmodule + db_title "Removing libnss-ldapd" + db_subst libnss-ldapd/clean_nsswitch services "`echo $configured | sed 's/ /, /g'`" + db_fset libnss-ldapd/clean_nsswitch seen false + if db_input high libnss-ldapd/clean_nsswitch + then + db_go + db_get libnss-ldapd/clean_nsswitch + if [ "$RET" = "true" ] + then + for n in $configured + do + nss_disable $n + done + fi + fi + # re-check which services are left enabled + configured=`nss_list_configured` + fi + # check if ldap is still configured + if [ -n "$configured" ] + then + echo "WARNING: LDAP is still configured in /etc/nsswitch.conf" >&2 + fi + fi +fi + +# call ldconfig to signal the removal of our NSS library +if [ "$1" = "remove" ] +then + ldconfig +fi + +#DEBHELPER# diff --git a/debian/libnss-ldapd.templates b/debian/libnss-ldapd.templates new file mode 100644 index 0000000..ea9852b --- /dev/null +++ b/debian/libnss-ldapd.templates @@ -0,0 +1,27 @@ +Template: libnss-ldapd/nsswitch +Type: multiselect +Choices: aliases, ethers, group, hosts, netgroup, networks, passwd, protocols, rpc, services, shadow +_Description: Name services to configure: + For this package to work, you need to modify your /etc/nsswitch.conf to use + the ldap datasource. + . + You can select the services that should have LDAP lookups enabled. The + new LDAP lookups will be added as the last datasource. Be sure to review + these changes. + +Template: libnss-ldapd/clean_nsswitch +Type: boolean +Default: false +_Description: Remove LDAP from nsswitch.conf now? + The following services are still configured to use LDAP for lookups: + ${services} + but the libnss-ldapd package is about to be removed. + . + You are advised to remove the entries if you don't plan on using LDAP for + name resolution any more. Not removing ldap from nsswitch.conf should, for + most services, not cause problems, but host name resolution could be affected + in subtle ways. + . + You can edit /etc/nsswitch.conf by hand or choose to remove the entries + automatically now. Be sure to review the changes to /etc/nsswitch.conf if you + choose to remove the entries now. diff --git a/debian/libpam-ldapd.install b/debian/libpam-ldapd.install new file mode 100644 index 0000000..5e7563c --- /dev/null +++ b/debian/libpam-ldapd.install @@ -0,0 +1,2 @@ +lib/*/security/pam_ldap.so +debian/pam-configs/ldap usr/share/pam-configs diff --git a/debian/libpam-ldapd.lintian-overrides b/debian/libpam-ldapd.lintian-overrides new file mode 100644 index 0000000..1f54a33 --- /dev/null +++ b/debian/libpam-ldapd.lintian-overrides @@ -0,0 +1,6 @@ +# we prompt in postinst instead of config because we can only +# reliably detect the actual configuration in postinst and are +# only doing this if we detect that there is something wrong +# with the actual config +libpam-ldapd: no-debconf-config +libpam-ldapd: postinst-uses-db-input diff --git a/debian/libpam-ldapd.manpages b/debian/libpam-ldapd.manpages new file mode 100644 index 0000000..f2c4103 --- /dev/null +++ b/debian/libpam-ldapd.manpages @@ -0,0 +1 @@ +debian/tmp/usr/share/man/man8/pam_ldap.8 diff --git a/debian/libpam-ldapd.postinst b/debian/libpam-ldapd.postinst new file mode 100644 index 0000000..e74381f --- /dev/null +++ b/debian/libpam-ldapd.postinst @@ -0,0 +1,63 @@ +#!/bin/sh + +set -e + +# source debconf library. +. /usr/share/debconf/confmodule +db_version 2.0 + +#DEBHELPER# + +pam-auth-update --package + +# check whether the name is configure to do lookups through +# LDAP +# Note: this function is in libnss-ldapd.postinst, libnss-ldapd.postrm +# and libpam-ldapd.postinst +nss_is_enabled() +{ + name="$1" + grep -q '^[[:space:]]*'$name'[[:space:]]*:.*ldap.*' /etc/nsswitch.conf +} + +# check to see if name is configured to do lookups through +# LDAP and enable if not +# Note: this function is in libnss-ldapd.postinst and libpam-ldapd.postinst +nss_enable() +{ + name="$1" + if ! nss_is_enabled "$name" + then + echo "/etc/nsswitch.conf: enable LDAP lookups for $name" >&2 + if grep -q '^[[:space:]]*'$name'[[:space:]]*:' /etc/nsswitch.conf + then + # modify an existing entry by just adding ldap to the end + sed -i 's/^\([[:space:]]*'$name'[[:space:]]*:.*[^[:space:]]\)[[:space:]]*$/\1 ldap/' /etc/nsswitch.conf + else + # append a new line + printf '%-15s ldap\n' $name':' >> /etc/nsswitch.conf + fi + # invalidate nscd cache + nscd -i "$name" > /dev/null 2>&1 || true + fi + # we're done + return 0 +} + +# if /etc/nsswitch.conf contains passwd: ..ldap but not shadow: ...ldap +# warn the user that this will not work and offer to fix it +# (only do this if it seems we have switched to pam-auth-update) +if nss_is_enabled "passwd" && \ + ! nss_is_enabled "shadow" && \ + grep -q pam-auth-update /etc/pam.d/common-auth +then + if db_input critical libpam-ldapd/enable_shadow + then + db_go + db_get libpam-ldapd/enable_shadow + if [ "$RET" = "true" ] + then + nss_enable "shadow" + fi + fi +fi diff --git a/debian/libpam-ldapd.prerm b/debian/libpam-ldapd.prerm new file mode 100644 index 0000000..4d4e093 --- /dev/null +++ b/debian/libpam-ldapd.prerm @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +if [ "$1" = remove ] +then + pam-auth-update --package --remove ldap +fi + +#DEBHELPER# + +exit 0 diff --git a/debian/libpam-ldapd.templates b/debian/libpam-ldapd.templates new file mode 100644 index 0000000..4f31a19 --- /dev/null +++ b/debian/libpam-ldapd.templates @@ -0,0 +1,12 @@ +Template: libpam-ldapd/enable_shadow +Type: boolean +Default: true +_Description: Enable shadow lookups through NSS? + To allow LDAP users to log in, the NSS module needs to be enabled to + perform shadow password lookups. The shadow entries themselves may be + empty - that is, there is no need for password hashes to be exposed. See + http://bugs.debian.org/583492 for background. + . + Please choose whether /etc/nsswitch.conf should have the required entry + added automatically (in which case it should be reviewed afterwards) or + whether it should be left for an administrator to edit manually. diff --git a/debian/nslcd.conffile b/debian/nslcd.conffile new file mode 100644 index 0000000..74ba8da --- /dev/null +++ b/debian/nslcd.conffile @@ -0,0 +1 @@ +nslcd.default /etc/default/nslcd diff --git a/debian/nslcd.config b/debian/nslcd.config new file mode 100644 index 0000000..da1dd52 --- /dev/null +++ b/debian/nslcd.config @@ -0,0 +1,368 @@ +#!/bin/sh + +set -e + +CONFFILE="/etc/nslcd.conf" +OCONFFILE="/etc/nss-ldapd.conf" + +# fall back to old configfile if new one isn't present but old one is +[ ! -f "$CONFFILE" ] && [ -f "$OCONFFILE" ] && CONFFILE="$OCONFFILE" + +# source debconf library. +. /usr/share/debconf/confmodule +db_version 2.0 +db_capb backup + +# +# This is the fist part of the script. In this part an attempt +# is made to get or guess the current configuration. This information +# is used later on to prompt the user and to provide a sensible +# default. +# + +# read a configuration value from the specified file +# (it takes care in not overwriting a previously written value) +read_config() +{ + debconf_param="$1" + cfg_param="$2" + # overwrite debconf value if different from config file + db_get "$debconf_param" + debconf_value="$RET" + cfgfile_value=`sed -n 's/^'"$cfg_param"'[[:space:]]*\([^[:space:]].*[^[:space:]]\)[[:space:]]*$/\1/ip' "$cfgfile" | tail -n 1` + [ -n "$cfgfile_value" ] && [ "$debconf_value" != "$cfgfile_value" ] && db_set "$debconf_param" "$cfgfile_value" + # we're done + return 0 +} + +# figure out the system's domain name +get_domain() +{ + domain=`hostname --domain` || true + [ -z "$domain" ] && domain=`hostname --nis | grep '\.'` || true + [ -z "$domain" ] && domain=`hostname --fqdn | sed -n 's/^[^.]*\.//p'` || true + [ -z "$domain" ] && domain=`sed -n 's/^ *\(domain\|search\) *\([^ ]*\) *$/\2/p' /etc/resolv.conf | head -n 1` || true + echo "$domain" +} + +# find a LDAP server URI by trying DNS and normal hostname lookups +guess_ldap_uri() +{ + # see if ldap server exists on localhost and is listening on ldapi:// + if [ -e /var/run/slapd/ldapi ] + then + echo "ldapi:///" + return + fi + # try to lookup _ldap._tcp SRV records + if [ -n "$domain" ] + then + server=`host -N 2 -t SRV _ldap._tcp.$domain 2> /dev/null | grep -v NXDOMAIN | awk '{print $NF}' | head -1 | sed 's/\.$//'` || true + if [ -n "$server" ] + then + echo "ldap://$server/" + return + fi + fi + # fall back to name lookups + if [ -z "$ldap_uri" ] + then + # try unqualified hostname lookup + server=`getent hosts ldap` || true + [ -z "$server" ] && server=`getent hosts dirhost` || true + # try qualified hostname + if [ -n "$domain" ] && [ -z "$server" ] + then + server=`getent hosts ldap."$domain"` || true + [ -z "$server" ] && server=`getent hosts dirhost."$domain"` || true + fi + # turn into URI with IP address + if [ -n "$server" ] + then + # extract IP address from host entry and quote IPv6 address + ip=`echo $server | sed 's/[[:space:]].*//;s/^\(.*:.*\)$/[\1]/'` + echo "ldap://$ip/" + fi + fi +} + +# guess the LDAP search base by performing LDAP searches on the +# found server +query_search_base() +{ + ldap_uri="$1" + # first try the default naming context + context=`ldapsearch -LLL -H "$ldap_uri" -x -b '' -s base defaultNamingContext 2>/dev/null | sed -n 's/^defaultNamingContext: //pi'` || true + if [ -n "$context" ] + then + echo "$context" + return + fi + # go over naming contexts, pick the first one with posixAccount or + # posixGroup objects in it + for context in `ldapsearch -LLL -H "$ldap_uri" -x -b '' -s base namingContexts 2>/dev/null | sed -n 's/^namingContexts: //pi'` + do + # search the context + found=`ldapsearch -LLL -H "$ldap_uri" -x -b "$context" -s sub -z 1 '(|(objectClass=posixAccount)(objectclass=posixGroup))' dn 2>/dev/null` || true + if [ -n "$found" ] + then + echo $context + return + fi + done +} + +# check the system (non-LDAP configuration files) for some +# reasonable defaults +parsesys() +{ + # guess domain based on system information + domain=`get_domain` + # guess ldap server URI + db_get nslcd/ldap-uris + if [ -z "$RET" ] + then + ldap_uri=`guess_ldap_uri "$domain"` + [ -n "$ldap_uri" ] && db_set nslcd/ldap-uris "$ldap_uri" + else + # only get first URI from any stored (preseeded) value + ldap_uri=`echo "$RET" | sed -n 's/[[:space:]].*//'` + fi + # guess search base + db_get nslcd/ldap-base + if [ -z "$RET" ] + then + # try to find the search base from the found URI + [ -n "$ldap_uri" ] && search_base=`query_search_base "$ldap_uri"` + # try to use the domain name to build the default base + if [ -z "$search_base" ] && [ -n "$domain" ] + then + search_base=`echo "$domain" | sed 's/^/dc=/;s/\./,dc=/g'` + fi + [ -n "$search_base" ] && db_set nslcd/ldap-base "$search_base" + fi + # we're done + return 0 +} + +# parse a LDAP-like configuration file +parsecfg() +{ + cfgfile="$1" + # check existance + [ -f "$cfgfile" ] || return 0 + # find uri/host/port combo + db_get nslcd/ldap-uris + if [ -z "$RET" ] + then + uris=`sed -n 's/^uri[[:space:]]*//ip' "$cfgfile" | tr '\n' ' '` + if [ -z "$uris" ] + then + hosts=`sed -n 's/^host[[:space:]]*//ip' "$cfgfile"` + port=`sed -n 's/^port[[:space:]]*//ip' "$cfgfile" | tail -n 1` + for host in $hosts + do + if [ -z "$port" ] || (echo "$host" | grep -q ':' ) + then + uris="$uris ldap://$host/" + else + uris="$uris ldap://$host:$port/" + fi + done + fi + [ -n "$uris" ] && db_set nslcd/ldap-uris "$uris" + fi + # read simple options + read_config nslcd/ldap-base base + read_config nslcd/ldap-binddn binddn + read_config nslcd/ldap-bindpw bindpw + read_config nslcd/ldap-sasl-mech sasl_mech + read_config nslcd/ldap-sasl-realm sasl_realm + read_config nslcd/ldap-sasl-authcid sasl_authcid + read_config nslcd/ldap-sasl-authzid sasl_authzid + read_config nslcd/ldap-sasl-secprops sasl_secprops + read_config nslcd/ldap-sasl-krb5-ccname krb5_ccname + # check ssl option + db_get nslcd/ldap-starttls + if [ -z "$RET" ] + then + if grep -qi '^ssl[[:space:]]*start_*tls' "$cfgfile" + then + db_set nslcd/ldap-starttls "true" + elif grep -qi '^ssl[[:space:]]' "$cfgfile" + then + db_set nslcd/ldap-starttls "false" + fi + fi + # check reqcert option + db_get nslcd/ldap-reqcert + if [ -z "$RET" ] + then + reqcert=`sed -n 's/^tls_\(reqcert\|checkpeer\)[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\2/ip' "$cfgfile" | tail -n 1` + # normalise value + reqcert=`echo "$reqcert" | tr 'A-Z' 'a-z' | sed 's/^no$/never/;s/^yes$/demand/'` + [ -n "$reqcert" ] && db_set nslcd/ldap-reqcert "$reqcert" + fi + # we're done + return 0 +} + +# fill our defaults with the current configuration if available +# and fall back to guessing the config from some other system files +if [ -f "$CONFFILE" ] +then + # parse current configuration + parsecfg "$CONFFILE" +else + # first match wins + parsecfg /etc/libnss-ldap.conf + parsecfg /etc/pam_ldap.conf + parsecfg /etc/ldap/ldap.conf + parsecfg /etc/ldap.conf + parsesys + # fallback default values + db_get nslcd/ldap-uris + [ -z "$RET" ] && db_set nslcd/ldap-uris "ldap://127.0.0.1/" + db_get nslcd/ldap-base + [ -z "$RET" ] && db_set nslcd/ldap-base "dc=example,dc=net" +fi + +# fallback for starttls option +db_get nslcd/ldap-starttls +[ -z "$RET" ] && db_set nslcd/ldap-starttls "false" + +# deduce auth-type from available information +db_get nslcd/ldap-auth-type +if [ -z "$RET" ] +then + db_get nslcd/ldap-sasl-mech + sasl_mech="$RET" + db_get nslcd/ldap-binddn + binddn="$RET" + if [ -n "$sasl_mech" ] + then + db_set nslcd/ldap-auth-type "SASL" + elif [ -n "$binddn" ] + then + db_set nslcd/ldap-auth-type "simple" + else + db_set nslcd/ldap-auth-type "none" + fi +fi + +# +# This is the second part of the script. In this part the configurable +# settings will be presented to the user for approval. The postinst +# will finaly perform the actual modifications. +# + +state="server" +while [ "$state" != "done" ] +do + case "$state" in + server) + # ask about server configuration + db_input high nslcd/ldap-uris || true + db_input high nslcd/ldap-base || true + # ask the questions, go to the next question or exit + state="authtype" + db_go || exit 1 + # TODO: add error checking on options + ;; + authtype) + # ask for authentication type + db_input medium nslcd/ldap-auth-type || true + # ask the question, go to the next question or back + state="authentication" + db_go || state="server" + ;; + authentication) + # check which questions to ask, depending on the authentication type + db_get nslcd/ldap-auth-type + case "$RET" in + none) + # anonymous bind, nothing to ask (clear password) + db_set nslcd/ldap-bindpw "" + state="starttls" + ;; + simple) + # ask for binddn and bindpw + db_input medium nslcd/ldap-binddn || true + db_input medium nslcd/ldap-bindpw || true + state="starttls" + ;; + SASL) + # ask about SASL mechanism (other SASL questions depend on this) + db_input medium nslcd/ldap-sasl-mech || true + state="sasloptions" + ;; + *) + exit 1 + ;; + esac + db_go || state="authtype" + ;; + sasloptions) + # get SASL mech + db_get nslcd/ldap-sasl-mech + sasl_mech="$RET" + # ask SASL questions + db_input medium nslcd/ldap-sasl-realm || true + if [ "$sasl_mech" != "GSSAPI" ] + then + db_input medium nslcd/ldap-sasl-authcid || true + db_input medium nslcd/ldap-bindpw || true + fi + db_input medium nslcd/ldap-sasl-authzid || true + db_input medium nslcd/ldap-sasl-secprops || true + if [ "$sasl_mech" = "GSSAPI" ] + then + # have a default for ldap-sasl-krb5-ccname + db_get nslcd/ldap-sasl-krb5-ccname + [ -z "$RET" ] && db_set nslcd/ldap-sasl-krb5-ccname "/var/run/nslcd/nslcd.tkt" + db_input low nslcd/ldap-sasl-krb5-ccname || true + fi + # ask the question, go to the next question or back + state="starttls" + db_go || state="authentication" + ;; + starttls) + # check if ldaps:// URL's are used + db_get nslcd/ldap-uris + uris="$RET" + if (echo "$uris" | grep -q 'ldaps://') + then + # ldaps: URI defined, don't ask about StartTLS + db_set nslcd/ldap-starttls "false" + else + # ask whether to use StartTLS + db_input medium nslcd/ldap-starttls || true + fi + # ask the question, go to the next question or back + # (we go back to authtype because the previous questions were optional) + state="reqcert" + db_go || state="authtype" + ;; + reqcert) + # check if ldaps:// URL's are used + db_get nslcd/ldap-uris + uris="$RET" + # check if StartTLS is used + db_get nslcd/ldap-starttls + starttls="$RET" + if (echo "$uris" | grep -q 'ldaps://') || [ "$starttls" = "true" ] + then + # ask whether to do certificate validation + db_input high nslcd/ldap-reqcert || true + else + db_set nslcd/ldap-reqcert "" + fi + # ask the question, go to the next question or back + # (we go back to authtype because the previous questions were optional) + state="done" + db_go || state="authtype" + ;; + esac +done + +exit 0 diff --git a/debian/nslcd.default b/debian/nslcd.default new file mode 100644 index 0000000..7e84d3a --- /dev/null +++ b/debian/nslcd.default @@ -0,0 +1,14 @@ +# Defaults for nslcd init script + +# Whether to start k5start (for obtaining and keeping a Kerberos ticket) +# By default k5start is started if nslcd.conf has sasl_mech set to GSSAPI +# and krb5_ccname is set to a file-type ticket cache. +# Set to "yes" to force starting k5start, any other value will not start +# k5start. +#K5START_START="yes" + +# Options for k5start. +#K5START_BIN=/usr/bin/k5start +#K5START_KEYTAB=/etc/krb5.keytab +#K5START_CCREFRESH=60 +#K5START_PRINCIPAL="host/$(hostname -f)" diff --git a/debian/nslcd.docs b/debian/nslcd.docs new file mode 100644 index 0000000..9a58ad6 --- /dev/null +++ b/debian/nslcd.docs @@ -0,0 +1,3 @@ +README +AUTHORS +NEWS diff --git a/debian/nslcd.examples b/debian/nslcd.examples new file mode 100644 index 0000000..08032cc --- /dev/null +++ b/debian/nslcd.examples @@ -0,0 +1 @@ +nslcd.conf diff --git a/debian/nslcd.init b/debian/nslcd.init new file mode 100644 index 0000000..562308d --- /dev/null +++ b/debian/nslcd.init @@ -0,0 +1,176 @@ +#! /bin/sh + +# /etc/init.d/nslcd script for starting and stopping nslcd +# Copyright (C) 2006 West Consulting +# Copyright (C) 2006, 2008, 2009, 2010 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +### BEGIN INIT INFO +# Provides: nslcd +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Should-Start: $named slapd +# X-Start-Before: $mail-transport-agent mail-transport-agent exim4 sendmail nullmailer masqmail citadel cron atd autofs am-utils apache2 +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: LDAP connection daemon +# Description: nslcd is a LDAP connection daemon that is used to +# do LDAP queries for the NSS and PAM modules. +### END INIT INFO + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +NSLCD_BIN=/usr/sbin/nslcd +NSLCD_DESC="LDAP connection daemon" +NSLCD_CFG=/etc/nslcd.conf +NSLCD_STATEDIR=/var/run/nslcd +NSLCD_PIDFILE=$NSLCD_STATEDIR/nslcd.pid + +[ -x "$NSLCD_BIN" ] || exit 0 +[ -f "$NSLCD_CFG" ] || exit 0 + +. /lib/lsb/init-functions + +# default options for k5start +K5START_BIN=/usr/bin/k5start +K5START_DESC="Keep alive Kerberos ticket" +K5START_START="" +K5START_PIDFILE=$NSLCD_STATEDIR/k5start_nslcd.pid +K5START_USER=$(sed -n 's/^uid *\([^ ]*\) *$/\1/ip' $NSLCD_CFG) +K5START_GROUP=$(sed -n 's/^gid *\([^ ]*\) *$/\1/ip' $NSLCD_CFG) +K5START_MODE=600 +K5START_KEYTAB=/etc/krb5.keytab +K5START_CCREFRESH=60 +K5START_PRINCIPAL="host/$(hostname -f)" +K5START_CCFILE=$(sed -n 's/^krb5_ccname *\(FILE:\)\?\([^: ]*\) *$/\2/ip' $NSLCD_CFG) + +# check if we should use k5start by default (sasl_mech should be GSSAPI and +# krb5_ccname should be found) +if [ -x "$K5START_BIN" ] && \ + grep -q '^sasl_mech *GSSAPI$' $NSLCD_CFG && \ + [ -n "$K5START_CCFILE" ] +then + K5START_START="yes" +fi + +# read defaults +[ -f /etc/default/nslcd ] && . /etc/default/nslcd + +k5start_start() +{ + if [ "$K5START_START" = "yes" ] + then + log_daemon_msg "Starting $K5START_DESC" "k5start" + start-stop-daemon --start \ + --pidfile $K5START_PIDFILE \ + --exec $K5START_BIN -- \ + -b -p $K5START_PIDFILE \ + -o $K5START_USER \ + -g $K5START_GROUP \ + -m $K5START_MODE \ + -f $K5START_KEYTAB \ + -K $K5START_CCREFRESH \ + -u $K5START_PRINCIPAL \ + -k $K5START_CCFILE + log_end_msg $? + fi +} + +k5start_stop() +{ + if [ "$K5START_START" = "yes" ] + then + log_daemon_msg "Stopping $K5START_DESC" "k5start" + start-stop-daemon --stop --oknodo --pidfile $K5START_PIDFILE + log_end_msg $? + # remove any left behind files + [ -n "$K5START_PIDFILE" ] && rm -f $K5START_PIDFILE + [ -n "$K5START_CCFILE" ] && rm -f $K5START_CCFILE + fi +} + +k5start_status() +{ + if [ "$K5START_START" = "yes" ] + then + status_of_proc -p "$K5START_PIDFILE" "$K5START_BIN" "k5start" + fi +} + +case "$1" in +start) + # set up state directory + [ -d "$NSLCD_STATEDIR" ] || ( mkdir -m 755 "$NSLCD_STATEDIR" ; \ + chown nslcd:nslcd "$NSLCD_STATEDIR" ) + # start k5start if needed + k5start_start + # start nslcd + log_daemon_msg "Starting $NSLCD_DESC" "nslcd" + start-stop-daemon --start --oknodo \ + --pidfile $NSLCD_PIDFILE \ + --startas $NSLCD_BIN + log_end_msg $? + ;; +stop) + # stop nslcd + log_daemon_msg "Stopping $NSLCD_DESC" "nslcd" + start-stop-daemon --stop --oknodo \ + --pidfile $NSLCD_PIDFILE \ + --name nslcd + log_end_msg $? + [ -n "$NSLCD_PIDFILE" ] && rm -f $NSLCD_PIDFILE + # stop k5start + k5start_stop + ;; +restart|force-reload) + [ -d "$NSLCD_STATEDIR" ] || ( mkdir -m 755 "$NSLCD_STATEDIR" ; \ + chown nslcd:nslcd "$NSLCD_STATEDIR" ) + log_daemon_msg "Restarting $NSLCD_DESC" "nslcd" + start-stop-daemon --stop --quiet --retry 10 \ + --pidfile $NSLCD_PIDFILE \ + --name nslcd + [ -n "$NSLCD_PIDFILE" ] && rm -f $NSLCD_PIDFILE + k5start_stop + k5start_start + start-stop-daemon --start \ + --pidfile $NSLCD_PIDFILE \ + --startas $NSLCD_BIN + log_end_msg $? + ;; +status) + if [ -f "$NSLCD_PIDFILE" ] + then + if $NSLCD_BIN --check + then + log_success_msg "nslcd running (pid `cat $NSLCD_PIDFILE`)" + exit 0 + else + log_success_msg "nslcd stopped" + exit 1 + fi + else + log_success_msg "nslcd stopped" + exit 3 + fi + k5start_status + ;; +*) + log_success_msg "Usage: $0 {start|stop|restart|force-reload|status}" + exit 1 + ;; +esac + +exit 0 diff --git a/debian/nslcd.install b/debian/nslcd.install new file mode 100644 index 0000000..236670a --- /dev/null +++ b/debian/nslcd.install @@ -0,0 +1 @@ +usr/sbin diff --git a/debian/nslcd.manpages b/debian/nslcd.manpages new file mode 100644 index 0000000..c0708f8 --- /dev/null +++ b/debian/nslcd.manpages @@ -0,0 +1,2 @@ +debian/tmp/usr/share/man/man8/nslcd.8 +debian/tmp/usr/share/man/man5/nslcd.conf.5 diff --git a/debian/nslcd.postinst b/debian/nslcd.postinst new file mode 100644 index 0000000..7262d88 --- /dev/null +++ b/debian/nslcd.postinst @@ -0,0 +1,262 @@ +#!/bin/sh + +set -e + +CONFFILE="/etc/nslcd.conf" +OCONFFILE="/etc/nss-ldapd.conf" + +# set an option in the configuration file to the specified value +cfg_set() +{ + parameter="$1" + value="$2" + # make matching of spaces better in parameter + # this is complicated becase of the "base [map] dn" keyword + param_re=`echo "$parameter" | sed 's#^#[[:space:]]*#;s#[[:space:]][[:space:]]*#[[:space:]][[:space:]]*#g'` + # lines to not match + nomatch_re="^$param_re[[:space:]][[:space:]]*\(aliases\|ethers\|group\|hosts\|netgroup\|networks\|passwd\|protocols\|rpc\|services\|shadow\)" + # check if the parameter is defined + line=`sed -n '/'"$nomatch_re"'/n;/^'"$param_re"'[[:space:]]/p' "$CONFFILE" | head -n 1` + if [ -z "$line" ] + then + # check if the parameter is commented out + param_re="#$param_re" + nomatch_re="^$param_re[[:space:]][[:space:]]*\(aliases\|ethers\|group\|hosts\|netgroup\|networks\|passwd\|protocols\|rpc\|services\|shadow\)" + line=`sed -n '/'"$nomatch_re"'/n;/^'"$param_re"'[[:space:]]/p' "$CONFFILE" | head -n 1` + fi + # decide what to do + if [ -z "$line" ] + then + # just append a new line + echo "$parameter $value" >> $CONFFILE + else + # escape line to replace + replace=`echo "$line" | sed 's#\\\#\\\\\\\#g;s#\([.*+?^$|]\)#\\\\\1#g'` + # escape value (parameter doesn't have any special stuff) + value=`echo "$value" | sed 's#\\\#\\\\\\\#g;s#|#\\\|#g;s#&#\\\&#g'` + # replace the first occurrence of the line + sed -i '1,\|^'"$replace"'$| s|^'"$replace"'$|'"$parameter"' '"$value"'|i' "$CONFFILE" + fi + # we're done + return 0 +} + +# disable options in the configuration file by commenting them out +cfg_disable() +{ + for parameter in $@ + do + # handle bindpw option specially by removing value from config first + if [ "$parameter" = "bindpw" ] && grep -i -q "^bindpw " $CONFFILE + then + cfg_set bindpw "*removed*" + fi + # make matching of spaces better in parameter + param_re=`echo "$parameter" | sed 's#^#[[:space:]]*#;s#[[:space:]][[:space:]]*#[[:space:]][[:space:]]*#g'` + # lines to not match + nomatch_re="^$param_re[[:space:]][[:space:]]*\(aliases\|ethers\|group\|hosts\|netgroup\|networks\|passwd\|protocols\|rpc\|services\|shadow\)" + # comment out the option + sed -i '/'"$nomatch_re"'/n;s/^'"$param_re"'[[:space:]].*$/#&/i' "$CONFFILE" + # we're done + done + return 0 +} + +# set the list of uris +cfg_uris() +{ + uris="$1" + # escape all uri directives + sed -i 's/^uri /_uri_ /i' $CONFFILE + # set the uri options + echo "$uris" | sed 's/^[ \t]*//;s/[ \t]*$//;s/ */\n/g' | while read uri + do + if grep -qi '^_uri_ ' $CONFFILE + then + # escape uri for use in regexp replacement + uri=`echo "$uri" | sed 's#\\\#\\\\\\\#g;s#|#\\\|#g;s#&#\\\&#g'` + # replace the first occurrence of _uri_ + sed -i '1,/^_uri_ / s|^_uri_ .*$|uri '"$uri"'|i' "$CONFFILE" + else + # append new uri + echo "uri $uri" >> $CONFFILE + fi + done + # comment out the remaining escaped uris + sed -i 's/^_uri_ /#uri /' $CONFFILE +} + +# create a default configuration file if nothing exists yet +create_config() +{ + if [ ! -e "$CONFFILE" ] + then + # check if the file with the old name exists + if [ -e "$OCONFFILE" ] + then + # copy the existing file + cp -p $OCONFFILE $CONFFILE + # fix reference to manual page + sed -i 's/nss-ldapd/nslcd/' $CONFFILE + else + # create a simple configuration file from this template + cat > "$CONFFILE" << EOM +# $CONFFILE +# nslcd configuration file. See nslcd.conf(5) +# for details. + +# The user and group nslcd should run as. +uid nslcd +gid nslcd + +# The location at which the LDAP server(s) should be reachable. +uri ldap://localhost/ + +# The search base that will be used for all queries. +base dc=example,dc=net + +# The LDAP protocol version to use. +#ldap_version 3 + +# The DN to bind with for normal lookups. +#binddn cn=annonymous,dc=example,dc=net +#bindpw secret + +# The DN used for password modifications by root. +#rootpwmoddn cn=admin,dc=example,dc=com + +# SSL options +#ssl off +#tls_reqcert never + +# The search scope. +#scope sub + +EOM + # fix permissions + chmod 640 "$CONFFILE" + chown root:nslcd "$CONFFILE" + fi + fi + # we're done + return 0 +} + +# update a configuration parameter, based on the debconf key +update_config() +{ + debconf_param="$1" + cfg_param="$2" + # update configuration option based on debconf value + db_get "$debconf_param" + if [ -n "$RET" ] + then + cfg_set "$cfg_param" "$RET" + else + cfg_disable "$cfg_param" + fi +} + +# real functions begin here +if [ "$1" = "configure" ] +then + # get configuration data from debconf + . /usr/share/debconf/confmodule + # check if the nslcd user exists + if getent passwd nslcd >/dev/null + then + : + else + # create nslcd user and group + adduser --system --group --home /var/run/nslcd/ \ + --gecos "nslcd name service LDAP connection daemon" \ + --no-create-home \ + nslcd + # add uid/gid options to the config file if it exists + # (this is when we're upgrading) + if [ -f "$CONFFILE" ] + then + echo "Adding uid and gid options to $CONFFILE..." >&2 + echo "# automatically added on upgrade of nslcd package" >> "$CONFFILE" + cfg_set uid nslcd + cfg_set gid nslcd + fi + fi + # create a default configuration + create_config + # rename tls_checkpeer to tls_reqcert + if grep -qi '^tls_checkpeer[[:space:]]' $CONFFILE + then + echo "Renaming tls_checkpeer to tls_reqcert in $CONFFILE..." >&2 + sed -i 's/^tls_checkpeer[[:space:]]/tls_reqcert /' "$CONFFILE" + fi + # rename reconnect_maxsleeptime to reconnect_retrytime + if grep -qi '^reconnect_maxsleeptime[[:space:]]' $CONFFILE + then + echo "Renaming reconnect_maxsleeptime to reconnect_retrytime in $CONFFILE..." >&2 + sed -i 's/^reconnect_maxsleeptime[[:space:]]/reconnect_retrytime /' "$CONFFILE" + fi + # set server uri + db_get nslcd/ldap-uris + cfg_uris "$RET" + # update some options + update_config nslcd/ldap-base base + db_get nslcd/ldap-auth-type + authtype="$RET" + case "$authtype" in + simple) + update_config nslcd/ldap-binddn binddn + update_config nslcd/ldap-bindpw bindpw + cfg_disable sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname + ;; + SASL) + update_config nslcd/ldap-sasl-mech sasl_mech + update_config nslcd/ldap-sasl-realm sasl_realm + # RFC4313 if SASL, binddn should be disabled + cfg_disable binddn + db_get nslcd/ldap-sasl-mech + saslmech="$RET" + case "$saslmech" in + GSSAPI) + update_config nslcd/ldap-sasl-krb5-ccname krb5_ccname + cfg_disable sasl_authcid + ;; + *) + update_config nslcd/ldap-sasl-authcid sasl_authcid + update_config nslcd/ldap-bindpw bindpw + cfg_disable krb5_ccname + ;; + esac + update_config nslcd/ldap-sasl-authzid sasl_authzid + update_config nslcd/ldap-sasl-secprops sasl_secprops + ;; + none) + cfg_disable binddn bindpw + cfg_disable sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname + esac + update_config nslcd/ldap-reqcert tls_reqcert + # remove password from database + db_set nslcd/ldap-bindpw "" + # set ssl option + db_get nslcd/ldap-starttls + if [ "$RET" = "true" ] + then + cfg_set ssl "start_tls" + elif grep -qi '^ssl[[:space:]]*start_*tls' $CONFFILE + then + cfg_disable ssl + fi + # we're done + db_stop + # fix permissions of configfile if upgrading from an old version + if dpkg --compare-versions "$2" lt-nl "0.6.7.1" + then + echo "Fixing permissions of $CONFFILE" + chmod 640 "$CONFFILE" + chown root:nslcd "$CONFFILE" + fi +fi + +#DEBHELPER# + +exit 0 diff --git a/debian/nslcd.postrm b/debian/nslcd.postrm new file mode 100644 index 0000000..7bdbd9a --- /dev/null +++ b/debian/nslcd.postrm @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e + +CONFFILE="/etc/nslcd.conf" +OCONFFILE="/etc/nss-ldapd.conf" + +# remove /var/run/nslcd directory +rm -rf /var/run/nslcd + +# remove our configuration file (not a conffile) on purge manually +if [ "$1" = "purge" ] +then + rm -f "$CONFFILE" "$OCONFFILE" +fi + +#DEBHELPER# diff --git a/debian/nslcd.templates b/debian/nslcd.templates new file mode 100644 index 0000000..5a57f0b --- /dev/null +++ b/debian/nslcd.templates @@ -0,0 +1,123 @@ +Template: nslcd/ldap-uris +Type: string +_Description: LDAP server URI: + Please enter the Uniform Resource Identifier of the LDAP server. The format + is "ldap://:/". Alternatively, "ldaps://" or + "ldapi://" can be used. The port number is optional. + . + When using an ldap or ldaps scheme it is recommended to use an IP address to + avoid failures when domain name services are unavailable. + . + Multiple URIs can be specified by separating them with spaces. + +Template: nslcd/ldap-base +Type: string +_Description: LDAP server search base: + Please enter the distinguished name of the LDAP search base. Many sites use + the components of their domain names for this purpose. For example, the + domain "example.net" would use "dc=example,dc=net" as the distinguished name + of the search base. + +Template: nslcd/ldap-auth-type +Type: select +__Choices: none, simple, SASL +Default: none +_Description: LDAP authentication to use: + Please choose what type of authentication the LDAP database should + require (if any): + . + * none: no authentication; + * simple: simple bind DN and password authentication; + * SASL: any Simple Authentication and Security Layer mechanism. + +Template: nslcd/ldap-binddn +Type: string +_Description: LDAP database user: + Enter the name of the account that will be used to log in to the LDAP + database. This value should be specified as a DN (distinguished name). + +Template: nslcd/ldap-bindpw +Type: password +_Description: LDAP user password: + Enter the password that will be used to log in to the LDAP database. + +Template: nslcd/ldap-sasl-mech +Type: select +Choices: auto, LOGIN, PLAIN, NTLM, CRAM-MD5, DIGEST-MD5, GSSAPI, OTP +_Description: SASL mechanism to use: + Choose the SASL mechanism that will be used to authenticate to the LDAP + database: + . + * auto: auto-negotiation; + * LOGIN: deprecated in favor of PLAIN; + * PLAIN: simple cleartext password mechanism; + * NTLM: NT LAN Manager authentication mechanism; + * CRAM-MD5: challenge-response scheme based on HMAC-MD5; + * DIGEST-MD5: HTTP Digest compatible challenge-response scheme; + * GSSAPI: used for Kerberos; + * OTP: a One Time Password mechanism. + +Template: nslcd/ldap-sasl-realm +Type: string +_Description: SASL realm: + Enter the SASL realm that will be used to authenticate to the LDAP + database. + . + The realm is appended to authentication and authorization identities. + . + For GSSAPI this can be left blank to use information from the Kerberos + credential cache. + +Template: nslcd/ldap-sasl-authcid +Type: string +_Description: SASL authentication identity: + Enter the SASL authentication identity that will be used to authenticate to + the LDAP database. + . + This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms. + +Template: nslcd/ldap-sasl-authzid +Type: string +_Description: SASL proxy authorization identity: + Enter the proxy authorization identity that will be used to authenticate to + the LDAP database. + . + This is the object in the name of which the LDAP request is done. + This value should be specified as a DN (distinguished name). + +Template: nslcd/ldap-sasl-secprops +Type: string +_Description: Cyrus SASL security properties: + Enter the Cyrus SASL security properties. + Allowed values are described in the ldap.conf(5) manual page + in the SASL OPTIONS section. + +Template: nslcd/ldap-sasl-krb5-ccname +Type: string +Default: /var/run/nslcd/nslcd.tkt +_Description: Kerberos credential cache file path: + Enter the GSSAPI/Kerberos credential cache file name that will be used. + +Template: nslcd/ldap-starttls +Type: boolean +_Description: Use StartTLS? + Please choose whether the connection to the LDAP server should use + StartTLS to encrypt the connection. + +Template: nslcd/ldap-reqcert +Type: select +__Choices: never, allow, try, demand +_Description: Check server's SSL certificate: + When an encrypted connection is used, a server certificate can be requested + and checked. Please choose whether lookups should be configured to require + a certificate, and whether certificates should be checked for validity: + . + * never: no certificate will be requested or checked; + * allow: a certificate will be requested, but it is not + required or checked; + * try: a certificate will be requested and checked, but if no + certificate is provided it is ignored; + * demand: a certificate will be requested, required, and checked. + . + If certificate checking is enabled, at least one of the tls_cacertdir or + tls_cacertfile options must be put in /etc/nslcd.conf. diff --git a/debian/pam-configs/ldap b/debian/pam-configs/ldap new file mode 100644 index 0000000..9181a69 --- /dev/null +++ b/debian/pam-configs/ldap @@ -0,0 +1,19 @@ +Name: LDAP Authentication +Default: yes +Priority: 128 +Auth-Type: Primary +Auth-Initial: + [success=end default=ignore] pam_ldap.so minimum_uid=1000 +Auth: + [success=end default=ignore] pam_ldap.so minimum_uid=1000 use_first_pass +Account-Type: Additional +Account: + [success=ok new_authtok_reqd=done ignore=ignore user_unknown=ignore authinfo_unavail=ignore default=bad] pam_ldap.so minimum_uid=1000 +Password-Type: Primary +Password-Initial: + [success=end default=ignore] pam_ldap.so minimum_uid=1000 +Password: + [success=end default=ignore] pam_ldap.so minimum_uid=1000 try_first_pass +Session-Type: Additional +Session: + [success=ok default=ignore] pam_ldap.so minimum_uid=1000 diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in new file mode 100644 index 0000000..395afba --- /dev/null +++ b/debian/po/POTFILES.in @@ -0,0 +1,3 @@ +[type: gettext/rfc822deb] nslcd.templates +[type: gettext/rfc822deb] libnss-ldapd.templates +[type: gettext/rfc822deb] libpam-ldapd.templates diff --git a/debian/po/ca.po b/debian/po/ca.po new file mode 100644 index 0000000..ce41d15 --- /dev/null +++ b/debian/po/ca.po @@ -0,0 +1,626 @@ +# Translation of nss-pam-ldapd debconf templates to Catalan. +# Copyright (C) 2004 Free Software Foundation, Inc. +# +# Translators: +# +# Aleix Badia i Bosch , 2004. +# Guillem Jover , 2004. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.7.9\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2010-08-24 09:14+0100\n" +"Last-Translator: Agustí Grau \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI del servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Introduiu la URI del servidor LDAP. El format és 'ldap://" +":/'. També es pot utilitzar 'ldaps://' or " +"'ldapi://'. El numero de port és opcional." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Quan s'utilitza l'esquema ldap o ldaps es recomana utilitzar l'adreça IP per " +"evitar fallides quan el servidors de noms de domini no sigui disponible." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Es poden especificar múltiples URIs separant-les per espaïs." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "base de cerca del servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Introduïu el nom distingit de la base de la cerca de l'LDAP. Molts llocs " +"utilitzen els components del seu nom del domini. Per exemple, el domini " +"«exemple.net» utilitzaria el nom distingit de la base de la cerca " +"«dc=exemple,dc=net»." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +#, fuzzy +msgid "LDAP authentication to use:" +msgstr "Versió de l'LDAP a utilitzar" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "usuari de la base de dades de l'LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "" +#| "Enter the name of the account that will be used to log in to the LDAP " +#| "database." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Introduïu el nom del compte que s'utilitzarà per entrar a la base de dades " +"de l'LDAP." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Contrasenya de l'usuari de l'LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Introduïu la contrasenya que s'utilitzarà per a l'accés autenticat a la base " +"de dades de l'LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Introduïu la contrasenya que s'utilitzarà per a l'accés autenticat a la base " +"de dades de l'LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Introduïu la contrasenya que s'utilitzarà per a l'accés autenticat a la base " +"de dades de l'LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "" +#| "Enter the name of the account that will be used to log in to the LDAP " +#| "database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Introduïu el nom del compte que s'utilitzarà per entrar a la base de dades " +"de l'LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Introduïu la contrasenya que s'utilitzarà per a l'accés autenticat a la base " +"de dades de l'LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Aquest valor hauria de ésser especificat com a DN (distinguished name)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Utilitzar StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Seleccioneu si la connexió amb el servidor LDAP ha d'utilitzar STARTTLS per " +"xifrar la connexió." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "Mai" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "Permet" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "Prova" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "Demanda" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Comprovar certificat SSL del servidor:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Quan s'utilitza una connexió xifrada, es demana el certificat del servidor i " +"es comprova. Seleccioneu si les consultes han de ésser configurades per a " +"requerir un certificat i quins certificates tenen que ésser comprovats per " +"validar-los:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * mai: cap certificat serà demanat o comprovat;\n" +" * permetre: es demana el certificat, però no és\n" +" requerit o comprovat;\n" +" * intent: el certificat serà demanat i comprovat, pero si no\n" +" es proporciona serà ignorat;\n" +" * demanda: el certiicat serà demanat, requerit i comprovat." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Si la comprovació de certificats està habilitada, s'haura d'habilitar en el " +"fitxer /etc/nslcd.conf com a mínim una opció de tls_cacertdir o " +"tls_cacertfile." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Serveis de noms a configurar:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Per a utilitzar aquest paquet, harieu de modificar el /etc/nsswitch.conf per " +"utilitzar l'origen de dades ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Podeu seleccionar els serveis que haurien de tenir habilitades les consultes " +"LDAP. Les noves consultes LDAP seran afegides com a l'últim origen de dades. " +"Assegureu's de revisar els canvis." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Eliminar l'LDAP del fitxer nsswitch.conf?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Els serveis següents estan configurats per utilitzar LDAP per a realitzar " +"consultes:\n" +" ${services}\n" +"pero el paquet libnss-ldapd està a punt de ser eliminat." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"S'aconsella eliminar les entrades si no utilitzareu més l'LDAP per a la " +"resolució de noms.No hauria de causar problemes si no s'elimina l'ldap del " +"fitxer nsswitch.conf, pero la resolució de noms pot ésser afectada de forma " +"subtil." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Podeu editar el fitxer /etc/nsswitch.conf a mà o escollir eliminar les " +"entrades automàticament. Assegureu-vos de revisar els canvis al fitxer /etc/" +"nsswitch.conf si escolliu eliminar les entrades ara." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Habilitar les cerques shadow a través de NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Per habilitar els usuaris de l'LDAP per a autenticar-se, el mòdul NSS " +"necessitar ser habilitar per a realitzar cerques de contrasenya shadow. Les " +"entrades shadow haurien de ser buides - no hi ha necessitat d'exposar els " +"resums de contrasenya. Visiteu http://bugs.debian.org/583492 per a més " +"informació." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Seleccioneu si el fitxer /etc/nsswitch.conf hauria de tenir la entrada " +"requerida afegida automàticament (en aquest cas s'hauria de revisar " +"posteriorment) o si hauria de deixar per a ser editada manualment per " +"l'administrador." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Si la base de dades LDAP requereix una autenticació per a realitzar " +#~ "cerques, entreu el nom del compte que serà utilitzat. Deixeu-lo en blanc " +#~ "en qualsevol altre cas." + +#, fuzzy +#~ msgid "" +#~ "Enter the password that will be used to log in to the LDAP database when " +#~ "the root process does lookups." +#~ msgstr "" +#~ "Introduïu la contrasenya que s'utilitzarà per a l'accés autenticat a la " +#~ "base de dades de l'LDAP." + +#, fuzzy +#~ msgid "" +#~ "Please enter which version of the LDAP protocol is to use. It is usually " +#~ "a good idea to set this to highest available version number." +#~ msgstr "" +#~ "Introduïu la versió del protocol d'LDAP que utilitza el ldapns. " +#~ "Normalment és una bona idea especificar el nombre de versió més gran " +#~ "disponible." + +#, fuzzy +#~ msgid "" +#~ "For this package to work, you need to modify your /etc/nsswitch.conf to " +#~ "use the ldap datasource. There is an example file at /usr/share/doc/" +#~ "libnss-ldap/examples/nsswitch.ldap which can be used as an example for " +#~ "your nsswitch setup." +#~ msgstr "" +#~ "Per fer funcionar el paquet necessiteu modificar el fitxer /etc/nsswitch." +#~ "conf perquè utilitzi l'origen de dades de l'LDAP. Podeu utilitzar " +#~ "d'exemple el fitxer /usr/share/doc/libnss-ldap/examples/nsswitch.ldap o " +#~ "copiar-lo sobre la vostra configuració actual." + +#~ msgid "distinguished name of the search base" +#~ msgstr "nom distingit de la base de la cerca" + +#~ msgid "password for database login account" +#~ msgstr "contrasenya pel compte d'accés autenticat de la base de dades" + +#~ msgid "nsswitch.conf is not managed automatically" +#~ msgstr "el fitxer nsswitch.conf no es gestiona automàticament" + +#~ msgid "make configuration readable/writeable by owner only" +#~ msgstr "" +#~ "fes que la configuració només la pugui llegir/escriure el propietari" + +#~ msgid "" +#~ "Should the libnss-ldap configuration file be readable and writable only " +#~ "by the file owner?" +#~ msgstr "" +#~ "Voleu que la configuració del libnss-ldap només la pugui llegir i " +#~ "escriure el propietari del fitxer?" + +#~ msgid "" +#~ "If you use passwords in your libnss-ldap configuration, it is usually a " +#~ "good idea to have the configuration set with mode 0600 (readable and " +#~ "writable only by the file's owner)." +#~ msgstr "" +#~ "Si la configuració del libnss-ldap conté contrasenyes, és una bona idea " +#~ "definir el mode 0600 pel fitxer (només el pot llegir i escriure el " +#~ "propietari)." + +#~ msgid "" +#~ "Note: As a sanity check, libnss-ldap will check if you have nscd " +#~ "installed and will only set the mode to 0600 if nscd is present." +#~ msgstr "" +#~ "Nota: el libnss-ldap comprovarà si teniu instal·lat l'nscd. Si ho està, " +#~ "definirà el mode 0600." + +#~ msgid "database requires login" +#~ msgstr "la base de dades requereix d'autenticació d'accés" + +#~ msgid "Does the LDAP database require login?" +#~ msgstr "La base de dades d'LDAP requereix d'autenticació d'accés?" + +#~ msgid "" +#~ "Answer this question affirmatively only if you can't retreive entries " +#~ "from the database without logging in." +#~ msgstr "" +#~ "Contesteu positivament només si no podeu obtenir les entrades de la base " +#~ "de dades sense autenticar-vos." + +#~ msgid "Note: Under a normal setup, this is not needed." +#~ msgstr "Nota: en una configuració normal no és necessari." + +#~ msgid "enable automatic configuration updates by debconf" +#~ msgstr "" +#~ "habilita les actualitzacions de configuració automàtiques a través del " +#~ "debconf" + +#~ msgid "" +#~ "Should debconf automatically update libnss-ldap's configuration file?" +#~ msgstr "" +#~ "Voleu que el debconf actualitzi automàticament el fitxer de configuració " +#~ "del libnss-ldap?" + +#~ msgid "libnss-ldap has been moved to use debconf for its configuration." +#~ msgstr "" +#~ "el libnss-ldap ha canviat a utilitzar el debconf en la configuració." + +#~ msgid "" +#~ "The file will be prepended with \"###DEBCONF###\"; you can disable the " +#~ "debconf updates by removing that line." +#~ msgstr "" +#~ "S'afegirà la línia «###DEBCONF###» al principi del fitxer; podeu " +#~ "inhabilitar-ne les actualitzacions del debconf suprimint-la." + +#~ msgid "All new installations will have this by default." +#~ msgstr "Totes les noves instal·lacions ho tindran de forma predeterminada." + +#~ msgid "" +#~ "Also, before removing this package, it is wise to remove the ldap entries " +#~ "from nsswitch.conf to keep basic services functioning." +#~ msgstr "" +#~ "Per mantenir els serveis bàsics funcionant i abans de suprimir el paquet, " +#~ "cal suprimir les entrades d'LDAP del fitxer nsswitch.conf." + +#~ msgid "dc=example,dc=net" +#~ msgstr "dc=exemple,dc=net" + +#~ msgid "cn=proxyuser,dc=example,dc=net" +#~ msgstr "cn=proxyuser,dc=exemple,dc=net" + +#~ msgid "3, 2" +#~ msgstr "3, 2" + +#, fuzzy +#~ msgid "ldap://127.0.0.1/" +#~ msgstr "127.0.0.1" + +#~ msgid "Please enter the address of the LDAP server used." +#~ msgstr "Introduïu l'adreça del servidor d'LDAP utilitzat." diff --git a/debian/po/cs.po b/debian/po/cs.po new file mode 100644 index 0000000..3a27651 --- /dev/null +++ b/debian/po/cs.po @@ -0,0 +1,609 @@ +# Translation of nss-pam-ldapd debconf templates to Czech. +# +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-23 21:16+0200\n" +"Last-Translator: Miroslav Kure \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI LDAP serveru:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Zadejte URI (Uniform Resource Identifier) LDAP serveru ve formátu „ldap://" +":/“. Možné jsou i varianty „ldaps://“ a " +"„ldapi://“. Číslo portu není povinné." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Při použití schémat ldap nebo ldaps se doporučuje použít IP adresu, protože " +"tím předejdete chybám v případech, kdy je služba překladu jmen nedostupná." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Více URI je možno zadat tak, že je oddělíte mezerami." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Kořen prohledávaného LDAP stromu:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Zadejte rozlišitelný název prohledávaného LDAP stromu. Mnoho serverů pro " +"tento účel využívá části svých doménových jmen. Například doména „priklad." +"cz“ by jako rozlišitelné jméno svého stromu použila „dc=priklad,dc=cz“." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "žádná" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "jednoduchá" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "LDAP autentizace, která se má použít:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Vyberte, jaký typ autentizace má LDAP databáze vyžadovat (pokud vůbec):" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * žádná: bez autentizace;\n" +" * jednoduchá: jednoduchá autentizace pomocí DN a hesla;\n" +" * SASL: libovolný mechanismus Simple Authentication and Security Layer." + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP uživatel:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Zadejte jméno účtu, který se použije pro přístup k LDAP databázi. Měli byste " +"jej zadat jako rozlišitelné jméno (DN)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Heslo LDAP uživatele:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "Zadejte heslo, které se použije pro přístup k LDAP databázi." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Metoda SASL, která se má použít:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Vyberte SASL mechanismus, který se použije pro autentizaci do LDAP databáze." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: automatické vyjednání parametrů;\n" +" * LOGIN: staré, nahrazeno PLAIN;\n" +" * PLAIN: jednoduché nešifrované heslo;\n" +" * NTLM: autentizace stylem NT LAN Manager;\n" +" * CRAM-MD5: challenge-response schéma založené na HMAC-MD5;\n" +" * DIGEST-MD5: challenge-response schéma kompatibilní s HTTP Digest;\n" +" * GSSAPI: používáno pro Kerberos;\n" +" * OTP: jednorázová hesla." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "SASL říše:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "Zadejte SASL říši, která se použije pro autentizaci do LDAP databáze." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "Říše se připojí k autentizačním a autorizačním identitám." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Pro GSSAPI můžete ponechat prázdné, aby se použily informace z cache identit " +"systému Kerberos." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "Identita pro SASL autentizaci:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Zadejte SASL identitu, která se použije pro autentizaci do LDAP databáze." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Jedná o uživatelské jméno používané u metod LOGIN, PLAIN, CRAM-MD5 a DIGEST-" +"MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "Identita pro SASL proxy autorizaci:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Zadejte proxy identitu, která se použije pro autentizaci do LDAP databáze." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Jedná se o objekt, v jehož jméně by měl být LDAP požadavek proveden. Tato " +"hodnota by měla být zadána jako rozlišitelné jméno (DN)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Bezpečnostní prvky Cyrus SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Zadejte bezpečnostní prvky Cyrus SASL. Povolené hodnoty jsou popsány v " +"manuálové stránce ldap.conf(5) v části SASL OPTIONS." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Cesta k cache souboru s Kerberos identitami:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Zadejte jméno souboru obsahujícího cache identit systému GSSAPI/Kerberos, " +"který se má použít." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Používat StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Vyberte, zda má přpojení k LDAP serveru používat StartTLS pro šifrování " +"spojení." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nikdy" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "povoleno" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "pokusit se" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "vyžadováno" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Kontrolovat SSL certifikát serveru:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Při použití šifrovaného spojení, může být vyžádán a zkontrolován certifikát " +"serveru. Vyberte si, zda mají dotazy certifikát vyžadovat a zda se má " +"kontrolovat jeho platnost:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * nikdy: certifikát nebude nikdy vyžadován ani kontrolován;\n" +" * povoleno: certifikát bude vyžádán, ale není povinný a nebude\n" +" kontrolován;\n" +" * pokusit se: certifikát bude vyžádán a zkontrolován, ale pokud\n" +" nebude certifikát obdržen, bude to ignorováno;\n" +" * vyžadováno: certifikát je povinný a bude zkontrolován." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Je-li zapnuta kontrola certifikátů, musí být v /etc/nslcd.conf povolena " +"minimálně jedna z voleb tls_cacertdir a tls_cacertfile." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Jmenné služby, které se mají nastavit:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Aby tento balík mohl fungovat, musíte upravit svůj /etc/nsswitch.conf tak, " +"aby používal datový zdroj ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Můžete si vybrat služby, které mají mít povoleno vyhledávání přes LDAP. " +"Vyhledávání přes LDAP bude přidáno jako poslední datový zdroj. Rozhodně " +"doporučujeme tyto změny zkontrolovat." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Odstranit LDAP z nsswitch.conf?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Následující služby jsou stále nastaveny, aby pro vyhledávání používaly " +"LDAP:\n" +" ${services}\n" +"avšak balík libnss-ldapd je právě odebírán ze systému." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Pokud již neplánujete používat pro překlad jmen LDAP, doporučujeme záznamy " +"odstranit. Neodstranění ldap záznamů z nsswitch.conf by většině služeb " +"nemělo dělat žádné problémy, ale překlad jmen by se mohl začít chovat " +"přinejmenším zajímavě." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"/etc/nsswitch.conf můžete upravit ručně, nebo nechat záznamy odstranit " +"automaticky. Zvolíte-li automatické odstranění, rozhodně si provedené změny " +"v /etc/nsswitch.conf prohlédněte." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Povolit vyhledávání v shadow pomocí NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Abyste umožnili LDAP uživatelům přihlášení do systému, musíte povolit NSS " +"modul pro vyhledávání ve st9nových heslech. Samotné záznamy v shadow mohou " +"být prázdné, tj. není důvod vystavovat na venek hashe hesel. Podrobnosti " +"naleznete v http://bugs.debian.org/583492." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Rozhodněte se, zda se má požadovaný záznam přidat do /etc/nsswitch.conf " +"automaticky (což byste měli následně zkontrolovat), nebo zda ho tam přidá " +"správce systému ručně." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Pokud LDAP databáze vyžaduje pro běžné vyhledávání přihlášení, zadejte " +#~ "jméno účtu, který se má použít. V opačném případě ponechte prázdné." + +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "/etc/nsswitch.conf můžete upravit ručně, nebo nechat záznamy přidat " +#~ "automaticky. Zvolíte-li automatické odstranění, rozhodně si provedené " +#~ "změny v /etc/nsswitch.conf prohlédněte." + +#~ msgid "LDAP server Uniform Resource Identifier:" +#~ msgstr "URI LDAP serveru:" + +#~ msgid "" +#~ "Enter the password that will be used to log in to the LDAP database when " +#~ "the root process does lookups." +#~ msgstr "" +#~ "Zadejte heslo, které se použije pro přístup k LDAP databázi v případech, ." +#~ "kdy rootovský proces něco vyhledává." + +#~ msgid "" +#~ "Please enter which version of the LDAP protocol is to use. It is usually " +#~ "a good idea to set this to highest available version number." +#~ msgstr "" +#~ "Zadejte verzi LDAP protokolu, kterou má se má používat. Obvykle se " +#~ "doporučuje použít nejvyšší dostupnou verzi." + +#~ msgid "" +#~ "For this package to work, you need to modify your /etc/nsswitch.conf to " +#~ "use the ldap datasource. There is an example file at /usr/share/doc/" +#~ "libnss-ldap/examples/nsswitch.ldap which can be used as an example for " +#~ "your nsswitch setup." +#~ msgstr "" +#~ "Aby tento balík fungoval, musíte upravit svůj /etc/nsswitch.conf, aby " +#~ "jako zdroj dat používal ldap. V /usr/share/doc/libnss-ldap/examples/" +#~ "nsswitch.ldap se nachází vzorový soubor, který můžete použít jako základ " +#~ "pro vaše nastavení." + +#~ msgid "distinguished name of the search base" +#~ msgstr "Rozlišitelný název prohledávaného stromu" + +#~ msgid "password for database login account" +#~ msgstr "Heslo pro přihlášení k databázi" + +#~ msgid "nsswitch.conf is not managed automatically" +#~ msgstr "nsswitch.conf není spravován automaticky" + +#~ msgid "make configuration readable/writeable by owner only" +#~ msgstr "Umožnit čtení/zápis do konfigurace pouze vlastníkovi" + +#~ msgid "" +#~ "Should the libnss-ldap configuration file be readable and writable only " +#~ "by the file owner?" +#~ msgstr "" +#~ "Nastavit oprávnění konfiguračního souboru libnss-ldap tak, aby jej mohl " +#~ "číst/zapisovat pouze vlastník souboru?" + +#~ msgid "" +#~ "If you use passwords in your libnss-ldap configuration, it is usually a " +#~ "good idea to have the configuration set with mode 0600 (readable and " +#~ "writable only by the file's owner)." +#~ msgstr "" +#~ "Používáte-li ve své konfiguraci libnss-ldap hesla, je obvykle dobrým " +#~ "nápadem nastavit souboru práva 0600 (čtení a zápis pouze pro vlastníka " +#~ "souboru)." + +#~ msgid "" +#~ "Note: As a sanity check, libnss-ldap will check if you have nscd " +#~ "installed and will only set the mode to 0600 if nscd is present." +#~ msgstr "" +#~ "Poznámka: libnss-ldap ještě zkontroluje, zda máte nainstalován nscd a " +#~ "oprávnění změní pouze v případě, že ano." + +#~ msgid "database requires login" +#~ msgstr "Databáze vyžaduje přihlášení" + +#~ msgid "Does the LDAP database require login?" +#~ msgstr "Vyžaduje LDAP databáze přihlášení?" + +#~ msgid "" +#~ "Answer this question affirmatively only if you can't retreive entries " +#~ "from the database without logging in." +#~ msgstr "" +#~ "Souhlaste pouze v případě, že nemůžete získávat záznamy z databáze bez " +#~ "přihlášení." + +#~ msgid "Note: Under a normal setup, this is not needed." +#~ msgstr "Poznámka: při běžném nastavení to není potřeba." + +#~ msgid "enable automatic configuration updates by debconf" +#~ msgstr "Povolit automatické zásahy do konfigurace pomocí debconfu" + +#~ msgid "" +#~ "Should debconf automatically update libnss-ldap's configuration file?" +#~ msgstr "" +#~ "Má debconf automaticky aktualizovat konfigurační soubor libnss-ldap?" + +#~ msgid "libnss-ldap has been moved to use debconf for its configuration." +#~ msgstr "" +#~ "libnss-ldap se konečně pochlapil a pro svou konfiguraci používá debconf." + +#~ msgid "" +#~ "The file will be prepended with \"###DEBCONF###\"; you can disable the " +#~ "debconf updates by removing that line." +#~ msgstr "" +#~ "Na začátek souboru bude přidán řádek \"###DEBCONF###\". Chcete-li, aby " +#~ "debconf do souboru nezasahoval, stačí zmíněný řádek odstranit." + +#~ msgid "All new installations will have this by default." +#~ msgstr "Toto je výchozí nastavení pro všechny nové instalace." + +#~ msgid "" +#~ "Also, before removing this package, it is wise to remove the ldap entries " +#~ "from nsswitch.conf to keep basic services functioning." +#~ msgstr "" +#~ "Podobně je vhodné při odinstalování balíčku tyto ldap záznamy z nsswitch." +#~ "conf zase odstranit, aby byla zachována funkčnost základních služeb." + +#~ msgid "dc=example,dc=net" +#~ msgstr "dc=priklad,dc=cz" + +#~ msgid "cn=proxyuser,dc=example,dc=net" +#~ msgstr "cn=proxyuzivatel,dc=priklad,dc=cz" + +#~ msgid "Please enter the address of the LDAP server used." +#~ msgstr "Zadejte prosím adresu použitého LDAP serveru." diff --git a/debian/po/da.po b/debian/po/da.po new file mode 100644 index 0000000..4c0cd28 --- /dev/null +++ b/debian/po/da.po @@ -0,0 +1,492 @@ +# Danish translation nss-pam-ldapd. +# Copyright (C) 2011 nss-pam-ldapd og nedenstående oversættere. +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# Jonas Smedegaard , 2008. +# Joe Hansen , 2010, 2011. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-14 23:51+0200\n" +"Last-Translator: Joe Hansen \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "Adresse for LDAP-server:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Angiv URI'en (Uniform Resource Identifier) for den anvendte LDAP-server. " +"Formatet er »ldap://:/«. Alternativt " +"»ldaps://« eller også kan »ldapi://« bruges. Portnummeret er valgfrit." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Når ldap- eller ldaps-skemaerne bruges, anbefales det, at bruge en IP-" +"adresse for at undgå fejl når domænenavnstjenester ikke er tilgængelige." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Flere URI'er kan angives ved at adskille dem med mellemrum." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Søgebase for LDAP-server:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Angiv det særlige navn på LDAP-søgebasen. Mange sider bruger komponenterne " +"fra deres domænenavne til dette formål. Eksempelvis ville domænet »eksempel." +"dk« bruge »dc=eksempel,dc=dk« som det særlige navn på søgebasen." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "ingen" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "simpel" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "LDAP-godkendelse at bruge:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Vælg venligst hvilken godkendelsestype LDAP-databasen skal kræve (hvis " +"nogen):" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * ingen: ingen godkendelse;\n" +" * simpel: simpel bind DN og godkendelse af adgangskode;\n" +" * SASL: enhver Simple Authentication og Security Layer-mekanisme." + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP-databasebruger:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Indtast navnet for kontoen som vil blive brugt til at logge ind i " +"LDAP-databasen. Denne værdi bør angives som et DN (særligt navn - " +"distinguished name)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Adgangskode for LDAP-bruger:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Angiv adgangskoden som vil blive brugt til at logge ind på LDAP-databasen." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "SASL-mekanisme at bruge:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Vælg den SASL-mekanisme som vil blive brugt til at godkende adgang til " +"LDAP-databasen:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: automatisk forhandling;\n" +" * LOGIN: forældet i forhold til PLAIN;\n" +" * PLAIN: simpel klartekst adgangskodemekanisme;\n" +" * NTLM: NT LAN Manager-godkendelsesmekanisme;\n" +" * CRAM-MD5: udfordr-svar skema baseret på HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest-kompatibel udfordr-svar skema;\n" +" * GSSAPI: brugt for Kerberos;\n" +" * OTP: en mekanisme hvor en adgangskode kun kan bruges en gang." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "SASL-område (realm):" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Angiv SASL-området (realm) som vil blive brugt til at godkende for LDAP-" +"databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "Området tilføjes godkendelses- og autorisationsidentiteter." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"For GSSAPI kan dette efterlades tomt for at bruge information fra " +"akkreditivmellemlageret for Kerberos." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "SASL-godkendelsesidentitet:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Angiv SASL-godkendelsesidentiteten som vil blive brugt til at godkende for " +"LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Dette er logindet brugt i LOGIN-, PLAIN-, CRAM-MD5- OG DIGEST-MD5-mekanismerne." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "SASL-proxygodkendelsesidentitet:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Angiv proxygodkendelsesidentiteten som vil blive brugt til at godkende for " +"LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Dette er objektet i hvis navn LDAP-forespørgslen foretages. Denne værdi bør " +"angives som et DN (særligt navn - distinguished name)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Cyrus SASL-sikkerhedsegenskaber:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Indtast Cyrus SASL-sikkerhedsegenskaber. Tilladte værdier er beskrevet i " +"ldap.conf(5)-manualsiden i SASL OPTIONS-afsnittet." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Kerberos' filsti for akkreditivmellemlageret:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Indtast filnavnet for GSSAPI/Kerberos' akkreditivmellemlager som vil " +"blive brugt." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Brug StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Vælg venligst hvorvidt forbindelsen til LDAP-serveren skal bruge StartTLS " +"til at kryptere forbindelsen." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "aldrig" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "tillad" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "forsøg" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "kræv" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Tjek servers SSL-certifikat:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Når en krypteret forbindelse bruges, kan der blive spurgt efter et " +"servercertifikat, som tjekkes. Vælg venligst hvorvidt opslag skal " +"konfigureres til at kræve et certifikat, og hvorvidt certifikater skal " +"validitetstjekkes:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * aldrig: Der vil ikke blive spurgt efter eller tjekket for certifikater;\n" +" * tillad: Der vil blive spurgt efter et certifikat, men det er ikke krævet\n" +" og tjekkes ikke;\n" +" * forsøg: Der vil blive spurgt efter et certifikat, som tjekkes, men hvis\n" +" intet certifikat tilbydes ignoreres det;\n" +" * kræv: Der vil blive spurgt efter et certifikat, det er krævet og det\n" +" tjekkes." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Hvis certifikattjek er aktiveret skal mindst en af tilvalgene tls_cacertdir " +"eller tls_cacertfile være placeret i /etc/nslcd.conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Navnetjenester at konfigurere:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"For at denne pakke fungerer, må du ændre din /etc/nsswitch.conf til at bruge " +"ldap-datakilden." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Du kan vælge de tjenester, som skal have LDAP-opslag aktiveret. De nye LDAP-" +"opslag vil blive tilføjet som den sidste datakilde. Sørg for at gennemgå " +"ændringerne." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Fjern LDAP fra nsswitch.conf nu?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"De følgende tjenester er stadig konfigureret til at bruge LDAP til\n" +"opslag:\n" +" ${services}\n" +"men pakken libnss-ldapd er ved at blive afinstalleret." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Du anbefales at fjerne punkterne, hvis du ikke længere har planer om at " +"bruge LDAP til navneopslag. For de fleste tjenester skulle det ikke give " +"problemer ikke at fjerne ldap fra nsswitch.conf, men opslag af værtsnavne " +"kan blive påvirket i mindre grad." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Du kan redigere /etc/nsswitch.conf i hånden eller vælge at fjerne punkterne " +"automatisk nu. Sørg for at gennemse ændringer til /etc/nsswitch.conf hvis du " +"vælger at fjerne indlæggene nu." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Aktiver skyggeopslag igennem NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"For at tillade LDAP-brugere at logge ind kræver det, at NSS-modulet er " +"aktiveret til at udføre opslag for skyggeadgangskoder. Skyggepunkterne i sig " +"selv kan være tomme - det vil sige, at der ingen grund er til at vise hasher " +"frem for adgangskoder. Se http://bugs.debian.org/583492 for baggrunden." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Vælg venligst hvorvidt /etc/nsswitch.conf automatisk skal have tilføjet det " +"krævede punkt (i dette tilfælde skal det fjernes efterfølgende) eller " +"hvorvidt, det skal efterlades til en administrator for manuel redigering." diff --git a/debian/po/de.po b/debian/po/de.po new file mode 100644 index 0000000..cbf7a2a --- /dev/null +++ b/debian/po/de.po @@ -0,0 +1,506 @@ +# Translation of nss-pam-ldapd debconf templates to German. +# Copyright (C) 2004 Erik Schanze +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# Erik Schanze , 2004-2009. +# Chris Leick 2010,2011. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-18 19:19+0200\n" +"Last-Translator: Chris Leick \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +# Template: shared/ldapns/ldap-server +# ddtp-prioritize: 56 +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI des LDAP-Servers:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Bitte geben Sie den Uniform Resource Identifier des benutzten LDAP-Servers " +"ein. Das Format ist »ldap://:/«. " +"Alternativ kann auch »ldaps://« oder »ldapi://« benutzt werden. Der Port " +"muss nicht angegeben werden." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Wenn Sie »ldap« oder »ldaps« verwenden, sollten Sie eine IP-Adresse " +"eingeben, um Ausfälle zu verhindern, falls die Namensauflösung einmal nicht " +"verfügbar ist." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Mehrere URIs können, durch Leerzeichen getrennt, eingegeben werden." + +# Template: shared/ldapns/ldap-server +# ddtp-prioritize: 56 +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Suchbasis des LDAP-Servers:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Bitte geben Sie den DN (distinguished name) der LDAP-Suchbasis ein. Oft " +"werden Teile des Domänennamens für diesen Zweck benutzt. Beispielsweise " +"würde bei der Domäne »example.net« der DN »dc=example,dc=net« als Suchbasis " +"verwendet werden." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "keine" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "einfach" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "LDAP-Authentifizierung, die benutzt werden soll:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Bitte wählen Sie aus, welchen Authentifizierungstyp die LDAP-Datenbank " +"verlangen soll (falls überhaupt):" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * keine: keine Authentifizierung;\n" +" * einfach: einfache Bind-DN- und Passwortauthentifizierung;\n" +" * SASL: jeder »Simple Authentication and Security Layer«-Mechanismus." + +# Template: libnss-ldap/binddn +# ddtp-prioritize: 56 +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP-Datenbank-Benutzer:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Geben Sie den Namen des Kontos ein, das zur Anmeldung in die LDAP-Datenbank " +"benutzt wird. Dieser Wert sollte ein DN (distinguished name/benanntes " +"LDAP-Objekt) sein." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Passwort des LDAP-Benutzers:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "Geben Sie das Passwort für die Anmeldung an der LDAP-Datenbank ein." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Zu benutzender SASL-Mechanismus:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Wählen Sie den SASL-Mechanismus aus, der für die Authentifizierung an der " +"LDAP-Datenbank benutzt wird." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +# http://de.wikipedia.org/wiki/Challenge-Response-Authentifizierung +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: Autonegotiation;\n" +" * LOGIN: missbilligt zugunsten von PLAIN;\n" +" * PLAIN: einfacher Klartextpasswort-Mechanismus;\n" +" * NTLM: NT-LAN-Manager Authentifizierungs-Mechanismus;\n" +" * CRAM-MD5: Challenge-Response-Schema, das auf HMAC-MD5 basiert;\n" +" * DIGEST-MD5: HTTP-Digest-kompatibles Challenge-Response-Schema;\n" +" * GSSAPI: benutzt für Kerberos;\n" +" * OTP: ein Einmalpasswort-Mechanismus." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "SASL-Bereich:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Geben Sie den SASL-Bereich ein, der für die Authentifizierung an der " +"LDAP-Datenbank benutzt wird." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" +"Der Bereich wird Authentifizierungs- und Berechtigungsidentitäten zugeordnet." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Für GSSAPI kann dies leer gelassen werden, um Informationen vom " +"Kerberos-Berechtigungszwischenspeicher zu benutzen." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "SASL-Authentifizierungsidentität:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Geben Sie die SASL-Authentifizierungsidentität ein, die für die " +"Authentifizierung an der LDAP-Datenbank benutzt wird." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Dies ist der Anmeldename bei den Mechanismen LOGIN, PLAIN, CRAM-MD5 und " +"DIGEST-MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "SASL-Proxy-Berechtigungsidentität:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Geben Sie die SASL-Proxy-Berechtigungsidentität ein, die für die " +"Authentifizierung an der LDAP-Datenbank benutzt wird." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Dies ist das Objekt, in dessen Name die LDAP-Abfrage durchgeführt wird. " +"Dieser Wert sollte als DN (distinguished name/benanntes LDAP-Objekt) " +"angegeben werden." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Cyrus-SASL-Sicherheitseigenschaften:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Geben Sie die Cyrus-SASL-Sicherheitseigenschaften ein. Erlaubte Werte werden " +"in der Handbuchseite ldap.conf(5) im Abschnitt SASL OPTIONS beschrieben." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Dateipfad des Kerberos-Berechtigungszwischenspeichers:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Geben Sie den Dateinamen des Kerberos-Berechtigungszwischenspeichers an, der " +"benutzt wird." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "StartTLS benutzen?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Bitte entscheiden Sie, ob die Verbindung zum LDAP-Server mittels StartTLS " +"verschlüsselt werden soll." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nie" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "erlauben" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "versuchen" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "anfordern" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Das SSL-Zertifikat des Servers überprüfen:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Wenn eine verschlüsselte Verbindung benutzt wird, kann ein Server-Zertifikat " +"erforderlich sein und überprüft werden. Bitte wählen Sie, ob Zertifikate " +"angefordert und deren Gültigkeit geprüft werden soll:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * nie: es wird kein Zertifikat angefordert oder überprüft;\n" +" * erlauben: ein Zertifikat wird angefordert, aber es ist nicht\n" +" erforderlich und wird nicht überprüft;\n" +" * versuchen: ein Zertifikat wird angefordert und überprüft,\n" +" aber es wird ignoriert, wenn keins angeboten wird\n" +" * anfordern: ein Zertifikat wird angefordert, ist erforderlich\n" +" und wird überprüft" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Wenn die Zertifikat-Überprüfung eingeschaltet ist, muss mindestens eine der " +"Optionen »tls_cacertdir« oder »tls_cacertfile« in die Datei /etc/nslcd.conf " +"eingetragen werden." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Namensauflösungsdienste, die eingerichtet werden sollen:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Damit dieses Paket funktionieren kann, müssen Sie die Datei /etc/nsswitch." +"conf verändern, damit die LDAP-Datenquelle verwendet wird." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Sie können die Dienste auswählen, für die LDAP-Anfragen zugelassen werden. " +"Die neuen LDAP-Anfragen werden als letzte Datenquelle angefügt. " +"Kontrollieren Sie unbedingt die Änderungen." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "LDAP aus der Datei nsswitch.conf entfernen?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Für die folgenden Dienste ist LDAP noch als Namensauflösung eingetragen:\n" +" ${services},\n" +"aber das Paket »libnss-ldapd« soll entfernt werden." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Sie sollten diese Einträge löschen, wenn Sie LDAP nicht mehr für die " +"Namensauflösung verwenden wollen. Wird LDAP nicht aus der Datei nsswitch." +"conf entfernt, sollte das bei den meisten Diensten keine Probleme " +"verursachen, aber die Namensauflösung kann dennoch gestört sein." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Sie können die Datei /etc/nsswitch.conf selbst ändern oder Sie stimmen jetzt " +"zu, die Einträge automatisch zu entfernen. Kontrollieren Sie unbedingt die " +"Änderungen in der Datei /etc/nsswitch.conf, wenn Sie zustimmen, die Einträge " +"jetzt zu löschen." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Shadow-Anfragen durch NSS einschalten?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Um LDAP-Anwendern die Anmeldung zu erlauben, muss das NSS-Modul aktiviert " +"sein, damit Shadow-Passwort-Anfragen durchgeführt werden können. Die Shadow-" +"Einträge selbst können leer sein - es besteht keine Notwendigkeit, " +"Passwortprüfsummen offenzulegen. Lesen Sie http://bugs.debian.org/583492 " +"bezüglich der Hintergründe." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Bitte wählen Sie, ob der benötigte Eintrag automatisch zu /etc/nsswitch.conf " +"hinzugefügt werden soll (in diesem Fall sollte dies anschließend nochmals " +"überprüft werden) oder ob das manuelle Bearbeiten dem Administrator " +"überlassen werden soll." diff --git a/debian/po/es.po b/debian/po/es.po new file mode 100644 index 0000000..4256180 --- /dev/null +++ b/debian/po/es.po @@ -0,0 +1,632 @@ +# Translation of nss-pam-ldapd debconf templates to Spanish. +# Copyright (C) 2007 Rudy Godoy Guillén +# Copyright (C) 2009, 2010, 2011 Software in the Public Interest +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Changes: +# - Initial translation +# Rudy Godoy , 2008 +# +# - Updates +# Francisco Javier Cuadrado , 2009, 2010, 2011 +# +# Traductores, si no conocen el formato PO, merece la pena leer la +# documentación de gettext, especialmente las secciones dedicadas a este +# formato, por ejemplo ejecutando: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Equipo de traducción al español, por favor lean antes de traducir +# los siguientes documentos: +# +# - El proyecto de traducción de Debian al español +# http://www.debian.org/intl/spanish/ +# especialmente las notas de traducción en +# http://www.debian.org/intl/spanish/notas +# +# - La guía de traducción de po's de debconf: +# /usr/share/doc/po-debconf/README-trans +# o http://www.debian.org/intl/l10n/po-debconf/README-trans +# +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-15 12:59+0100\n" +"Last-Translator: Francisco Javier Cuadrado \n" +"Language-Team: Debian l10n Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI del servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Introduzca el URI («Uniform Resource Identifier») del servidor LDAP. Éste " +"debe tener el formato «ldap://:/», también " +"se pueden utilizar «ldaps://» o «ldapi://». El número de puerto es opcional." + +# +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Cuando utilice los esquemas ldap o ldaps es siempre una buena idea " +"especificar una dirección IP para evitar fallos en caso de que el servicio " +"de nombres no esté disponible." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Se pueden especificar múltiples URI separándolos con espacios." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Base de búsqueda en el servidor LDAP:" + +# +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Introduzca el nombre distintivo (DN) de la base de búsquedas de LDAP. En " +"muchos sitios se utilizan las componentes del nombre de dominio con este " +"propósito. Por ejemplo, el dominio «ejemplo.net» utilizaría «dc=ejemplo," +"dc=net» como nombre distintivo de la base de búsquedas." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "ninguna" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "sencilla" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +# Template: libnss-ldap/dblogin +# ddtp-prioritize: 56 +# +# msgid "" +# "database requires login" +# msgstr "" +# +# msgid "" +# "Does the LDAP database require login?" +# msgstr "" +# +# msgid "" +# "Answer this question affirmatively only if you can't retreive entries from " +# "the database without logging in." +# msgstr "" +# +# msgid "" +# "Note: Under a normal setup, this is not needed." +# msgstr "" +# Template: libnss-ldap/override +# ddtp-prioritize: 56 +# +# msgid "" +# "enable automatic configuration updates by debconf" +# msgstr "" +# +# msgid "" +# "Should debconf automatically update libnss-ldap's configuration file?" +# msgstr "" +# +# msgid "" +# "libnss-ldap has been moved to use debconf for its configuration." +# msgstr "" +# +# msgid "" +# "The file will be prepended with \"###DEBCONF###\"; you can disable the " +# "debconf updates by removing that line." +# msgstr "" +# +# msgid "" +# "All new installations will have this by default." +# msgstr "" +# Template: libnss-ldap/binddn +# ddtp-prioritize: 56 +# +# msgid "" +# "unprivileged database user" +# msgstr "" +# +# msgid "" +# "Enter the name of the account that will be used to log in to the LDAP " +# "database." +# msgstr "" +# Template: libnss-ldap/bindpw +# ddtp-prioritize: 56 +# +# msgid "" +# "password for database login account" +# msgstr "" +# +# msgid "" +# "Enter the password that will be used to log in to the LDAP database." +# msgstr "" +# Template: shared/ldapns/ldap_version +# ddtp-prioritize: 56 +# +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "Autenticación de LDAP a utilizar:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Escoja qué tipo de autenticación (si es que la hay) se debería utilizar con " +"la base de datos de LDAP:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * ninguna: sin autenticación.\n" +" * sencilla: una autenticación sencilla que asocia el DN con una " +"contraseña.\n" +" * SASL: cualquier mecanismo «Simple Authentication and Security " +"Layer» (SASL)." + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Usuario de la base de datos LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Introduzca el nombre de la cuenta que se utilizará para acceder a la base de " +"datos de LDAP. Este valor se debería introducir como un DN (Nombre " +"Distinguido)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Contraseña del usuario LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Introduzca la contraseña que se utilizará para acceder a la base de datos " +"LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Mecanismo SASL a utilizar:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Escoja el mecanismo SASL que se utilizará para autenticarse en la base de " +"datos de LDAP:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: negociación automática.\n" +" * LOGIN: obsoleta, sustituida por PLAIN.\n" +" * PLAIN: mecanismo sencillo con contraseñas en claro.\n" +" * NTLM: mecanismo de autenticación mediante el gestor NT LAN.\n" +" * CRAM-MD5: esquema desafío-respuesta basado en HMAC-MD5.\n" +" * DIGEST-MD5: esquema desafío-respuesta compatible con HTTP Digest.\n" +" * GSSAPI: utilizado por Kerberos.\n" +" * OTP: mecanismo de contraseñas de un solo uso («One Time Password»)." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "Reino SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Introduzca el reino SASL que se utilizará para autenticarse con la base de " +"datos de LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "El reino se añade a las identidades de autenticación y autorización." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Para GSSAPI esto se puede dejar vacío para utilizar la información de la " +"caché de credenciales de Kerberos." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "Identidad de autenticación de SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Introduzca la identidad de autenticación SASL que se utilizará para " +"autenticarse con la base de datos de LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Este es el usuario utilizado en los mecanismos LOGIN, PLAIN, CRAM-MDT y " +"DIGEST-MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "Identidad de autorización del proxy SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Introduzca la identidad de autorización del proxy que se utilizará para " +"autenticarse con la base de datos de LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Este es el objeto en el nombre de la petición LDAP realizada. Este valor se " +"debería introducir como un DN (Nombre Distinguido)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Propiedades de seguridad de Cyrus SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Introduzca las propiedades de seguridad de Cyrus SASL. Los valores " +"permitidos se describen en la página del manual ldap.conf(5) en la sección " +"«SASL OPTIONS»." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Ruta a la caché de las credenciales de Kerberos:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Introduzca el nombre del archivo de la caché de las credenciales de GSSAPI/" +"Kerberos a utilizar." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "¿Desea utilizar StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Escoja si la conexión del servidor LDAP debería utilizar StartTLS para " +"cifrar la conexión." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nunca" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "permitir" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "intentar" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "exigir" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Comprobar el certificado SSL del servidor:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Cuando se utiliza una conexión cifrada, se podrá pedir y comprobar un " +"certificado del servidor. Escoja si las búsquedas se deberían configurar " +"para necesitar un certificado, y si se debería comprobar la validez de los " +"certificados." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * nunca: no se pedirá ni comprobará ningún certificado.\n" +" * permitir: se pedirá un certificado, pero no se\n" +" necesitará o se comprobará.\n" +" * intentar: se pedirá y comprobará un certificado, pero si no\n" +" se proporciona se ignorará.\n" +" * exigir: se pedirá, necesitará y comprobará un certificado." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Si la comprobación del certificado está activa, se debe utilizar al menos " +"una de las opciones «tls_cacertdir» o «tls_cacertfile» en el archivo «/etc/" +"nslcd.conf»." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Indique los servicios a configurar:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Para que este programa funcione, debe modificar el archivo «/etc/nsswitch." +"conf» para que utilice la fuente de datos de LDAP." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Puede escoger los servicios que se deben habilitar para las búsquedas de " +"LDAP. Las nuevas búsquedas de LDAP se añadirán como última fuente de datos. " +"Asegúrese de revisar estos cambios." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "¿Desea borrar LDAP del archivo «nsswitch.conf» ahora?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Los siguientes servicios todavía están configurados para utilizar LDAP para " +"las búsquedas:\n" +" ${services}\n" +"pero se va a borrar el paquete libnss-ldapd." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Se le aconseja que borre las entradas si no planea volver a utilizar LDAP " +"para la resolución de nombres. Si no borra ldap del archivo «nsswitch.conf» " +"no debería tener problemas con la mayoría de los servicios, pero podría " +"afectar ligeramente a la resolución de nombres de máquinas." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Puede editar manualmente el archivo «/etc/nsswitch.conf» o escoger borrar " +"las entradas automáticamente ahora. Asegúrese de que revisa los cambios en " +"el archivo «/etc/nsswitch.conf» si escoge borrar las entradas ahora." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "¿Desea activar las búsquedas de «shadow» por NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Para permitir identificarse a los usuarios del LDAP, el módulo NSS tiene que " +"estar activo para realizar las búsquedas de las contraseñas en «shadow». Las " +"entradas de «shadow» pueden estar vacías, esto es, los hashes de las " +"contraseñas no tienen que estar expuestos. Para más información, vea «http://" +"bugs.debian.org/583492»." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Escoja si «/etc/nsswitch.conf» debería haber añadido la entrada necesaria " +"automáticamente (en el caso de que se deba revisar después) o si se debería " +"dejar al administrador editarla manualmente." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Introduzca el nombre de la cuenta que utilizará, si la base de datos LDAP " +#~ "requiere una identificación para las búsquedas normales. En caso " +#~ "contrario, déjelo en blanco." + +#~| msgid "" +#~| "You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +#~| "automatically now. Be sure to review the changes to /etc/nsswitch.conf " +#~| "if you choose to remove the entries now." +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "Puede editar manualmente el archivo «/etc/nsswitch.conf» o escoger borrar " +#~ "las entradas automáticamente ahora. Asegúrese de que revisa los cambios " +#~ "en el archivo «/etc/nsswitch.conf» si escoge borrar las entradas ahora." + +#~ msgid "LDAP server Uniform Resource Identifier:" +#~ msgstr "Identificador de Recurso Uniforme (URI) del servidor LDAP:" + +#~ msgid "LDAP account for root:" +#~ msgstr "Cuenta de superusuario LDAP:" + +#~ msgid "" +#~ "This account will be used for nss requests with root privileges. This can " +#~ "be used to give root processes more information (e.g. users' shadow " +#~ "entries or group passwords)." +#~ msgstr "" +#~ "Esta cuenta será utilizada para solicitudes nss con privilegios de " +#~ "superusuario. Esto se puede utilizar para ofrecer más información a los " +#~ "procesos del superusuario (ej. entradas shadow de usuarios, o contraseñas " +#~ "de grupo)." + +#~ msgid "Leave this empty to not do anything special for root lookups." +#~ msgstr "Deje en blanco si no desea utilizar esta característica." + +#~ msgid "LDAP root account password:" +#~ msgstr "Contraseña de la cuenta de superusuario LDAP:" diff --git a/debian/po/fi.po b/debian/po/fi.po new file mode 100644 index 0000000..7c7caa1 --- /dev/null +++ b/debian/po/fi.po @@ -0,0 +1,481 @@ +# Translation of nss-pam-ldapd debconf templates to Finnish. +# Copyright (C) 2009 Esko Arajärvi +# This file is distributed under the same license as the nss-ldapd package. +# +# Translators: +# +# Esko Arajärvi , 2009. +msgid "" +msgstr "" +"Project-Id-Version: nss-ldapd\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2009-06-23 21:44+0300\n" +"Last-Translator: Esko Arajärvi \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "LDAP-palvelimen URI:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Anna käytettävän LDAP-palvelimen URI (Uniform Resource Identifier). " +"Merkkijonon muoto on ”ldap://:/”. Myös " +"skeemoja ”ldaps://” ja ”ldapi://” voidaan käyttää. Porttinumero ei ole " +"pakollinen." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Käytettäessä ldap- ja ldaps-skeemoja on suositeltavaa käyttää IP-osoitetta, " +"koska tällöin nimipalvelun toimimattomuus ei aiheuta toimintahäiriötä." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Voit syöttää useamman URIn erottamalla ne välilyönneillä." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "LDAP-palvelimen hakukanta:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Anna LDAP-hakukannan erittelevä nimi (Distinguished Name, DN). Useilla " +"sivustoilla käytetään verkkonimen osia tähän tarkoitukseen. Esimerkiksi " +"verkkotunnus ”esimerkki.fi” käyttäisi nimeä ”dc=esimerkki,dc=fi” hakukannan " +"erittelevänä nimenä." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP-tietokannan käyttäjätunnus:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "Tämä arvo tulisi antaa erittelevänä nimenä." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "LDAP-tunnuksen salasana:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "Anna salasana, jota käytetään kirjauduttaessa LDAP-tietokantaan." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "Anna salasana, jota käytetään kirjauduttaessa LDAP-tietokantaan." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "Anna salasana, jota käytetään kirjauduttaessa LDAP-tietokantaan." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "Anna salasana, jota käytetään kirjauduttaessa LDAP-tietokantaan." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "Anna salasana, jota käytetään kirjauduttaessa LDAP-tietokantaan." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "Tämä arvo tulisi antaa erittelevänä nimenä." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Käytetäänkö StartTLS:ää?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Valitse tulisiko LDAP-palvelimelle otettava yhteys salata käyttäen StartTLS:" +"ää." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "ei koskaan" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "salli" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "yritä" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "vaadi" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Palvelimen SSL-varmenteen tarkistus:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Käytettäessä salattua yhteyttä, palvelimelta voidaan pyytää varmenne " +"tarkastettavaksi. Valitse tulisiko hakujen pyytää varmennetta ja tulisiko " +"varmenteiden oikeellisuus tarkastaa:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * ei koskaan: Varmennetta ei pyydetä tai tarkasteta\n" +" * salli: Varmenne pyydetään, mutta sitä ei vaadita tai tarkasteta\n" +" * yritä: Varmenne pyydetään ja tarkastetaan, mutta jos sitä\n" +" ei saada, tästä ei välitetä\n" +" * vaadi: Varmenne vaaditaan ja tarkastetaan." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Jos tarkastus on käytössä, tulisi ainakin toinen asetuksista tls_cacertdir " +"ja tls_cacertfile laittaa tiedostoon /etc/nslcd.conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Asetettavat nimipalvelimet:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Jotta tämä paketti toimisi, täytyy tiedosto /etc/nsswitch.conf muokata " +"käyttämään ldap-tietolähdettä." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Voit valita palvelut, jotka tarvitsevat LDAP-hakuja. Uudet LDAP-haut " +"lisätään viimeiseksi tietolähteeksi. Muista tarkastaa nämä muutokset." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Poistetaan LDAP tiedostosta nsswitch.conf nyt?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Seuraavat palvelut käyttävät edelleen LDAP:ia hauissaan:\n" +" ${services}\n" +"Pakettia libnss-ldapd ollaan kuitenkin poistamassa." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"On suositeltavaa poistaa tietueet, jos LDAP:ia ei aiota enää käyttää nimien " +"selvittämiseen. Jos ldap jätetään tiedostoon nsswitch.conf, sen ei pitäisi " +"useimpien palveluiden kohdalla aiheuttaa ongelmia, mutta konenimien selvitys " +"saattaa muuttua joillain tavoilla." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Voit muokata tiedostoa /etc/nsswitch.conf käsin tai poistaa tietueet nyt " +"automaattisesti. Muista tarkastaa tiedoston /etc/nsswitch.conf muutokset, " +"jos poistat tietueet nyt." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Jos LDAP-tietokannan täytyy kirjautua tehdäkseen normaaleja hakuja, anna " +#~ "käytettävän tunnuksen nimi tässä. Jätä muuten kenttä tyhjäksi." + +#, fuzzy +#~| msgid "" +#~| "You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +#~| "automatically now. Be sure to review the changes to /etc/nsswitch.conf " +#~| "if you choose to remove the entries now." +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "Voit muokata tiedostoa /etc/nsswitch.conf käsin tai poistaa tietueet nyt " +#~ "automaattisesti. Muista tarkastaa tiedoston /etc/nsswitch.conf muutokset, " +#~ "jos poistat tietueet nyt." diff --git a/debian/po/fr.po b/debian/po/fr.po new file mode 100644 index 0000000..dac19ff --- /dev/null +++ b/debian/po/fr.po @@ -0,0 +1,580 @@ +# Translation of nss-pam-ldapd debconf templates to French. +# Copyright (C) 2007, 2009, 2010 Debian French l10n team +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# Cyril Brulebois , 2007. +# Philippe Batailler , 2007. +# Guillaume Delacour , 2009. +# Christian Perrier , 2009, 2010, 2011. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-14 08:59+0200\n" +"Last-Translator: Christian Perrier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI du serveur LDAP :" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Veuillez indiquer l'URI (« Uniform Resource Identifier ») du serveur LDAP à " +"utiliser. Il s'agit d'une adresse de la forme « ldap://:/ ». Des adresses sous la forme « ldaps:// » et « ldapi:// » " +"peuvent aussi être utilisées. Le numéro de port est facultatif." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Lorsque le protocole utilisé est « ldap » ou « ldaps », il est recommandé " +"d'utiliser une adresse IP plutôt qu'un nom d'hôte afin de réduire les " +"risques d'échec en cas d'indisponibilité du service de noms." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "" +"Des adresses multiples peuvent être indiquées, séparées par des espaces." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Base de recherche du serveur LDAP :" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Veuillez indiquer le nom distinctif (« DN ») de la base de recherche du " +"serveur LDAP. Beaucoup de sites utilisent les éléments composant leur nom de " +"domaine à cette fin. Par exemple, le domaine « example.net » utiliserait " +"« dc=example,dc=net »." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "aucune" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "simple" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "Authentification LDAP :" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Veuillez choisir le type d'authentification que la base de données LDAP " +"utilise (si nécessaire)." + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" - aucune : pas d'authentification;\n" +" - simple : authentification simple avec un identifiant (DN) et un\n" +" mot de passe;\n" +" - SASL   : mécanisme basé sur SASL (« Simple Authentication and\n" +" Security Layer » : méthode simplifiée d'authentification\n" +" et de sécurité;" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Utilisateur de la base LDAP :" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Veuillez indiquer le compte à utiliser pour s'identifier sur la base LDAP. " +"Cette valeur doit être indiquée sur la forme d'un nom distinctif " +"(DN : « Distinguished Name »)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Mot de passe de l'utilisateur LDAP :" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Veuillez indiquer le mot de passe à utiliser pour s'identifier sur la base " +"LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Mécanisme SASL à utiliser :" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Veuillez indiquer le mécanisme SASL à utiliser pour s'identifier sur la base " +"LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" - auto   : négociation automatique ;\n" +" - LOGIN   : obsolète et remplacé par PLAIN ;\n" +" - PLAIN   : mot de passe simple en clair ;\n" +" - NTLM   : authentification NT LAN Manager ;\n" +" - CRAM-MD5   : schéma de challenge-réponse basé sur HMAC-MD5 ;\n" +" - DIGEST-MD5 : schéma de challenge-réponse compatible avec HTTP Digest ;\n" +" - GSSAPI   : utilisé pour Kerberos ;\n" +" - OTP   : mots de passe jetables (« One Time Password »)." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "Royaume (« realm ») SASL :" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Veuillez indiquer le royaume SASL à utiliser pour s'identifier sur la base " +"LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "Il sera ajouté aux identifiants d'authentification et d'autorisation." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Pour GSSAPI, ce champ peut être laissé vide afin d'utiliser l'information du " +"cache d'authentification de Kerberos." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "Identité d'authentification SASL :" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Veuillez indiquer l'identité d'authentification SASL à utiliser pour " +"s'identifier sur la base LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Il s'agit de l'identifiant utilisé avec les mécanismes LOGIN, PLAIN, CRAM-" +"MD5 et DIGEST-MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "Identité d'authentification du pare-feu SASL :" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Veuillez indiquer l'identité d'authentification de pare-feu à utiliser pour " +"s'identifier sur la base LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Il s'agit de l'objet au nom duquel les requêtes LDAP seront effectuées. " +"Cette valeur doit être indiquée sous forme d'un nom distinctif (DN : " +"« Distinguished Name »)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Propriétés de sécurité pour Cyrus SASL :" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Veuillez indiquer les propriétés de sécurité Cyrus SASL. Les valeurs " +"autorisées sont décrites dans la page de manuel ldap.conf(5), dans la " +"section « SASL OPTIONS »." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Chemin d'accès au fichier de cache d'authentification Kerberos :" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Veuillez indiquer le nom du fichier à utiliser pour le cache " +"d'authentification GSSAPI/Kerberos." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Faut-il utiliser StartTLS ?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Veuillez choisir si la connexion au serveur LDAP doit être chiffrée avec " +"StartTLS." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "Jamais" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "Autoriser" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "Essayer" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "Demander" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Contrôle du certificat SSL du serveur :" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"En cas de connexion chiffrée, le certificat du serveur peut être demandé et " +"contrôlé. Veuillez choisir la façon de réaliser ce contrôle :" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" - Jamais   : certificat non demandé ni contrôlé ;\n" +" - Autoriser : certificat demandé mais facultatif et non\n" +" contrôlé ;\n" +" - Essayer   : certificat demandé et contrôlé, mais facultatif ;\n" +" - Demander  : certificat obligatoire et contrôlé." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Si le contrôle du certificat est activé, il est indispensable d'utiliser au " +"moins l'une des options « tls_cacertdir » ou « tls_cacertfile » dans le " +"fichier /etc/nslcd.conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Services de nom à configurer :" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Le fichier /etc/nsswitch.conf doit être modifié pour rendre ce paquet " +"fonctionnel." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Vous pouvez aussi choisir les services qui doivent être activés ou " +"désactivés pour les requêtes LDAP. Les nouvelles requêtes LDAP seront " +"ajoutées comme dernière source possible. Il est important de bien contrôler " +"ces modifications." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Faut-il supprimer LDAP de nsswitch.conf maintenant ?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Les services suivants utilisent toujours LDAP pour la recherche de nom :\n" +" ${services}\n" +"mais le paquet libnss-ldapd est sur le point d'être supprimé." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Il est conseillé de supprimer les entrées si vous ne pensez pas utiliser " +"LDAP pour la résolution de noms. Il est probable qu'omettre de supprimer " +"LDAP dans nsswitch.conf soit sans conséquences pour la plupart des services, " +"mais la résolution de noms peut être affectée de manière subtile." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Vous pouvez modifier /etc/nsswitch.conf vous-même ou choisir de supprimer " +"les entrées automatiquement maintenant. Il est important de vérifier les " +"changements effectués automatiquement dans /etc/nsswitch.conf si vous " +"choisissez de supprimer les entrées maintenant." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Faut-il activer les recherches de mots de passe cachés avec NSS ?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Pour permettre aux utilisateurs LDAP de se connecter, le module NSS doit " +"être activé afin de pouvoir faire des recherches de mots de passe cachés " +"(« shadow passwords »). Les entrées cachées elles-mêmes peuvent être vides, " +"ce qui signifie qu'il n'est pas nécessaire de faire apparaître les hachages " +"de mots de passe. Veuillez consulter http://bugs.debian.org/583492 pour plus " +"de détails." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Veuillez choisir si l'entrée appropriée dans /etc/nsswitch.conf peut être " +"ajoutée automatiquement (ce qui peut nécessiter de la vérifier ensuite). " +"Dans le cas contraire, un administrateur devra l'ajouter plus tard." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Si le serveur LDAP nécessite un identifiant pour les recherches " +#~ "ordinaires, veuillez indiquer le compte qui doit être utilisé. N'indiquez " +#~ "rien dans le cas contraire." + +#, fuzzy +#~| msgid "" +#~| "You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +#~| "automatically now. Be sure to review the changes to /etc/nsswitch.conf " +#~| "if you choose to remove the entries now." +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "Vous pouvez modifier /etc/nsswitch.conf vous-même ou choisir de supprimer " +#~ "les entrées automatiquement maintenant. Il est important de vérifier les " +#~ "changements effectués automatiquement dans /etc/nsswitch.conf si vous " +#~ "choisissez de supprimer les entrées maintenant." + +#~ msgid "LDAP server Uniform Resource Identifier:" +#~ msgstr "Adresse du serveur LDAP :" + +#~ msgid "LDAP account for root:" +#~ msgstr "Identifiant LDAP du superutilisateur :" + +#~ msgid "" +#~ "This account will be used for nss requests with root privileges. This can " +#~ "be used to give root processes more information (e.g. users' shadow " +#~ "entries or group passwords)." +#~ msgstr "" +#~ "Veuillez indiquer l'identifiant à utiliser pour les requêtes NSS avec les " +#~ "droits superutilisateur. Cela peut être utilisé pour fournir plus " +#~ "d'informations à des processus lancés avec les droits superutilisateur " +#~ "(p. ex. les entrées des utilisateurs dans « shadow » ou les mots de passe " +#~ "de groupe)." + +#~ msgid "Leave this empty to not do anything special for root lookups." +#~ msgstr "" +#~ "N'indiquez rien si aucune identification particulière n'est nécessaire " +#~ "pour les requêtes superutilisateur." + +#~ msgid "LDAP root account password:" +#~ msgstr "Mot de passe du superutilisateur LDAP :" + +#~ msgid "" +#~ "When using the ldapi scheme, %2f should be used to escape slashes (e.g. " +#~ "ldapi://%2fvar%2frun%2fldapi_sock/)" +#~ msgstr "" +#~ "Lorsque le protocole « ldapi » est utilisé, %2f doit être utilisé pour " +#~ "remplacer les barres obliques (« slashes »), par exemple : « ldapi://" +#~ "%2fvar%2frun%2fldapi_sock/ »." + +#~ msgid "" +#~ "Please enter which version of the LDAP protocol is to use. It is usually " +#~ "a good idea to set this to highest available version number." +#~ msgstr "" +#~ "Veuillez indiquer la version du protocole LDAP à utiliser. Il est " +#~ "conseillé d'utiliser la version la plus récente." + +#~ msgid "" +#~ "For this package to work, you need to modify your /etc/nsswitch.conf to " +#~ "use the ldap datasource. There is an example file at /usr/share/doc/" +#~ "libnss-ldap/examples/nsswitch.ldap which can be used as an example for " +#~ "your nsswitch setup." +#~ msgstr "" +#~ "Pour que ce paquet fonctionne, il est nécessaire de modifier le fichier " +#~ "« /etc/nsswitch.conf » pour pointer vers la source de données LDAP. Le " +#~ "fichier /usr/share/doc/libnss-ldap/examples/nsswitch.ldap est un exemple " +#~ "que vous pouvez adapter à votre configuration." diff --git a/debian/po/gl.po b/debian/po/gl.po new file mode 100644 index 0000000..4960faa --- /dev/null +++ b/debian/po/gl.po @@ -0,0 +1,497 @@ +# Translation of nss-pam-ldapd debconf templates to Galician. +# Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# marce villarino , 2009. +# Marce Villarino , 2009. +msgid "" +msgstr "" +"Project-Id-Version: nss-ldapd 0.6\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2009-07-18 10:02+0200\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI do servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Introduza o URI do servidor LDAP. O formato é «ldap://:" +"/». Tamén se poden empregar «ldaps://» ou «ldapi://» . O número do " +"porto é opcional." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Cando se emprega un esquema ldap ou ldaps recoméndase empregar un enderezo " +"IP para evitar fallos se o servizo de nomes non está dispoñíbel." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Poden especificarse varios URI separándoos con espazos." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Base da procura de servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Indique o nome distintivo da base de procura LDAP. Moitos sitios empregan as " +"compoñentes dos seus nomes de dominio para este propósito. Por exemplo, o " +"dominio «exemplo.net» debería empregar «dc=exemplo,dc=net» como nome " +"distintivo da base de procura." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Usuario da base de datos LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "Este valor debe especificarse como un DN (nome distintivo)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Contrasinal do usuario de LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Indique o contrasinal que se ha empregar para acceder á base de datos do " +"LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Indique o contrasinal que se ha empregar para acceder á base de datos do " +"LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Indique o contrasinal que se ha empregar para acceder á base de datos do " +"LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Indique o contrasinal que se ha empregar para acceder á base de datos do " +"LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Indique o contrasinal que se ha empregar para acceder á base de datos do " +"LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "Este valor debe especificarse como un DN (nome distintivo)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Debe empregarse StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Indique se a conexión co servidor LDAP debe empregar StartTLS para cifrar a " +"conexión." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nunca" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "permitir" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "tentar" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "demandar" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Comprobación do certificado SSL do servidor:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Cando se emprega unha conexión cifrada pode pedirse e comprobarse un " +"certificado do servidor. Escolla se as procuras deben estar configuradas " +"para requirir un certificado e se debe comprobarse a validez destes:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * nunca: non se pedirá nin se comprobará ningún certificado,\n" +" * permitir: pedirase un certificado, pero non é requirido nin comprobado,\n" +" * tentar: pedirase e comprobarase un certificado, pero de non fornecerse\n" +" ningún ignorarase,\n" +" * demandar:pedirase, requirirase e comprobarase un certificado." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Se desactiva a comprobación do certificado, debe ter no ficheiro /etc/nslcd." +"conf polo menos unha das opcións tls_cacertdir ou tlscacertfile." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Servizos de nome a configurar:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Para que este paquete funcione, debe modificar o ficheiro /etc/nsswitch.conf " +"para que empregue a fonte de datos ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Pode escoller os servizos que se deben ter activadas as procuras LDAP. As " +"novas procuras LDAP engadiranse como última fonte de datos. Revise estas " +"modificacións." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Desexa eliminar LDAP de nsswitch.conf?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Os seguintes servizos aínda están configurados para facer procuras mediante " +"LDAP:\n" +" ${services}\n" +"pero o paquete libnss-ldapd está a piques de ser eliminado." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Recoméndase que elimine as entradas se non prevé seguir a empregar LDAP para " +"a resolución de nomes. Se non elimina ldap de nsswitch.conf non debería ter " +"problemas coa maioría dos servizos, pero a resolución de nomes podería verse " +"afectada de maneiras sutís." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Pode editar manualmente /etc/nsswitch.conf ou escoller agora eliminar " +"automaticamente as entradas. Asegúrese de revisar as modificacións a /etc/" +"nsswitch.conf se escolle agora eliminar as entradas." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Se a base de datos do LDAP require de identificación para procuras " +#~ "normais, indique aquí o nome da conta que se empregará. Caso contrario " +#~ "déixeo en branco." + +#, fuzzy +#~| msgid "" +#~| "You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +#~| "automatically now. Be sure to review the changes to /etc/nsswitch.conf " +#~| "if you choose to remove the entries now." +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "Pode editar manualmente /etc/nsswitch.conf ou escoller agora eliminar " +#~ "automaticamente as entradas. Asegúrese de revisar as modificacións a /etc/" +#~ "nsswitch.conf se escolle agora eliminar as entradas." + +#~ msgid "LDAP server Uniform Resource Identifier:" +#~ msgstr "URI do servidor LDAP:" diff --git a/debian/po/it.po b/debian/po/it.po new file mode 100644 index 0000000..947b4ca --- /dev/null +++ b/debian/po/it.po @@ -0,0 +1,501 @@ +# Translation of nss-pam-ldapd debconf templates to Italian. +# Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# Vincenzo Campanella , 2009, 2010. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.7.9\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2010-08-19 14:20+0200\n" +"Last-Translator: Vincenzo Campanella \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI del server LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Inserire l'Uniform Resource Identifier (URI) del server LDAP. Il formato è " +"«ldap://:»; è anche possibile usare " +"«ldaps://» oppure «ldapi://». Il numero della porta è facoltativo." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Quando si usa lo schema ldap o ldaps si raccomanda di usare un indirizzo IP, " +"al fine di ridurre i rischi di errore quando i servizi dei nomi di dominio " +"non sono disponibili." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "È possibile specificare URI multipli, dividendoli con spazi." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Base di ricerca del server LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Inserire il DN (distinguished name) della base di ricerca LDAP. A tal fine " +"molti siti usano le componenti del loro nome di dominio: ad esempio, il " +"dominio «esempio.net» userebbe «dc=esempio,dc=net» come DN della base di " +"ricerca." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Utente del database LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Questo valore dovrebbe essere specificato come DN (distinguished name)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Password dell'utente LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Inserire la password che verrà utilizzata per accedere al database LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Inserire la password che verrà utilizzata per accedere al database LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Inserire la password che verrà utilizzata per accedere al database LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Inserire la password che verrà utilizzata per accedere al database LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Inserire la password che verrà utilizzata per accedere al database LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Questo valore dovrebbe essere specificato come DN (distinguished name)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Utilizzare StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Scegliere se la connessione al server LDAP deve utilizzare StartTLS per " +"cifrare la connessione." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "mai" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "consenti" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "prova" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "richiedi" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Controllare il certificato del server SSL?" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Quando viene utilizzata una connessione cifrata è possibile chiedere e " +"controllare un certificato del server. Scegliere se le ricerche devono " +"essere configurate per richiedere un certificato e se la validità dei " +"certificati deve essere controllata:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * mai: non verrà richiesto né controllato alcun certificato;\n" +" * consenti: un certificato viene richiesto, ma non in modo vincolante,\n" +" né viene controllato;\n" +" * prova: un certificato verrà richiesto e controllato, ma la mancata\n" +" fornitura di un certificato viene ignorata;\n" +" * richiedi: viene chiesto in modo vincolante e controllato." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Se è abilitata la richiesta di certificati, almeno una delle opzioni " +"tls_cacertdir o tls_cacertfile devono trovarsi in «/etc/nslcd.conf»." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Servizi dei nomi da configurare:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Affinché questo pacchetto funzioni è necessario modificare il proprio file «/" +"etc/nsswitch.conf» in modo che utilizzi l'origine dati LDAP." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"È possibile selezionare i servizi che dovrebbero essere abilitati per le " +"ricerche LDAP. Le nuove ricerche LDAP verranno aggiunte come ultima sorgente " +"di dati. Ci si assicuri di controllare queste modifiche." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Rimuovere LDAP da nsswitch.con ora?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"I seguenti servizi sono tuttora configurati per utilizzare LDAP per le " +"ricerche:\n" +" ${services}\n" +"ma il pacchetto libnss-ldapd sta per essere rimosso." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Rimuovere le voci solo se si prevede di non utilizzare più LDAP per le " +"risoluzioni dei nomi. Per la maggior parte dei servizi la mancata rimozione " +"di LDAP da nsswitch.conf non dovrebbe causare problemi, ma la risoluzione " +"dei nomi degli host potrebbe essere in qualche modo influenzata." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"È possibile modificare manualmente «/etc/nsswitch.conf» o scegliere di " +"rimuovere le voci automaticamente adesso. Controllare le modifiche a «/etc/" +"nsswitch.conf» se si sceglie la rimozione automatica." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Abilitare le ricerche «shadow» tramite NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Per consentire l'accesso agli utenti LDAP, il modulo NSS deve essere " +"abilitato per le ricerche «shadow» di password. Le voci «shadow» possono " +"essere vuote, ossia non è necessario esporre le hash delle password. Per " +"maggiori informazioni consultare http://bugs.debian.org/583492." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Scegliere se la voce richiesta deve essere aggiunta automaticamente a «/etc/" +"nsswitch.conf» o se si preferisce l'immissione manuale da parte di un " +"amministratore." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Se il database LDAP richiede l'accesso per le normali ricerche, inserire " +#~ "il nome dell'account che verrà utilizzato per l'accesso. In caso " +#~ "contrario, lasciare vuoto." + +#, fuzzy +#~| msgid "" +#~| "You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +#~| "automatically now. Be sure to review the changes to /etc/nsswitch.conf " +#~| "if you choose to remove the entries now." +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "È possibile modificare manualmente «/etc/nsswitch.conf» o scegliere di " +#~ "rimuovere le voci automaticamente adesso. Controllare le modifiche a «/" +#~ "etc/nsswitch.conf» se si sceglie la rimozione automatica." + +#~ msgid "LDAP server Uniform Resource Identifier:" +#~ msgstr "Uniform Resource Identifier (URI) del server LDAP:" diff --git a/debian/po/ja.po b/debian/po/ja.po new file mode 100644 index 0000000..9079153 --- /dev/null +++ b/debian/po/ja.po @@ -0,0 +1,457 @@ +# Translation of nss-pam-ldapd debconf templates to Japanese. +# +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-18 00:10+0900\n" +"Last-Translator: Kenshi Muto \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "LDAP サーバの URI:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"LDAP サーバの Uniform Resource Identifier を入力してください。形式は 'ldap://" +"<ホスト名または IP>:<ポート>/' です。このほかに 'ldaps://' または 'ldapi://' " +"も利用できます。ポート番号は省略できます。" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"ldap または ldaps スキーマを使う際には、ネームサービスが利用できないときの障" +"害回避のために IP アドレスを使うことを推奨します。" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "スペースで区切って、複数の URI を指定できます。" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "LDAP サーバの検索ベース:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"LDAP 検索ベースの識別名を入力してください。多くのサイトではそのドメイン名の要" +"素をこの目的に使っています。たとえば、ドメイン \"example.net\" では検索ベース" +"の識別名として \"dc=example,dc=net\" を使っているでしょう。" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "なし" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "simple" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "使用する LDAP 認証:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "LDAP データベースが (もし何か) 必要とすべき認証の形式を選択してください:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * なし: 認証なし;\n" +" * simple: シンプルバインド DN とパスワード認証;\n" +" * SASL: 何らかの Simple Authentication and Security Layer 機構。" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP データベースユーザ:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "LDAP データベースへのログインに使われるアカウントの名前を入力してください。この値は DN (識別名) として指定すべきです。" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "LDAP ユーザパスワード:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "LDAP データベースにログインするのに使うパスワードを入力してください。" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "使用する SASL 機構:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "LDAP データベースを認証するのに使われる SASL 機構を選んでください:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * 自動: 自動ネゴシエーション;\n" +" * LOGIN: PLAIN によって代替された;\n" +" * PLAIN: シンプルクリアテキストパスワード機構;\n" +" * NTLM: NT LAN Manager 認証機構;\n" +" * CRAM-MD5: HMAC-MD5 ベースのチャレンジ-レスポンス機構;\n" +" * DIGEST-MD5: HTTP ダイジェスト互換のチャレンジ-レスポンス機構;\n" +" * GSSAPI: Kerberos により利用;\n" +" * OTP: ワンタイムパスワード機構。" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "SASL レルム:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "LDAP データベースを認証するのに使われる SASL レルムを入力してください。" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "レルムは認証および認可識別子に追加されます。" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "GSSAPI では、Kerberos 信用キャッシュからの情報を使うためにこれは空のままにしておくことができます。" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "SASL 認証アイデンティティ:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "LDAP データベースを認証するのに使われる SASL 認証アイデンティティを入力してください。" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "これは、LOGIN、PLAIN、CRAM-MD5、DIGEST-MD5 機構で使われるログインです。" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "SASL 代理認可アイデンティティ:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "LDAP データベースを認証するのに使われる代理認可アイデンティティを入力してください。" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "これは、LDAP 要求が行われる名前のオブジェクトです。この値は DN (識別名) として指定すべきです。" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Cyrus SASL セキュリティプロパティ:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "Cyrus SASL セキュリティプロパティを入力してください。許される値は、ldap.conf(5) マニュアルページの SASL OPTIONS セクションに記載されています。" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Kerberos 信用キャッシュファイルのパス:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "使われる GSSAPI/Kerberos 信用キャッシュファイル名を入力してください。" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "StartTLS を利用しますか?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"接続の暗号化のために LDAP サーバに StartTLS を使って接続するかどうかを選んで" +"ください。" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "使わない" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "許可" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "試行" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "要求" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "サーバの SSL 証明書のチェック:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"暗号化接続を利用する場合、サーバ証明書を要求して確認できます。ルックアップで" +"証明書を必須とするよう設定するかどうか、および証明書の妥当性を確認するかどう" +"かを選んでください。" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * 使わない: 証明書は要求もチェックもされない\n" +" * 許可: 証明書を要求するが、必須ではなくチェックも\n" +" されない\n" +" * 試行: 証明書は要求およびチェックされるが、\n" +" 証明書が提供されなかった場合は単に無視される\n" +" * 要求: 証明書は要求され、必須であり、チェックされる。" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"証明書のチェックが有効の場合、tls_cacertdir、tls_cacertfile オプションのうち" +"の少なくとも 1 つは /etc/nslcd.conf に掲載されている必要があります。" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "設定する名前サービス:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"このパッケージが動作するために、ldap データソースを使うようあなたの /etc/" +"nsswitch.conf を変更する必要があります。" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"LDAP ルックアップを有効にしたいサービスを選択できます。新しい LDAP ルックアッ" +"プは最後のデータソースとして追加されます。これらの変更を見て確認してくださ" +"い。" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "nsswitch.conf から LDAP を今削除しますか?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"以下のサービスはまだルックアップに LDAP を使うよう設定されています:\n" +" ${services}\n" +"しかし、libnss-ldapd パッケージは削除されようとしています。" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"名前解決にもう LDAP を使う予定がないのであれば、エントリを削除することを勧め" +"ます。nsswitch.conf から ldap を除かない場合でもほとんどのサービスでは問題は" +"起きませんが、ホスト名解決は奇妙なふうに影響を受ける可能性があります。" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"/etc/nsswitch.conf を手動で編集するか、エントリを自動で今削除することを選べま" +"す。エントリを今削除することを選ぶ場合、/etc/nsswitch.conf の変更内容を確認し" +"てください。" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "NSS によるシャドーのルックアップを有効にしますか?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"LDAP ユーザがログインできるようにするためには、シャドーパスワードのルックアッ" +"プを行えるよう NSS モジュールを有効にする必要があります。シャドーのエントリ自" +"体は空でよく、つまりパスワードハッシュをさらす必要はありません。この背景につ" +"いては http://bugs.debian.org/583492 を参照してください。" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"/etc/nsswitch.conf に自動で必須エントリを追加するか (この場合、後で再確認して" +"ください)、管理者が手動で変更するためにそのままにしておくかを選んでください。" diff --git a/debian/po/nb.po b/debian/po/nb.po new file mode 100644 index 0000000..a9707e9 --- /dev/null +++ b/debian/po/nb.po @@ -0,0 +1,474 @@ +# Translation of nss-pam-ldapd debconf templates to Norwegian Bokmål. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# Bjørn Steensrud , 2010. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.6.9\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2010-08-18 20:24+0200\n" +"Last-Translator: Bjørn Steensrud \n" +"Language-Team: Norwegian Bokmål \n" +"Language: nb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI til LDAP-tjener:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Skriv inn Uniform Resource Identifier for LDAP-tjeneren, Formatet er «ldap://" +":/». «ldaps://» eller «ldapi://» kan også " +"brukes. Portnummer kan utelates." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Når ldap eller ldaps-formen brukes anbefales det å bruke en IP-adresse for å " +"unngå svikt når en DNS-tjeneste ikke et tilgjengelig." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Flere URI-er kan oppgis, atskilt med mellomrom." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Søkebase for LDAP-tjener:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Oppgi det entydige navnet (DN) til LDAPs søkebase. Mange steder brukes " +"komponentene i domenenavnet til dette, For eksempel, domenet «example.net» " +"ville bruke «dc=example,dc=net» som entydig navn på søkebasen." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP databasebruker:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "Verdien må oppgis som et DN - entydig navn." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "LDAP bruker-passord:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "Oppgi passordet som vil bli brukt til å logge inn i LDAP-databasen." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "Oppgi passordet som vil bli brukt til å logge inn i LDAP-databasen." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "Oppgi passordet som vil bli brukt til å logge inn i LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "Oppgi passordet som vil bli brukt til å logge inn i LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "Oppgi passordet som vil bli brukt til å logge inn i LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "Verdien må oppgis som et DN - entydig navn." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Bruke StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Velg om forbindelsen til LDAP-tjeneren skal bruke StartTLS til å kryptere " +"forbindelsen." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "aldri" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "tillat" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "forsøk" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "krev" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Kontroller tjenerens SSL-sertifikat:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Når det brukes en kryptert forbindelse kan det utbes og kontrolleres et " +"tjenersertifikat. Velg om oppslag skal settes opp til å kreve et sertifikat, " +"og om gyldigheten av sertifikatet skal kontrolleres:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +"* aldri: det blir ikke bedt om sertifikater og ikke kontrollert;\n" +"* tillat: det blir bedt om et sertifikat, men det er ikke påkrevet\n" +" eller kontrollert.\n" +"* forsøk: det blir bedt om et sertifikat som blir kontrollert, men\n" +" det blir ignorert dersom det ikke blir oppgitt et sertifikat.\n" +"* krev: det blir bedt om et sertifikat som blir krevet og kontrollert." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Hvis sertifikatkontroll er slått på, så må minst ett av valgene tls." +"cacertdir eller tls.cscertfile være lagt inn i /etc/nslcd.conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Navnetjenester som skal settes opp:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"For at denne pakka skal virke må du endre /etc/nsswitch.conf til å bruke " +"ldap-datakilden." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Du kan velge tjenester som skal ha slått på LDAP-oppslag. De nye LDAP- " +"oppslagene vil bli lagt til som siste datakilde. Pass på å se gjennom disse " +"endringene." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Skal LDAP fjernes fra nsswitch.conf nå?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Følgende tjenester er fortsatt satt opp til å bruke LDAP il oppslag:\n" +" ${services}\n" +"men pakka libnss-ldapd er i ferd med å bli fjernet." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Det tilrådes at du fjerner innslagene hvis du ikke har tenkt å bruke LDAP " +"til navneoppslag lenger. Det vil ikke skape problemer for de fleste " +"tjenestene om ldap ikke fjernes fra nsswitch,.conf, men oppslag av vertsnavn " +"kan bli påvirket på spissfindige måter." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Du kan redigere /etc/nsswitch.conf for hånd, eller velge å fjerne innslagene " +"automatisk nå. Pass på at du kontrollerer endringene i /etc/nsswitch,conf " +"hvis du velger å fjerne innslagene nå." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Skal skyggeoppslag gjennom NSS være slått på?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"For at LDAP-brukere skal kunne logge inn må NSS-modulen kunne utføre oppslag " +"i skygge-passordene. Skyggeoppføringene selv kan være tomme, dvs. det trengs " +"ikke å avsløre passord-hasher. Bakgrunnen for dette finnes på http://bugs." +"debian.org/583492" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Velg om /etc/nsswitch.conf skal få det nødvendige innslaget lagt til " +"automatisk (i så fall bør det kontrolleres etterpå), eller om det skal " +"legges til manuelt siden av en administrator." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Hvis LDAP-databasen trenger et login-navn for normale oppslag, så skriv " +#~ "inn her navnet på kontoen som vil bli brukt. La det stå tomt ellers." diff --git a/debian/po/nl.po b/debian/po/nl.po new file mode 100644 index 0000000..144631e --- /dev/null +++ b/debian/po/nl.po @@ -0,0 +1,489 @@ +# Translation of nss-pam-ldapd debconf templates to Dutch. +# +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-29 20:57+0100\n" +"Last-Translator: Arthur de Jong \n" +"Language-Team: debian-l10n-dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "LDAP-server URI:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Vul de URI (Uniform Resource Identifier) van de LDAP-server in. Het formaat " +"is 'ldap://:/'. Ook kan 'ldaps://' of " +"'ldapi://' gebruikt worden. Het poortnummer is optioneel." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Als u gebruik maakt van de ldap- of ldaps-schema's, is het aan te bevelen om " +"een IP-adres te gebruiken. Dit voorkomt problemen in het geval dat " +"naamdiensten onbeschikbaar zijn." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Meerdere URI's kunnen door spaties gescheiden worden." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "LDAP-server zoekbasis:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Voer de unieke naam (distinguished name) van de LDAP-zoekbasis in. Veel " +"sites gebruiken de componenten van hun domeinnaam voor dit doel. " +"Bijvoorbeeld: het domein \"example.net\" zou gebruik maken van \"dc=example," +"dc=net\" als de DN van de zoekbasis." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "geen" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "eenvoudig" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "Te gebruiken LDAP-authenticatie:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Welk soort authenticatie wilt u dat gebruikt wordt om bij de LDAP-database " +"aan te melden (indien van toepassing)?" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * geen: geen authenticatie;\n" +" * eenvoudig: eenvoudige combinatie van bind-DN en wachtwoord;\n" +" * SASL: één van de 'Simple Authentication and Security Layer'-mechanismen." + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP-databasegebruiker:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Welke gebruikersnaam wilt u dat er gebruikt zal worden om bij de LDAP-" +"database aan te melden? Deze waarde moet als een DN (distinguished name) " +"opgegeven worden." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Wachtwoord van de LDAP-gebruiker:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Welk wachtwoord wilt u dat er gebruikt zal worden om bij de LDAP-database " +"aan te melden?" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "SASL-mechanisme dat gebruikt zal worden:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Welk SASL-mechanisme wilt u dat er gebruikt zal worden om bij de LDAP-" +"database aan te melden?" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: automatische onderhandeling;\n" +" * LOGIN: achterhaald en vervangen door PLAIN;\n" +" * PLAIN: eenvoudig klare tekst wachtwoord-mechanisme;\n" +" * NTLM: NT LAN Manager authenticatie-mechanisme;\n" +" * CRAM-MD5: challenge-response-systeem op basis van HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatibel challenge-response-systeem;\n" +" * GSSAPI: gebruikt voor Kerberos;\n" +" * OTP: een eenmalig wachtwoord-mechanisme." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "SASL-gebied:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Welk SASL-gebied wilt u dat er gebruikt zal worden om bij de LDAP-database " +"aan te melden?" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" +"Het gebied wordt toegevoegd aan de authenticatie- en autorisatie-" +"identiteiten." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Voor GSSAPI kan dit leeg gelaten worden zodat informatie uit de Kerberos " +"identificatie cache gebruikt zal worden." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "SASL authenticatie-identiteit:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Welke SASL authenticatie-identiteit wilt u dat er gebruikt zal worden om bij " +"de LDAP-database aan te melden?" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Deze waarde wordt gebruikt bij de LOGIN, PLAIN, CRAM-MD5 en DIGEST-MD5 " +"mechanismen." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "SASL proxy autorisatie-identiteit:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Welke proxy autorisatie-identiteit wilt u date er gebruikt zal worden om bij " +"de LDAP-database aan te melden?" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Dit is de naam van het object waarmee de LDAP-verzoeken gedaan worden. Deze " +"waarde dient opgegeven te worden als een DN (distinguished name)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Cyrus SASL beveiliginseigenschappen:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Voer de Cyrus SASL geveiligingseigenschappen in. Toegestane waarden staan " +"beschreven in de ldap.conf(5) handleiding in het SASL OPTIONS deel." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Pad naar de Kerberos identificatie-cache:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "Voer de filenaam in van de GSSAPI/Kerberos identificatie-cache." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "StartTLS gebruiken?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Moet voor de verbinding naar de LDAP server gebruik gemaakt worden van " +"StartTLS-versleuteling?" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nooit" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "toestaan" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "probeer" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "eis" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "SSL servercertificaat controleren:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Als een versleutelde verbinding gebruikt wordt kan een servercertificaat " +"gevraagd en gecontroleerd worden. Moeten verzoeken aan de server een " +"certificaat vereisen en moet het certificaat gecontroleerd worden op " +"geldigheid." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * nooit: certificaat zal niet gevraagd of gecontroleerd worden;\n" +" * toestaan: certificaat zal gevraagd worden, maar niet vereist\n" +" en wordt niet gecontroleerd;\n" +" * probeer: certificaat zal gevraagd en gecontroleerd worden maar\n" +" een ontbrekend certificaat wordt genegeerd;\n" +" * eis: een certificaat wordt gevraagd, gecontroleerd en is\n" +" verplicht." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Als certificaat-controle is ingeschakeld moet minstens één van de " +"tls_cacertdir of tls_cacertfile opties geconfigureerd worden in /etc/nslcd." +"conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Te configureren naamdiensten:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Om dit pakket te laten werken, dient het bestand /etc/nsswitch.conf " +"aangepast te worden om de ldap-gegevensbron te gebruiken." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Hier kunt u de diensten selecteren die voor LDAP-zoekacties geactiveerd " +"dienen te worden. De nieuwe LDAP-zoekacties worden toegevoegd als de laatste " +"gegevensbron. Gelieve deze aanpassingen te controleren." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Verwijder LDAP uit nsswitch.conf?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"De volgende diensten zijn nog geconfigureerd om LDAP te gebruiken:\n" +" ${services}\n" +"maar het libnss-ldapd pakket gaat verwijderd worden." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"U wordt aangeraden om de gegevens te verwijderen als u LDAP niet langer voor " +"naamomzetting wilt gebruiken. Het achterlaten van ldap in nsswitch.conf zou, " +"voor de meeste diensten, geen problemen moeten veroorzaken, maar het " +"opzoeken van computernamen zou op subtiele manier beïnvloed kunnen worden." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"U kunt /etc/nsswitch.conf met de hand bijwerken kunt de items nu automatisch " +"laten verwijderen. Controleer de inhoud van /etc/nsswitch.conf als u ervoor " +"kiest om ze nu te verwijderen." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Shadow opzoeken aanzetten via NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Om inloggen van LDAP-gebruikers toe te staan moet de NSS module password en " +"shadow verzoeken afhandelen. De shadow resultaten kunnen zelf leeg zijn, dat " +"wil zeggen, er is geen noodzaak om wachtwoorden-hashes bloot te stellen. Zie " +"http://bugs.debian.org/583492 voor meer informatie." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Wilt u dat /etc/nsswitch.conf automatisch wordt bijgewerkt om de vereiste " +"vermelding toe te voegen (controleer in dat geval de aanpassingen achteraf) " +"of wilt u het later handmatig doen?" diff --git a/debian/po/pt.po b/debian/po/pt.po new file mode 100644 index 0000000..3b7842f --- /dev/null +++ b/debian/po/pt.po @@ -0,0 +1,516 @@ +# Translation of nss-pam-ldapd debconf to Portuguese. +# Copyright (C) 2007 the nss-pam-ldapd's copyright holder +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# Américo Monteiro , 2007, 2009, 2010, 2011. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-14 00:07+0100\n" +"Last-Translator: Américo Monteiro \n" +"Language-Team: Portuguese \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI do servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Por favor insira o Uniform Resource Identifier do servidor LDAP. O formato é " +"'ldap://:/'. Alternativamente, pode " +"ser usado 'ldaps://' ou 'ldapi://'. O número do porto é opcional." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Quando se usa um esquema ldap ou ldaps é recomendado usar endereços IP para " +"evitar falhas quando os serviços de nomes de domínio não estão disponíveis." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Podem ser especificados múltiplos URIs, separando-os com espaços." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Base de busca do servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Por favor insira o nome distinto da base de busca LDAP. Muitos sítios usam " +"componentes dos seus nomes de domínio para este propósito. Por exemplo, o " +"domínio \"exemplo.net\" deverá usar \"dc=exemplo,dc=net\" como nome distinto " +"da base de busca." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "nenhum" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "simples" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "Autenticação LDAP a usar:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Por favor escolha que tipo de autenticação a base de dados LDAP deverá pedir " +"(se algum):" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * nenhum: nehuma autenticação;\n" +" * simples: ligação DN simples e autenticação por palavra-passe;\n" +" * SASL: qualquer mecanismo Simple Authentication e Security Layer." + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Utilizador da base de dados LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Indique o nome da conta que irá ser usada para login na base de dados LDAP. " +"Este valor deve ser especificado como um DN (nome distinto)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Palavra-passe de utilizador LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Indique a palavra-passe que vai ser usada para autenticação na base de dados " +"LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Mecanismo SASL a usar:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Escolha o mecanismo SASL que irá ser usado para se autentica à base de dados " +"LDAP:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: negociação automática;\n" +" * LOGIN: descontinuado em favor do PLAIN;\n" +" * PLAIN: mecanismo simples de palavra-passe em texto normal;\n" +" * NTLM: mecanismo de autenticação de Gestor NT LAN;\n" +" * CRAM-MD5: esquema de resposta a desafio baseado em HMAC-MD5;\n" +" * DIGEST-MD5: esquema de resposta a desafio compatível com HTTP Digest;\n" +" * GSSAPI: usado para o Kerberos;\n" +" * OTP: um mecanismo de Palavra-passe de Uma Vez." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "Reino do SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Indique o reino de SASL que irá ser usado para autenticação à base de dados " +"LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "O reino é acrescentado às identidades de autenticação e autorização." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Para GSSAPI isto pode ser deixado vazio para usar informação da cache de " +"credenciais do Kerberos." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "Identidade de autenticação do SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Indique a identidade de autenticação SASL que irá ser usada para " +"autenticação à base de dados LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Este é o login usado nos mecanismos LOGIN, PLAIN, CRAM-MD5, e DIGEST-MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "Identidade de autenticação do proxy SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Indique a identidade de autenticação de proxy que irá ser usada para " +"autenticação à base de dados LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Este é o objecto no nome no qual o pedido LDAP é feito. Este valor deve ser " +"especificado como um DN (nome distinto)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Propriedades de segurança do Cyrus SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Indique as propriedades de segurança do Cyrus SASL. Os valores permitidos " +"estão descritos no manual do ldap.conf(5) na secção de OPÇÕES do SASL." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Caminho do ficheiro de cache das credenciais de Kerberos:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Indique o nome de ficheiro de cache de credenciais de GSSAPI/Kerberos que " +"irá ser usado." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Utilizar StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Por favor escolha se a ligação ao servidor LDAP deverá usar StartTLS para " +"encriptar a ligação." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nunca" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "permitir" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "tentar" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "obrigar" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Verificar o certificado SSL do servidor:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Quando é usada uma ligação encriptada, pode ser requisitado e verificado um " +"certificado do servidor. Por favor escolha se as buscas devem ser " +"configuradas para requisitar um certificado, e se a validade dos " +"certificados deve ser verificada :" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * nunca: nenhum certificado será requisitado ou verificado;\n" +" * permitir: será requisitado um certificado, mas não será obrigatório\n" +" nem verificado;\n" +" * tentar: um certificado será requisitado e verificado, mas é ignorado\n" +" se nenhum certificado for disponibilizado;\n" +" * obrigar: será obrigatória a requisição e verificação de um certificado." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Se a verificação de certificados for activada, pelo menos uma das opções " +"tls_cacertdir ou tls_cacertfile tem que ser colocada em /etc/nslcd.conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Nomes de serviços para configurar:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Para que este pacote funcione, você precisa de modificar o seu /etc/nsswitch." +"conf para usar a fonte de dados ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Você pode seleccionar os serviços que deverão estar activos para buscas " +"LDAP. As novas buscas LDAP serão adicionadas como a última fonte de dados. " +"Certifique-se de rever estas alterações." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Remover agora o LDAP do nsswitch.conf?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Os seguintes serviços ainda estão configurados para usar o LDAP para " +"buscas:\n" +" ${services}\n" +"mas o pacote libnss-ldapd está prestes a ser removido." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Você é aconselhado a remover as entradas se não planeia continuar a usar o " +"LDAP para resolução de nomes. A não remoção do ldap do nsswitch.conf não " +"deverá causar problemas (para a maioria dos serviços), mas a resolução de " +"nomes de máquinas pode ficar afectada." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Você pode editar manualmente o /etc/nsswitch.conf ou escolher remover as " +"entradas automaticamente agora. Certifique-se que revê as alterações em /etc/" +"nsswitch.conf se escolher remover as entradas agora." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Activar as buscas shadow através de NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Para permitir que os utilizadores do LDAP façam login, o módulo NSS precisa " +"de estar capaz de fazer buscas de palavras-passe shadow. As próprias " +"entradas shadow podem estar vazias - isto é, não há necessidade de expor as " +"hashes das palavras-passe. Veja http://bugs.debian.org/583492 para " +"antecedentes." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Por favor escolha se o /etc/nsswitch.conf deverá ter a entrada necessária " +"adicionada automaticamente (que neste caso deverá ser verificada " +"posteriormente) ou se deverá ser deixado para um administrador editar " +"manualmente." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Se a base de dados LDAP requerer autenticação para buscas normais, " +#~ "indique aqui o nome da conta que vai ser usada. Em caso contrário, deixe " +#~ "o campo vazio." + +#, fuzzy +#~| msgid "" +#~| "You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +#~| "automatically now. Be sure to review the changes to /etc/nsswitch.conf " +#~| "if you choose to remove the entries now." +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "Você pode editar manualmente o /etc/nsswitch.conf ou escolher remover as " +#~ "entradas automaticamente agora. Certifique-se que revê as alterações em /" +#~ "etc/nsswitch.conf se escolher remover as entradas agora." diff --git a/debian/po/pt_BR.po b/debian/po/pt_BR.po new file mode 100644 index 0000000..45e3a47 --- /dev/null +++ b/debian/po/pt_BR.po @@ -0,0 +1,611 @@ +# Translation of nss-pam-ldapd debconf templates to Brazilian Portuguese. +# +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-14 15:53-0300\n" +"Last-Translator: Denis Doria \n" +"Language-Team: Debian-BR Project \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI do servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Por favor entre com o Identicador Uniforme do Recurso (URI) do servidor " +"LDAP. O formato é \"ldap://:/\". " +"Alternativamente, \"ldaps://\" ou \"ldapi://\" pode ser usado. O número da " +"porta é opcional." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Quando usando métodos ldap ou ldaps é recomendado o uso de um endereço IP " +"para evitar falhas quando os serviços de nome de domínio estão indisponí­veis." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Múltiplas URIs podem ser especifícadas separando-as com espaços." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Base de buscas do servidor LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Por favor informe o nome distinto da base de procura LDAP. Muitos sites usam " +"componentes de seus nomes de domí­nio para este propósito. Por exemplo, o " +"domínio \"example.net\" usaria \"dc=example,dc=net\" como o nome distinto da " +"base de procura." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "nenhum" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "simples" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "Autenticação LDAP a ser usada:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Por favor escolha qual o tipo de autenticação a base de dados LDAP deve " +"requerir (se alguma):" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +"* none: sem autenticação;\n" +"* simple: DN vínculo simples e autenticação por senha;\n" +"* SASL: qualquer Autenticação Simples e um mecanismo de Camada de Segurança" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Base de dados de usuários LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Informe o nome da conta que será usada para se autenticar na base de dados " +"LDAP. Este valor deverá ser especificado como um ND (nome distinto)" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Senha do usuário LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Informe a senha que será usada para a autenticação na base de dados LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Mecanismo SASL para utilizar:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Escolha o mecanismo SASL que deverá ser utilizado para autenticar na base de " +"dados LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: negociação automática;\n" +" * LOGIN: depreciada em favor de PLAIN;\n" +" * PLAIN: mecanismo simples de senha em texto puro\n" +" * NTLM: mecanismo de autenticação NT LAN Manager;\n" +" * CRAM-MD5: método desafio-resposta baseado em HMAC-MD5;\n" +" * DIGEST-MD5: método compatí­vel desafio-resposta HTTP Digest;\n" +" * GSSAPI: utilizado pelo Kerberos;\n" +" * OTP: um mecanismo de senha de apenas uma vez." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "Domí­nio SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Entre com o domínio SASL que será utilizado para autenticação na base de " +"dados LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "O domí­nio é anexado a autenticação e as identidades de autorização." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Para o GSSAPI isto pode ser deixado em branco para utilizar a informação do " +"cache de credenciais Kerberos." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "Identidade de autenticação SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Entre com a identidade de autenticação SASL que será utilizada para " +"autenticar na base de dados LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Este é o login usado nos mecanismos LOGIN, PLAIN, CRAM-MD5, e DIGEST-MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "Identidade do proxy de autorização SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Entre com a identidade de autorização do proxy que será utilizada para " +"autenticar na base de dados LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Este é o nome do objeto o qual a requisição LDAP é feita. Este valor deveria " +"ser especificado como um ND (nome distinto)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Propriedades de segurança Cyrus SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Entre com as propriedades de segurança Cyrus SASL. Valores permitidos estão " +"descritos na página de manual ldap.conf(5) na seção SASL OPTIONS." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Caminho do arquivo de cache de credenciais Kerberos:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Entre com o nome do arquivo de cache GSSAPI/Kerberos que será utilizado." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Usar StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Por favor escolha se a conexão com o servidor LDAP deve usar StartTLS para " +"criptografar a mesma." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nunca" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "permitir" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "tentar" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "demanda" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Verificar o certificado SSL do servidor:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Quando uma conexão criptografada é utilizada, um servidor certificado pode " +"ser requerido e verificado. Por favor escolha se as pesquisas devem ser " +"configuradas para requerir um certificado, e se o certificado deve ter a " +"validade verificada." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * never: nenhum certificado será requisitado ou verificado;\n" +" * allow: um certificado será requisitado, mas não é\n" +" requerido ou verificado;\n" +" * try: um certificado será requisitado e verificado, mas se nenhum\n" +" certificado é provido o mesmo é ignorado;\n" +" * demand: um certificado será requisitado, requerido, e validado." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Se a verificação do certificado está ativa, pelo menos uma das opções " +"tls_cacertdir ou tls_cacertfile deve ser inclusa no /etc/nslcd.conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Serviços de nome para configurar:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Para que este pacote funcione, você precisa modificar seu /etc/nsswitch.conf " +"para utilizar a fonte de dados ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Você pode selecionar os serviços que deveriam ter pesquisas LDAP ativadas. " +"As novas pesquisas LDAP serão adicionadas como última fonte de dados. Tenha " +"certeza de rever essas mudanças." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Remover agora o LDAP do nsswitch.conf?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Os serviços a seguir continuam configuradas para utilizar o LDAP para " +"pesquisas:\n" +" ${services}\n" +"mas o pacote libnss-ldapd está prestes a ser removido." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Você está avisado para remover as entradas se não planeja continuar " +"utilizando o LDAP para resolução de nomes. Não remover o ldap do nsswitch." +"conf deve, para a maioria dos serviços, não causar problemas, mas a " +"resolução de nome do host deverá ser afetada de maneiras misteriosas." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Você pode editar /etc/nsswitch.conf manualmente ou escolher remover as " +"entradas automaticamente agora. Tenha certeza de rever as mudanças no /etc/" +"nsswitch.conf se escolher remover as entradas agora." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Ativar pesquisas obscuras através do NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Para permitir os usuários LDAP conectarrem-se, o módulo NSS deve estar " +"ativado para fazer as pesquisas de senhas obscuras. As entradas obscuras " +"podem estar vazias - isto é, nã há necessidade de hashes de senhas serem " +"expostos. Veja http://bugs.debian.org/583492 para mais informações." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Por favor escolha se /etc/nsswitch.conf deve ter a entrada de valor " +"acrescentado automaticamente (caso ao qual deve ser revisto mais tarde) ou " +"se deve ser deixado para um administrador para editar manualmente." + +#, fuzzy +#~ msgid "" +#~ "Enter the password that will be used to log in to the LDAP database when " +#~ "the root process does lookups." +#~ msgstr "" +#~ "Informe a senha que será usada para a autenticação na base de dados LDAP." + +#, fuzzy +#~ msgid "" +#~ "Please enter which version of the LDAP protocol is to use. It is usually " +#~ "a good idea to set this to highest available version number." +#~ msgstr "" +#~ "Por favor informe qual versão do protocolo LDAP ldapns deve ser usada. " +#~ "Normalmente é uma boa idéia definir esta opção para o número de versão " +#~ "mais alto disponível." + +#, fuzzy +#~ msgid "" +#~ "For this package to work, you need to modify your /etc/nsswitch.conf to " +#~ "use the ldap datasource. There is an example file at /usr/share/doc/" +#~ "libnss-ldap/examples/nsswitch.ldap which can be used as an example for " +#~ "your nsswitch setup." +#~ msgstr "" +#~ "Para que este pacote funcione, você precisa modificar seu arquivo /etc/" +#~ "nsswitch.conf para usar a fonte de dados ldap. Existe um arquivo de " +#~ "exemplo em /usr/share/doc/libnss-ldap/examples/nsswitch.ldap que pode ser " +#~ "usado como um exemplo para a sua configuração do nsswitch ou que pode ser " +#~ "copiado sobrepondo sua configuração atual." + +#~ msgid "distinguished name of the search base" +#~ msgstr "O nome distinto (dn) da base de procura." + +#~ msgid "password for database login account" +#~ msgstr "Senha para a autenticação na base de dados." + +#~ msgid "nsswitch.conf is not managed automatically" +#~ msgstr "O arquivo nsswitch.conf não é gerenciado automaticamente." + +#~ msgid "make configuration readable/writeable by owner only" +#~ msgstr "Tornar a configuração legível/gravável somente pelo dono" + +#~ msgid "" +#~ "Should the libnss-ldap configuration file be readable and writable only " +#~ "by the file owner?" +#~ msgstr "" +#~ "O arquivo de configuração da libnss-ldap deve ser legível e gravável " +#~ "somente pelo dono do arquivo ?" + +#~ msgid "" +#~ "If you use passwords in your libnss-ldap configuration, it is usually a " +#~ "good idea to have the configuration set with mode 0600 (readable and " +#~ "writable only by the file's owner)." +#~ msgstr "" +#~ "Caso você use senhas em seu arquivo de configuração da libnss-ldap é " +#~ "normalmente uma boa idéia ter as permissões do arquivo de configuração " +#~ "definidas para o modo 0600 (legível e gravável apenas pelo dono do " +#~ "arquivo)." + +#~ msgid "" +#~ "Note: As a sanity check, libnss-ldap will check if you have nscd " +#~ "installed and will only set the mode to 0600 if nscd is present." +#~ msgstr "" +#~ "Nota : Como uma medida extra, a libnss-ldap irá checar se você possui o " +#~ "nscd instalado e somente irá deinir o modo 0600 caso o nscd esteja " +#~ "instalado." + +#~ msgid "database requires login" +#~ msgstr "Base de dados requer autenticação." + +#~ msgid "Does the LDAP database require login?" +#~ msgstr "A base de dados LDAP requer autenticação ?" + +#~ msgid "" +#~ "Answer this question affirmatively only if you can't retreive entries " +#~ "from the database without logging in." +#~ msgstr "" +#~ "Responda a esta questão afirmativamente somente caso você não possa obter " +#~ "entradas da base de dados LDAP sem antes se autenticar." + +#~ msgid "Note: Under a normal setup, this is not needed." +#~ msgstr "Nota : Sob um configuração normal, isto não é necessário." + +#~ msgid "enable automatic configuration updates by debconf" +#~ msgstr "Habilitar atualizações automáticas de configuração pelo debconf" + +#~ msgid "" +#~ "Should debconf automatically update libnss-ldap's configuration file?" +#~ msgstr "" +#~ "O debconf deve atualizar automaticamente o arquivo de configuração da " +#~ "libnss-ldap ?" + +#~ msgid "libnss-ldap has been moved to use debconf for its configuration." +#~ msgstr "A libnss-ldap está agora usando debconf para sua configuração." + +#~ msgid "" +#~ "The file will be prepended with \"###DEBCONF###\"; you can disable the " +#~ "debconf updates by removing that line." +#~ msgstr "" +#~ "O arquivo de configuração será marcado com \"###DEBCONF###\"; você pode " +#~ "desabilitar as atualizações debconf removendo essa linha." + +#~ msgid "All new installations will have this by default." +#~ msgstr "Todas as novas instalações terão isso por padrão." + +#~ msgid "" +#~ "Also, before removing this package, it is wise to remove the ldap entries " +#~ "from nsswitch.conf to keep basic services functioning." +#~ msgstr "" +#~ "Adicionalmente, antes de remover este pacote, é sábio remover as entradas " +#~ "ldap do arquivo nsswitch.conf para manter os serviços básicos funcionando." + +#~ msgid "dc=example,dc=net" +#~ msgstr "dc=example,dc=net" + +#~ msgid "cn=proxyuser,dc=example,dc=net" +#~ msgstr "cn=proxyuser,dc=example,dc=net" + +#~ msgid "3, 2" +#~ msgstr "3, 2" + +#, fuzzy +#~ msgid "ldap://127.0.0.1/" +#~ msgstr "127.0.0.1" + +#~ msgid "Please enter the address of the LDAP server used." +#~ msgstr "Por favor informe o endereço do servidor LDAP usada." diff --git a/debian/po/ru.po b/debian/po/ru.po new file mode 100644 index 0000000..ea91069 --- /dev/null +++ b/debian/po/ru.po @@ -0,0 +1,515 @@ +# Translation of nss-pam-ldapd debconf templates to Russian. +# +# Translators: +# +# Debian Description Translation Project , 2003. +# Ilgiz Kalmetev , 2003. +# Yuri Kozlov , 2009, 2010, 2011. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-14 09:15+0400\n" +"Last-Translator: Yuri Kozlov \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI сервера LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Укажите универсальный индикатор ресурса (URI) сервера LDAP. Формат: «ldap://" +"<имя_узла или IP>:<порт>/». Также можно использовать «ldaps://» или " +"«ldapi://». Номер порта необязателен." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"При использовании схемы ldap или ldaps, обычно, лучше указывать IP-адрес; " +"это снижает риск появления проблем в случае отказа службы имён." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Можно указывать несколько URI через пробел." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "База поиска сервера LDAP:" + +# +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Введите уникальное имя базы поиска LDAP. Для этой цели на многих серверах " +"используют части своих доменных имён. Например, для домена «example.net» в " +"качестве уникального имени базы поиска использовалось бы «dc=example,dc=net»." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "отсутствует" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "простой" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "Используемый метод аутентификации LDAP:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Укажите, какой тип аутентификации нужно использовать для получения доступа к " +"базе данных LDAP (если нужно):" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * отсутствует: без аутентификации;\n" +" * простой: привязка DN и пароль;\n" +" * SASL: любой механизм простой аутентификацию и слоя безопасности." + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Пользователь базы данных LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Введите имя учетной записи, которая будет использована для подключения к " +"базе данных LDAP. Значение должно быть указано в форме DN (уникального " +"имени)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Пароль пользователя LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" +"Введите пароль, который будет использован для подключения к базе данных LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Используемый механизм SASL:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Выберите механизм SASL, который будет использован для аутентификации при " +"подключении к базе данных LDAP:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: применить автоматическое согласование;\n" +" * LOGIN: устарел, используйте PLAIN;\n" +" * PLAIN: механизм с нешифрованным паролем;\n" +" * NTLM: механизм аутентификации NT LAN Manager;\n" +" * CRAM-MD5: схема запрос-ответ на основе HMAC-MD5;\n" +" * DIGEST-MD5: схема запрос-ответ, совместимая с HTTP Digest;\n" +" * GSSAPI: использовать Kerberos;\n" +" * OTP: механизм одноразового пароля." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "Область SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Введите область SASL, которая будет использована для аутентификации при " +"подключении к базе данных LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "Область добавляется к удостоверениям аутентификации и авторизации." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Для GSSAPI можно ничего не вводить; в этом случае будет использована " +"информация из кэша свидетельств Kerberos." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "Аутентификационное удостоверение SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Введите аутентификационное удостоверение SASL, которое будет использовано " +"для аутентификации при подключении к базе данных LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Это имя учётной записи используется в механизмах LOGIN, PLAIN, CRAM-MD5 и " +"DIGEST-MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "Проксированное авторизационное удостоверение SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Введите проксированное авторизационное удостоверение SASL, которое будет " +"использовано для аутентификации при подключении к базе данных LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Это объект, от имени которого выполняется запрос LDAP. Значение должно быть " +"указано в форме DN (уникального имени)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Параметры безопасности Cyrus SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Введите параметры безопасности Cyrus SASL. Разрешено указывать значения, " +"описанные в справочной странице ldap.conf(5) в разделе SASL OPTIONS." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Файл кэша свидетельств Kerberos:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Введите имя файла кэша свидетельств GSSAPI/Kerberos, который нужно " +"использовать." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Использовать StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Выберите нужно ли использовать StartTLS для шифрования соединения с сервером " +"LDAP." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "никогда" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "запросить" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "попытаться" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "обязательна" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Проверка SSL-сертификат сервера:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"При использовании шифрованного соединения, можно запросить и проверить " +"сертификат сервера. Выберите нужно ли запрашивать и проверять сертификат:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * никогда: не запрашивать и не проверять сертификат;\n" +" * запросить: запросить сертификат, но его наличие и проверка\n" +" не обязательны;\n" +" * попытаться: запросить и проверить сертификат, но если его\n" +" нет, то продолжать работу;\n" +" * обязательна: обязательно запросить и проверить сертификат." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Если разрешена проверка сертификата, то в файле /etc/nslcd.conf должен быть " +"параметр tls_cacertdir или tls_cacertfile." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Имена настраиваемых служб:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Чтобы этот пакет использовался в работе нужно изменить /etc/nsswitch.conf, " +"указав в нём источник данных ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Вы можете выбрать службы, для которых нужно осуществлять поиск в LDAP. Поиск " +"по LDAP будет добавлен в конец списка опрашиваемых служб. Позже просмотрите " +"получившиеся изменения." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Удалить LDAP из nsswitch.conf прямо сейчас?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Следующие службы всё ещё используют LDAP при поиске имён:\n" +" ${services}\n" +"но пакет libnss-ldapd удаляется из системы." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Советуем удалить записи, если вы больше не планируете использовать LDAP для " +"поиска имён. Если ldap останется в nsswitch.conf, то для большинства служб " +"это не вызовет проблем, но может негативно отразиться при определении имён " +"узлов." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Вы можете отредактировать файл /etc/nsswitch.conf вручную или выбрать " +"автоматическое удаление записей прямо сейчас. После этого проверьте " +"изменённый /etc/nsswitch.conf." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Включить поиск в теневых паролях через NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Чтобы разрешить вход пользователям LDAP, для модуля NSS нужно включить поиск " +"в теневых паролях. Сами теневые элементы могут быть пусты, то есть туда " +"ненужно копировать хэши паролей. Подробней см. в http://bugs.debian." +"org/583492." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Выберите, нужно ли для этого добавить настройку в /etc/nsswitch.conf " +"автоматически (по окончании проверьте изменения), или предоставить " +"возможность администратору сделать это вручную." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Если для обычного поиска по базе данных LDAP требуется регистрация, то " +#~ "введите здесь имя этой учётной записи. Иначе оставьте поле пустым." + +#, fuzzy +#~| msgid "" +#~| "You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +#~| "automatically now. Be sure to review the changes to /etc/nsswitch.conf " +#~| "if you choose to remove the entries now." +#~ msgid "" +#~ "You can edit /etc/nsswitch.conf by hand or choose to add the entry " +#~ "automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +#~ "you choose to add the entry now." +#~ msgstr "" +#~ "Вы можете отредактировать файл /etc/nsswitch.conf вручную или выбрать " +#~ "автоматическое удаление записей прямо сейчас. После этого проверьте " +#~ "изменённый /etc/nsswitch.conf." + +#~ msgid "LDAP server Uniform Resource Identifier:" +#~ msgstr "Единообразный идентификатор ресурса сервера LDAP:" diff --git a/debian/po/sk.po b/debian/po/sk.po new file mode 100644 index 0000000..191170d --- /dev/null +++ b/debian/po/sk.po @@ -0,0 +1,488 @@ +# Slovak translations for nss-pam-ldapd package +# Slovenské preklady pre balík nss-pam-ldapd. +# Copyright (C) 2011 THE nss-pam-ldapd'S COPYRIGHT HOLDER +# This file is distributed under the same license as the nss-pam-ldapd package. +# +# Translators: +# +# Slavko , 2011. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.8.4\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2011-08-14 09:38+0200\n" +"Last-Translator: Slavko \n" +"Language-Team: Slovak \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI servera LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Prosím, zadajte Jednotný identifikátor zdroja (URI) servera LDAP. Formát je " +"„ldap://:/”. Môže byť použité aj „ldaps://” " +"alebo „ldapi://”. Číslo portu je voliteľné." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Pri použití schémy ldap alebo ldaps odporúčame použiť IP adresu, aby ste sa " +"vyhli výpadkom, keď nie sú dostupné služby prekladu doménových mien." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Viacero URI možno zadať ich oddelením medzerami." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Základ (base) hľadania servera LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Prosím zadajte distingvované meno (distinguished name) základu hľadania " +"LDAP. Veľa stránok používa na tento účel časti svojho doménového mena. " +"Napríklad, doména „example.net” by ako distingvované meno základu hľadania " +"použila \"dc=example,dc=net\"." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "žiadna" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "jednoduchá" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "SASL" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "Použitá autentifikácia LDAP:" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" +"Prosím, vyberte si ktorý typ autentifikácie má databáza LDAP vyžadovať (ak " +"nejaký):" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" +" * žiadna: bez autentifikácie;\n" +" * jednoduchá: autentifikácia jednoduchého zviazania DN a hesla;\n" +" * SASL: Jednoduchá autentifikácia a mechanizmus Security Layer." + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Používateľ databázy LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" +"Zadajte meno účtu, ktorý bude používaný na prihlásenie sa k databáze LDAP. " +"Táto hodnota má byť zadaná ako DN (distinguished name)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Heslo používateľa LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "Zadajte heslo, ktoré bude použité na prihlásenia k databáze LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "Použitý mechanizmus SASL:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" +"Vyberte si mechanizmus SASL, ktorý bude použitý na autentifikáciu do " +"databázy LDAP:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" +" * auto: automatické dohodnutie;\n" +" * LOGIN: zastarané v prospech PLAIN;\n" +" * PLAIN: jednoduchý mechanizmus hesla prostým textom;\n" +" * NTLM: autentifikačný mechanizmus NT LAN Manager;\n" +" * CRAM-MD5: schéma výzva-odpoveď, založená na HMAC-MD5;\n" +" * DIGEST-MD5: HTTP schéma výzva-odpoveď, kompatibilná s Digest;\n" +" * GSSAPI: použité pre Kerberos;\n" +" * OTP: mechanizmus jednorázového hesla (One Time Password)." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "SASL realm:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" +"Zadajte SASL realm, ktoré bude použité na autentifikáciu do databázy LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "realm je pripojený k autentifikačným a autorizačným identitám." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" +"Pri GSSAPI môžete nechať toto pole prázdne a budú použité informácie z " +"vyrovnávacej pamäte Kerberos credential." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "Autentifikačná identita SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Zadajte autentifikačnú identitu SASL, ktorá bude použitá na autentifikáciu k " +"databáze LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" +"Toto je prihlasovacie meno, použité v mechanizmoch LOGIN, PLAIN, CRAM-MD5 a " +"DIGEST-MD5." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "SASL proxy autorizačná identita:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" +"Zadajte proxy autorizačnú identitu, ktorá bude použitá na autentifikáciu do " +"databázy LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" +"Je to objekt, v ktorého mene je vykonaný požiadavok LDAP. Táto hodnota musí " +"byť zadaná vo forme DN (distinguished name)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "Bezpečnostné vlastnosti Cyrus SASL:" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" +"Zadajte bezpečnostné vlastnosti Cyrus SASL. Povolené hodnoty sú popísané v " +"manuálovej stránke ldap.conf(5), v časti SASL OPTIONS." + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "Cesta k súboru vyrovnávacej pamäte Kerberos credential:" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" +"Zadajte meno súboru vyrovnávacej pamäte GSSAPI/Kerberos, ktorý bude použitý." + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Použiť StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Prosím, vyberte si, či pripojenie k serveru LDAP má na šifrovanie spojenia " +"použiť StartTLS." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "nikdy" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "povoliť" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "skúsiť" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "žiadať" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Kontrolovať SSL certifikát servera:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Pri použití šifrovaného spojenia môže byť vyžiadaný a skontrolovaný " +"certifikát servera. Prosím, vyberte či majú byť vyhľadávania nastavené na " +"vyžadovanie certifikátu a či má byť skontrolovaná platnosť certifikátov:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * nikdy: certifikát nebude vyžiadaný ani kontrolovaný;\n" +" * povoliť: certifikát bude vyžiadaný, ale nie je \n" +" vyžadovaný ani kontrolovaný;\n" +" * skúsiť: certifikát bude vyžiadaný a skontrolovaný, ale ak nie je\n" +" certifikát poskytnutý, je ignorovaný;\n" +" * žiadať: certifikát bude vyžiadaný, vyžadovaný a skontrolovaný." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Ak je zapnutá kontrola certifikátu, musí byť v súbore /etc/nslcd.conf " +"vložená aspoň jedna z volieb tls_cacertdir alebo tls_cacertfile." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Nastavovaná služba mien:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Aby tento balík fungoval, musíte upraviť svoj /etc/nsswitch.conf tak, aby " +"používal dátový zdroj ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Môžete si vybrať, ktoré služby majú mať zapnuté vyhľadávania LDAP. Nové " +"vyhľadávania LDAP budú pridané ako posledný dátový zdroj. Nezabudnite " +"skontrolovať tieto zmeny." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Odstrániť teraz LDAP z nsswitch.conf?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Nasledujúce služby sú stále nastavené tak, aby na vyhľadávanie používali " +"LDAP:\n" +" ${services}\n" +"ale balík libnss-ldapd je odoberaný." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Odporúčame odstrániť tieto položky, ak už viac neplánujete používať LDAP na " +"preklad mien. Ponechanie ldap v nsswitch.conf by nemalo, pri väčšine " +"služieb, spôsobovať problémy, ale preklad mien hostiteľov môže byť nejakým " +"spôsobom dotknutý." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Súbor /etc/nsswitch.conf môžete upraviť manuálne alebo si zvoliť odstránenie " +"položiek automaticky teraz. Ak si vyberiete odstránenie položiek teraz, " +"nezabudnite si skontrolovať zmeny v /etc/nsswitch.conf." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Zapnúť tieňové vyhľadávanie cez NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Aby sa mohli používatelia LDAP prihlásiť, musí mať modul NSS povolené " +"vykonávanie tieňové (shadow) vyhľadávanie hesla. Samotné tieňové položky " +"môžu byť prázdne - čo znamená, že nie je potrebné aby boli vystavené " +"odtlačky hesiel. Podrobností hľadajte v http://bugs.debian.org/583492." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Prosím, vyberte či majú byť vyžadované polia do /etc/nsswitch.conf pridané " +"automaticky (v tom prípade musia byť neskôr skontrolované) alebo či to má " +"byť ponechané na manuálnu úpravu administrátorom." diff --git a/debian/po/sv.po b/debian/po/sv.po new file mode 100644 index 0000000..38e45ba --- /dev/null +++ b/debian/po/sv.po @@ -0,0 +1,474 @@ +# Translation of nss-pam-ldapd debconf templates to Swedish. +# +# Translators: +# +# Martin gren , 2008, 2009, 2010. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.7.9\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2010-08-28 12:21+0200\n" +"Last-Translator: Martin gren \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: sv\n" +"X-Poedit-Country: sv\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI fr LDAP-server:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Ange URI:n (eng. \"Uniform Resource Identifier\") till LDAP-servern. " +"Formatet r 'ldap://:/'. Alternativt kan 'ldaps://' " +"eller 'ldapi://' anvndas. Portnumret behver inte anges." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Nr ldap och ldaps anvnds r det vanligtvis en bra id att anvnda en IP-" +"adress fr att undvika fel nr namntjnsten (DNS) r otillgnglig." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "Flera URI:er kan anges separerade med blanksteg." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Skbas fr LDAP-server:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Ange namnet (DN) fr LDAPs skbas. Mnga system anvnder komponenter av " +"deras domnnamn fr denna funktion. Till exempel att domnen \"example.net\" " +"skulle anvnda \"dc=example,dc=net\" som sitt DN-namn fr skbasen." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP-databasanvndare:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "Detta vrde ska anges som ett DN (eng. \"distinguished name\")." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "LDAP-anvndarlsenord:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "Ange lsenordet som ska anvndas fr att logga in p LDAP-databasen." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "Ange lsenordet som ska anvndas fr att logga in p LDAP-databasen." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "Ange lsenordet som ska anvndas fr att logga in p LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "Ange lsenordet som ska anvndas fr att logga in p LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "Ange lsenordet som ska anvndas fr att logga in p LDAP-databasen." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "Detta vrde ska anges som ett DN (eng. \"distinguished name\")." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Anvnda StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Vlj huruvida uppkopplingen till LDAP-servern ska anvnda StartTLS fr att " +"kryptera uppkopplingen." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "aldrig" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "tillt" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "frsk" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "krv" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Kontrollera serverns SSL-certifikat:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Nr en krypterad uppkoppling anvnds, kan ett servercertifikat efterfrgas " +"och kontrolleras. Vlj huruvida uppslag ska konfigureras fr att krva ett " +"certifikat och huruvida certifikatens giltighet ska kontrolleras:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * aldrig: inget certifikat kommer efterfrgas eller kontrolleras;\n" +" * tillt: ett certifikat kommer efterfrgas, men det krvs inget\n" +" och det kontrolleras inte;\n" +" * frsk: ett certifikat kommer efterfrgas och kontrolleras, men om\n" +" inget certifikat tillhandahlls kommer detta ignoreras;\n" +" * krv: ett certifikat kommer efterfrgas och kontrolleras." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Om certifikatkontroll r aktiverad mste tminstone ett avtls_cacertdir- och " +"tls_cacertfile-direktiven lggas i /etc/nslcd.conf." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Namntjnster som ska konfigureras:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Fr att det hr paketet ska fungera, behver du modifiera /etc/nsswitch.conf " +"s att ldaps dataklla anvnds." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Du kan vlja de tjnster som ska ha LDAP-uppslag aktiverade. De nya LDAP-" +"uppslagen kommer att lggas till som en sista dataklla. Se till att se ver " +"dessa ndringar." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Ta bort LDAP frn nsswitch.conf nu?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"Fljande tjnster r fortfarande konfigurerade att anvnda LDAP fr " +"uppslag:\n" +" ${services}\n" +"men libnss-ldapd-paketet kommer tas bort." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Du br ta bort uppgifterna om du inte tnker anvnda LDAP fr namnuppslag. " +"Att inte ta bort ldap frn nsswitch.conf br, fr de flesta tjnster, inte " +"orsaka ngra problem, men vrdnamnsuppslag kan pverkas p sm, subtila stt." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Du kan ndra /etc/nsswitch.conf fr hand eller vlja att ta bort posterna " +"automatiskt nu. Se ver ndringarna i /etc/nsswitch.conf om du vljer att ta " +"bort posterna nu." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Aktivera shadow-uppslag genom NSS?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Om LDAP-anvndare ska kunna logga in, mste NSS-modulen ha mjlighet att " +"utfra shadow-uppslag av lsenord. Sjlva shadow-posterna kan vara tomma, " +"vilket innebr att de hashade lsenorden inte mste gras tillgngliga. Se " +"http://bugs.debian.org/583492 fr bakgrundsinformation." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Vlj huruvida den ndvndiga posten ska lggas till i /etc/nsswitch.conf " +"automatiskt (det br i s fall kontrolleras i efterhand) eller om det ska " +"lmnas t en administratr att redigera filen manuellt." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Om LDAP-databasen krver inloggning fr vanliga uppslag, ange namnet p " +#~ "det konto som ska anvndas hr. Lmna annars tomt." diff --git a/debian/po/templates.pot b/debian/po/templates.pot new file mode 100644 index 0000000..4ce9a56 --- /dev/null +++ b/debian/po/templates.pot @@ -0,0 +1,409 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" diff --git a/debian/po/vi.po b/debian/po/vi.po new file mode 100644 index 0000000..4952332 --- /dev/null +++ b/debian/po/vi.po @@ -0,0 +1,476 @@ +# Translation of nss-pam-ldapd debconf templates to Vietnamese. +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# Translators: +# +# Clytie Siddall , 2005-2010. +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.7.9\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: 2010-09-29 22:21+0930\n" +"Last-Translator: Clytie Siddall \n" +"Language-Team: \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: LocFactoryEditor 1.8\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "URI trình phục vụ LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"Hãy gõ địa chỉ URI (nhận diện tài nguyên thống nhất) của máy phục vụ LDAP. " +"Định dạng nên là « ldap://tên_máy_hay_địa_chỉ_IP:cổng/ ». Cũng có thể sử " +"dụng tiền tố « ldaps:// » hay « ldapi:// ». Số thứ tự dộng vẫn còn tuỳ chọn" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "" +"Khi sử dụng lược đồ ldap hay ldaps, tốt hơn khi đặt một địa chỉ IP, thì " +"tránh kết nối bị lỗi khi dịch vụ tên miền không sẵn sàng." + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "" +"Cũng có thể đưa ra nhiều địa chỉ URI bằng cách định giới bằng dấu cách." + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "Cơ bản tìm kiếm máy phục vụ LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"Hãy gõ tên phân biệt (DN) của cơ bản tìm kiếm LDAP. Nhiều chỗ sử dụng thành " +"phần tên miền cho mục đích này, v.d. miền « ví_dụ.net » sẽ sử dụng « " +"dc=ví_dụ,dc=net » làm tên phân biệt của cơ bản tìm kiếm." + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "Người dùng cơ sở dữ liệu LDAP:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "Giá trị này nên được ghi rõ dưới dạng một DN (tên phân biệt)." + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "Mật khẩu người dùng LDAP:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "Hãy gõ mật khẩu sẽ được dùng để đăng nhập vào cơ sở dữ liệu LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "Hãy gõ mật khẩu sẽ được dùng để đăng nhập vào cơ sở dữ liệu LDAP." + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "Hãy gõ mật khẩu sẽ được dùng để đăng nhập vào cơ sở dữ liệu LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "Hãy gõ mật khẩu sẽ được dùng để đăng nhập vào cơ sở dữ liệu LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "Hãy gõ mật khẩu sẽ được dùng để đăng nhập vào cơ sở dữ liệu LDAP." + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "Giá trị này nên được ghi rõ dưới dạng một DN (tên phân biệt)." + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "Dùng StartTLS ?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "" +"Hãy chọn nếu kết nối tới máy phục vụ LDAP nên sử dụng StarTLS để mật mã hoá " +"kết nối, hay không." + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "không bao giờ" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "cho phép" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "thử" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "đòi hỏi" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "Kiểm tra chứng nhận SSL của máy phục vụ :" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"Khi sử dụng một kết nối đã mật mã, cũng có thể yêu cầu và kiểm tra một chứng " +"nhận máy phục vụ. Hãy chọn nếu chức năng tra cứu nên được cấu hình để yêu " +"cầu một chứng nhận, và nếu chứng nhận nên được kiểm tra là hợp lệ hay không." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" • không bao giờ\tkhông có chứng nhận nào được yêu cầu hoặc kiểm tra\n" +" • cho phép\t\tmột chứng nhận sẽ được yêu cầu, còn nó không phải\n" +"\t\t\t\tđược đòi hỏi hoặc kiểm tra\n" +" • thử\t\t\tmột chứng nhận được yêu cầu và kiểm tra, nhưng mà lờ đi\n" +"\t\t\t\tnếu chứng nhận không được cung cấp\n" +" • đòi hỏi\t\t\tmột chứng nhận được yêu cầu, đòi hỏi và kiểm tra." + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"Nếu tính năng kiểm tra được hiệu lực thì ít nhất một của hai tuỳ chọn « " +"tls_cacertdir » và « tls_cacertfile » phải được để vào tập tin cấu hình « /" +"etc/nslcd.conf »." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "Các dịch vụ tên cần cấu hình:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "" +"Để gói này hoạt động được, bạn cần phải sửa đổi tập tin cấu hình « /etc/" +"nsswitch.conf » để sử dụng nguồn dữ liệu ldap." + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"Bạn có khả năng chọn những dịch vụ nên được bật hay tắt cho chức năng tra " +"cứu LDAP. Các sự tra cứu LDAP mới sẽ được thêm như là nguồn dữ liệu cuối " +"cùng. Hãy xem lại kỹ những thay đổi này." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "Gỡ bỏ LDAP khỏi « nsswitch.conf » ngay bây giờ ?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"LDAP vẫn còn được cấu hình cho sự tra cứu tên đối với những dịch vụ theo " +"đây:\n" +" ${services}\n" +"còn gói « libnss-ldapd » sắp bị gỡ bỏ." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"Khuyên bạn gỡ bỏ các mục nhập này nếu không còn định lại sử dụng LDAP để " +"quyết định tên. Không gỡ bỏ ldap khởi tập tin cấu hình « nsswitch.conf » thì " +"không nên gây ra vấn đề cho phần lớn dịch vụ, nhưng dịch vụ quyết định tên " +"máy có thể bị ảnh hưởng bằng cách tế nhị." + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"Bạn có thể tự sửa đổi tập tin cấu hình « /etc/nsswitch.conf », hoặc chọn tự " +"động gỡ bỏ các mục nhập ngay bây giờ. Xem lại kỹ các thay đổi trong « /etc/" +"nsswitch.conf » nếu bạn chọn gỡ bỏ các mục nhập ngay bây giờ." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "Bật tra tìm bóng qua NSS ?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"Để cho phép người dùng LDAP đăng nhập, mô-đun NSS cần có khả năng thực hiện " +"việc tra tìm mật khẩu bóng. Mục nhập bóng chính nó có thể là trống, đó là " +"không cần hiển thị chuỗi duy nhất của mật khẩu. Xem vấn đề http://bugs." +"debian.org/583492 để đọc về nền của vấn đề này." + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"Hãy chọn nếu « /etc/nsswitch.conf » nên có mục nhập yêu cầu được tự động " +"thêm (trong trường hợp đó nó nên được xem lại về sau), hoặc nếu nên để lại " +"để quản trị xem lại." + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "" +#~ "Nếu cơ sở dữ liệu LDAP yêu cầu đăng nhập để tra cứu một cách tiêu chuẩn, " +#~ "hãy gõ vào đây tên của tài khoản sẽ dùng. Không thì bỏ trống trường này." diff --git a/debian/po/zh_CN.po b/debian/po/zh_CN.po new file mode 100644 index 0000000..291d6c8 --- /dev/null +++ b/debian/po/zh_CN.po @@ -0,0 +1,450 @@ +# Translation of nss-pam-ldapd debconf templates to Simplified Chinese. +# +msgid "" +msgstr "" +"Project-Id-Version: nss-pam-ldapd 0.7.9\n" +"Report-Msgid-Bugs-To: nss-pam-ldapd@packages.debian.org\n" +"POT-Creation-Date: 2011-08-09 11:04+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: zym \n" +"Language-Team: \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Chinese\n" +"X-Poedit-Country: CHINA\n" +"X-Poedit-SourceCharset: utf-8\n" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "LDAP server URI:" +msgstr "LDAP 服务器URI地址:" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"Please enter the Uniform Resource Identifier of the LDAP server. The format " +"is \"ldap://:/\". Alternatively, \"ldaps://\" " +"or \"ldapi://\" can be used. The port number is optional." +msgstr "" +"请输入LDAP服务器的统一资源标识符(URI),格式为 'ldap://<服务器名或IP地址>:<" +"端口>/ ',也可以用'ldaps://'或'ldapi://',端口号可选。" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "" +"When using an ldap or ldaps scheme it is recommended to use an IP address to " +"avoid failures when domain name services are unavailable." +msgstr "使用ldap或ldaps模式时,推荐使用IP地址以防止域名无法解析造成失效。" + +#. Type: string +#. Description +#: ../nslcd.templates:1001 +msgid "Multiple URIs can be specified by separating them with spaces." +msgstr "可以加入多个URI地址,用空格分开。" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "LDAP server search base:" +msgstr "LDAP服务器搜索起点:" + +#. Type: string +#. Description +#: ../nslcd.templates:2001 +msgid "" +"Please enter the distinguished name of the LDAP search base. Many sites use " +"the components of their domain names for this purpose. For example, the " +"domain \"example.net\" would use \"dc=example,dc=net\" as the distinguished " +"name of the search base." +msgstr "" +"请输入LDAP搜索起点DN。多数网站使用域名作,如域名\"example.net\"会使用" +"\"dc=example,dc=net\"作为搜索的起点DN。" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "none" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "simple" +msgstr "" + +#. Type: select +#. Choices +#: ../nslcd.templates:3001 +msgid "SASL" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "LDAP authentication to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +"Please choose what type of authentication the LDAP database should require " +"(if any):" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:3002 +msgid "" +" * none: no authentication;\n" +" * simple: simple bind DN and password authentication;\n" +" * SASL: any Simple Authentication and Security Layer mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +msgid "LDAP database user:" +msgstr "LDAP数据库用户名:" + +#. Type: string +#. Description +#: ../nslcd.templates:4001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"Enter the name of the account that will be used to log in to the LDAP " +"database. This value should be specified as a DN (distinguished name)." +msgstr "这个值应该设置为一个DN (distinguished name)。" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "LDAP user password:" +msgstr "LDAP用户密码:" + +#. Type: password +#. Description +#: ../nslcd.templates:5001 +msgid "Enter the password that will be used to log in to the LDAP database." +msgstr "输入登录LDAP数据库的的密码:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "SASL mechanism to use:" +msgstr "" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Choose the SASL mechanism that will be used to authenticate to the LDAP " +"database:" +msgstr "输入登录LDAP数据库的的密码:" + +#. Type: select +#. Description +#: ../nslcd.templates:6001 +msgid "" +" * auto: auto-negotiation;\n" +" * LOGIN: deprecated in favor of PLAIN;\n" +" * PLAIN: simple cleartext password mechanism;\n" +" * NTLM: NT LAN Manager authentication mechanism;\n" +" * CRAM-MD5: challenge-response scheme based on HMAC-MD5;\n" +" * DIGEST-MD5: HTTP Digest compatible challenge-response scheme;\n" +" * GSSAPI: used for Kerberos;\n" +" * OTP: a One Time Password mechanism." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "SASL realm:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL realm that will be used to authenticate to the LDAP database." +msgstr "输入登录LDAP数据库的的密码:" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "The realm is appended to authentication and authorization identities." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:7001 +msgid "" +"For GSSAPI this can be left blank to use information from the Kerberos " +"credential cache." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "SASL authentication identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the SASL authentication identity that will be used to authenticate to " +"the LDAP database." +msgstr "输入登录LDAP数据库的的密码:" + +#. Type: string +#. Description +#: ../nslcd.templates:8001 +msgid "" +"This is the login used in LOGIN, PLAIN, CRAM-MD5, and DIGEST-MD5 mechanisms." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +msgid "SASL proxy authorization identity:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "Enter the password that will be used to log in to the LDAP database." +msgid "" +"Enter the proxy authorization identity that will be used to authenticate to " +"the LDAP database." +msgstr "输入登录LDAP数据库的的密码:" + +#. Type: string +#. Description +#: ../nslcd.templates:9001 +#, fuzzy +#| msgid "This value should be specified as a DN (distinguished name)." +msgid "" +"This is the object in the name of which the LDAP request is done. This value " +"should be specified as a DN (distinguished name)." +msgstr "这个值应该设置为一个DN (distinguished name)。" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "Cyrus SASL security properties:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:10001 +msgid "" +"Enter the Cyrus SASL security properties. Allowed values are described in " +"the ldap.conf(5) manual page in the SASL OPTIONS section." +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Kerberos credential cache file path:" +msgstr "" + +#. Type: string +#. Description +#: ../nslcd.templates:11001 +msgid "Enter the GSSAPI/Kerberos credential cache file name that will be used." +msgstr "" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "Use StartTLS?" +msgstr "使用 StartTLS?" + +#. Type: boolean +#. Description +#: ../nslcd.templates:12001 +msgid "" +"Please choose whether the connection to the LDAP server should use StartTLS " +"to encrypt the connection." +msgstr "请选择是否使用StartTLS来加密到LDAP服务器的连接。" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "never" +msgstr "从不" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "allow" +msgstr "允许" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "try" +msgstr "尝试" + +#. Type: select +#. Choices +#: ../nslcd.templates:13001 +msgid "demand" +msgstr "必须" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "Check server's SSL certificate:" +msgstr "检查服务器端的SSL证书:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"When an encrypted connection is used, a server certificate can be requested " +"and checked. Please choose whether lookups should be configured to require a " +"certificate, and whether certificates should be checked for validity:" +msgstr "" +"使用加密连接的时候,可以要求检查服务器端的证书。请选择设置是否需要服务器证" +"书,是否需要验证证书的有效性:" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +" * never: no certificate will be requested or checked;\n" +" * allow: a certificate will be requested, but it is not\n" +" required or checked;\n" +" * try: a certificate will be requested and checked, but if no\n" +" certificate is provided it is ignored;\n" +" * demand: a certificate will be requested, required, and checked." +msgstr "" +" * never: 不检查证书\n" +" * allow: 会请求服务器证书,但是不检查证书是否存在和有效。\n" +" * try: 会请求服务器证书,如服务器提供证书则验证,如无则忽略。\n" +" * demand: 会请求服务器证书,必须有证书并验证证书。" + +#. Type: select +#. Description +#: ../nslcd.templates:13002 +msgid "" +"If certificate checking is enabled, at least one of the tls_cacertdir or " +"tls_cacertfile options must be put in /etc/nslcd.conf." +msgstr "" +"如果启用证书检查,/etc/nslcd.conf必须有tls_cacertdir或者tls_cacertfile选项。" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "Name services to configure:" +msgstr "配置名称服务:" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"For this package to work, you need to modify your /etc/nsswitch.conf to use " +"the ldap datasource." +msgstr "启用需要修改 /etc/nsswitch.conf 来使用ldap数据源。" + +#. Type: multiselect +#. Description +#: ../libnss-ldapd.templates:1001 +msgid "" +"You can select the services that should have LDAP lookups enabled. The new " +"LDAP lookups will be added as the last datasource. Be sure to review these " +"changes." +msgstr "" +"请选择您需要启用或者停用LDAP名称服务。新的LDAP源将会追加在其他源后面。请务必" +"检查验证。" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "Remove LDAP from nsswitch.conf now?" +msgstr "从nsswitch.conf中停用LDAP模式?" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"The following services are still configured to use LDAP for lookups:\n" +" ${services}\n" +"but the libnss-ldapd package is about to be removed." +msgstr "" +"下列服务仍然设置为使用LDAP模式:\n" +" ${services}\n" +"但libnss-ldapd会被删除。" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You are advised to remove the entries if you don't plan on using LDAP for " +"name resolution any more. Not removing ldap from nsswitch.conf should, for " +"most services, not cause problems, but host name resolution could be " +"affected in subtle ways." +msgstr "" +"如您不想再使用LDAP进行名称解析,推荐您删除LDAP相关条目。如不从nsswitch.conf删" +"除ldap多数服务不会有问题,但是会对名称解析产生一些细微的影响。" + +#. Type: boolean +#. Description +#: ../libnss-ldapd.templates:2001 +msgid "" +"You can edit /etc/nsswitch.conf by hand or choose to remove the entries " +"automatically now. Be sure to review the changes to /etc/nsswitch.conf if " +"you choose to remove the entries now." +msgstr "" +"您现在可以手工修改/etc/nsswitch.conf或者勾选来删除LDAP功能。如果您删除了条" +"目,请确保检查/etc/nsswitch.conf文件。" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "Enable shadow lookups through NSS?" +msgstr "启用通过NSS查询shadow信息?" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"To allow LDAP users to log in, the NSS module needs to be enabled to perform " +"shadow password lookups. The shadow entries themselves may be empty - that " +"is, there is no need for password hashes to be exposed. See http://bugs." +"debian.org/583492 for background." +msgstr "" +"为了允许LDAP用户登录,NSS模块需要启用shadow密码信息查询功能。就shadow密码本身" +"而言,其可以是空的:即不会暴露shadow中的密码哈希串。请参考http://bugs.debian." +"org/583492。" + +#. Type: boolean +#. Description +#: ../libpam-ldapd.templates:1001 +msgid "" +"Please choose whether /etc/nsswitch.conf should have the required entry " +"added automatically (in which case it should be reviewed afterwards) or " +"whether it should be left for an administrator to edit manually." +msgstr "" +"请选择/etc/nsswitch.conf是自动添加必需的条目(后续应当进行审核)还是留给管理" +"员手工修改。" + +#~ msgid "" +#~ "If the LDAP database requires a login for normal lookups, enter the name " +#~ "of the account that will be used here. Leave it empty otherwise." +#~ msgstr "如LDAP数据库在查询时需要登录,请输入登录帐号,否则请空着。" diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..972a4bc --- /dev/null +++ b/debian/rules @@ -0,0 +1,20 @@ +#!/usr/bin/make -f + +export DH_VERBOSE=1 + +# multiarch support +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) + +%: + dh $@ + +# pass extra flags to configure +override_dh_auto_configure: + dh_auto_configure -- \ + --libdir=/lib/$(DEB_HOST_MULTIARCH) \ + --with-pam-seclib-dir=/lib/$(DEB_HOST_MULTIARCH)/security \ + --enable-warnings + +# run the tests but ignore the results +override_dh_auto_test: + -dh_auto_test diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides new file mode 100644 index 0000000..5389f68 --- /dev/null +++ b/debian/source/lintian-overrides @@ -0,0 +1,3 @@ +# we are building with multiarch support which requires a compatibility level +# that is still open for development +source: package-needs-versioned-debhelper-build-depends 9 diff --git a/depcomp b/depcomp new file mode 100644 index 0000000..df8eea7 --- /dev/null +++ b/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 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, see . + +# 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. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..6781b98 --- /dev/null +++ b/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# 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. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # 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 $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 new file mode 100644 index 0000000..a6bf596 --- /dev/null +++ b/m4/ax_pthread.m4 @@ -0,0 +1,302 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# 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 3 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, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 16 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) + AC_MSG_RESULT($ax_pthread_ok) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + *-darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($ax_pthread_ok) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + ax_cv_PTHREAD_PRIO_INHERIT, [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..144167c --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,48 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2007, 2009, 2010 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +dist_man_MANS = nslcd.conf.5 nslcd.8 + +EXTRA_DIST = nslcd.conf.5.xml nslcd.8.xml pam_ldap.8.xml + +# ensure that the pam_ldap manpage is always built but only installed +# if the PAM module is built +if ENABLE_PAM +dist_man_MANS += pam_ldap.8 +else +EXTRA_DIST += pam_ldap.8 +noinst_DATA = pam_ldap.8 +endif + +if GENMAN + +MAINTAINERCLEANFILES = $(dist_man_MANS) + +SUFFIXES = .xml +.xml: + $(DOCBOOK2X_MAN) \ + --string-param header-3='$(RELEASE_MONTH)' \ + --string-param header-4='Version $(VERSION)' \ + --encoding=utf-8 \ + $< + +.xml.html: + xmlto xhtml-nochunks $< + +endif diff --git a/man/nslcd.8.xml b/man/nslcd.8.xml new file mode 100644 index 0000000..3f9d96e --- /dev/null +++ b/man/nslcd.8.xml @@ -0,0 +1,145 @@ + + + + + + + + + + Arthur + de Jong + + + + + nslcd + 8 + Version 0.8.4 + System Manager's Manual + Sep 2011 + + + + nslcd + local LDAP name service daemon. + + + + + nslcd + + options + + + + + + Description + + nslcd is a daemon that will do LDAP queries for local + processes that want to do user, group and other naming lookups (NSS) or do + user authentication, authorisation or password modification (PAM). + + + nslcd is configured through a configuration file + (see nslcd.conf5). + + + See the included README for information on configuring the LDAP server. + + + + + Options + + nslcd accepts the following options: + + + + + + + + Check if the daemon is running. + This causes nslcd to return 0 if the daemon is already running and 1 if it is not. + + + + + + + + + + Enable debugging mode. + nslcd will not put itself in the background and sends + verbose debugging info to stderr. + nslcd will handle connections as usual. + This option is for debugging purposes only. + Specify this option multiple times to also include more detailed logging + from the LDAP library. + + + + + + + + + Display short help and exit. + + + + + + + + Output version information and exit. + + + + + + + Files + + /etc/nslcd.conf - the configuration file + (see nslcd.conf5) + + + + + See Also + + nslcd.conf5 + + + + + Author + This manual was written by Arthur de Jong <arthur@arthurdejong.org>. + + + diff --git a/man/nslcd.conf.5.xml b/man/nslcd.conf.5.xml new file mode 100644 index 0000000..97d22f7 --- /dev/null +++ b/man/nslcd.conf.5.xml @@ -0,0 +1,907 @@ + + + + + + + + + + Arthur + de Jong + + + + + nslcd.conf + 5 + Version 0.8.4 + System Manager's Manual + Sep 2011 + + + + nslcd.conf + configuration file for LDAP nameservice daemon + + + + Description + + The nss-pam-ldapd package allows LDAP + directory servers to be used as a primary source of name service + information. (Name service information typically includes users, hosts, + groups, and other such data historically stored in flat files or + NIS.) + + + The file nslcd.conf contains the + configuration information for running nslcd (see + nslcd8). + The file contains options, one on each line, defining the way + NSS lookups and PAM actions + are mapped to LDAP lookups. + + + + + Options + + + Runtime options + + + + NUM + + + Specifies the number of threads to start that can handle requests + and perform LDAP queries. + The default is to start 5 threads. + + + + + + UID + + + This specifies the user id with which the daemon should be run. + This can be a numerical id or a symbolic value. + If no uid is specified no attempt to change the user will be made. + Note that you should use values that don't need LDAP + to resolve. + + + + + + GID + + + This specifies the group id with which the daemon should be run. + This can be a numerical id or a symbolic value. + If no gid is specified no attempt to change the group will be made. + Note that you should use values that don't need LDAP + to resolve. + + + + + + + + + General connection options + + + + URI + + + Specifies the LDAP URI of the + server to connect to. + The URI scheme may be ldap, + ldapi or ldaps, specifying + LDAP over TCP, + ICP or SSL respectively (if + supported by the LDAP library). + + + Alternatively, the value DNS may be + used to try to lookup the server using DNS + SRV records. + By default the current domain is used but another domain can + be queried by using the + DNS:DOMAIN syntax. + + + When using the ldapi scheme, %2f should be used to escape slashes + (e.g. ldapi://%2fvar%2frun%2fslapd%2fldapi/), although most of the + time this should not be needed. + + + This option may be specified multiple times. Normally, only the first + server will be used with the following servers as fall-back (see + below). + + + If LDAP lookups are used for host name resolution, + any host names should be specified as an IP address or name that can be + resolved without using LDAP. + + + + + + VERSION + + + Specifies the version of the LDAP protocol to use. + The default is to use the maximum version supported by the + LDAP library. + + + + + DN + + + Specifies the distinguished name with which to bind to the directory + server for lookups. + The default is to bind anonymously. + + + + + + PASSWORD + + + Specifies the credentials with which to bind. + This option is only applicable when used with above. + If you set this option you should consider changing the permissions + of the nslcd.conf file to only grant access to + the root user. + + + + + + + DN + + + Specifies the distinguished name to use when the root user tries to + modify a user's password using the PAM module. + + + + + + PASSWORD + + + Specifies the credentials with which to bind if the root + user tries to change a user's password. + This option is only applicable when used with + above. + If this option is not specified the PAM module prompts the user for + this password. + If you set this option you should consider changing the permissions + of the nslcd.conf file to only grant access to + the root user. + + + + + + + + + <acronym>SASL</acronym> authentication options + + + + MECHANISM + + + Specifies the SASL mechanism to be used when + performing SASL authentication. + + + + + + REALM + + + Specifies the SASL realm to be used when performing + SASL authentication. + + + + + + AUTHCID + + + Specifies the authentication identity to be used when performing + SASL authentication. + + + + + + AUTHZID + + + Specifies the authorization identity to be used when performing + SASL authentication. + Must be specified in one of the formats: dn:<distinguished name> + or u:<username>. + + + + + + PROPERTIES + + + Specifies Cyrus SASL security properties. + Allowed values are described in the + ldap.conf5 + manual page. + + + + + + + + + Kerberos authentication options + + + + NAME + + + Set the name for the GSS-API Kerberos credentials cache. + + + + + + + + + Search/mapping options + + + + + MAP + DN + + + Specifies the base distinguished name (DN) + to use as search base. + This option may be supplied multiple times and all specified bases + will be searched. + + + A global search base may be specified or a MAP-specific one. + If no MAP-specific search bases are defined the global ones are used. + + + If, instead of a DN, the value + DOMAIN is specified, the host's + DNS domain is used to construct a search base. + + + If this value is not defined an attempt is made to look it up + in the configured LDAP server. Note that if the + LDAP server is unavailable during start-up + nslcd will not start. + + + + + + + MAP + subtree|onelevel|base + + + Specifies the search scope (subtree, one level or base object). + The default scope is subtree; base scope is almost never useful for + name service lookups. + + + + + + never|searching|finding|always + + + Specifies the policy for dereferencing aliases. + The default policy is to never dereference aliases. + + + + + + yes|no + + + Specifies whether automatic referral chasing should be enabled. + The default behaviour is to chase referrals. + + + + + + + MAP + FILTER + + + The FILTER + is an LDAP search filter to use for a + specific map. + The default filter is a basic search on the + objectClass for the map (e.g. (objectClass=posixAccount)). + + + + + + + MAP + ATTRIBUTE + NEWATTRIBUTE + + + This option allows for custom attributes to be looked up instead of + the default RFC 2307 attributes. + The MAP may be one of + the supported maps below. + The ATTRIBUTE is the one as + used in RFC 2307 (e.g. userPassword, + ipProtocolNumber, macAddress, etc.). + The NEWATTRIBUTE may be any attribute + as it is available in the directory. + + + If the NEWATTRIBUTE is presented in + quotes (") it is treated as an expression which will be evaluated + to build up the actual value used. + See the section on attribute mapping expressions below for more details. + + + Only some attributes for group, passwd and shadow entries may be mapped + with an expression (because other attributes may be used in search + filters). + For group entries only the userPassword attribute + may be mapped with an expression. + For passwd entries the following attributes may be mapped with an + expression: userPassword, gidNumber, + gecos, homeDirectory and + loginShell. + For shadow entries the following attributes may be mapped with an + expression: userPassword, shadowLastChange, + shadowMin, shadowMax, + shadowWarning, shadowInactive, + shadowExpire and shadowFlag. + + + The uidNumber and gidNumber + attributes in the passwd and group + maps may be mapped to the objectSid followed by + the domain SID to derive numeric user and group ids from the SID + (e.g. objectSid:S-1-5-21-3623811015-3361044348-30300820). + + + By default all userPassword attributes are mapped + to the unmatchable password ("*") to avoid accidentally leaking + password information. + + + + + + + + + Timing/reconnect options + + + + SECONDS + + + Specifies the time limit (in seconds) to use when connecting to the + directory server. + This is distinct from the time limit specified in + and affects the set-up of the connection only. + Note that not all LDAP client libraries have support + for setting the connection time out. + The default is 10 seconds. + + + + + + SECONDS + + + Specifies the time limit (in seconds) to wait for a response from the + LDAP server. + A value of zero (0), which is the default, is to wait indefinitely for + searches to be completed. + + + + + + SECONDS + + + Specifies the period if inactivity (in seconds) after which the + connection to the LDAP server will be closed. + The default is not to time out connections. + + + + + + SECONDS + + + Specifies the number of seconds to sleep when connecting to all + LDAP servers fails. + By default 1 second is waited between the first failure and the first + retry. + + + + + + SECONDS + + + Specifies the time after which the LDAP server is + considered to be permanently unavailable. + Once this time is reached retries will be done only once per this time period. + The default value is 10 seconds. + + + + + + + + Note that the reconnect logic as described above is the mechanism that + is used between nslcd and the LDAP + server. The mechanism between the NSS and + PAM client libraries on one end and + nslcd on the other is simpler with a fixed compiled-in + time out of a 10 seconds for writing to nslcd and + a time out of 60 seconds for reading answers. + nslcd itself has a read time out of 0.5 seconds + and a write time out of 60 seconds. + + + + + + <acronym>SSL</acronym>/<acronym>TLS</acronym> options + + + + on|off|start_tls + + + Specifies whether to use SSL/TLS or not (the default is not to). If + start_tls + is specified then StartTLS is used rather than raw LDAP over SSL. + Not all LDAP client libraries support both SSL, + StartTLS and all related configuration options. + + + + + + never|allow|try|demand|hard + + + Specifies what checks to perform on a server-supplied certificate. + The meaning of the values is described in the + ldap.conf5 + manual page. + At least one of and + is required if peer verification is + enabled. + + + + + + PATH + + + Specifies the directory containing X.509 certificates for peer + authentication. + This parameter is ignored when using GnuTLS. + On Debian OpenLDAP is linked against GnuTLS. + + + + + + PATH + + + Specifies the path to the X.509 certificate for peer authentication. + + + + + + PATH + + + Specifies the path to an entropy source. + This parameter is ignored when using GnuTLS. + On Debian OpenLDAP is linked against GnuTLS. + + + + + + CIPHERS + + + Specifies the ciphers to use for TLS. + See your TLS implementation's + documentation for further information. + + + + + + PATH + + + Specifies the path to the file containing the local certificate for + client TLS authentication. + + + + + + PATH + + + Specifies the path to the file containing the private key for client + TLS authentication. + + + + + + + + + Other options + + + + + + NUMBER + + + Set this to a number greater than 0 to request paged results from + the LDAP server in accordance with RFC2696. + The default (0) is to not request paged results. + + + This is useful for LDAP servers that contain a + lot of entries (e.g. more than 500) and limit the number of entries + that are returned with one request. + For OpenLDAP servers you may need to set + + for allowing more entries to be returned over multiple pages. + + + + + + user1,user2,... + + + This option prevents group membership lookups through + LDAP for the specified users. This can be useful + in case of unavailability of the LDAP server. + This option may be specified multiple times. + + + Alternatively, the value ALLLOCAL may be + used. With that value nslcd builds a full list of + non-LDAP users on startup. + + + + + + UID + + + This option ensures that LDAP users with a numeric + user id lower than the specified value are ignored. Also requests for + users with a lower user id are ignored. + + + + + + REGEX + + + This option can be used to specify how user and group names are + verified within the system. This pattern is used to check all user and + group names that are requested and returned from LDAP. + + + The regular expression should be specified as a POSIX extended regular + expression. The expression itself needs to be separated by slash (/) + characters and the 'i' flag may be appended at the end to indicate + that the match should be case-insensetive. + The default value is + /^[a-z0-9._@$][a-z0-9._@$ \\~-]*[a-z0-9._@$~-]$/i + + + + + + + FILTER + + + This option allows flexible fine tuning of the authorisation check that + should be performed. The search filter specified is executed and + if any entries match, access is granted, otherwise access is denied. + + + The search filter can contain the following variable references: + $username, $service, + $ruser, $rhost, + $tty, $hostname, + $fqdn, + $dn, and $uid. + These references are substituted in the search filter using the + same syntax as described in the section on attribute mapping + expressions below. + + + For example, to check that the user has a proper authorizedService + value if the attribute is present (this almost emulates the + option in PADL's pam_ldap): + (&(objectClass=posixAccount)(uid=$username)(|(authorizedService=$service)(!(authorizedService=*)))) + + + The option can be emulated with: + (&(objectClass=posixAccount)(uid=$username)(|(host=$hostname)(host=$fqdn)(host=\\*))) + + + The default behaviour is not to do this extra search and always + grant access. + + + + + + + + + + + Supported maps + + The following maps are supported. They are referenced as + MAP in the options above. + + + + aliases + + Mail aliases. + Note that most mail servers do not use the NSS + interface for requesting mail aliases and parse + /etc/aliases on their own. + + + + ethers + Ethernet numbers (mac addresses). + + + group + Posix groups. + + + hosts + Host names. + + + netgroup + Host and user groups used for access control. + + + networks + Network numbers. + + + passwd + Posix users. + + + protocols + Protocol definitions (like in /etc/protocols). + + + rpc + Remote procedure call names and numbers. + + + services + Network service names and numbers. + + + shadow + Shadow user password information. + + + + + + Attribute mapping expressions + + For some attributes a mapping expression may be used to construct the + resulting value. + This is currently only possible for attributes that do + not need to be used in search filters. + The expressions are a subset of the double quoted string expressions in the + Bourne (POSIX) shell. + Instead of variable substitution, attribute lookups are done on the current + entry and the attribute value is substituted. + The following expressions are supported: + + + + ${attr} (or $attr for short) + + will substitute the value of the attribute + + + + ${attr:-word} + + (use default) will substitbute the value of the attribute or, if the + attribute is not set or empty substitute the word + + + + ${attr:+word} + + (use alternative) will substitbute word if attribute is set, otherwise + substitute the empty string + + + + + Quote ("), dollar ($) or + backslash (\) characters should be escaped with a + backslash (\). + + + The nslcd daemon checks the expressions to figure + out which attributes to fetch from LDAP. + Some examples to demonstrate how these expressions may be used in + attribute mapping: + + + + "${shadowFlag:-0}" + + use the shadowFlag attribute, using the + value 0 as default + + + + "${homeDirectory:-/home/$uid}" + + use the uid attribute to build a + homeDirectory value if that attribute is missing + + + + "${isDisabled:+100}" + + if the isDisabled attribute is set, return 100, + otherwise leave value empty + + + + + + + Files + + + /etc/nslcd.conf + the main configuration file + + + /etc/nsswitch.conf + Name Service Switch configuration file + + + + + + See Also + + nslcd8, + nsswitch.conf5 + + + + + Author + This manual was written by Arthur de Jong <arthur@arthurdejong.org> + and is based on the + nss_ldap5 + manual developed by PADL Software Pty Ltd. + + + diff --git a/man/pam_ldap.8.xml b/man/pam_ldap.8.xml new file mode 100644 index 0000000..b1c34ec --- /dev/null +++ b/man/pam_ldap.8.xml @@ -0,0 +1,220 @@ + + + + + + + + + + Arthur + de Jong + + + + + pam_ldap + 8 + Version 0.8.4 + System Manager's Manual + Sep 2011 + + + + pam_ldap + PAM module for LDAP-based authentication + + + + + pam_ldap.so + ... + + + + + Description + + This is a PAM module that uses an + LDAP server to verify user access rights and + credentials. + + + + + Options + + + + + + + + Specifies that the PAM module should use the first + password provided in the authentication stack and not prompt the user + for a password. + + + + + + + + + + Specifies that the PAM module should use the first + password provided in the authentication stack and if that fails prompt + the user for a password. + + + + + + + + + + Specifying this option allows users to log in with a blank password. + Normally logins without a password are denied. + + + + + + + + + + Specifies that the PAM module should return + PAM_IGNORE for users that are not present in the LDAP + directory. + This causes the PAM framework to ignore this module. + + + + + + + + + + Specifies that the PAM module should return + PAM_IGNORE if it cannot contact the LDAP server. + This causes the PAM framework to ignore this module. + + + + + + + + + + Specifies that warning messages should not be propagated to the + PAM application. + + + + + + + + + + This causes the PAM module to use the earlier + provided password when changing the password. The module will not + prompt the user for a new password (it is analogous to + ). + + + + + + + + + + This option causes the PAM module to log debugging + information to + syslog3. + + + + + + + + + + This option causes the PAM module to ignore the user + if the user id is lower than the specified value. This can be used to + bypass LDAP checks for system users + (e.g. by setting it to 1000). + + + + + + + + Module Services Provided + + All services are provided by this module but currently sessions changes + are not implemented in the nslcd daemon. + + + + + Files + + + /etc/pam.conf + the main PAM configuration file + + + /etc/nslcd.conf + + The configuration file for the nslcd daemon + (see nslcd.conf5) + + + + + + + See Also + + pam.conf5, + nslcd8, + nslcd.conf5 + + + + + Author + + This manual was written by Arthur de Jong <arthur@arthurdejong.org>. + + + + diff --git a/missing b/missing new file mode 100755 index 0000000..28055d2 --- /dev/null +++ b/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois 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, see . + +# 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. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -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 + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + 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 + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. 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 $msg. You should only need it if + you modified \`${configure_ac}'. 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 $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. 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_ac}` + 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 $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + 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 + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. 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 test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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 test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + 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 prerequisites 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 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..4191a45 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,162 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2009-04-28.21; # UTC + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' +IFS=" "" $nl" +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + 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 + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr= + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp=$pathcomp/ + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/nslcd.conf b/nslcd.conf new file mode 100644 index 0000000..7b1bcf3 --- /dev/null +++ b/nslcd.conf @@ -0,0 +1,142 @@ +# This is the configuration file for the LDAP nameservice +# switch library's nslcd daemon. It configures the mapping +# between NSS names (see /etc/nsswitch.conf) and LDAP +# information in the directory. +# See the manual page nslcd.conf(5) for more information. + +# The user and group nslcd should run as. +uid nslcd +gid nslcd + +# The uri pointing to the LDAP server to use for name lookups. +# Multiple entries may be specified. The address that is used +# here should be resolvable without using LDAP (obviously). +#uri ldap://127.0.0.1/ +#uri ldaps://127.0.0.1/ +#uri ldapi://%2fvar%2frun%2fldapi_sock/ +# Note: %2f encodes the '/' used as directory separator +uri ldap://127.0.0.1/ + +# The LDAP version to use (defaults to 3 +# if supported by client library) +#ldap_version 3 + +# The distinguished name of the search base. +base dc=example,dc=com + +# The distinguished name to bind to the server with. +# Optional: default is to bind anonymously. +#binddn cn=proxyuser,dc=example,dc=com + +# The credentials to bind with. +# Optional: default is no credentials. +# Note that if you set a bindpw you should check the permissions of this file. +#bindpw secret + +# The distinguished name to perform password modifications by root by. +#rootpwmoddn cn=admin,dc=example,dc=com + +# The default search scope. +#scope sub +#scope one +#scope base + +# Customize certain database lookups. +#base group ou=Groups,dc=example,dc=com +#base passwd ou=People,dc=example,dc=com +#base shadow ou=People,dc=example,dc=com +#scope group onelevel +#scope hosts sub + +# Bind/connect timelimit. +#bind_timelimit 30 + +# Search timelimit. +#timelimit 30 + +# Idle timelimit. nslcd will close connections if the +# server has not been contacted for the number of seconds. +#idle_timelimit 3600 + +# Use StartTLS without verifying the server certificate. +#ssl start_tls +#tls_reqcert never + +# CA certificates for server certificate verification +#tls_cacertdir /etc/ssl/certs +#tls_cacertfile /etc/ssl/ca.cert + +# Seed the PRNG if /dev/urandom is not provided +#tls_randfile /var/run/egd-pool + +# SSL cipher suite +# See man ciphers for syntax +#tls_ciphers TLSv1 + +# Client certificate and key +# Use these, if your server requires client authentication. +#tls_cert +#tls_key + +# Mappings for Services for UNIX 3.5 +#filter passwd (objectClass=User) +#map passwd uid msSFU30Name +#map passwd userPassword msSFU30Password +#map passwd homeDirectory msSFU30HomeDirectory +#map passwd homeDirectory msSFUHomeDirectory +#filter shadow (objectClass=User) +#map shadow uid msSFU30Name +#map shadow userPassword msSFU30Password +#filter group (objectClass=Group) +#map group member msSFU30PosixMember + +# Mappings for Services for UNIX 2.0 +#filter passwd (objectClass=User) +#map passwd uid msSFUName +#map passwd userPassword msSFUPassword +#map passwd homeDirectory msSFUHomeDirectory +#map passwd gecos msSFUName +#filter shadow (objectClass=User) +#map shadow uid msSFUName +#map shadow userPassword msSFUPassword +#map shadow shadowLastChange pwdLastSet +#filter group (objectClass=Group) +#map group member posixMember + +# Mappings for Active Directory +#pagesize 1000 +#referrals off +#idle_timelimit 800 +#filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*)) +#map passwd uid sAMAccountName +#map passwd homeDirectory unixHomeDirectory +#map passwd gecos displayName +#filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*)) +#map shadow uid sAMAccountName +#map shadow shadowLastChange pwdLastSet +#filter group (objectClass=group) + +# Alternative mappings for Active Directory +# (replace the SIDs in the objectSid mappings with the value for your domain) +#pagesize 1000 +#referrals off +#idle_timelimit 800 +#filter passwd (&(objectClass=user)(objectClass=person)(!(objectClass=computer))) +#map passwd uid cn +#map passwd uidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820 +#map passwd gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820 +#map passwd homeDirectory "/home/$cn" +#map passwd gecos displayName +#map passwd loginShell "/bin/bash" +#filter group (|(objectClass=group)(objectClass=person)) +#map group gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820 + +# Mappings for AIX SecureWay +#filter passwd (objectClass=aixAccount) +#map passwd uid userName +#map passwd userPassword passwordChar +#map passwd uidNumber uid +#map passwd gidNumber gid +#filter group (objectClass=aixAccessGroup) +#map group cn groupName +#map group gidNumber gid diff --git a/nslcd.h b/nslcd.h new file mode 100644 index 0000000..e87ff04 --- /dev/null +++ b/nslcd.h @@ -0,0 +1,261 @@ +/* + nslcd.h - file describing client/server protocol + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef _NSLCD_H +#define _NSLCD_H 1 + +/* + The protocol used between the nslcd client and server is a simple binary + protocol. It is request/response based where the client initiates a + connection, does a single request and closes the connection again. Any + mangled or not understood messages will be silently ignored by the server. + + A request looks like: + INT32 NSLCD_VERSION + INT32 NSLCD_ACTION_* + [request parameters if any] + A response looks like: + INT32 NSLCD_VERSION + INT32 NSLCD_ACTION_* (the original request type) + [result(s)] + INT32 NSLCD_RESULT_END + A single result entry looks like: + INT32 NSLCD_RESULT_BEGIN + [result value(s)] + If a response would return multiple values (e.g. for NSLCD_ACTION_*_ALL + functions) each return value will be preceded by a NSLCD_RESULT_BEGIN + value. After the last returned result the server sends + NSLCD_RESULT_END. If some error occurs (e.g. LDAP server unavailable, + error in the request, etc) the server terminates the connection to signal + an error condition (breaking the protocol). + + These are the available basic data types: + INT32 - 32-bit integer value + TYPE - a typed field that is transferred using sizeof() + STRING - a string length (32bit) followed by the string value (not + null-terminted) the string itself is assumed to be UTF-8 + STRINGLIST - a 32-bit number noting the number of strings followed by + the strings one at a time + + Furthermore the ADDRESS compound data type is defined as: + INT32 type of address: e.g. AF_INET or AF_INET6 + INT32 lenght of address + RAW the address itself in network byte order + With the ADDRESSLIST using the same construct as with STRINGLIST. + + The protocol uses host-byte order for all types (except in the raw + address above). +*/ + +/* The current version of the protocol. Note that version 1 + is experimental and this version will be used until a + 1.0 release of nss-pam-ldapd is made. */ +#define NSLCD_VERSION 1 + +/* Email alias (/etc/aliases) NSS requests. The result values for a + single entry are: + STRING alias name + STRINGLIST alias rcpts */ +#define NSLCD_ACTION_ALIAS_BYNAME 4001 +#define NSLCD_ACTION_ALIAS_ALL 4002 + +/* Ethernet address/name mapping NSS requests. The result values for a + single entry are: + STRING ether name + TYPE(uint8_t[6]) ether address */ +#define NSLCD_ACTION_ETHER_BYNAME 3001 +#define NSLCD_ACTION_ETHER_BYETHER 3002 +#define NSLCD_ACTION_ETHER_ALL 3005 + +/* Group and group membership related NSS requests. The result values + for a single entry are: + STRING group name + STRING group password + TYPE(gid_t) group id + STRINGLIST members (usernames) of the group + (not that the BYMEMER call returns an emtpy members list) */ +#define NSLCD_ACTION_GROUP_BYNAME 5001 +#define NSLCD_ACTION_GROUP_BYGID 5002 +#define NSLCD_ACTION_GROUP_BYMEMBER 5003 +#define NSLCD_ACTION_GROUP_ALL 5004 + +/* Hostname (/etc/hosts) lookup NSS requests. The result values + for an entry are: + STRING host name + STRINGLIST host aliases + ADDRESSLIST host addresses */ +#define NSLCD_ACTION_HOST_BYNAME 6001 +#define NSLCD_ACTION_HOST_BYADDR 6002 +#define NSLCD_ACTION_HOST_ALL 6005 + +/* Netgroup NSS request return a number of results. Result values + can be either a reference to another netgroup: + INT32 NSLCD_NETGROUP_TYPE_NETGROUP + STRING other netgroup name + or a netgroup triple: + INT32 NSLCD_NETGROUP_TYPE_TRIPLE + STRING host + STRING user + STRING domain */ +#define NSLCD_ACTION_NETGROUP_BYNAME 12001 +#define NSLCD_NETGROUP_TYPE_NETGROUP 123 +#define NSLCD_NETGROUP_TYPE_TRIPLE 456 + +/* Network name (/etc/networks) NSS requests. Result values for a single + entry are: + STRING network name + STRINGLIST network aliases + ADDRESSLIST network addresses */ +#define NSLCD_ACTION_NETWORK_BYNAME 8001 +#define NSLCD_ACTION_NETWORK_BYADDR 8002 +#define NSLCD_ACTION_NETWORK_ALL 8005 + +/* User account (/etc/passwd) NSS requests. Result values are: + STRING user name + STRING user password + TYPE(uid_t) user id + TYPE(gid_t) group id + STRING gecos information + STRING home directory + STRING login shell */ +#define NSLCD_ACTION_PASSWD_BYNAME 1001 +#define NSLCD_ACTION_PASSWD_BYUID 1002 +#define NSLCD_ACTION_PASSWD_ALL 1004 + +/* Protocol information requests. Result values are: + STRING protocol name + STRINGLIST protocol aliases + INT32 protocol number */ +#define NSLCD_ACTION_PROTOCOL_BYNAME 9001 +#define NSLCD_ACTION_PROTOCOL_BYNUMBER 9002 +#define NSLCD_ACTION_PROTOCOL_ALL 9003 + +/* RPC information requests. Result values are: + STRING rpc name + STRINGLIST rpc aliases + INT32 rpc number */ +#define NSLCD_ACTION_RPC_BYNAME 10001 +#define NSLCD_ACTION_RPC_BYNUMBER 10002 +#define NSLCD_ACTION_RPC_ALL 10003 + +/* Service (/etc/services) information requests. Result values are: + STRING service name + STRINGLIST service aliases + INT32 service (port) number + STRING service protocol */ +#define NSLCD_ACTION_SERVICE_BYNAME 11001 +#define NSLCD_ACTION_SERVICE_BYNUMBER 11002 +#define NSLCD_ACTION_SERVICE_ALL 11005 + +/* Extended user account (/etc/shadow) information requests. Result + values for a single entry are: + STRING user name + STRING user password + INT32 last password change + INT32 mindays + INT32 maxdays + INT32 warn + INT32 inact + INT32 expire + INT32 flag */ +#define NSLCD_ACTION_SHADOW_BYNAME 2001 +#define NSLCD_ACTION_SHADOW_ALL 2005 + +/* PAM-related requests. The request parameters for all these requests + begin with: + STRING user name + STRING DN (if value is known already, otherwise empty) + STRING service name + all requests, except the SESSION requests start the result value with: + STRING user name (cannonical name) + STRING DN (can be used to speed up requests) + Some functions may return an authorisation message. This message, if + supplied will be used by the PAM module instead of a message that is + generated by the PAM module itself. */ + +/* PAM authentication check request. The extra request values are: + STRING password + and the result value ends with: + INT32 authc NSLCD_PAM_* result code + INT32 authz NSLCD_PAM_* result code + STRING authorisation error message + If the username is empty in this request an attempt is made to + authenticate as the administrator (set using rootpwmoddn). The returned DN + is that of the administrator. */ +#define NSLCD_ACTION_PAM_AUTHC 20001 + +/* PAM authorisation check request. The extra request values are: + STRING ruser + STRING rhost + STRING tty + and the result value ends with: + INT32 authz NSLCD_PAM_* result code + STRING authorisation error message */ +#define NSLCD_ACTION_PAM_AUTHZ 20002 + +/* PAM session open and close requests. These requests have the following + extra request values: + STRING tty + STRING rhost + STRING ruser + INT32 session id (ignored for SESS_O) + and these calls only return the session ID: + INT32 session id + The SESS_C must contain the ID that is retured by SESS_O to close the + correct session. */ +#define NSLCD_ACTION_PAM_SESS_O 20003 +#define NSLCD_ACTION_PAM_SESS_C 20004 + +/* PAM password modification request. This requests has the following extra + request values: + STRING old password + STRING new password + and returns there extra result values: + INT32 authz NSLCD_PAM_* result code + STRING authorisation error message + In this request the DN may be set to the administrator's DN. In this + case old password should be the administrator's password. This allows + the administrator to change any user's password. */ +#define NSLCD_ACTION_PAM_PWMOD 20005 + +/* Request result codes. */ +#define NSLCD_RESULT_BEGIN 0 +#define NSLCD_RESULT_END 3 + +/* Partial list of PAM result codes. */ +#define NSLCD_PAM_SUCCESS 0 /* everything ok */ +#define NSLCD_PAM_PERM_DENIED 6 /* Permission denied */ +#define NSLCD_PAM_AUTH_ERR 7 /* Authc failure */ +#define NSLCD_PAM_CRED_INSUFFICIENT 8 /* Cannot access authc data */ +#define NSLCD_PAM_AUTHINFO_UNAVAIL 9 /* Cannot retrieve authc info */ +#define NSLCD_PAM_USER_UNKNOWN 10 /* User not known */ +#define NSLCD_PAM_MAXTRIES 11 /* Retry limit reached */ +#define NSLCD_PAM_NEW_AUTHTOK_REQD 12 /* Password expired */ +#define NSLCD_PAM_ACCT_EXPIRED 13 /* Account expired */ +#define NSLCD_PAM_SESSION_ERR 14 /* Cannot make/remove session record */ +#define NSLCD_PAM_AUTHTOK_ERR 20 /* Authentication token manipulation error */ +#define NSLCD_PAM_AUTHTOK_DISABLE_AGING 23 /* Password aging disabled */ +#define NSLCD_PAM_IGNORE 25 /* Ignore module */ +#define NSLCD_PAM_ABORT 26 /* Fatal error */ +#define NSLCD_PAM_AUTHTOK_EXPIRED 27 /* authentication token has expired */ + +#endif /* not _NSLCD_H */ diff --git a/nslcd/Makefile.am b/nslcd/Makefile.am new file mode 100644 index 0000000..7a1d4c7 --- /dev/null +++ b/nslcd/Makefile.am @@ -0,0 +1,38 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2006, 2007 West Consulting +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +sbin_PROGRAMS = nslcd + +AM_CPPFLAGS=-I$(top_srcdir) +AM_CFLAGS = $(PTHREAD_CFLAGS) + +nslcd_SOURCES = nslcd.c ../nslcd.h ../common/nslcd-prot.h \ + ../compat/attrs.h \ + log.c log.h \ + common.c common.h \ + myldap.c myldap.h \ + cfg.c cfg.h \ + attmap.c attmap.h \ + nsswitch.c \ + alias.c ether.c group.c host.c netgroup.c network.c \ + passwd.c protocol.c rpc.c service.c shadow.c pam.c +nslcd_LDADD = ../common/libtio.a ../common/libdict.a \ + ../common/libexpr.a ../compat/libcompat.a \ + @nslcd_LIBS@ @PTHREAD_LIBS@ diff --git a/nslcd/alias.c b/nslcd/alias.c new file mode 100644 index 0000000..f20537c --- /dev/null +++ b/nslcd/alias.c @@ -0,0 +1,140 @@ +/* + alias.c - alias entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-alias.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* Vendor-specific attributes and object classes. + * (Mainly from Sun.) + * ( 1.3.6.1.4.1.42.2.27.1.2.5 NAME 'nisMailAlias' SUP top STRUCTURAL + * DESC 'NIS mail alias' + * MUST cn + * MAY rfc822MailMember ) + */ + +/* the search base for searches */ +const char *alias_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int alias_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *alias_filter = "(objectClass=nisMailAlias)"; + +/* the attributes to request with searches */ +const char *attmap_alias_cn = "cn"; +const char *attmap_alias_rfc822MailMember = "rfc822MailMember"; + +/* the attribute list to request with searches */ +static const char *alias_attrs[3]; + +/* create a search filter for searching an alias by name, + return -1 on errors */ +static int mkfilter_alias_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if (myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + alias_filter, + attmap_alias_cn,safename); +} + +void alias_init(void) +{ + int i; + /* set up search bases */ + if (alias_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (alias_scope==LDAP_SCOPE_DEFAULT) + alias_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + alias_attrs[0]=attmap_alias_cn; + alias_attrs[1]=attmap_alias_rfc822MailMember; + alias_attrs[2]=NULL; +} + +static int write_alias(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqalias) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + const char **names,**members; + int i; + /* get the name of the alias */ + names=myldap_get_values(entry,attmap_alias_cn); + if ((names==NULL)||(names[0]==NULL)) + { + log_log(LOG_WARNING,"alias entry %s does not contain %s value", + myldap_get_dn(entry),attmap_alias_cn); + return 0; + } + /* get the members of the alias */ + members=myldap_get_values(entry,attmap_alias_rfc822MailMember); + /* for each name, write an entry */ + for (i=0;names[i]!=NULL;i++) + { + if ((reqalias==NULL)||(strcasecmp(reqalias,names[i])==0)) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,names[i]); + WRITE_STRINGLIST(fp,members); + } + } + return 0; +} + +NSLCD_HANDLE( + alias,byname, + char name[256]; + char filter[1024]; + READ_STRING(fp,name); + log_setrequest("alias=\"%s\"",name);, + NSLCD_ACTION_ALIAS_BYNAME, + mkfilter_alias_byname(name,filter,sizeof(filter)), + write_alias(fp,entry,name) +) + +NSLCD_HANDLE( + alias,all, + const char *filter; + log_setrequest("alias(all)");, + NSLCD_ACTION_ALIAS_ALL, + (filter=alias_filter,0), + write_alias(fp,entry,NULL) +) diff --git a/nslcd/attmap.c b/nslcd/attmap.c new file mode 100644 index 0000000..d4eb3ba --- /dev/null +++ b/nslcd/attmap.c @@ -0,0 +1,295 @@ +/* + attmap.c - attribute mapping values and functions + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "attmap.h" +#include "log.h" +#include "common/expr.h" + +/* these are the bases that are defined per database */ +extern const char *alias_bases[]; +extern const char *ether_bases[]; +extern const char *group_bases[]; +extern const char *host_bases[]; +extern const char *netgroup_bases[]; +extern const char *network_bases[]; +extern const char *passwd_bases[]; +extern const char *protocol_bases[]; +extern const char *rpc_bases[]; +extern const char *service_bases[]; +extern const char *shadow_bases[]; + +const char **base_get_var(enum ldap_map_selector map) +{ + switch (map) + { + case LM_ALIASES: return alias_bases; + case LM_ETHERS: return ether_bases; + case LM_GROUP: return group_bases; + case LM_HOSTS: return host_bases; + case LM_NETGROUP: return netgroup_bases; + case LM_NETWORKS: return network_bases; + case LM_PASSWD: return passwd_bases; + case LM_PROTOCOLS: return protocol_bases; + case LM_RPC: return rpc_bases; + case LM_SERVICES: return service_bases; + case LM_SHADOW: return shadow_bases; + case LM_NONE: + default: return NULL; + } +} + +/* these are the scopes that are defined per database */ +extern int alias_scope; +extern int ether_scope; +extern int group_scope; +extern int host_scope; +extern int netgroup_scope; +extern int network_scope; +extern int passwd_scope; +extern int protocol_scope; +extern int rpc_scope; +extern int service_scope; +extern int shadow_scope; + +int *scope_get_var(enum ldap_map_selector map) +{ + switch (map) + { + case LM_ALIASES: return &alias_scope; + case LM_ETHERS: return ðer_scope; + case LM_GROUP: return &group_scope; + case LM_HOSTS: return &host_scope; + case LM_NETGROUP: return &netgroup_scope; + case LM_NETWORKS: return &network_scope; + case LM_PASSWD: return &passwd_scope; + case LM_PROTOCOLS: return &protocol_scope; + case LM_RPC: return &rpc_scope; + case LM_SERVICES: return &service_scope; + case LM_SHADOW: return &shadow_scope; + case LM_NONE: + default: return NULL; + } +} + +/* these are the filters that are defined per database */ +extern const char *alias_filter; +extern const char *ether_filter; +extern const char *group_filter; +extern const char *host_filter; +extern const char *netgroup_filter; +extern const char *network_filter; +extern const char *passwd_filter; +extern const char *protocol_filter; +extern const char *rpc_filter; +extern const char *service_filter; +extern const char *shadow_filter; + +const char **filter_get_var(enum ldap_map_selector map) +{ + switch (map) + { + case LM_ALIASES: return &alias_filter; + case LM_ETHERS: return ðer_filter; + case LM_GROUP: return &group_filter; + case LM_HOSTS: return &host_filter; + case LM_NETGROUP: return &netgroup_filter; + case LM_NETWORKS: return &network_filter; + case LM_PASSWD: return &passwd_filter; + case LM_PROTOCOLS: return &protocol_filter; + case LM_RPC: return &rpc_filter; + case LM_SERVICES: return &service_filter; + case LM_SHADOW: return &shadow_filter; + case LM_NONE: + default: return NULL; + } +} + +const char **attmap_get_var(enum ldap_map_selector map,const char *name) +{ + if (map==LM_ALIASES) + { + if (strcasecmp(name,"cn")==0) return &attmap_alias_cn; + if (strcasecmp(name,"rfc822MailMember")==0) return &attmap_alias_rfc822MailMember; + } + else if (map==LM_ETHERS) + { + if (strcasecmp(name,"cn")==0) return &attmap_ether_cn; + if (strcasecmp(name,"macAddress")==0) return &attmap_ether_macAddress; + } + else if (map==LM_GROUP) + { + if (strcasecmp(name,"cn")==0) return &attmap_group_cn; + if (strcasecmp(name,"userPassword")==0) return &attmap_group_userPassword; + if (strcasecmp(name,"gidNumber")==0) return &attmap_group_gidNumber; + if (strcasecmp(name,"memberUid")==0) return &attmap_group_memberUid; + if (strcasecmp(name,"member")==0) return &attmap_group_member; + } + else if (map==LM_HOSTS) + { + if (strcasecmp(name,"cn")==0) return &attmap_host_cn; + if (strcasecmp(name,"ipHostNumber")==0) return &attmap_host_ipHostNumber; + } + else if (map==LM_NETGROUP) + { + if (strcasecmp(name,"cn")==0) return &attmap_netgroup_cn; + if (strcasecmp(name,"nisNetgroupTriple")==0) return &attmap_netgroup_nisNetgroupTriple; + if (strcasecmp(name,"memberNisNetgroup")==0) return &attmap_netgroup_memberNisNetgroup; + } + else if (map==LM_NETWORKS) + { + if (strcasecmp(name,"cn")==0) return &attmap_network_cn; + if (strcasecmp(name,"ipNetworkNumber")==0) return &attmap_network_ipNetworkNumber; + } + else if (map==LM_PASSWD) + { + if (strcasecmp(name,"uid")==0) return &attmap_passwd_uid; + if (strcasecmp(name,"userPassword")==0) return &attmap_passwd_userPassword; + if (strcasecmp(name,"uidNumber")==0) return &attmap_passwd_uidNumber; + if (strcasecmp(name,"gidNumber")==0) return &attmap_passwd_gidNumber; + if (strcasecmp(name,"gecos")==0) return &attmap_passwd_gecos; + if (strcasecmp(name,"homeDirectory")==0) return &attmap_passwd_homeDirectory; + if (strcasecmp(name,"loginShell")==0) return &attmap_passwd_loginShell; + } + else if (map==LM_PROTOCOLS) + { + if (strcasecmp(name,"cn")==0) return &attmap_protocol_cn; + if (strcasecmp(name,"ipProtocolNumber")==0) return &attmap_protocol_ipProtocolNumber; + } + else if (map==LM_RPC) + { + if (strcasecmp(name,"cn")==0) return &attmap_rpc_cn; + if (strcasecmp(name,"oncRpcNumber")==0) return &attmap_rpc_oncRpcNumber; + } + else if (map==LM_SERVICES) + { + if (strcasecmp(name,"cn")==0) return &attmap_service_cn; + if (strcasecmp(name,"ipServicePort")==0) return &attmap_service_ipServicePort; + if (strcasecmp(name,"ipServiceProtocol")==0) return &attmap_service_ipServiceProtocol; + } + else if (map==LM_SHADOW) + { + if (strcasecmp(name,"uid")==0) return &attmap_shadow_uid; + if (strcasecmp(name,"userPassword")==0) return &attmap_shadow_userPassword; + if (strcasecmp(name,"shadowLastChange")==0) return &attmap_shadow_shadowLastChange; + if (strcasecmp(name,"shadowMin")==0) return &attmap_shadow_shadowMin; + if (strcasecmp(name,"shadowMax")==0) return &attmap_shadow_shadowMax; + if (strcasecmp(name,"shadowWarning")==0) return &attmap_shadow_shadowWarning; + if (strcasecmp(name,"shadowInactive")==0) return &attmap_shadow_shadowInactive; + if (strcasecmp(name,"shadowExpire")==0) return &attmap_shadow_shadowExpire; + if (strcasecmp(name,"shadowFlag")==0) return &attmap_shadow_shadowFlag; + } + return NULL; +} + +const char *attmap_set_mapping(const char **var,const char *value) +{ + /* check if we are setting an expression */ + if (value[0]=='"') + { + /* these attributes may contain an expression + (note that this needs to match the functionality in the specific + lookup module) */ + if ( (var!=&attmap_group_userPassword) && + (var!=&attmap_passwd_userPassword) && + (var!=&attmap_passwd_gidNumber) && + (var!=&attmap_passwd_gecos) && + (var!=&attmap_passwd_homeDirectory) && + (var!=&attmap_passwd_loginShell) && + (var!=&attmap_shadow_userPassword) && + (var!=&attmap_shadow_shadowLastChange) && + (var!=&attmap_shadow_shadowMin) && + (var!=&attmap_shadow_shadowMax) && + (var!=&attmap_shadow_shadowWarning) && + (var!=&attmap_shadow_shadowInactive) && + (var!=&attmap_shadow_shadowExpire) && + (var!=&attmap_shadow_shadowFlag) ) + return NULL; + } + /* check if the value will be changed */ + if ( (*var==NULL) || (strcmp(*var,value)!=0) ) + *var=strdup(value); + return *var; +} + +static const char *entry_expand(const char *name,void *expander_attr) +{ + MYLDAP_ENTRY *entry=(MYLDAP_ENTRY *)expander_attr; + const char **values; + if (strcasecmp(name,"dn")==0) + return myldap_get_dn(entry); + values=myldap_get_values(entry,name); + if (values==NULL) + return ""; + /* TODO: handle userPassword attribute specially */ + if ((values[0]!=NULL)&&(values[1]!=NULL)) + { + log_log(LOG_WARNING,"entry %s contains multiple %s values", + myldap_get_dn(entry),name); + } + return values[0]; +} + +const char *attmap_get_value(MYLDAP_ENTRY *entry,const char *attr,char *buffer,size_t buflen) +{ + const char **values; + /* check and clear buffer */ + if ((buffer==NULL)||(buflen<=0)) + return NULL; + buffer[0]='\0'; + /* for simple values just return the attribute */ + if (attr[0]!='"') + { + values=myldap_get_values(entry,attr); + if ((values==NULL)||(values[0]==NULL)) + return NULL; + strncpy(buffer,values[0],buflen); + buffer[buflen-1]='\0'; + return buffer; + /* TODO: maybe warn when multiple values are found */ + } + /* we have an expression, try to parse */ + if ( (attr[strlen(attr)-1]!='"') || + (expr_parse(attr+1,buffer,buflen,entry_expand,(void *)entry)==NULL) ) + { + log_log(LOG_ERR,"attribute mapping %s is invalid",attr); + buffer[0]='\0'; + return NULL; + } + /* strip trailing " */ + if (buffer[strlen(buffer)-1]=='"') + buffer[strlen(buffer)-1]='\0'; + return buffer; +} + +SET *attmap_add_attributes(SET *set,const char *attr) +{ + if (attr[0]!='\"') + set_add(set,attr); + else + expr_vars(attr,set); + return set; +} diff --git a/nslcd/attmap.h b/nslcd/attmap.h new file mode 100644 index 0000000..83d3489 --- /dev/null +++ b/nslcd/attmap.h @@ -0,0 +1,98 @@ +/* + attmap.h - attribute mapping variables + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef NSLCD__ATTMAP_H +#define NSLCD__ATTMAP_H 1 + +#include "cfg.h" +#include "myldap.h" +#include "common/set.h" + +/* these are the attribute names per database */ +extern const char *attmap_alias_cn; +extern const char *attmap_alias_rfc822MailMember; +extern const char *attmap_ether_cn; +extern const char *attmap_ether_macAddress; +extern const char *attmap_group_cn; +extern const char *attmap_group_userPassword; +extern const char *attmap_group_gidNumber; +extern const char *attmap_group_memberUid; +extern const char *attmap_group_member; +extern const char *attmap_host_cn; +extern const char *attmap_host_ipHostNumber; +extern const char *attmap_netgroup_cn; +extern const char *attmap_netgroup_nisNetgroupTriple; +extern const char *attmap_netgroup_memberNisNetgroup; +extern const char *attmap_network_cn; +extern const char *attmap_network_ipNetworkNumber; +extern const char *attmap_passwd_uid; +extern const char *attmap_passwd_userPassword; +extern const char *attmap_passwd_uidNumber; +extern const char *attmap_passwd_gidNumber; +extern const char *attmap_passwd_gecos; +extern const char *attmap_passwd_homeDirectory; +extern const char *attmap_passwd_loginShell; +extern const char *attmap_protocol_cn; +extern const char *attmap_protocol_ipProtocolNumber; +extern const char *attmap_rpc_cn; +extern const char *attmap_rpc_oncRpcNumber; +extern const char *attmap_service_cn; +extern const char *attmap_service_ipServicePort; +extern const char *attmap_service_ipServiceProtocol; +extern const char *attmap_shadow_uid; +extern const char *attmap_shadow_userPassword; +extern const char *attmap_shadow_shadowLastChange; +extern const char *attmap_shadow_shadowMin; +extern const char *attmap_shadow_shadowMax; +extern const char *attmap_shadow_shadowWarning; +extern const char *attmap_shadow_shadowInactive; +extern const char *attmap_shadow_shadowExpire; +extern const char *attmap_shadow_shadowFlag; + +/* return a reference to the map specific base variable */ +const char **base_get_var(enum ldap_map_selector map); + +/* return a reference to the map specific scope variable */ +int *scope_get_var(enum ldap_map_selector map); + +/* return a reference to the map specific filter variable */ +const char **filter_get_var(enum ldap_map_selector map); + +/* return a reference to the attribute mapping variable for the specified name + the name is the name after the attmap_... variables above with the + underscode replaced by a dot (e.g passwd.homeDirectory) */ +const char **attmap_get_var(enum ldap_map_selector map,const char *name); + +/* Set the attribute mapping of the variable to the value specified. + Returns the new value on success. */ +MUST_USE const char *attmap_set_mapping(const char **var,const char *value); + +/* Return a value for the attribute, handling the case where attr + is an expression. On error (e.g. problem parsing expression, attribute + value not found) it returns NULL and the buffer is made empty. */ +const char *attmap_get_value(MYLDAP_ENTRY *entry,const char *attr,char *buffer,size_t buflen); + +/* Add the attributes from attr to the set. The attr argumenent + can either be an attribute or an attribute expression. */ +SET *attmap_add_attributes(SET *set,const char *attr); + +#endif /* not NSLCD__ATTMAP_H */ diff --git a/nslcd/cfg.c b/nslcd/cfg.c new file mode 100644 index 0000000..00dd8c4 --- /dev/null +++ b/nslcd/cfg.c @@ -0,0 +1,1295 @@ +/* + cfg.c - functions for configuration information + This file contains parts that were part of the nss_ldap + library which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2007 West Consulting + Copyright (C) 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_GSSAPI_H +#include +#endif /* HAVE_GSSAPI_H */ +#ifdef HAVE_GSSAPI_GSSAPI_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_H */ +#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */ +#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */ +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "cfg.h" +#include "attmap.h" +#include "common/expr.h" + +struct ldap_config *nslcd_cfg=NULL; + +/* the maximum line length in the configuration file */ +#define MAX_LINE_LENGTH 4096 + +/* the delimiters of tokens */ +#define TOKEN_DELIM " \t\n\r" + +/* convenient wrapper macro for ldap_set_option() */ +#define LDAP_SET_OPTION(ld,option,invalue) \ + rc=ldap_set_option(ld,option,invalue); \ + if (rc!=LDAP_SUCCESS) \ + { \ + log_log(LOG_ERR,"ldap_set_option(" #option ") failed: %s",ldap_err2string(rc)); \ + exit(EXIT_FAILURE); \ + } + +/* prototype for parse_validnames_statement() because it is used in + cfg_defaults() */ +static void parse_validnames_statement(const char *filename,int lnr, + const char *keyword,char *line,struct ldap_config *cfg); + +/* set the configuration information to the defaults */ +static void cfg_defaults(struct ldap_config *cfg) +{ + int i; + memset(cfg,0,sizeof(struct ldap_config)); + cfg->ldc_threads=5; + cfg->ldc_uid=NOUID; + cfg->ldc_gid=NOGID; + for (i=0;i<(NSS_LDAP_CONFIG_URI_MAX+1);i++) + { + cfg->ldc_uris[i].uri=NULL; + cfg->ldc_uris[i].firstfail=0; + cfg->ldc_uris[i].lastfail=0; + } +#ifdef LDAP_VERSION3 + cfg->ldc_version=LDAP_VERSION3; +#else /* LDAP_VERSION3 */ + cfg->ldc_version=LDAP_VERSION2; +#endif /* not LDAP_VERSION3 */ + cfg->ldc_binddn=NULL; + cfg->ldc_bindpw=NULL; + cfg->ldc_rootpwmoddn=NULL; + cfg->ldc_rootpwmodpw=NULL; + cfg->ldc_sasl_mech=NULL; + cfg->ldc_sasl_realm=NULL; + cfg->ldc_sasl_authcid=NULL; + cfg->ldc_sasl_authzid=NULL; + cfg->ldc_sasl_secprops=NULL; + for (i=0;ildc_bases[i]=NULL; + cfg->ldc_scope=LDAP_SCOPE_SUBTREE; + cfg->ldc_deref=LDAP_DEREF_NEVER; + cfg->ldc_referrals=1; + cfg->ldc_bind_timelimit=10; + cfg->ldc_timelimit=LDAP_NO_LIMIT; + cfg->ldc_idle_timelimit=0; + cfg->ldc_reconnect_sleeptime=1; + cfg->ldc_reconnect_retrytime=10; +#ifdef LDAP_OPT_X_TLS + cfg->ldc_ssl_on=SSL_OFF; +#endif /* LDAP_OPT_X_TLS */ + cfg->ldc_restart=1; + cfg->ldc_pagesize=0; + cfg->ldc_nss_initgroups_ignoreusers=NULL; + cfg->ldc_pam_authz_search=NULL; + cfg->ldc_nss_min_uid=0; + parse_validnames_statement(__FILE__,__LINE__,"", + "/^[a-z0-9._@$][a-z0-9._@$ \\~-]*[a-z0-9._@$~-]$/i",cfg); +} + +/* simple strdup wrapper */ +static char *xstrdup(const char *s) +{ + char *tmp; + if (s==NULL) + { + log_log(LOG_CRIT,"xstrdup() called with NULL"); + exit(EXIT_FAILURE); + } + tmp=strdup(s); + if (tmp==NULL) + { + log_log(LOG_CRIT,"strdup() failed to allocate memory"); + exit(EXIT_FAILURE); + } + return tmp; +} + +/* add a single URI to the list of URIs in the configuration */ +static void add_uri(const char *filename,int lnr, + struct ldap_config *cfg,const char *uri) +{ + int i; + log_log(LOG_DEBUG,"add_uri(%s)",uri); + /* find the place where to insert the URI */ + for (i=0;cfg->ldc_uris[i].uri!=NULL;i++) + ; + /* check for room */ + if (i>=NSS_LDAP_CONFIG_URI_MAX) + { + log_log(LOG_ERR,"%s:%d: maximum number of URIs exceeded",filename,lnr); + exit(EXIT_FAILURE); + } + /* append URI to list */ + cfg->ldc_uris[i].uri=xstrdup(uri); +} + +#ifdef HAVE_LDAP_DOMAIN2HOSTLIST +/* return the domain name of the current host + the returned string must be freed by caller */ +static const char *cfg_getdomainname(const char *filename,int lnr) +{ + const char *fqdn,*domain; + fqdn=getfqdn(); + if ((fqdn!=NULL)&&((domain=strchr(fqdn,'.'))!=NULL)&&(domain[1]!='\0')) + return domain+1; + log_log(LOG_ERR,"%s:%d: unable to determinate a domain name", + filename,lnr); + exit(EXIT_FAILURE); +} + +/* add URIs by doing DNS queries for SRV records */ +static void add_uris_from_dns(const char *filename,int lnr, + struct ldap_config *cfg, + const char *domain) +{ + int rc; + char *hostlist=NULL,*nxt; + char buf[HOST_NAME_MAX+sizeof("ldap://")]; + log_log(LOG_DEBUG,"query %s for SRV records",domain); + rc=ldap_domain2hostlist(domain,&hostlist); + /* FIXME: have better error handling */ + if ((hostlist==NULL)||(*hostlist=='\0')) + { + log_log(LOG_ERR,"%s:%d: no servers found in DNS zone %s",filename,lnr,domain); + exit(EXIT_FAILURE); + } + /* hostlist is a space-separated list of host names that we use to build + URIs */ + while(hostlist!=NULL) + { + /* find the next space and split the string there */ + nxt=strchr(hostlist,' '); + if (nxt!=NULL) + { + *nxt='\0'; + nxt++; + } + /* add the URI */ + mysnprintf(buf,sizeof(buf),"ldap://%s",hostlist); + log_log(LOG_DEBUG,"add_uris_from_dns(): found uri: %s",buf); + add_uri(filename,lnr,cfg,buf); + /* get next entry from list */ + hostlist=nxt; + } +} +#endif /* HAVE_LDAP_DOMAIN2HOSTLIST */ + +static int parse_boolean(const char *filename,int lnr,const char *value) +{ + if ( (strcasecmp(value,"on")==0) || + (strcasecmp(value,"yes")==0) || + (strcasecmp(value,"true")==0) || + (strcasecmp(value,"1")==0) ) + return 1; + else if ( (strcasecmp(value,"off")==0) || + (strcasecmp(value,"no")==0) || + (strcasecmp(value,"false")==0) || + (strcasecmp(value,"0")==0) ) + return 0; + else + { + log_log(LOG_ERR,"%s:%d: not a boolean argument: '%s'",filename,lnr,value); + exit(EXIT_FAILURE); + } +} + +static int parse_scope(const char *filename,int lnr,const char *value) +{ + if ( (strcasecmp(value,"sub")==0) || (strcasecmp(value,"subtree")==0) ) + return LDAP_SCOPE_SUBTREE; + else if ( (strcasecmp(value,"one")==0) || (strcasecmp(value,"onelevel")==0) ) + return LDAP_SCOPE_ONELEVEL; + else if (strcasecmp(value,"base")==0) + return LDAP_SCOPE_BASE; + else + { + log_log(LOG_ERR,"%s:%d: not a scope argument: '%s'",filename,lnr,value); + exit(EXIT_FAILURE); + } +} + +/* This function works like strtok() except that the original string is + not modified and a pointer within str to where the next token begins + is returned (this can be used to pass to the function on the next + iteration). If no more tokens are found or the token will not fit in + the buffer, NULL is returned. */ +static char *get_token(char **line,char *buf,size_t buflen) +{ + size_t len; + if ((line==NULL)||(*line==NULL)||(**line=='\0')||(buf==NULL)) + return NULL; + /* find the beginning and length of the token */ + *line+=strspn(*line,TOKEN_DELIM); + len=strcspn(*line,TOKEN_DELIM); + /* check if there is a token */ + if (len==0) + { + *line=NULL; + return NULL; + } + /* limit the token length */ + if (len>=buflen) + len=buflen-1; + /* copy the token */ + strncpy(buf,*line,len); + buf[len]='\0'; + /* skip to the next token */ + *line+=len; + *line+=strspn(*line,TOKEN_DELIM); + /* return the token */ + return buf; +} + +static enum ldap_map_selector parse_map(const char *value) +{ + if ( (strcasecmp(value,"alias")==0) || (strcasecmp(value,"aliases")==0) ) + return LM_ALIASES; + else if ( (strcasecmp(value,"ether")==0) || (strcasecmp(value,"ethers")==0) ) + return LM_ETHERS; + else if (strcasecmp(value,"group")==0) + return LM_GROUP; + else if ( (strcasecmp(value,"host")==0) || (strcasecmp(value,"hosts")==0) ) + return LM_HOSTS; + else if (strcasecmp(value,"netgroup")==0) + return LM_NETGROUP; + else if ( (strcasecmp(value,"network")==0) || (strcasecmp(value,"networks")==0) ) + return LM_NETWORKS; + else if (strcasecmp(value,"passwd")==0) + return LM_PASSWD; + else if ( (strcasecmp(value,"protocol")==0) || (strcasecmp(value,"protocols")==0) ) + return LM_PROTOCOLS; + else if (strcasecmp(value,"rpc")==0) + return LM_RPC; + else if ( (strcasecmp(value,"service")==0) || (strcasecmp(value,"services")==0) ) + return LM_SERVICES; + else if (strcasecmp(value,"shadow")==0) + return LM_SHADOW; + else + return LM_NONE; +} + +/* check to see if the line begins with a named map */ +static enum ldap_map_selector get_map(char **line) +{ + char token[32]; + char *old; + enum ldap_map_selector map; + /* get the token */ + old=*line; + if (get_token(line,token,sizeof(token))==NULL) + return LM_NONE; + /* find the map if any */ + map=parse_map(token); + /* unknown map, return to the previous state */ + if (map==LM_NONE) + *line=old; + return map; +} + +/* check that the condition is true and otherwise log an error + and bail out */ +static inline void check_argumentcount(const char *filename,int lnr, + const char *keyword,int condition) +{ + if (!condition) + { + log_log(LOG_ERR,"%s:%d: %s: wrong number of arguments",filename,lnr,keyword); + exit(EXIT_FAILURE); + } +} + +/* check that the file is not world readable */ +static void check_permissions(const char *filename,const char *keyword) +{ + struct stat sb; + /* get file status */ + if (stat(filename,&sb)) + { + log_log(LOG_ERR,"cannot stat() %s: %s",filename,strerror(errno)); + exit(EXIT_FAILURE); + } + /* check permissions */ + if ((sb.st_mode&0007)!=0) + { + if (keyword!=NULL) + log_log(LOG_ERR,"%s: file should not be world readable if %s is set", + filename, keyword); + else + log_log(LOG_ERR,"%s: file should not be world readable",filename); + exit(EXIT_FAILURE); + } +} + +static void get_int(const char *filename,int lnr, + const char *keyword,char **line, + int *var) +{ + /* TODO: refactor to have less overhead */ + char token[32]; + check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL); + /* TODO: replace with correct numeric parse */ + *var=atoi(token); +} + +static void get_boolean(const char *filename,int lnr, + const char *keyword,char **line, + int *var) +{ + /* TODO: refactor to have less overhead */ + char token[32]; + check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL); + *var=parse_boolean(filename,lnr,token); +} + +static void get_strdup(const char *filename,int lnr, + const char *keyword,char **line, + char **var) +{ + /* TODO: refactor to have less overhead */ + char token[64]; + check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL); + /* Note: we have a memory leak here if a single variable is changed + multiple times in one config (deemed not a problem) */ + *var=xstrdup(token); +} + +static void get_restdup(const char *filename,int lnr, + const char *keyword,char **line, + char **var) +{ + check_argumentcount(filename,lnr,keyword,(*line!=NULL)&&(**line!='\0')); + /* Note: we have a memory leak here if a single mapping is changed + multiple times in one config (deemed not a problem) */ + *var=xstrdup(*line); + /* mark that we are at the end of the line */ + *line=NULL; +} + +static void get_eol(const char *filename,int lnr, + const char *keyword,char **line) +{ + if ((line!=NULL)&&(*line!=NULL)&&(**line!='\0')) + { + log_log(LOG_ERR,"%s:%d: %s: too may arguments",filename,lnr,keyword); + exit(EXIT_FAILURE); + } +} + +static void get_uid(const char *filename,int lnr, + const char *keyword,char **line, + uid_t *var) +{ + /* TODO: refactor to have less overhead */ + char token[32]; + struct passwd *pwent; + char *tmp; + check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL); + /* check if it is a valid numerical uid */ + errno=0; + *var=strtouid(token,&tmp,0); + if ((*token!='\0')&&(*tmp=='\0')&&(errno==0)) + return; + /* find by name */ + pwent=getpwnam(token); + if (pwent!=NULL) + { + *var=pwent->pw_uid; + return; + } + /* log an error */ + log_log(LOG_ERR,"%s:%d: %s: not a valid uid: '%s'",filename,lnr,keyword,token); + exit(EXIT_FAILURE); +} + +static void get_gid(const char *filename,int lnr, + const char *keyword,char **line, + gid_t *var) +{ + /* TODO: refactor to have less overhead */ + char token[32]; + struct group *grent; + char *tmp; + check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL); + /* check if it is a valid numerical gid */ + errno=0; + *var=strtogid(token,&tmp,0); + if ((*token!='\0')&&(*tmp=='\0')&&(errno==0)) + return; + /* find by name */ + grent=getgrnam(token); + if (grent!=NULL) + { + *var=grent->gr_gid; + return; + } + /* log an error */ + log_log(LOG_ERR,"%s:%d: %s: not a valid gid: '%s'",filename,lnr,keyword,token); + exit(EXIT_FAILURE); +} + +#ifdef LDAP_OPT_X_TLS +static void get_reqcert(const char *filename,int lnr, + const char *keyword,char **line, + int *var) +{ + char token[16]; + /* get token */ + check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL); + /* check if it is a valid value for tls_reqcert option */ + if ( (strcasecmp(token,"never")==0) || + (strcasecmp(token,"no")==0) ) + *var=LDAP_OPT_X_TLS_NEVER; + else if (strcasecmp(token,"allow")==0) + *var=LDAP_OPT_X_TLS_ALLOW; + else if (strcasecmp(token,"try")==0) + *var=LDAP_OPT_X_TLS_TRY; + else if ( (strcasecmp(token,"demand")==0) || + (strcasecmp(token,"yes")==0) ) + *var=LDAP_OPT_X_TLS_DEMAND; + else if (strcasecmp(token,"hard")==0) + *var=LDAP_OPT_X_TLS_HARD; + else + { + log_log(LOG_ERR,"%s:%d: %s: invalid argument: '%s'",filename,lnr,keyword,token); + exit(EXIT_FAILURE); + } +} +#endif /* LDAP_OPT_X_TLS */ + +static void parse_krb5_ccname_statement(const char *filename,int lnr, + const char *keyword,char *line) +{ + char token[80]; + const char *ccname; + const char *ccfile; + size_t ccenvlen; + char *ccenv; +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + OM_uint32 minor_status; +# endif /* HAVE_GSS_KRB5_CCACHE_NAME */ + /* get token */ + check_argumentcount(filename,lnr,keyword, + (get_token(&line,token,sizeof(token))!=NULL)&&(*line=='\0')); + /* set default kerberos ticket cache for SASL-GSSAPI */ + ccname=token; + /* check that cache exists and is readable if it is a file */ + if ( (strncasecmp(ccname,"FILE:",sizeof("FILE:")-1)==0) || + (strncasecmp(ccname,"WRFILE:",sizeof("WRFILE:")-1)==0)) + { + ccfile=strchr(ccname,':')+1; + if (access(ccfile,R_OK)!=0) + { + log_log(LOG_ERR,"%s:%d: error accessing %s: %s",filename,lnr,ccfile,strerror(errno)); + exit(EXIT_FAILURE); + } + } + /* set the environment variable (we have a memory leak if this option + is set multiple times) */ + ccenvlen=strlen(ccname)+sizeof("KRB5CCNAME="); + ccenv=(char *)malloc(ccenvlen); + if (ccenv==NULL) + { + log_log(LOG_CRIT,"malloc() failed to allocate memory"); + exit(EXIT_FAILURE); + } + mysnprintf(ccenv,ccenvlen,"KRB5CCNAME=%s",ccname); + putenv(ccenv); +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + /* set the name with gss_krb5_ccache_name() */ + if (gss_krb5_ccache_name(&minor_status,ccname,NULL)!=GSS_S_COMPLETE) + { + log_log(LOG_ERR,"%s:%d: unable to set default credential cache: %s",filename,lnr,ccname); + exit(EXIT_FAILURE); + } +# endif /* HAVE_GSS_KRB5_CCACHE_NAME */ +} + +/* assigns the base to the specified variable doing domain expansion + and a simple check to avoid overwriting duplicate values */ +static void set_base(const char *filename,int lnr, + const char *value,const char **var) +{ +#ifdef HAVE_LDAP_DOMAIN2DN + const char *domain=NULL; + char *domaindn=NULL; +#endif /* HAVE_LDAP_DOMAIN2DN */ + /* if the base is "DOMAIN" use the domain name */ + if (strcasecmp(value,"domain")==0) + { +#ifdef HAVE_LDAP_DOMAIN2DN + domain=cfg_getdomainname(filename,lnr); + ldap_domain2dn(domain,&domaindn); + log_log(LOG_DEBUG,"set_base(): setting base to %s from domain",domaindn); + value=domaindn; +#else /* not HAVE_LDAP_DOMAIN2DN */ + log_log(LOG_ERR,"%s:%d: value %s not supported on platform",filename,lnr,value); + exit(EXIT_FAILURE); +#endif /* not HAVE_LDAP_DOMAIN2DN */ + } + /* set the new value */ + *var=xstrdup(value); +} + +/* parse the validnames statement */ +static void parse_validnames_statement(const char *filename,int lnr, + const char *keyword,char *line,struct ldap_config *cfg) +{ + char *value; + int i,l; + int flags=REG_EXTENDED|REG_NOSUB; + /* the rest of the line should be a regular expression */ + get_restdup(filename,lnr,keyword,&line,&value); + /* check formatting and update flags */ + if (value[0]!='/') + { + log_log(LOG_ERR,"%s:%d: regular expression incorrectly delimited",filename,lnr); + exit(EXIT_FAILURE); + } + l=strlen(value); + if (value[l-1]=='i') + { + value[l-1]='\0'; + l--; + flags|=REG_ICASE; + } + if (value[l-1]!='/') + { + log_log(LOG_ERR,"%s:%d: regular expression incorrectly delimited",filename,lnr); + exit(EXIT_FAILURE); + } + value[l-1]='\0'; + /* compile the regular expression */ + if ((i=regcomp(&cfg->validnames,value+1,flags))!= 0) + { + /* get the error message */ + l=regerror(i,&cfg->validnames,NULL,0); + value=malloc(l); + if (value==NULL) + log_log(LOG_ERR,"%s:%d: invalid regular expression",filename,lnr); + else + { + regerror(i,&cfg->validnames,value,l); + log_log(LOG_ERR,"%s:%d: invalid regular expression: %s",filename,lnr, + value); + } + exit(EXIT_FAILURE); + } +} + +static void parse_base_statement(const char *filename,int lnr, + const char *keyword,char *line, + struct ldap_config *cfg) +{ + const char **bases; + int i; + /* get the list of bases to update */ + bases=base_get_var(get_map(&line)); + if (bases==NULL) + bases=cfg->ldc_bases; + /* find the spot in the list of bases */ + for (i=0;ildc_scope; + check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0')); + *var=parse_scope(filename,lnr,line); +} + +static void parse_filter_statement(const char *filename,int lnr, + const char *keyword,char *line) +{ + const char **var; + const char *map=line; + var=filter_get_var(get_map(&line)); + if (var==NULL) + { + log_log(LOG_ERR,"%s:%d: unknown map: '%s'",filename,lnr,map); + exit(EXIT_FAILURE); + } + check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0')); + /* check if the value will be changed */ + if (strcmp(*var,line)!=0) + { + /* Note: we have a memory leak here if a single mapping is changed + multiple times in one config (deemed not a problem) */ + *var=xstrdup(line); + } +} + +/* this function modifies the statement argument passed */ +static void parse_map_statement(const char *filename,int lnr, + const char *keyword,char *line) +{ + enum ldap_map_selector map; + const char **var; + char oldatt[32], newatt[1024]; + /* get the map */ + if ((map=get_map(&line))==LM_NONE) + { + log_log(LOG_ERR,"%s:%d: unknown map: '%s'",filename,lnr,line); + exit(EXIT_FAILURE); + } + /* read the other tokens */ + check_argumentcount(filename,lnr,keyword, + (get_token(&line,oldatt,sizeof(oldatt))!=NULL)&& + (get_token(&line,newatt,sizeof(newatt))!=NULL)); + /* check that there are no more tokens left on the line */ + get_eol(filename,lnr,keyword,&line); + /* change attribute mapping */ + var=attmap_get_var(map,oldatt); + if (var==NULL) + { + log_log(LOG_ERR,"%s:%d: unknown attribute to map: '%s'",filename,lnr,oldatt); + exit(EXIT_FAILURE); + } + if (attmap_set_mapping(var,newatt)==NULL) + { + log_log(LOG_ERR,"%s:%d: attribute %s cannot be an expression",filename,lnr,oldatt); + exit(EXIT_FAILURE); + } +} + +/* this function modifies the statement argument passed */ +static void parse_nss_initgroups_ignoreusers_statement( + const char *filename,int lnr,const char *keyword, + char *line,struct ldap_config *cfg) +{ + char token[MAX_LINE_LENGTH]; + char *username,*next; + struct passwd *pwent; + check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0')); + if (cfg->ldc_nss_initgroups_ignoreusers==NULL) + cfg->ldc_nss_initgroups_ignoreusers=set_new(); + while (get_token(&line,token,sizeof(token))!=NULL) + { + if (strcasecmp(token,"alllocal")==0) + { + /* go over all users (this will work because nslcd is not yet running) */ + setpwent(); + while ((pwent=getpwent())!=NULL) + set_add(cfg->ldc_nss_initgroups_ignoreusers,pwent->pw_name); + endpwent(); + } + else + { + next=token; + while (*next!='\0') + { + username=next; + /* find the end of the current username */ + while ((*next!='\0')&&(*next!=',')) next++; + if (*next==',') + { + *next='\0'; + next++; + } + /* check if user exists (but add anyway) */ + pwent=getpwnam(username); + if (pwent==NULL) + log_log(LOG_ERR,"%s:%d: user '%s' does not exist",filename,lnr,username); + set_add(cfg->ldc_nss_initgroups_ignoreusers,username); + } + } + } +} + +static void parse_pam_authz_search_statement( + const char *filename,int lnr,const char *keyword, + char *line,struct ldap_config *cfg) +{ + SET *set; + const char **list; + int i; + check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0')); + cfg->ldc_pam_authz_search=xstrdup(line); + /* check the variables used in the expression */ + set=expr_vars(cfg->ldc_pam_authz_search,NULL); + list=set_tolist(set); + for (i=0;list[i]!=NULL;i++) + { + if ((strcmp(list[i],"username")!=0)&& + (strcmp(list[i],"service")!=0)&& + (strcmp(list[i],"ruser")!=0)&& + (strcmp(list[i],"rhost")!=0)&& + (strcmp(list[i],"tty")!=0)&& + (strcmp(list[i],"hostname")!=0)&& + (strcmp(list[i],"fqdn")!=0)&& + (strcmp(list[i],"dn")!=0)&& + (strcmp(list[i],"uid")!=0)) + { + log_log(LOG_ERR,"%s:%d: unknown variable $%s",filename,lnr,list[i]); + exit(EXIT_FAILURE); + } + } + /* free memory */ + set_free(set); + free(list); +} + +static void cfg_read(const char *filename,struct ldap_config *cfg) +{ + FILE *fp; + int lnr=0; + char linebuf[MAX_LINE_LENGTH]; + char *line; + char keyword[32]; + char token[64]; + int i; +#ifdef LDAP_OPT_X_TLS + int rc; + char *value; +#endif + /* open config file */ + if ((fp=fopen(filename,"r"))==NULL) + { + log_log(LOG_ERR,"cannot open config file (%s): %s",filename,strerror(errno)); + exit(EXIT_FAILURE); + } + /* read file and parse lines */ + while (fgets(linebuf,sizeof(linebuf),fp)!=NULL) + { + lnr++; + line=linebuf; + /* strip newline */ + i=(int)strlen(line); + if ((i<=0)||(line[i-1]!='\n')) + { + log_log(LOG_ERR,"%s:%d: line too long or last line missing newline",filename,lnr); + exit(EXIT_FAILURE); + } + line[i-1]='\0'; + /* ignore comment lines */ + if (line[0]=='#') + continue; + /* strip trailing spaces */ + for (i--;(i>0)&&isspace(line[i-1]);i--) + line[i-1]='\0'; + /* get keyword from line and ignore empty lines */ + if (get_token(&line,keyword,sizeof(keyword))==NULL) + continue; + /* runtime options */ + if (strcasecmp(keyword,"threads")==0) + { + get_int(filename,lnr,keyword,&line,&cfg->ldc_threads); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"uid")==0) + { + get_uid(filename,lnr,keyword,&line,&cfg->ldc_uid); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"gid")==0) + { + get_gid(filename,lnr,keyword,&line,&cfg->ldc_gid); + get_eol(filename,lnr,keyword,&line); + } + /* general connection options */ + else if (strcasecmp(keyword,"uri")==0) + { + check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0')); + while (get_token(&line,token,sizeof(token))!=NULL) + { + if (strcasecmp(token,"dns")==0) + { +#ifdef HAVE_LDAP_DOMAIN2HOSTLIST + add_uris_from_dns(filename,lnr,cfg,cfg_getdomainname(filename,lnr)); +#else /* not HAVE_LDAP_DOMAIN2HOSTLIST */ + log_log(LOG_ERR,"%s:%d: value %s not supported on platform",filename,lnr,token); + exit(EXIT_FAILURE); +#endif /* not HAVE_LDAP_DOMAIN2HOSTLIST */ + } + else if (strncasecmp(token,"dns:",4)==0) + { +#ifdef HAVE_LDAP_DOMAIN2HOSTLIST + add_uris_from_dns(filename,lnr,cfg,strdup(token+sizeof("dns"))); +#else /* not HAVE_LDAP_DOMAIN2HOSTLIST */ + log_log(LOG_ERR,"%s:%d: value %s not supported on platform",filename,lnr,token); + exit(EXIT_FAILURE); +#endif /* not HAVE_LDAP_DOMAIN2HOSTLIST */ + } + else + add_uri(filename,lnr,cfg,token); + } + } + else if (strcasecmp(keyword,"ldap_version")==0) + { + get_int(filename,lnr,keyword,&line,&cfg->ldc_version); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"binddn")==0) + { + get_restdup(filename,lnr,keyword,&line,&cfg->ldc_binddn); + } + else if (strcasecmp(keyword,"bindpw")==0) + { + check_permissions(filename,keyword); + get_restdup(filename,lnr,keyword,&line,&cfg->ldc_bindpw); + } + else if (strcasecmp(keyword,"rootpwmoddn")==0) + { + get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootpwmoddn); + } + else if (strcasecmp(keyword,"rootpwmodpw")==0) + { + check_permissions(filename,keyword); + get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootpwmodpw); + } + /* SASL authentication options */ + else if (strcasecmp(keyword,"use_sasl")==0) + { + log_log(LOG_WARNING,"%s:%d: option %s is deprecated (and will be removed in an upcoming release), use sasl_mech instead",filename,lnr,keyword); + } + else if (strcasecmp(keyword,"sasl_mech")==0) + { + get_strdup(filename,lnr,keyword,&line,&cfg->ldc_sasl_mech); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"sasl_realm")==0) + { + get_strdup(filename,lnr,keyword,&line,&cfg->ldc_sasl_realm); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"sasl_authcid")==0) + { + get_strdup(filename,lnr,keyword,&line,&cfg->ldc_sasl_authcid); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"sasl_authzid")==0) + { + get_strdup(filename,lnr,keyword,&line,&cfg->ldc_sasl_authzid); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"sasl_secprops")==0) + { + get_strdup(filename,lnr,keyword,&line,&cfg->ldc_sasl_secprops); + get_eol(filename,lnr,keyword,&line); + } + /* Kerberos authentication options */ + else if (strcasecmp(keyword,"krb5_ccname")==0) + { + parse_krb5_ccname_statement(filename,lnr,keyword,line); + } + /* search/mapping options */ + else if (strcasecmp(keyword,"base")==0) + { + parse_base_statement(filename,lnr,keyword,line,cfg); + } + else if (strcasecmp(keyword,"scope")==0) + { + parse_scope_statement(filename,lnr,keyword,line,cfg); + } + else if (strcasecmp(keyword,"deref")==0) + { + check_argumentcount(filename,lnr,keyword, + (get_token(&line,token,sizeof(token))!=NULL)); + if (strcasecmp(token,"never")==0) + cfg->ldc_deref=LDAP_DEREF_NEVER; + else if (strcasecmp(token,"searching")==0) + cfg->ldc_deref=LDAP_DEREF_SEARCHING; + else if (strcasecmp(token,"finding")==0) + cfg->ldc_deref=LDAP_DEREF_FINDING; + else if (strcasecmp(token,"always")==0) + cfg->ldc_deref=LDAP_DEREF_ALWAYS; + else + { + log_log(LOG_ERR,"%s:%d: wrong argument: '%s'",filename,lnr,token); + exit(EXIT_FAILURE); + } + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"referrals")==0) + { + get_boolean(filename,lnr,keyword,&line,&cfg->ldc_referrals); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"filter")==0) + { + parse_filter_statement(filename,lnr,keyword,line); + } + else if (strcasecmp(keyword,"map")==0) + { + parse_map_statement(filename,lnr,keyword,line); + } + /* timing/reconnect options */ + else if (strcasecmp(keyword,"bind_timelimit")==0) + { + get_int(filename,lnr,keyword,&line,&cfg->ldc_bind_timelimit); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"timelimit")==0) + { + get_int(filename,lnr,keyword,&line,&cfg->ldc_timelimit); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"idle_timelimit")==0) + { + get_int(filename,lnr,keyword,&line,&cfg->ldc_idle_timelimit); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"reconnect_tries")==0) + log_log(LOG_WARNING,"%s:%d: option %s has been removed and will be ignored",filename,lnr,keyword); + else if (!strcasecmp(keyword,"reconnect_sleeptime")) + { + get_int(filename,lnr,keyword,&line,&cfg->ldc_reconnect_sleeptime); + get_eol(filename,lnr,keyword,&line); + } + else if ( (strcasecmp(keyword,"reconnect_retrytime")==0) || + (strcasecmp(keyword,"reconnect_maxsleeptime")==0) ) + { + if (strcasecmp(keyword,"reconnect_maxsleeptime")==0) + log_log(LOG_WARNING,"%s:%d: option %s has been renamed to reconnect_retrytime",filename,lnr,keyword); + get_int(filename,lnr,keyword,&line,&cfg->ldc_reconnect_retrytime); + get_eol(filename,lnr,keyword,&line); + } +#ifdef LDAP_OPT_X_TLS + /* SSL/TLS options */ + else if (strcasecmp(keyword,"ssl")==0) + { + check_argumentcount(filename,lnr,keyword, + (get_token(&line,token,sizeof(token))!=NULL)); + if ( (strcasecmp(token,"start_tls")==0) || + (strcasecmp(token,"starttls")==0) ) + cfg->ldc_ssl_on=SSL_START_TLS; + else if (parse_boolean(filename,lnr,token)) + cfg->ldc_ssl_on=SSL_LDAPS; + get_eol(filename,lnr,keyword,&line); + } + else if ( (strcasecmp(keyword,"tls_reqcert")==0) || + (strcasecmp(keyword,"tls_checkpeer")==0) ) + { + if (strcasecmp(keyword,"tls_checkpeer")==0) + log_log(LOG_WARNING,"%s:%d: option %s is deprecated (and will be removed in an upcoming release), use tls_reqcert instead",filename,lnr,keyword); + get_reqcert(filename,lnr,keyword,&line,&i); + get_eol(filename,lnr,keyword,&line); + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT,%d)",i); + LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,&i); + } + else if (strcasecmp(keyword,"tls_cacertdir")==0) + { + get_strdup(filename,lnr,keyword,&line,&value); + get_eol(filename,lnr,keyword,&line); + /* TODO: check that the path is valid */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS_CACERTDIR,\"%s\")",value); + LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_CACERTDIR,value); + free(value); + } + else if ( (strcasecmp(keyword,"tls_cacertfile")==0) || + (strcasecmp(keyword,"tls_cacert")==0) ) + { + get_strdup(filename,lnr,keyword,&line,&value); + get_eol(filename,lnr,keyword,&line); + /* TODO: check that the path is valid */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE,\"%s\")",value); + LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_CACERTFILE,value); + free(value); + } + else if (strcasecmp(keyword,"tls_randfile")==0) + { + get_strdup(filename,lnr,keyword,&line,&value); + get_eol(filename,lnr,keyword,&line); + /* TODO: check that the path is valid */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS_RANDOM_FILE,\"%s\")",value); + LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_RANDOM_FILE,value); + free(value); + } + else if (strcasecmp(keyword,"tls_ciphers")==0) + { + get_restdup(filename,lnr,keyword,&line,&value); + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS_CIPHER_SUITE,\"%s\")",value); + LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_CIPHER_SUITE,value); + free(value); + } + else if (strcasecmp(keyword,"tls_cert")==0) + { + get_strdup(filename,lnr,keyword,&line,&value); + get_eol(filename,lnr,keyword,&line); + /* TODO: check that the path is valid */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS_CERTFILE,\"%s\")",value); + LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_CERTFILE,value); + free(value); + } + else if (strcasecmp(keyword,"tls_key")==0) + { + get_strdup(filename,lnr,keyword,&line,&value); + get_eol(filename,lnr,keyword,&line); + /* TODO: check that the path is valid */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS_KEYFILE,\"%s\")",value); + LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_KEYFILE,value); + free(value); + } +#endif /* LDAP_OPT_X_TLS */ + /* other options */ + else if (strcasecmp(keyword,"restart")==0) + { + log_log(LOG_WARNING,"%s:%d: option %s is currently untested (and may be removed in an upcoming release)",filename,lnr,keyword); + get_boolean(filename,lnr,keyword,&line,&cfg->ldc_restart); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"pagesize")==0) + { + get_int(filename,lnr,keyword,&line,&cfg->ldc_pagesize); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"nss_initgroups_ignoreusers")==0) + { + parse_nss_initgroups_ignoreusers_statement(filename,lnr,keyword,line,cfg); + } + else if (strcasecmp(keyword,"pam_authz_search")==0) + { + parse_pam_authz_search_statement(filename,lnr,keyword,line,cfg); + } + else if (strcasecmp(keyword,"nss_min_uid")==0) + { + get_uid(filename,lnr,keyword,&line,&cfg->ldc_nss_min_uid); + get_eol(filename,lnr,keyword,&line); + } + else if (strcasecmp(keyword,"validnames")==0) + { + parse_validnames_statement(filename,lnr,keyword,line,cfg); + } +#ifdef ENABLE_CONFIGFILE_CHECKING + /* fallthrough */ + else + { + log_log(LOG_ERR,"%s:%d: unknown keyword: '%s'",filename,lnr,keyword); + exit(EXIT_FAILURE); + } +#endif + } + /* we're done reading file, close */ + fclose(fp); +} + +#ifdef NSLCD_BINDPW_PATH +static void bindpw_read(const char *filename,struct ldap_config *cfg) +{ + FILE *fp; + char linebuf[MAX_LINE_LENGTH]; + int i; + /* open config file */ + errno=0; + if ((fp=fopen(filename,"r"))==NULL) + { + if (errno==ENOENT) + { + log_log(LOG_DEBUG,"no bindpw file (%s)",filename); + return; /* ignore */ + } + else + { + log_log(LOG_ERR,"cannot open bindpw file (%s): %s",filename,strerror(errno)); + exit(EXIT_FAILURE); + } + } + /* check permissions */ + check_permissions(filename,NULL); + /* read the first line */ + if (fgets(linebuf,sizeof(linebuf),fp)==NULL) + { + log_log(LOG_ERR,"%s: error reading first line",filename); + exit(EXIT_FAILURE); + } + /* chop the last char off and save the rest as bindpw */ + i=(int)strlen(linebuf); + if ((i<=0)||(linebuf[i-1]!='\n')) + { + log_log(LOG_ERR,"%s:1: line too long or missing newline",filename); + exit(EXIT_FAILURE); + } + linebuf[i-1]='\0'; + if (strlen(linebuf)==0) + { + log_log(LOG_ERR,"%s:1: the password is empty",filename); + exit(EXIT_FAILURE); + } + cfg->ldc_bindpw=strdup(linebuf); + /* check if there is no more data in the file */ + if (fgets(linebuf,sizeof(linebuf),fp)!=NULL) + { + log_log(LOG_ERR,"%s:2: there is more than one line in the bindpw file",filename); + exit(EXIT_FAILURE); + } + fclose(fp); +} +#endif /* NSLCD_BINDPW_PATH */ + +/* This function tries to get the LDAP search base from the LDAP server. + Note that this returns a string that has been allocated with strdup(). + For this to work the myldap module needs enough configuration information + to make an LDAP connection. */ +static MUST_USE char *get_base_from_rootdse(void) +{ + MYLDAP_SESSION *session; + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + const char *attrs[] = { "+", NULL }; + int i; + int rc; + const char **values; + char *base=NULL; + /* initialize session */ + session=myldap_create_session(); + assert(session!=NULL); + /* perform search */ + search=myldap_search(session,"",LDAP_SCOPE_BASE,"(objectClass=*)",attrs,NULL); + if (search==NULL) + { + myldap_session_close(session); + return NULL; + } + /* go over results */ + for (i=0;(entry=myldap_get_entry(search,&rc))!=NULL;i++) + { + /* get defaultNamingContext */ + values=myldap_get_values(entry,"defaultNamingContext"); + if ((values!=NULL)&&(values[0]!=NULL)) + { + base=xstrdup(values[0]); + log_log(LOG_DEBUG,"get_basedn_from_rootdse(): found attribute defaultNamingContext with value %s",values[0]); + break; + } + /* get namingContexts */ + values=myldap_get_values(entry,"namingContexts"); + if ((values!=NULL)&&(values[0]!=NULL)) + { + base=xstrdup(values[0]); + log_log(LOG_DEBUG,"get_basedn_from_rootdse(): found attribute namingContexts with value %s",values[0]); + break; + } + } + /* clean up */ + myldap_session_close(session); + return base; +} + +void cfg_init(const char *fname) +{ +#ifdef LDAP_OPT_X_TLS + int i; +#endif /* LDAP_OPT_X_TLS */ + /* check if we were called before */ + if (nslcd_cfg!=NULL) + { + log_log(LOG_CRIT,"cfg_init() may only be called once"); + exit(EXIT_FAILURE); + } + /* allocate the memory (this memory is not freed anywhere) */ + nslcd_cfg=(struct ldap_config *)malloc(sizeof(struct ldap_config)); + if (nslcd_cfg==NULL) + { + log_log(LOG_CRIT,"malloc() failed to allocate memory"); + exit(EXIT_FAILURE); + } + /* clear configuration */ + cfg_defaults(nslcd_cfg); + /* read configfile */ + cfg_read(fname,nslcd_cfg); +#ifdef NSLCD_BINDPW_PATH + bindpw_read(NSLCD_BINDPW_PATH,nslcd_cfg); +#endif /* NSLCD_BINDPW_PATH */ + /* do some sanity checks */ + if (nslcd_cfg->ldc_uris[0].uri==NULL) + { + log_log(LOG_ERR,"no URIs defined in config"); + exit(EXIT_FAILURE); + } + /* if ssl is on each URI should start with ldaps */ +#ifdef LDAP_OPT_X_TLS + if (nslcd_cfg->ldc_ssl_on==SSL_LDAPS) + { + for (i=0;nslcd_cfg->ldc_uris[i].uri!=NULL;i++) + { + if (strncasecmp(nslcd_cfg->ldc_uris[i].uri,"ldaps://",8)!=0) + log_log(LOG_WARNING,"%s doesn't start with ldaps:// and \"ssl on\" is specified", + nslcd_cfg->ldc_uris[i].uri); + } + } + /* TODO: check that if some tls options are set the ssl option should be set to on (just warn) */ +#endif /* LDAP_OPT_X_TLS */ + /* if basedn is not yet set, get if from the rootDSE */ + if (nslcd_cfg->ldc_bases[0]==NULL) + nslcd_cfg->ldc_bases[0]=get_base_from_rootdse(); + /* TODO: handle the case gracefully when no LDAP server is available yet */ + /* see if we have a valid basedn */ + if ((nslcd_cfg->ldc_bases[0]==NULL)||(nslcd_cfg->ldc_bases[0][0]=='\0')) + { + log_log(LOG_ERR,"no base defined in config and couldn't get one from server"); + exit(EXIT_FAILURE); + } + /* initialise all database modules */ + alias_init(); + ether_init(); + group_init(); + host_init(); + netgroup_init(); + network_init(); + passwd_init(); + protocol_init(); + rpc_init(); + service_init(); + shadow_init(); +} diff --git a/nslcd/cfg.h b/nslcd/cfg.h new file mode 100644 index 0000000..3a9b66b --- /dev/null +++ b/nslcd/cfg.h @@ -0,0 +1,156 @@ +/* + cfg.h - definition of configuration information + This file contains parts that were part of the nss_ldap + library which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2007 West Consulting + Copyright (C) 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef NSLCD__CFG_H +#define NSLCD__CFG_H + +#include +#include +#include +#include +#include + +#include "compat/attrs.h" +#include "common/set.h" + +/* values for uid and gid */ +#define NOUID ((gid_t)-1) +#define NOGID ((gid_t)-1) + +/* maximum number of URIs */ +#define NSS_LDAP_CONFIG_URI_MAX 31 + +/* maximum number of 'passwd base's */ +#define NSS_LDAP_CONFIG_MAX_BASES 7 + +enum ldap_ssl_options +{ + SSL_OFF, + SSL_LDAPS, + SSL_START_TLS +}; + +/* selectors for different maps */ +enum ldap_map_selector +{ + LM_PASSWD, + LM_SHADOW, + LM_GROUP, + LM_HOSTS, + LM_SERVICES, + LM_NETWORKS, + LM_PROTOCOLS, + LM_RPC, + LM_ETHERS, + LM_ALIASES, + LM_NETGROUP, + LM_NONE +}; + +struct myldap_uri +{ + char *uri; + /* time of first failed operation */ + time_t firstfail; + /* time of last failed operation */ + time_t lastfail; +}; + +struct ldap_config +{ + /* the number of threads to start */ + int ldc_threads; + /* the user id nslcd should be run as */ + uid_t ldc_uid; + /* the group id nslcd should be run as */ + gid_t ldc_gid; + /* NULL terminated list of URIs */ + struct myldap_uri ldc_uris[NSS_LDAP_CONFIG_URI_MAX+1]; + /* protocol version */ + int ldc_version; + /* bind DN */ + char *ldc_binddn; + /* bind cred */ + char *ldc_bindpw; + /* bind DN for password modification by administrator */ + char *ldc_rootpwmoddn; + /* bind password for password modification by root */ + char *ldc_rootpwmodpw; + /* sasl mech */ + char *ldc_sasl_mech; + /* sasl realm */ + char *ldc_sasl_realm; + /* sasl authentication id */ + char *ldc_sasl_authcid; + /* sasl authorization id */ + char *ldc_sasl_authzid; + /* sasl security */ + char *ldc_sasl_secprops; + /* base DN, eg. dc=gnu,dc=org */ + const char *ldc_bases[NSS_LDAP_CONFIG_MAX_BASES]; + /* scope for searches */ + int ldc_scope; + /* dereference aliases/links */ + int ldc_deref; + /* chase referrals */ + int ldc_referrals; + /* bind timelimit */ + int ldc_bind_timelimit; + /* search timelimit */ + int ldc_timelimit; + /* idle timeout */ + int ldc_idle_timelimit; + /* seconds to sleep; doubled until max */ + int ldc_reconnect_sleeptime; + /* maximum seconds to sleep */ + int ldc_reconnect_retrytime; +#ifdef LDAP_OPT_X_TLS + /* SSL enabled */ + enum ldap_ssl_options ldc_ssl_on; +#endif /* LDAP_OPT_X_TLS */ + /* whether the LDAP library should restart the select(2) system call when interrupted */ + int ldc_restart; + /* set to a greater than 0 to enable handling of paged results with the specified size */ + int ldc_pagesize; + /* the users for which no initgroups() searches should be done */ + SET *ldc_nss_initgroups_ignoreusers; + /* the search that should be performed to do autorisation checks */ + char *ldc_pam_authz_search; + /* minimum uid for users retreived from LDAP */ + uid_t ldc_nss_min_uid; + /* the regular expression to determine valid names */ + regex_t validnames; +}; + +/* this is a pointer to the global configuration, it should be available + once cfg_init() was called */ +extern struct ldap_config *nslcd_cfg; + +/* Initialize the configuration in nslcd_cfg. This method + will read the default configuration file and call exit() + if an error occurs. */ +void cfg_init(const char *fname); + +#endif /* NSLCD__CFG_H */ diff --git a/nslcd/common.c b/nslcd/common.c new file mode 100644 index 0000000..264439a --- /dev/null +++ b/nslcd/common.c @@ -0,0 +1,288 @@ +/* + common.c - common server code routines + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nslcd.h" +#include "common.h" +#include "log.h" +#include "attmap.h" +#include "cfg.h" + +/* simple wrapper around snptintf() to return non-0 in case + of any failure (but always keep string 0-terminated) */ +int mysnprintf(char *buffer,size_t buflen,const char *format, ...) +{ + int res; + va_list ap; + /* do snprintf */ + va_start(ap,format); + res=vsnprintf(buffer,buflen,format,ap); + /* NULL-terminate the string just to be on the safe side */ + buffer[buflen-1]='\0'; + /* check if the string was completely written */ + return ((res<0)||(((size_t)res)>=buflen)); +} + +/* return the fully qualified domain name of the current host */ +const char *getfqdn(void) +{ + static char *fqdn=NULL; + char hostname[HOST_NAME_MAX+1]; + int hostnamelen; + int i; + struct hostent *host=NULL; + /* if we already have a fqdn return that */ + if (fqdn!=NULL) + return fqdn; + /* get system hostname */ + if (gethostname(hostname,sizeof(hostname))<0) + { + log_log(LOG_ERR,"gethostname() failed: %s",strerror(errno)); + return NULL; + } + hostnamelen=strlen(hostname); + /* lookup hostent */ + host=gethostbyname(hostname); + if (host==NULL) + { + log_log(LOG_ERR,"gethostbyname(%s): %s",hostname,hstrerror(h_errno)); + /* fall back to hostname */ + fqdn=strdup(hostname); + return fqdn; + } + /* check h_name for fqdn starting with our hostname */ + if ((strncasecmp(hostname,host->h_name,hostnamelen)==0)&& + (host->h_name[hostnamelen]=='.')&& + (host->h_name[hostnamelen+1]!='\0')) + { + fqdn=strdup(host->h_name); + return fqdn; + } + /* also check h_aliases */ + for (i=0;host->h_aliases[i]!=NULL;i++) + { + if ((strncasecmp(hostname,host->h_aliases[i],hostnamelen)==0)&& + (host->h_aliases[i][hostnamelen]=='.')&& + (host->h_aliases[i][hostnamelen+1]!='\0')) + { + fqdn=strdup(host->h_aliases[i]); + return fqdn; + } + } + /* fall back to h_name if it has a dot in it */ + if (strchr(host->h_name,'.')!=NULL) + { + fqdn=strdup(host->h_name); + return fqdn; + } + /* also check h_aliases */ + for (i=0;host->h_aliases[i]!=NULL;i++) + { + if (strchr(host->h_aliases[i],'.')!=NULL) + { + fqdn=strdup(host->h_aliases[i]); + return fqdn; + } + } + /* nothing found, fall back to hostname */ + fqdn=strdup(hostname); + return fqdn; +} + +const char *get_userpassword(MYLDAP_ENTRY *entry,const char *attr,char *buffer,size_t buflen) +{ + const char *tmpvalue; + /* get the value */ + tmpvalue=attmap_get_value(entry,attr,buffer,buflen); + if (tmpvalue==NULL) + return NULL; + /* go over the entries and return the remainder of the value if it + starts with {crypt} or crypt$ */ + if (strncasecmp(tmpvalue,"{crypt}",7)==0) + return tmpvalue+7; + if (strncasecmp(tmpvalue,"crypt$",6)==0) + return tmpvalue+6; + /* just return the first value completely */ + return tmpvalue; + /* TODO: support more password formats e.g. SMD5 + (which is $1$ but in a different format) + (any code for this is more than welcome) */ +} + +/* Checks if the specified name seems to be a valid user or group name. */ +int isvalidname(const char *name) +{ + return regexec(&nslcd_cfg->validnames,name,0,NULL,0)==0; +} + +/* this writes a single address to the stream */ +int write_address(TFILE *fp,const char *addr) +{ + int32_t tmpint32; + struct in_addr ipv4addr; + struct in6_addr ipv6addr; + /* try to parse the address as IPv4 first, fall back to IPv6 */ + if (inet_pton(AF_INET,addr,&ipv4addr)>0) + { + /* write address type */ + WRITE_INT32(fp,AF_INET); + /* write the address length */ + WRITE_INT32(fp,sizeof(struct in_addr)); + /* write the address itself (in network byte order) */ + WRITE_TYPE(fp,ipv4addr,struct in_addr); + } + else if (inet_pton(AF_INET6,addr,&ipv6addr)>0) + { + /* write address type */ + WRITE_INT32(fp,AF_INET6); + /* write the address length */ + WRITE_INT32(fp,sizeof(struct in6_addr)); + /* write the address itself (in network byte order) */ + WRITE_TYPE(fp,ipv6addr,struct in6_addr); + } + else + { + /* failure, log but write simple invalid address + (otherwise the address list is messed up) */ + /* TODO: have error message in correct format */ + log_log(LOG_WARNING,"unparseble address: %s",addr); + /* write an illegal address type */ + WRITE_INT32(fp,-1); + /* write an emtpy address */ + WRITE_INT32(fp,0); + } + /* we're done */ + return 0; +} + +int read_address(TFILE *fp,char *addr,int *addrlen,int *af) +{ + int32_t tmpint32; + int len; + /* read address family */ + READ_INT32(fp,*af); + if ((*af!=AF_INET)&&(*af!=AF_INET6)) + { + log_log(LOG_WARNING,"incorrect address family specified: %d",*af); + return -1; + } + /* read address length */ + READ_INT32(fp,len); + if ((len>*addrlen)||(len<=0)) + { + log_log(LOG_WARNING,"address length incorrect: %d",len); + return -1; + } + *addrlen=len; + /* read address */ + READ(fp,addr,len); + /* we're done */ + return 0; +} + +/* convert the provided string representation of a sid + (e.g. S-1-5-21-1936905831-823966427-12391542-23578) + to a format that can be used to search the objectSid property with */ +char *sid2search(const char *sid) +{ + const char *tmpsid=sid; + char *res,*tmp; + int i=0; + long int l; + /* check the beginning of the string */ + if (strncasecmp(sid,"S-",2)!=0) + { + log_log(LOG_ERR,"error in SID %s",sid); + exit(EXIT_FAILURE); + } + /* count the number of dashes in the sid */ + while (tmpsid!=NULL) + { + i++; + tmpsid=strchr(tmpsid+1,'-'); + } + i-=2; /* number of security ids plus one because we add the uid later */ + /* allocate memory */ + res=malloc(3+3+6*3+i*4*3+1); + if (res==NULL) + { + log_log(LOG_CRIT,"malloc() failed to allocate memory"); + exit(1); + } + /* build the first part */ + l=strtol(sid+2,&tmp,10); + sprintf(res,"\\%02x\\%02x",(int)l&0xff,(int)i); + /* build authority part (we only handle 32 of the 48 bits) */ + l=strtol(tmp+1,&tmp,10); + sprintf(res+strlen(res),"\\00\\00\\%02x\\%02x\\%02x\\%02x", + (int)((l>>24)&0xff),(int)((l>>16)&0xff),(int)((l>>8)&0xff),(int)(l&0xff)); + /* go over the rest of the bits */ + while (*tmp!='\0') + { + l=strtol(tmp+1,&tmp,10); + sprintf(res+strlen(res),"\\%02x\\%02x\\%02x\\%02x", + (int)(l&0xff),(int)((l>>8)&0xff),(int)((l>>16)&0xff),(int)((l>>24)&0xff)); + } + return res; +} + +/* return the last security identifier of the binary sid */ +long int binsid2id(const char *binsid) +{ + int i; + /* find the position of the last security id */ + i=2+6+((((int)binsid[1])&0xff)-1)*4; + return (((long int)binsid[i])&0xff)|((((long int)binsid[i+1])&0xff)<<8)| + ((((long int)binsid[i+2])&0xff)<<16)|((((long int)binsid[i+3])&0xff)<<24); +} + +#ifdef WANT_STRTOUI +/* provide a strtoui() implementation, similar to strtoul() but returning + an range-checked unsigned int instead */ +unsigned int strtoui(const char *nptr,char **endptr,int base) +{ + unsigned long val; + val=strtoul(nptr,endptr,base); + if (val>UINT_MAX) + { + errno=ERANGE; + return UINT_MAX; + } + /* If errno was set by strtoull, we'll pass it back as-is */ + return (unsigned int)val; +} +#endif /* WANT_STRTOUI */ diff --git a/nslcd/common.h b/nslcd/common.h new file mode 100644 index 0000000..63a535f --- /dev/null +++ b/nslcd/common.h @@ -0,0 +1,266 @@ +/* + common.h - common server code routines + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef NSLCD__COMMON_H +#define NSLCD__COMMON_H 1 + +#include + +#include "nslcd.h" +#include "common/nslcd-prot.h" +#include "common/tio.h" +#include "compat/attrs.h" +#include "myldap.h" + +/* macros for basic read and write operations, the following + ERROR_OUT* marcos define the action taken on errors + the stream is not closed because the caller closes the + stream */ + +#define ERROR_OUT_WRITEERROR(fp) \ + log_log(LOG_WARNING,"error writing to client: %s",strerror(errno)); \ + return -1; + +#define ERROR_OUT_READERROR(fp) \ + log_log(LOG_WARNING,"error reading from client: %s",strerror(errno)); \ + return -1; + +#define ERROR_OUT_BUFERROR(fp) \ + log_log(LOG_WARNING,"client supplied argument %d bytes too large",tmpint32); \ + return -1; + +/* a simple wrapper around snprintf, + returns 0 if ok, -1 on error */ +int mysnprintf(char *buffer,size_t buflen,const char *format, ...) + LIKE_PRINTF(3,4); + +/* return the fully qualified domain name of the current host + the returned value does not need to be freed but is re-used for every + call */ +MUST_USE const char *getfqdn(void); + +/* This tries to get the user password attribute from the entry. + It will try to return an encrypted password as it is used in /etc/passwd, + /etc/group or /etc/shadow depending upon what is in the directory. + This function will return NULL if no passwd is found and will return the + literal value in the directory if conversion is not possible. */ +const char *get_userpassword(MYLDAP_ENTRY *entry,const char *attr, + char *buffer,size_t buflen); + +/* write out an address, parsing the addr value */ +int write_address(TFILE *fp,const char *addr); + +/* a helper macro to write out addresses and bail out on errors */ +#define WRITE_ADDRESS(fp,addr) \ + if (write_address(fp,addr)) \ + return -1; + +/* read an address from the stream */ +int read_address(TFILE *fp,char *addr,int *addrlen,int *af); + +/* helper macro to read an address from the stream */ +#define READ_ADDRESS(fp,addr,len,af) \ + len=(int)sizeof(addr); \ + if (read_address(fp,addr,&(len),&(af))) \ + return -1; + +/* convert the provided string representation of a sid + (e.g. S-1-5-21-1936905831-823966427-12391542-23578) + to a format that can be used to search the objectSid property with */ +MUST_USE char *sid2search(const char *sid); + +/* return the last security identifier of the binary sid */ +MUST_USE long int binsid2id(const char *binsid); + +/* checks to see if the specified string is a valid user or group name */ +MUST_USE int isvalidname(const char *name); + +/* Perform an LDAP lookup to translate the DN into a uid. + This function either returns NULL or a strdup()ed string. */ +MUST_USE char *lookup_dn2uid(MYLDAP_SESSION *session,const char *dn,int *rcp,char *buf,size_t buflen); + +/* transforms the DN info a uid doing an LDAP lookup if needed */ +MUST_USE char *dn2uid(MYLDAP_SESSION *session,const char *dn,char *buf,size_t buflen); + +/* use the user id to lookup an LDAP entry */ +MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *session,const char *uid,int *rcp); + +/* transforms the uid into a DN by doing an LDAP lookup */ +MUST_USE char *uid2dn(MYLDAP_SESSION *session,const char *uid,char *buf,size_t buflen); + +/* try to update the shadowLastChange attribute of the entry if possible */ +int update_lastchange(MYLDAP_SESSION *session,const char *userdn); + +/* use the user id to lookup an LDAP entry with the shadow attributes + requested*/ +MYLDAP_ENTRY *shadow_uid2entry(MYLDAP_SESSION *session,const char *username,int *rcp); + +/* return shadown information */ +void get_shadow_properties(MYLDAP_ENTRY *entry,long *lastchangedate, + long *mindays,long *maxdays,long *warndays, + long *inactdays,long *expiredate,unsigned long *flag); + + +/* check whether the nsswitch.conf file has LDAP as a naming source for db */ +int nsswitch_db_uses_ldap(const char *filename,const char *db); + +/* fallback definition of HOST_NAME_MAX */ +#ifndef HOST_NAME_MAX +#ifdef _POSIX_HOST_NAME_MAX +#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +#else +#define HOST_NAME_MAX 255 +#endif /* _POSIX_HOST_NAME_MAX */ +#endif /* not HOST_NAME_MAX */ + +/* provide strtouid() function alias */ +#if SIZEOF_UID_T == SIZEOF_UNSIGNED_LONG_INT +#define strtouid (uid_t)strtoul +#elif SIZEOF_UID_T == SIZEOF_UNSIGNED_LONG_LONG_INT +#define strtouid (uid_t)strtoull +#elif SIZEOF_UID_T == SIZEOF_UNSIGNED_INT +#define WANT_STRTOUI 1 +#define strtouid (uid_t)strtoui +#else +#error unable to find implementation for strtouid() +#endif + +/* provide strtouid() function alias */ +#if SIZEOF_GID_T == SIZEOF_UNSIGNED_LONG_INT +#define strtogid (gid_t)strtoul +#elif SIZEOF_GID_T == SIZEOF_UNSIGNED_LONG_LONG_INT +#define strtogid (gid_t)strtoull +#elif SIZEOF_GID_T == SIZEOF_UNSIGNED_INT +#ifndef WANT_STRTOUI +#define WANT_STRTOUI 1 +#endif +#define strtogid (uid_t)strtoui +#else +#error unable to find implementation for strtogid() +#endif + +#ifdef WANT_STRTOUI +/* provide a strtoui() if it is needed */ +unsigned int strtoui(const char *nptr,char **endptr,int base); +#endif /* WANT_STRTOUI */ + +/* these are the functions for initialising the database specific + modules */ +void alias_init(void); +void ether_init(void); +void group_init(void); +void host_init(void); +void netgroup_init(void); +void network_init(void); +void passwd_init(void); +void protocol_init(void); +void rpc_init(void); +void service_init(void); +void shadow_init(void); + +/* these are the different functions that handle the database + specific actions, see nslcd.h for the action descriptions */ +int nslcd_alias_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_alias_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_ether_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_ether_byether(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_ether_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_group_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_group_bygid(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_group_bymember(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_group_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_host_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_host_byaddr(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_host_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_netgroup_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_network_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_network_byaddr(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_network_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_passwd_byname(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid); +int nslcd_passwd_byuid(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid); +int nslcd_passwd_all(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid); +int nslcd_protocol_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_protocol_bynumber(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_protocol_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_rpc_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_rpc_bynumber(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_rpc_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_service_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_service_bynumber(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_service_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_shadow_byname(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_shadow_all(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid); +int nslcd_pam_authz(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_pam_sess_o(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_pam_sess_c(TFILE *fp,MYLDAP_SESSION *session); +int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid); + +/* macros for generating service handling code */ +#define NSLCD_HANDLE(db,fn,readfn,action,mkfilter,writefn) \ + int nslcd_##db##_##fn(TFILE *fp,MYLDAP_SESSION *session) \ + NSLCD_HANDLE_BODY(db,fn,readfn,action,mkfilter,writefn) +#define NSLCD_HANDLE_UID(db,fn,readfn,action,mkfilter,writefn) \ + int nslcd_##db##_##fn(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid) \ + NSLCD_HANDLE_BODY(db,fn,readfn,action,mkfilter,writefn) +#define NSLCD_HANDLE_BODY(db,fn,readfn,action,mkfilter,writefn) \ + { \ + /* define common variables */ \ + int32_t tmpint32; \ + MYLDAP_SEARCH *search; \ + MYLDAP_ENTRY *entry; \ + const char *base; \ + int rc,i; \ + /* read request parameters */ \ + readfn; \ + /* write the response header */ \ + WRITE_INT32(fp,NSLCD_VERSION); \ + WRITE_INT32(fp,action); \ + /* prepare the search filter */ \ + if (mkfilter) \ + { \ + log_log(LOG_WARNING,"nslcd_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small"); \ + return -1; \ + } \ + /* perform a search for each search base */ \ + for (i=0; (base=db##_bases[i])!=NULL; i++) \ + { \ + /* do the LDAP search */ \ + if ((search=myldap_search(session,base,db##_scope,filter,db##_attrs,NULL))==NULL) \ + return -1; \ + /* go over results */ \ + while ((entry=myldap_get_entry(search,&rc))!=NULL) \ + { \ + if (writefn) \ + return -1; \ + } \ + } \ + /* write the final result code */ \ + if (rc==LDAP_SUCCESS) \ + { \ + WRITE_INT32(fp,NSLCD_RESULT_END); \ + } \ + return 0; \ + } + +#endif /* not NSLCD__COMMON_H */ diff --git a/nslcd/ether.c b/nslcd/ether.c new file mode 100644 index 0000000..9176095 --- /dev/null +++ b/nslcd/ether.c @@ -0,0 +1,196 @@ +/* + ether.c - ethernet address entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-ethers.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" +#include "compat/ether.h" + +/* ( nisSchema.2.11 NAME 'ieee802Device' SUP top AUXILIARY + * DESC 'A device with a MAC address; device SHOULD be + * used as a structural class' + * MAY macAddress ) + */ + +/* the search base for searches */ +const char *ether_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int ether_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *ether_filter = "(objectClass=ieee802Device)"; + +/* the attributes to request with searches */ +const char *attmap_ether_cn = "cn"; +const char *attmap_ether_macAddress = "macAddress"; + +/* the attribute list to request with searches */ +static const char *ether_attrs[3]; + +/* create a search filter for searching an ethernet address + by name, return -1 on errors */ +static int mkfilter_ether_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if(myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + ether_filter, + attmap_ether_cn,safename); +} + +static int mkfilter_ether_byether(const struct ether_addr *addr, + char *buffer,size_t buflen) +{ + char ethername[20]; + /* transform into string */ + if (ether_ntoa_r(addr,ethername)==NULL) + return -1; + /* FIXME: this has a bug when the directory has 01:00:0e:... + and we're looking for 1:0:e:... (leading zeros) */ + /* there should be no characters that need escaping */ + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + ether_filter, + attmap_ether_macAddress,ethername); +} + +void ether_init(void) +{ + int i; + /* set up search bases */ + if (ether_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (ether_scope==LDAP_SCOPE_DEFAULT) + ether_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + ether_attrs[0]=attmap_ether_cn; + ether_attrs[1]=attmap_ether_macAddress; + ether_attrs[2]=NULL; +} + +/* TODO: check for errors in aton() */ +#define WRITE_ETHER(fp,addr) \ + ether_aton_r(addr,&tmpaddr); \ + WRITE_TYPE(fp,tmpaddr,uint8_t[6]); + +static int write_ether(TFILE *fp,MYLDAP_ENTRY *entry, + const char *reqname,const char *reqether) +{ + int32_t tmpint32; + struct ether_addr tmpaddr; + const char *tmparr[2]; + const char **names,**ethers; + int i,j; + /* get the name of the ether entry */ + names=myldap_get_values(entry,attmap_ether_cn); + if ((names==NULL)||(names[0]==NULL)) + { + log_log(LOG_WARNING,"ether entry %s does not contain %s value", + myldap_get_dn(entry),attmap_ether_cn); + return 0; + } + /* get the addresses */ + if (reqether!=NULL) + { + ethers=tmparr; + ethers[0]=reqether; + ethers[1]=NULL; + } + else + { + ethers=myldap_get_values(entry,attmap_ether_macAddress); + if ((ethers==NULL)||(ethers[0]==NULL)) + { + log_log(LOG_WARNING,"ether entry %s does not contain %s value", + myldap_get_dn(entry),attmap_ether_macAddress); + return 0; + } + /* TODO: move parsing of addresses up here */ + } + /* write entries for all names and addresses */ + for (i=0;names[i]!=NULL;i++) + if ((reqname==NULL)||(strcasecmp(reqname,names[i])==0)) + for (j=0;ethers[j]!=NULL;j++) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,names[i]); + WRITE_ETHER(fp,ethers[j]); + } + return 0; +} + +NSLCD_HANDLE( + ether,byname, + char name[256]; + char filter[1024]; + READ_STRING(fp,name); + log_setrequest("ether=\"%s\"",name);, + NSLCD_ACTION_ETHER_BYNAME, + mkfilter_ether_byname(name,filter,sizeof(filter)), + write_ether(fp,entry,name,NULL) +) + +NSLCD_HANDLE( + ether,byether, + struct ether_addr addr; + char ether[20]; + char filter[1024]; + READ_TYPE(fp,addr,uint8_t[6]); + if (ether_ntoa_r(&addr,ether)==NULL) + return -1; + log_setrequest("ether=%s",ether);, + NSLCD_ACTION_ETHER_BYETHER, + mkfilter_ether_byether(&addr,filter,sizeof(filter)), + write_ether(fp,entry,NULL,ether) +) + +NSLCD_HANDLE( + ether,all, + const char *filter; + log_setrequest("ether(all)");, + NSLCD_ACTION_ETHER_ALL, + (filter=ether_filter,0), + write_ether(fp,entry,NULL,NULL) +) diff --git a/nslcd/group.c b/nslcd/group.c new file mode 100644 index 0000000..010240a --- /dev/null +++ b/nslcd/group.c @@ -0,0 +1,377 @@ +/* + group.c - group entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-grp.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2006 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +/* for gid_t */ +#include + +#include "common/set.h" +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" +#include "compat/strndup.h" + +/* ( nisSchema.2.2 NAME 'posixGroup' SUP top STRUCTURAL + * DESC 'Abstraction of a group of accounts' + * MUST ( cn $ gidNumber ) + * MAY ( userPassword $ memberUid $ description ) ) + * + * apart from the above a member attribute is also supported that + * may contains a DN of a user + * + * nested groups (groups that are member of a group) are currently + * not supported + */ + +/* the search base for searches */ +const char *group_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int group_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *group_filter = "(objectClass=posixGroup)"; + +/* the attributes to request with searches */ +const char *attmap_group_cn = "cn"; +const char *attmap_group_userPassword = "\"*\""; +const char *attmap_group_gidNumber = "gidNumber"; +const char *attmap_group_memberUid = "memberUid"; +const char *attmap_group_member = "member"; + +/* special property for objectSid-based searches + (these are already LDAP-escaped strings) */ +static char *gidSid=NULL; + +/* default values for attributes */ +static const char *default_group_userPassword = "*"; /* unmatchable */ + +/* the attribute list to request with searches */ +static const char **group_attrs=NULL; + +/* create a search filter for searching a group entry + by name, return -1 on errors */ +static int mkfilter_group_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if(myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + group_filter, + attmap_group_cn,safename); +} + +/* create a search filter for searching a group entry + by gid, return -1 on errors */ +static int mkfilter_group_bygid(gid_t gid, + char *buffer,size_t buflen) +{ + if (gidSid!=NULL) + { + return mysnprintf(buffer,buflen, + "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))", + group_filter, + attmap_group_gidNumber,gidSid, + (int)(gid&0xff),(int)((gid>>8)&0xff), + (int)((gid>>16)&0xff),(int)((gid>>24)&0xff)); + } + else + { + return mysnprintf(buffer,buflen, + "(&%s(%s=%d))", + group_filter, + attmap_group_gidNumber,(int)gid); + } +} + +/* create a search filter for searching a group entry + by member uid, return -1 on errors */ +static int mkfilter_group_bymember(MYLDAP_SESSION *session, + const char *uid, + char *buffer,size_t buflen) +{ + char dn[256]; + char safeuid[300]; + char safedn[300]; + /* escape attribute */ + if(myldap_escape(uid,safeuid,sizeof(safeuid))) + return -1; + /* try to translate uid to DN */ + if (uid2dn(session,uid,dn,sizeof(dn))==NULL) + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + group_filter, + attmap_group_memberUid,safeuid); + /* escape DN */ + if(myldap_escape(dn,safedn,sizeof(safedn))) + return -1; + /* also lookup using user DN */ + return mysnprintf(buffer,buflen, + "(&%s(|(%s=%s)(%s=%s)))", + group_filter, + attmap_group_memberUid,safeuid, + attmap_group_member,safedn); +} + +void group_init(void) +{ + int i; + SET *set; + /* set up search bases */ + if (group_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (group_scope==LDAP_SCOPE_DEFAULT) + group_scope=nslcd_cfg->ldc_scope; + /* special case when gidNumber references objectSid */ + if (strncasecmp(attmap_group_gidNumber,"objectSid:",10)==0) + { + gidSid=sid2search(attmap_group_gidNumber+10); + attmap_group_gidNumber=strndup(attmap_group_gidNumber,9); + } + /* set up attribute list */ + set=set_new(); + attmap_add_attributes(set,attmap_group_cn); + attmap_add_attributes(set,attmap_group_userPassword); + attmap_add_attributes(set,attmap_group_memberUid); + attmap_add_attributes(set,attmap_group_gidNumber); + attmap_add_attributes(set,attmap_group_member); + group_attrs=set_tolist(set); + set_free(set); +} + +static int do_write_group( + TFILE *fp,MYLDAP_ENTRY *entry,const char **names,gid_t gids[],int numgids, + const char *passwd,const char **members,const char *reqname) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + int i,j; + /* write entries for all names and gids */ + for (i=0;names[i]!=NULL;i++) + { + if (!isvalidname(names[i])) + { + log_log(LOG_WARNING,"group entry %s name denied by validnames option: \"%s\"", + myldap_get_dn(entry),names[i]); + } + else if ((reqname==NULL)||(strcmp(reqname,names[i])==0)) + { + for (j=0;jldc_nss_initgroups_ignoreusers!=NULL)&& + set_contains(nslcd_cfg->ldc_nss_initgroups_ignoreusers,name)) + { + log_log(LOG_DEBUG,"ignored group member"); + /* just end the request, returning no results */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_GROUP_BYMEMBER); + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; + }, + NSLCD_ACTION_GROUP_BYMEMBER, + mkfilter_group_bymember(session,name,filter,sizeof(filter)), + write_group(fp,entry,NULL,NULL,0,session) +) + +NSLCD_HANDLE( + group,all, + const char *filter; + log_setrequest("group(all)");, + NSLCD_ACTION_GROUP_ALL, + (filter=group_filter,0), + write_group(fp,entry,NULL,NULL,1,session) +) diff --git a/nslcd/host.c b/nslcd/host.c new file mode 100644 index 0000000..f3d7e53 --- /dev/null +++ b/nslcd/host.c @@ -0,0 +1,192 @@ +/* + host.c - host name lookup routines + Parts of this file were part of the nss_ldap library (as ldap-hosts.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* ( nisSchema.2.6 NAME 'ipHost' SUP top AUXILIARY + * DESC 'Abstraction of a host, an IP device. The distinguished + * value of the cn attribute denotes the host's canonical + * name. Device SHOULD be used as a structural class' + * MUST ( cn $ ipHostNumber ) + * MAY ( l $ description $ manager ) ) + */ + +/* the search base for searches */ +const char *host_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int host_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *host_filter = "(objectClass=ipHost)"; + +/* the attributes to request with searches */ +const char *attmap_host_cn = "cn"; +const char *attmap_host_ipHostNumber = "ipHostNumber"; + +/* the attribute list to request with searches */ +static const char *host_attrs[3]; + +/* create a search filter for searching a host entry + by name, return -1 on errors */ +static int mkfilter_host_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if (myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + host_filter, + attmap_host_cn,safename); +} + +static int mkfilter_host_byaddr(const char *addrname, + char *buffer,size_t buflen) +{ + char safeaddr[64]; + /* escape attribute */ + if (myldap_escape(addrname,safeaddr,sizeof(safeaddr))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + host_filter, + attmap_host_ipHostNumber,safeaddr); +} + +void host_init(void) +{ + int i; + /* set up search bases */ + if (host_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (host_scope==LDAP_SCOPE_DEFAULT) + host_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + host_attrs[0]=attmap_host_cn; + host_attrs[1]=attmap_host_ipHostNumber; + host_attrs[2]=NULL; +} + +/* write a single host entry to the stream */ +static int write_host(TFILE *fp,MYLDAP_ENTRY *entry) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + int numaddr,i; + const char *hostname; + const char **hostnames; + const char **addresses; + /* get the most canonical name */ + hostname=myldap_get_rdn_value(entry,attmap_host_cn); + /* get the other names for the host */ + hostnames=myldap_get_values(entry,attmap_host_cn); + if ((hostnames==NULL)||(hostnames[0]==NULL)) + { + log_log(LOG_WARNING,"host entry %s does not contain %s value", + myldap_get_dn(entry),attmap_host_cn); + return 0; + } + /* if the hostname is not yet found, get the first entry from hostnames */ + if (hostname==NULL) + hostname=hostnames[0]; + /* get the addresses */ + addresses=myldap_get_values(entry,attmap_host_ipHostNumber); + if ((addresses==NULL)||(addresses[0]==NULL)) + { + log_log(LOG_WARNING,"host entry %s does not contain %s value", + myldap_get_dn(entry),attmap_host_ipHostNumber); + return 0; + } + /* write the entry */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,hostname); + WRITE_STRINGLIST_EXCEPT(fp,hostnames,hostname); + for (numaddr=0;addresses[numaddr]!=NULL;numaddr++) + /*noting*/ ; + WRITE_INT32(fp,numaddr); + for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" + +/* set the logname */ +#undef PACKAGE +#define PACKAGE "nslcd" + +/* default loglevel when no logging is configured */ +static int prelogging_loglevel=LOG_INFO; + +/* loglevel to use before logging to syslog */ +static int loglevel=LOG_INFO; + +/* the session id that is set for this thread */ +static __thread char *sessionid=NULL; + +/* the request identifier that is set for this thread */ +static __thread char *requestid=NULL; +#define MAX_REQUESTID_LENGTH 40 + +/* set loglevel when no logging is configured */ +void log_setdefaultloglevel(int pri) +{ + prelogging_loglevel=pri; +} + +/* start the logging with the configured logging methods + if no method is configured yet, logging is done to syslog */ +void log_startlogging(void) +{ + openlog(PACKAGE,LOG_PID,LOG_DAEMON); + prelogging_loglevel=-1; +} + +/* indicate that we should clear any session identifiers set by + log_newsession */ +void log_clearsession(void) +{ + /* set the session id to empty */ + if (sessionid!=NULL) + sessionid[0]='\0'; + /* set the request id to empty */ + if (requestid!=NULL) + requestid[0]='\0'; +} + +/* indicate that a session id should be included in the output + and set it to a new value */ +void log_newsession(void) +{ + /* ensure that sessionid can hold a string */ + if (sessionid==NULL) + { + sessionid=(char *)malloc(7); + if (sessionid==NULL) + { + fprintf(stderr,"malloc() failed: %s",strerror(errno)); + return; /* silently fail */ + } + } + sprintf(sessionid,"%06x",(int)(rand()&0xffffff)); + /* set the request id to empty */ + if (requestid!=NULL) + requestid[0]='\0'; +} + +/* indicate that a request identifier should be included in the output + from this point on, until log_newsession() is called */ +void log_setrequest(const char *format, ...) +{ + va_list ap; + /* ensure that requestid can hold a string */ + if (requestid==NULL) + { + requestid=(char *)malloc(MAX_REQUESTID_LENGTH); + if (requestid==NULL) + { + fprintf(stderr,"malloc() failed: %s",strerror(errno)); + return; /* silently fail */ + } + } + /* make the message */ + va_start(ap,format); + vsnprintf(requestid,MAX_REQUESTID_LENGTH,format,ap); + requestid[MAX_REQUESTID_LENGTH-1]='\0'; + va_end(ap); +} + +/* log the given message using the configured logging method */ +void log_log(int pri,const char *format, ...) +{ + int res; + char buffer[200]; + va_list ap; + /* make the message */ + va_start(ap,format); + res=vsnprintf(buffer,sizeof(buffer),format,ap); + if ((res<0)||(res>=(int)sizeof(buffer))) + { + /* truncate with "..." */ + buffer[sizeof(buffer)-2]='.'; + buffer[sizeof(buffer)-3]='.'; + buffer[sizeof(buffer)-4]='.'; + } + buffer[sizeof(buffer)-1]='\0'; + va_end(ap); + /* do the logging */ + if (prelogging_loglevel>=0) + { + /* if logging is not yet defined, log to stderr */ + if (pri<=prelogging_loglevel) + { + if ((requestid!=NULL)&&(requestid[0]!='\0')) + fprintf(stderr,"%s: [%s] <%s> %s%s\n",PACKAGE,sessionid,requestid,pri==LOG_DEBUG?"DEBUG: ":"",buffer); + else if ((sessionid!=NULL)&&(sessionid[0]!='\0')) + fprintf(stderr,"%s: [%s] %s%s\n",PACKAGE,sessionid,pri==LOG_DEBUG?"DEBUG: ":"",buffer); + else + fprintf(stderr,"%s: %s%s\n",PACKAGE,pri==LOG_DEBUG?"DEBUG: ":"",buffer); + } + } + else + { + if (pri<=loglevel) + { + if ((requestid!=NULL)&&(requestid[0]!='\0')) + syslog(pri,"[%s] <%s> %s",sessionid,requestid,buffer); + else if ((sessionid!=NULL)&&(sessionid[0]!='\0')) + syslog(pri,"[%s] %s",sessionid,buffer); + else + syslog(pri,"%s",buffer); + } + } +} diff --git a/nslcd/log.h b/nslcd/log.h new file mode 100644 index 0000000..27003a6 --- /dev/null +++ b/nslcd/log.h @@ -0,0 +1,53 @@ +/* + log.h - definitions of logging funtions + + Copyright (C) 2002, 2003, 2007, 2008, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + + +#ifndef NSLCD__LOG_H +#define NSLCD__LOG_H 1 + +#include +#include "compat/attrs.h" + +/* set loglevel when no logging is configured */ +void log_setdefaultloglevel(int pri); + +/* start the logging with the configured logging methods + if no method is configured yet, logging is done to syslog */ +void log_startlogging(void); + +/* indicate that a session id should be included in the output + and set it to a new value */ +void log_newsession(void); + +/* indicate that we should clear any session identifiers set by + log_newsession */ +void log_clearsession(void); + +/* indicate that a request identifier should be included in the output + from this point on, until log_newsession() is called */ +void log_setrequest(const char *format, ...) + LIKE_PRINTF(1,2); + +/* log the given message using the configured logging method */ +void log_log(int pri,const char *format, ...) + LIKE_PRINTF(2,3); + +#endif /* not NSLCD__LOG_H */ diff --git a/nslcd/myldap.c b/nslcd/myldap.c new file mode 100644 index 0000000..c5d898e --- /dev/null +++ b/nslcd/myldap.c @@ -0,0 +1,1860 @@ +/* + myldap.c - simple interface to do LDAP requests + Parts of this file were part of the nss_ldap library (as ldap-nss.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2006 Luke Howard + Copyright (C) 2006, 2007 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +/* + This library expects to use an LDAP library to provide the real + functionality and only provides a convenient wrapper. + Some pointers for more information on the LDAP API: + http://tools.ietf.org/id/draft-ietf-ldapext-ldap-c-api-05.txt + http://www.mozilla.org/directory/csdk-docs/function.htm + http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/apis/dirserv1.htm + http://www.openldap.org/software/man.cgi?query=ldap +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LDAP_SSL_H +#include +#endif +#ifdef HAVE_GSSLDAP_H +#include +#endif +#ifdef HAVE_GSSSASL_H +#include +#endif +#ifdef HAVE_SASL_SASL_H +#include +#endif +#ifdef HAVE_SASL_H +#include +#endif +#include +#include + +#include "myldap.h" +#include "common.h" +#include "log.h" +#include "cfg.h" +#include "common/set.h" +#include "compat/ldap_compat.h" + +/* the maximum number of searches per session */ +#define MAX_SEARCHES_IN_SESSION 4 + +/* This refers to a current LDAP session that contains the connection + information. */ +struct ldap_session +{ + /* the connection */ + LDAP *ld; + /* the username to bind with */ + char binddn[256]; + /* the password to bind with if any */ + char bindpw[64]; + /* timestamp of last activity */ + time_t lastactivity; + /* index into ldc_uris: currently connected LDAP uri */ + int current_uri; + /* a list of searches registered with this session */ + struct myldap_search *searches[MAX_SEARCHES_IN_SESSION]; +}; + +/* A search description set as returned by myldap_search(). */ +struct myldap_search +{ + /* reference to the session */ + MYLDAP_SESSION *session; + /* indicator that the search is still valid */ + int valid; + /* the parameters descibing the search */ + const char *base; + int scope; + const char *filter; + char **attrs; + /* a pointer to the current result entry, used for + freeing resource allocated with that entry */ + MYLDAP_ENTRY *entry; + /* LDAP message id for the search, -1 indicates absense of an active search */ + int msgid; + /* the last result that was returned by ldap_result() */ + LDAPMessage *msg; + /* cookie for paged searches */ + struct berval *cookie; + /* to indicate that we can retry the search from myldap_get_entry() */ + int may_retry_search; +}; + +/* The maximum number of calls to myldap_get_values() that may be + done per returned entry. */ +#define MAX_ATTRIBUTES_PER_ENTRY 16 + +/* The maximum number of ranged attribute values that may be stoted + per entry. */ +#define MAX_RANGED_ATTRIBUTES_PER_ENTRY 8 + +/* A single entry from the LDAP database as returned by + myldap_get_entry(). */ +struct myldap_entry +{ + /* reference to the search to be used to get parameters + (e.g. LDAP connection) for other calls */ + MYLDAP_SEARCH *search; + /* the DN */ + const char *dn; + /* a cached version of the exploded rdn */ + char **exploded_rdn; + /* a cache of attribute to value list */ + char **attributevalues[MAX_ATTRIBUTES_PER_ENTRY]; + /* a reference to ranged attribute values so we can free() them later on */ + char **rangedattributevalues[MAX_RANGED_ATTRIBUTES_PER_ENTRY]; +}; + +static MYLDAP_ENTRY *myldap_entry_new(MYLDAP_SEARCH *search) +{ + MYLDAP_ENTRY *entry; + int i; + /* Note: as an alternative we could embed the myldap_entry into the + myldap_search struct to save on malloc() and free() calls. */ + /* allocate new entry */ + entry=(MYLDAP_ENTRY *)malloc(sizeof(struct myldap_entry)); + if (entry==NULL) + { + log_log(LOG_CRIT,"myldap_entry_new(): malloc() failed to allocate memory"); + exit(EXIT_FAILURE); + } + /* fill in fields */ + entry->search=search; + entry->dn=NULL; + entry->exploded_rdn=NULL; + for (i=0;iattributevalues[i]=NULL; + for (i=0;irangedattributevalues[i]=NULL; + /* return the fresh entry */ + return entry; +} + +static void myldap_entry_free(MYLDAP_ENTRY *entry) +{ + int i; + /* free the DN */ + if (entry->dn!=NULL) + ldap_memfree((char *)entry->dn); + /* free the exploded RDN */ + if (entry->exploded_rdn!=NULL) + ldap_value_free(entry->exploded_rdn); + /* free all attribute values */ + for (i=0;iattributevalues[i]!=NULL) + ldap_value_free(entry->attributevalues[i]); + /* free all ranged attribute values */ + for (i=0;irangedattributevalues[i]!=NULL) + free(entry->rangedattributevalues[i]); + /* we don't need the result anymore, ditch it. */ + ldap_msgfree(entry->search->msg); + entry->search->msg=NULL; + /* free the actual memory for the struct */ + free(entry); +} + +static MYLDAP_SEARCH *myldap_search_new( + MYLDAP_SESSION *session, + const char *base,int scope,const char *filter,const char **attrs) +{ + char *buffer; + MYLDAP_SEARCH *search; + int i; + size_t sz; + /* figure out size for new memory block to allocate + this has the advantage that we can free the whole lot with one call */ + sz=sizeof(struct myldap_search); + sz+=strlen(base)+1+strlen(filter)+1; + for (i=0;attrs[i]!=NULL;i++) + sz+=strlen(attrs[i])+1; + sz+=(i+1)*sizeof(char *); + /* allocate new results memory region */ + buffer=(char *)malloc(sz); + if (buffer==NULL) + { + log_log(LOG_CRIT,"myldap_search_new(): malloc() failed to allocate memory"); + exit(EXIT_FAILURE); + } + /* initialize struct */ + search=(MYLDAP_SEARCH *)(void *)(buffer); + buffer+=sizeof(struct myldap_search); + /* save pointer to session */ + search->session=session; + /* flag as valid search */ + search->valid=1; + /* initialize array of attributes */ + search->attrs=(char **)(void *)buffer; + buffer+=(i+1)*sizeof(char *); + /* copy base */ + strcpy(buffer,base); + search->base=buffer; + buffer+=strlen(base)+1; + /* just plainly store scope */ + search->scope=scope; + /* copy filter */ + strcpy(buffer,filter); + search->filter=buffer; + buffer+=strlen(filter)+1; + /* copy attributes themselves */ + for (i=0;attrs[i]!=NULL;i++) + { + strcpy(buffer,attrs[i]); + search->attrs[i]=buffer; + buffer+=strlen(attrs[i])+1; + } + search->attrs[i]=NULL; + /* initialize context */ + search->cookie=NULL; + search->msg=NULL; + search->msgid=-1; + search->may_retry_search=1; + /* clear result entry */ + search->entry=NULL; + /* return the new search struct */ + return search; +} + +static MYLDAP_SESSION *myldap_session_new(void) +{ + MYLDAP_SESSION *session; + int i; + /* allocate memory for the session storage */ + session=(struct ldap_session *)malloc(sizeof(struct ldap_session)); + if (session==NULL) + { + log_log(LOG_CRIT,"myldap_session_new(): malloc() failed to allocate memory"); + exit(EXIT_FAILURE); + } + /* initialize the session */ + session->ld=NULL; + session->binddn[0]='\0'; + session->bindpw[0]='\0'; + session->lastactivity=0; + session->current_uri=0; + for (i=0;isearches[i]=NULL; + /* return the new session */ + return session; +} + +PURE static inline int is_valid_session(MYLDAP_SESSION *session) +{ + return (session!=NULL); +} + +PURE static inline int is_open_session(MYLDAP_SESSION *session) +{ + return is_valid_session(session)&&(session->ld!=NULL); +} + +/* note that this does not check the valid flag of the search */ +PURE static inline int is_valid_search(MYLDAP_SEARCH *search) +{ + return (search!=NULL)&&is_open_session(search->session); +} + +PURE static inline int is_valid_entry(MYLDAP_ENTRY *entry) +{ + return (entry!=NULL)&&is_valid_search(entry->search)&&(entry->search->msg!=NULL); +} + +#ifdef HAVE_SASL_INTERACT_T +/* this is registered with ldap_sasl_interactive_bind_s() in do_bind() */ +static int do_sasl_interact(LDAP UNUSED(*ld),unsigned UNUSED(flags),void *defaults,void *_interact) +{ + struct ldap_config *cfg=defaults; + sasl_interact_t *interact=_interact; + while (interact->id!=SASL_CB_LIST_END) + { + switch(interact->id) + { + case SASL_CB_GETREALM: + if (cfg->ldc_sasl_realm) + { + log_log(LOG_DEBUG,"do_sasl_interact(): returning sasl_realm \"%s\"",cfg->ldc_sasl_realm); + interact->result=cfg->ldc_sasl_realm; + interact->len=strlen(cfg->ldc_sasl_realm); + } + else + log_log(LOG_DEBUG,"do_sasl_interact(): were asked for sasl_realm but we don't have any"); + break; + case SASL_CB_AUTHNAME: + if (cfg->ldc_sasl_authcid) + { + log_log(LOG_DEBUG,"do_sasl_interact(): returning sasl_authcid \"%s\"",cfg->ldc_sasl_authcid); + interact->result=cfg->ldc_sasl_authcid; + interact->len=strlen(cfg->ldc_sasl_authcid); + } + else + log_log(LOG_DEBUG,"do_sasl_interact(): were asked for sasl_authcid but we don't have any"); + break; + case SASL_CB_USER: + if (cfg->ldc_sasl_authzid) + { + log_log(LOG_DEBUG,"do_sasl_interact(): returning sasl_authzid \"%s\"",cfg->ldc_sasl_authzid); + interact->result=cfg->ldc_sasl_authzid; + interact->len=strlen(cfg->ldc_sasl_authzid); + } + else + log_log(LOG_DEBUG,"do_sasl_interact(): were asked for sasl_authzid but we don't have any"); + break; + case SASL_CB_PASS: + if (cfg->ldc_bindpw) + { + log_log(LOG_DEBUG,"do_sasl_interact(): returning bindpw \"***\""); + interact->result=cfg->ldc_bindpw; + interact->len=strlen(cfg->ldc_bindpw); + } + else + log_log(LOG_DEBUG,"do_sasl_interact(): were asked for bindpw but we don't have any"); + break; + default: + /* just ignore */ + break; + } + interact++; + } + return LDAP_SUCCESS; +} +#endif /* HAVE_SASL_INTERACT_T */ + +#define LDAP_SET_OPTION(ld,option,invalue) \ + rc=ldap_set_option(ld,option,invalue); \ + if (rc!=LDAP_SUCCESS) \ + { \ + log_log(LOG_ERR,"ldap_set_option(" #option ") failed: %s",ldap_err2string(rc)); \ + return rc; \ + } + +/* This function performs the authentication phase of opening a connection. + The binddn and bindpw parameters may be used to override the authentication + mechanism defined in the configuration. This returns an LDAP result + code. */ +static int do_bind(LDAP *ld,const char *binddn,const char *bindpw,const char *uri) +{ + int rc; +#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S +#ifndef HAVE_SASL_INTERACT_T + struct berval cred; +#endif /* not HAVE_SASL_INTERACT_T */ +#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */ +#ifdef LDAP_OPT_X_TLS + /* check if StartTLS is requested */ + if (nslcd_cfg->ldc_ssl_on==SSL_START_TLS) + { + log_log(LOG_DEBUG,"ldap_start_tls_s()"); + errno=0; + rc=ldap_start_tls_s(ld,NULL,NULL); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_WARNING,"ldap_start_tls_s() failed: %s%s%s (uri=\"%s\")", + ldap_err2string(rc),(errno==0)?"":": ", + (errno==0)?"":strerror(errno),uri); + return rc; + } + } +#endif /* LDAP_OPT_X_TLS */ + /* check if the binddn and bindpw are overwritten in the session */ + if ((binddn!=NULL)&(binddn[0]!='\0')) + { + /* do a simple bind */ + log_log(LOG_DEBUG,"ldap_simple_bind_s(\"%s\",%s) (uri=\"%s\")",binddn, + ((bindpw!=NULL)&&(bindpw[0]!='\0'))?"\"***\"":"\"\"",uri); + return ldap_simple_bind_s(ld,binddn,bindpw); + } + /* perform SASL bind if requested and available on platform */ +#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S + /* TODO: store this information in the session */ + if (nslcd_cfg->ldc_sasl_mech!=NULL) + { + /* do a SASL bind */ + if (nslcd_cfg->ldc_sasl_secprops!=NULL) + { + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_SASL_SECPROPS,\"%s\")",nslcd_cfg->ldc_sasl_secprops); + LDAP_SET_OPTION(ld,LDAP_OPT_X_SASL_SECPROPS,(void *)nslcd_cfg->ldc_sasl_secprops); + } +#ifdef HAVE_SASL_INTERACT_T + if (nslcd_cfg->ldc_binddn!=NULL) + log_log(LOG_DEBUG,"ldap_sasl_interactive_bind_s(\"%s\",\"%s\") (uri=\"%s\")", + nslcd_cfg->ldc_binddn,nslcd_cfg->ldc_sasl_mech,uri); + else + log_log(LOG_DEBUG,"ldap_sasl_interactive_bind_s(NULL,\"%s\") (uri=\"%s\")", + nslcd_cfg->ldc_sasl_mech,uri); + return ldap_sasl_interactive_bind_s(ld,nslcd_cfg->ldc_binddn,nslcd_cfg->ldc_sasl_mech,NULL,NULL, + LDAP_SASL_QUIET, + do_sasl_interact,(void *)nslcd_cfg); +#else /* HAVE_SASL_INTERACT_T */ + if (nslcd_cfg->ldc_bindpw!=NULL) + { + cred.bv_val=nslcd_cfg->ldc_bindpw; + cred.bv_len=strlen(nslcd_cfg->ldc_bindpw); + } + else + { + cred.bv_val=""; + cred.bv_len=0; + } + if (nslcd_cfg->ldc_binddn!=NULL) + log_log(LOG_DEBUG,"ldap_sasl_bind_s(\"%s\",\"%s\",%s) (uri=\"%s\")", + nslcd_cfg->ldc_binddn,nslcd_cfg->ldc_sasl_mech, + nslcd_cfg->ldc_bindpw?"\"***\"":"NULL",uri); + else + log_log(LOG_DEBUG,"ldap_sasl_bind_s(NULL,\"%s\",%s) (uri=\"%s\")", + nslcd_cfg->ldc_sasl_mech, + nslcd_cfg->ldc_bindpw?"\"***\"":"NULL",uri); + return ldap_sasl_bind_s(ld,nslcd_cfg->ldc_binddn,nslcd_cfg->ldc_sasl_mech,&cred,NULL,NULL,NULL); +#endif /* not HAVE_SASL_INTERACT_T */ + } +#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */ + /* do a simple bind */ + if (nslcd_cfg->ldc_binddn) + log_log(LOG_DEBUG,"ldap_simple_bind_s(\"%s\",%s) (uri=\"%s\")",nslcd_cfg->ldc_binddn, + nslcd_cfg->ldc_bindpw?"\"***\"":"NULL",uri); + else + log_log(LOG_DEBUG,"ldap_simple_bind_s(NULL,%s) (uri=\"%s\")", + nslcd_cfg->ldc_bindpw?"\"***\"":"NULL",uri); + return ldap_simple_bind_s(ld,nslcd_cfg->ldc_binddn,nslcd_cfg->ldc_bindpw); +} + +#ifdef HAVE_LDAP_SET_REBIND_PROC +/* This function is called by the LDAP library when chasing referrals. + It is configured with the ldap_set_rebind_proc() below. */ +static int do_rebind(LDAP *ld,LDAP_CONST char *url, + ber_tag_t UNUSED(request), + ber_int_t UNUSED(msgid),void *arg) +{ + MYLDAP_SESSION *session=(MYLDAP_SESSION *)arg; + log_log(LOG_DEBUG,"rebinding to %s",url); + return do_bind(ld,session->binddn,session->bindpw,url); +} +#endif /* HAVE_LDAP_SET_REBIND_PROC */ + +/* set a recieve and send timeout on a socket */ +static int set_socket_timeout(LDAP *ld,time_t sec,suseconds_t usec) +{ + struct timeval tv; + int rc=LDAP_SUCCESS; + int sd; + log_log(LOG_DEBUG,"set_socket_timeout(%lu,%lu)",sec,usec); + /* get the socket */ + if ((rc=ldap_get_option(ld,LDAP_OPT_DESC,&sd))!=LDAP_SUCCESS) + { + log_log(LOG_ERR,"ldap_get_option(LDAP_OPT_DESC) failed: %s",ldap_err2string(rc)); + return rc; + } + /* ignore invalid (probably closed) file descriptors */ + if (sd<=0) + return LDAP_SUCCESS; + /* set timeouts */ + memset(&tv,0,sizeof(tv)); + tv.tv_sec=sec; + tv.tv_usec=usec; + if (setsockopt(sd,SOL_SOCKET,SO_RCVTIMEO,(void *)&tv,sizeof(tv))) + { + log_log(LOG_ERR,"setsockopt(%d,SO_RCVTIMEO) failed: %s",sd,strerror(errno)); + rc=LDAP_LOCAL_ERROR; + } + if (setsockopt(sd,SOL_SOCKET,SO_SNDTIMEO,(void *)&tv,sizeof(tv))) + { + log_log(LOG_ERR,"setsockopt(%d,SO_RCVTIMEO) failed: %s",sd,strerror(errno)); + rc=LDAP_LOCAL_ERROR; + } + return rc; +} + +#ifdef LDAP_OPT_CONNECT_CB +/* This function is called by the LDAP library once a connection was made to the server. We + set a timeout on the socket here, to catch netzwork timeouts during the ssl + handshake phase. It is configured with LDAP_OPT_CONNECT_CB. */ +static int connect_cb(LDAP *ld,Sockbuf UNUSED(*sb),LDAPURLDesc UNUSED(*srv), + struct sockaddr UNUSED(*addr),struct ldap_conncb UNUSED(*ctx)) +{ + /* set timeout options on socket to avoid hang in some cases (a little + more than the normal timeout so this should only be triggered in cases + where the library behaves incorrectly) */ + if (nslcd_cfg->ldc_timelimit) + set_socket_timeout(ld,nslcd_cfg->ldc_timelimit,500000); + return LDAP_SUCCESS; +} + +/* We have an empty disconnect callback because LDAP_OPT_CONNECT_CB expects + both functions to be available. */ +static void disconnect_cb(LDAP UNUSED(*ld),Sockbuf UNUSED(*sb),struct ldap_conncb UNUSED(*ctx)) +{ +} +#endif /* LDAP_OPT_CONNECT_CB */ + +/* This function sets a number of properties on the connection, based + what is configured in the configfile. This function returns an + LDAP status code. */ +static int do_set_options(MYLDAP_SESSION *session) +{ + /* FIXME: move this to a global initialisation routine */ + int rc; + struct timeval tv; +#ifdef LDAP_OPT_CONNECT_CB + /* make this static because OpenLDAP doesn't make it's own copy */ + static struct ldap_conncb cb; +#endif /* LDAP_OPT_CONNECT_CB */ +#ifdef LDAP_OPT_X_TLS + int i; +#endif /* LDAP_OPT_X_TLS */ +#ifdef HAVE_LDAP_SET_REBIND_PROC + /* the rebind function that is called when chasing referrals, see + http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/apis/ldap_set_rebind_proc.htm + http://www.openldap.org/software/man.cgi?query=ldap_set_rebind_proc&manpath=OpenLDAP+2.4-Release */ + /* TODO: probably only set this if we should chase referrals */ + log_log(LOG_DEBUG,"ldap_set_rebind_proc()"); +#ifndef LDAP_SET_REBIND_PROC_RETURNS_VOID /* it returns int */ + rc=ldap_set_rebind_proc(session->ld,do_rebind,session); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_ERR,"ldap_set_rebind_proc() failed: %s",ldap_err2string(rc)); + return rc; + } +#else /* ldap_set_rebind_proc() returns void */ + ldap_set_rebind_proc(session->ld,do_rebind,session); +#endif +#endif /* HAVE_LDAP_SET_REBIND_PROC */ + /* set the protocol version to use */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,%d)",nslcd_cfg->ldc_version); + LDAP_SET_OPTION(session->ld,LDAP_OPT_PROTOCOL_VERSION,&nslcd_cfg->ldc_version); + /* set some other options */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_DEREF,%d)",nslcd_cfg->ldc_deref); + LDAP_SET_OPTION(session->ld,LDAP_OPT_DEREF,&nslcd_cfg->ldc_deref); + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_TIMELIMIT,%d)",nslcd_cfg->ldc_timelimit); + LDAP_SET_OPTION(session->ld,LDAP_OPT_TIMELIMIT,&nslcd_cfg->ldc_timelimit); + tv.tv_sec=nslcd_cfg->ldc_bind_timelimit; + tv.tv_usec=0; +#ifdef LDAP_OPT_TIMEOUT + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_TIMEOUT,%d)",nslcd_cfg->ldc_timelimit); + LDAP_SET_OPTION(session->ld,LDAP_OPT_TIMEOUT,&tv); +#endif /* LDAP_OPT_TIMEOUT */ +#ifdef LDAP_OPT_NETWORK_TIMEOUT + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,%d)",nslcd_cfg->ldc_timelimit); + LDAP_SET_OPTION(session->ld,LDAP_OPT_NETWORK_TIMEOUT,&tv); +#endif /* LDAP_OPT_NETWORK_TIMEOUT */ +#ifdef LDAP_X_OPT_CONNECT_TIMEOUT + log_log(LOG_DEBUG,"ldap_set_option(LDAP_X_OPT_CONNECT_TIMEOUT,%d)",nslcd_cfg->ldc_timelimit); + LDAP_SET_OPTION(session->ld,LDAP_X_OPT_CONNECT_TIMEOUT,&tv); +#endif /* LDAP_X_OPT_CONNECT_TIMEOUT */ + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_REFERRALS,%s)",nslcd_cfg->ldc_referrals?"LDAP_OPT_ON":"LDAP_OPT_OFF"); + LDAP_SET_OPTION(session->ld,LDAP_OPT_REFERRALS,nslcd_cfg->ldc_referrals?LDAP_OPT_ON:LDAP_OPT_OFF); + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_RESTART,%s)",nslcd_cfg->ldc_restart?"LDAP_OPT_ON":"LDAP_OPT_OFF"); + LDAP_SET_OPTION(session->ld,LDAP_OPT_RESTART,nslcd_cfg->ldc_restart?LDAP_OPT_ON:LDAP_OPT_OFF); +#ifdef LDAP_OPT_CONNECT_CB + /* register a connection callback */ + cb.lc_add=connect_cb; + cb.lc_del=disconnect_cb; + cb.lc_arg=NULL; + LDAP_SET_OPTION(session->ld,LDAP_OPT_CONNECT_CB,(void *)&cb); +#endif /* LDAP_OPT_CONNECT_CB */ +#ifdef LDAP_OPT_X_TLS + /* if SSL is desired, then enable it */ + if ( (nslcd_cfg->ldc_ssl_on==SSL_LDAPS) || + (strncasecmp(nslcd_cfg->ldc_uris[session->current_uri].uri,"ldaps://",8)==0) ) + { + /* use tls */ + i=LDAP_OPT_X_TLS_HARD; + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_X_TLS,LDAP_OPT_X_TLS_HARD)"); + LDAP_SET_OPTION(session->ld,LDAP_OPT_X_TLS,&i); + } +#endif /* LDAP_OPT_X_TLS */ + /* if nothing above failed, everything should be fine */ + return LDAP_SUCCESS; +} + +/* close the connection to the server and invalidate any running searches */ +static void do_close(MYLDAP_SESSION *session) +{ + int i; + int rc; + time_t sec; + /* if we had reachability problems with the server close the connection */ + if (session->ld!=NULL) + { + /* set timeout options on socket to avoid hang in some cases + (we set a short timeout because we don't care too much about properly + shutting down the connection) */ + if (nslcd_cfg->ldc_timelimit) + { + sec=nslcd_cfg->ldc_timelimit/2; + if (!sec) sec=1; + set_socket_timeout(session->ld,sec,0); + } + /* go over the other searches and partially close them */ + for (i=0;isearches[i]!=NULL) + { + /* free any messages (because later ld is no longer valid) */ + if (session->searches[i]->msg!=NULL) + { + ldap_msgfree(session->searches[i]->msg); + session->searches[i]->msg=NULL; + } + /* abandon the search if there were more results to fetch */ + if (session->searches[i]->msgid!=-1) + { + log_log(LOG_DEBUG,"ldap_abandon()"); + if (ldap_abandon(session->searches[i]->session->ld,session->searches[i]->msgid)) + { + if (ldap_get_option(session->ld,LDAP_OPT_ERROR_NUMBER,&rc)!=LDAP_SUCCESS) + rc=LDAP_OTHER; + log_log(LOG_WARNING,"ldap_abandon() failed to abandon search: %s",ldap_err2string(rc)); + } + session->searches[i]->msgid=-1; + } + /* flag the search as invalid */ + session->searches[i]->valid=0; + } + } + /* close the connection to the server */ + log_log(LOG_DEBUG,"ldap_unbind()"); + rc=ldap_unbind(session->ld); + session->ld=NULL; + if (rc!=LDAP_SUCCESS) + log_log(LOG_WARNING,"ldap_unbind() failed: %s",ldap_err2string(rc)); + } +} + +void myldap_session_check(MYLDAP_SESSION *session) +{ + int i; + time_t current_time; + /* check parameters */ + if (!is_valid_session(session)) + { + log_log(LOG_ERR,"myldap_session_check(): invalid parameter passed"); + errno=EINVAL; + return; + } + /* check if we should time out the connection */ + if ((session->ld!=NULL)&&(nslcd_cfg->ldc_idle_timelimit>0)) + { + /* if we have any running searches, don't time out */ + for (i=0;isearches[i]!=NULL)&&(session->searches[i]->valid)) + return; + /* consider timeout (there are no running searches) */ + time(¤t_time); + if ((session->lastactivity+nslcd_cfg->ldc_idle_timelimit)ld!=NULL) + return LDAP_SUCCESS; + /* we should build a new session now */ + session->ld=NULL; + session->lastactivity=0; + /* open the connection */ + log_log(LOG_DEBUG,"ldap_initialize(%s)",nslcd_cfg->ldc_uris[session->current_uri].uri); + errno=0; + rc=ldap_initialize(&(session->ld),nslcd_cfg->ldc_uris[session->current_uri].uri); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_WARNING,"ldap_initialize(%s) failed: %s%s%s", + nslcd_cfg->ldc_uris[session->current_uri].uri, + ldap_err2string(rc),(errno==0)?"":": ", + (errno==0)?"":strerror(errno)); + if (session->ld!=NULL) + do_close(session); + return rc; + } + else if (session->ld==NULL) + { + log_log(LOG_WARNING,"ldap_initialize() returned NULL"); + return LDAP_LOCAL_ERROR; + } + /* set the options for the connection */ + rc=do_set_options(session); + if (rc!=LDAP_SUCCESS) + { + do_close(session); + return rc; + } + /* bind to the server */ + errno=0; + rc=do_bind(session->ld,session->binddn,session->bindpw, + nslcd_cfg->ldc_uris[session->current_uri].uri); + if (rc!=LDAP_SUCCESS) + { + /* log actual LDAP error code */ + log_log((session->binddn[0]=='\0')?LOG_WARNING:LOG_DEBUG, + "failed to bind to LDAP server %s: %s%s%s", + nslcd_cfg->ldc_uris[session->current_uri].uri, + ldap_err2string(rc),(errno==0)?"":": ", + (errno==0)?"":strerror(errno)); + do_close(session); + return rc; + } + /* update last activity and finish off state */ + time(&(session->lastactivity)); + return LDAP_SUCCESS; +} + +/* Set alternative credentials for the session. */ +void myldap_set_credentials(MYLDAP_SESSION *session,const char *dn, + const char *password) +{ + /* copy dn and password into session */ + strncpy(session->binddn,dn,sizeof(session->binddn)); + session->binddn[sizeof(session->binddn)-1]='\0'; + strncpy(session->bindpw,password,sizeof(session->bindpw)); + session->bindpw[sizeof(session->bindpw)-1]='\0'; +} + +static int do_try_search(MYLDAP_SEARCH *search) +{ + int rc; + LDAPControl *serverCtrls[2]; + LDAPControl **pServerCtrls; + int msgid; + /* ensure that we have an open connection */ + rc=do_open(search->session); + if (rc!=LDAP_SUCCESS) + return rc; + /* if we're using paging, build a page control */ + if ((nslcd_cfg->ldc_pagesize>0)&&(search->scope!=LDAP_SCOPE_BASE)) + { + rc=ldap_create_page_control(search->session->ld,nslcd_cfg->ldc_pagesize, + NULL,0,&serverCtrls[0]); + if (rc==LDAP_SUCCESS) + { + serverCtrls[1]=NULL; + pServerCtrls=serverCtrls; + } + else + { + log_log(LOG_WARNING,"ldap_create_page_control() failed: %s",ldap_err2string(rc)); + /* clear error flag */ + rc=LDAP_SUCCESS; + ldap_set_option(search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc); + pServerCtrls=NULL; + } + } + else + pServerCtrls=NULL; + /* perform the search */ + rc=ldap_search_ext(search->session->ld,search->base,search->scope, + search->filter,(char **)(search->attrs), + 0,pServerCtrls,NULL,NULL, + LDAP_NO_LIMIT,&msgid); + /* free the controls if we had them */ + if (pServerCtrls!=NULL) + { + ldap_control_free(serverCtrls[0]); + serverCtrls[0]=NULL; + } + /* handle errors */ + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_WARNING,"ldap_search_ext() failed: %s",ldap_err2string(rc)); + return rc; + } + /* update the last activity on the connection */ + time(&(search->session->lastactivity)); + /* save msgid */ + search->msgid=msgid; + /* return the new search */ + return LDAP_SUCCESS; +} + +MYLDAP_SESSION *myldap_create_session(void) +{ + return myldap_session_new(); +} + +void myldap_session_cleanup(MYLDAP_SESSION *session) +{ + int i; + /* check parameter */ + if (!is_valid_session(session)) + { + log_log(LOG_ERR,"myldap_session_cleanup(): invalid session passed"); + return; + } + /* go over all searches in the session and close them */ + for (i=0;isearches[i]!=NULL) + { + myldap_search_close(session->searches[i]); + session->searches[i]=NULL; + } + } +} + +void myldap_session_close(MYLDAP_SESSION *session) +{ + /* check parameter */ + if (!is_valid_session(session)) + { + log_log(LOG_ERR,"myldap_session_cleanup(): invalid session passed"); + return; + } + /* close pending searches */ + myldap_session_cleanup(session); + /* close any open connections */ + do_close(session); + /* free allocated memory */ + free(session); +} + +/* mutex for updating the times in the uri */ +pthread_mutex_t uris_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int do_retry_search(MYLDAP_SEARCH *search) +{ + int sleeptime=0; + int start_uri; + time_t endtime; + time_t nexttry; + time_t t; + int rc=LDAP_UNAVAILABLE; + struct myldap_uri *current_uri; + int dotry[NSS_LDAP_CONFIG_URI_MAX]; + /* clear time stamps */ + for (start_uri=0;start_urildc_reconnect_retrytime; + while (1) + { + nexttry=endtime; + /* try each configured URL once */ + pthread_mutex_lock(&uris_mutex); + start_uri=search->session->current_uri; + do + { + current_uri=&(nslcd_cfg->ldc_uris[search->session->current_uri]); + /* only try this URI if we should */ + if (!dotry[search->session->current_uri]) + { /* skip this URI */ } + else if ( (current_uri->lastfail > (current_uri->firstfail+nslcd_cfg->ldc_reconnect_retrytime)) && + ((t=time(NULL)) < (current_uri->lastfail+nslcd_cfg->ldc_reconnect_retrytime)) ) + { + /* we are in a hard fail state and have retried not long ago */ + log_log(LOG_DEBUG,"not retrying server %s which failed just %d second(s) ago and has been failing for %d seconds", + current_uri->uri,(int)(t-current_uri->lastfail), + (int)(t-current_uri->firstfail)); + dotry[search->session->current_uri]=0; + } + else + { + /* try to start the search */ + pthread_mutex_unlock(&uris_mutex); + rc=do_try_search(search); + if (rc==LDAP_SUCCESS) + { + /* update ok time */ + pthread_mutex_lock(&uris_mutex); + current_uri->firstfail=0; + current_uri->lastfail=0; + /* check if we are coming back from an error */ + if ((current_uri->lastfail>0)||(search->session->current_uri!=start_uri)) + log_log(LOG_INFO,"connected to LDAP server %s",current_uri->uri); + pthread_mutex_unlock(&uris_mutex); + /* flag the search as valid */ + search->valid=1; + return LDAP_SUCCESS; + } + /* close the current connection */ + do_close(search->session); + /* update time of failure and figure out when we should retry */ + pthread_mutex_lock(&uris_mutex); + t=time(NULL); + /* update timestaps unless we are doing an authentication search */ + if (search->session->binddn[0]=='\0') + { + if (current_uri->firstfail==0) + current_uri->firstfail=t; + current_uri->lastfail=t; + } + /* if it is one of these, retrying this URI is not going to help */ + if ((rc==LDAP_INVALID_CREDENTIALS)||(rc==LDAP_INSUFFICIENT_ACCESS)|| + (rc==LDAP_AUTH_METHOD_NOT_SUPPORTED)) + dotry[search->session->current_uri]=0; + /* check when we should try this URI again */ + else if (t <= (current_uri->firstfail+nslcd_cfg->ldc_reconnect_retrytime)) + { + t+=nslcd_cfg->ldc_reconnect_sleeptime; + if (tsession->current_uri++; + if (nslcd_cfg->ldc_uris[search->session->current_uri].uri==NULL) + search->session->current_uri=0; + } + while (search->session->current_uri!=start_uri); + pthread_mutex_unlock(&uris_mutex); + /* see if it is any use sleeping */ + if (nexttry>=endtime) + { + if (search->session->binddn[0]=='\0') + log_log(LOG_ERR,"no available LDAP server found: %s",ldap_err2string(rc)); + return rc; + } + /* sleep between tries */ + sleeptime=nexttry-time(NULL); + if (sleeptime>0) + { + log_log(LOG_WARNING,"no available LDAP server found, sleeping %d seconds",sleeptime); + (void)sleep(sleeptime); + } + } +} + +MYLDAP_SEARCH *myldap_search( + MYLDAP_SESSION *session, + const char *base,int scope,const char *filter,const char **attrs, + int *rcp) +{ + MYLDAP_SEARCH *search; + int i; + int rc; + /* check parameters */ + if (!is_valid_session(session)||(base==NULL)||(filter==NULL)||(attrs==NULL)) + { + log_log(LOG_ERR,"myldap_search(): invalid parameter passed"); + errno=EINVAL; + if (rcp!=NULL) + *rcp=LDAP_OPERATIONS_ERROR; + return NULL; + } + /* log the call */ + log_log(LOG_DEBUG,"myldap_search(base=\"%s\", filter=\"%s\")", + base,filter); + /* check if the idle time for the connection has expired */ + myldap_session_check(session); + /* allocate a new search entry */ + search=myldap_search_new(session,base,scope,filter,attrs); + /* find a place in the session where we can register our search */ + for (i=0;(session->searches[i]!=NULL)&&(i=MAX_SEARCHES_IN_SESSION) + { + log_log(LOG_ERR,"myldap_search(): too many searches registered with session (max %d)", + MAX_SEARCHES_IN_SESSION); + myldap_search_close(search); + if (rcp!=NULL) + *rcp=LDAP_OPERATIONS_ERROR; + return NULL; + } + /* regsiter search with the session so we can free it later on */ + session->searches[i]=search; + /* do the search with retries to all configured servers */ + rc=do_retry_search(search); + if (rc!=LDAP_SUCCESS) + { + myldap_search_close(search); + if (rcp!=NULL) + *rcp=rc; + return NULL; + } + if (rcp!=NULL) + *rcp=LDAP_SUCCESS; + return search; +} + +void myldap_search_close(MYLDAP_SEARCH *search) +{ + int i; + if (search==NULL) + return; + /* free any messages */ + if (search->msg!=NULL) + { + ldap_msgfree(search->msg); + search->msg=NULL; + } + /* abandon the search if there were more results to fetch */ + if ((search->session->ld!=NULL)&&(search->msgid!=-1)) + { + ldap_abandon(search->session->ld,search->msgid); + search->msgid=-1; + } + /* find the reference to this search in the session */ + for (i=0;isession->searches[i]==search) + search->session->searches[i]=NULL; + } + /* free any search entries */ + if (search->entry!=NULL) + myldap_entry_free(search->entry); + /* clean up cookie */ + if (search->cookie!=NULL) + ber_bvfree(search->cookie); + /* free read messages */ + if (search->msg!=NULL) + ldap_msgfree(search->msg); + /* free the storage we allocated */ + free(search); +} + +MYLDAP_ENTRY *myldap_get_entry(MYLDAP_SEARCH *search,int *rcp) +{ + int rc; + int parserc; + int msgid; + struct timeval tv,*tvp; + LDAPControl **resultcontrols; + LDAPControl *serverctrls[2]; + ber_int_t count; + /* check parameters */ + if (!is_valid_search(search)) + { + log_log(LOG_ERR,"myldap_get_entry(): invalid search passed"); + errno=EINVAL; + if (rcp!=NULL) + *rcp=LDAP_OPERATIONS_ERROR; + return NULL; + } + /* check if the connection wasn't closed in another search */ + if (!search->valid) + { + log_log(LOG_WARNING,"myldap_get_entry(): connection was closed"); + /* retry the search */ + if (search->may_retry_search) + { + log_log(LOG_DEBUG,"myldap_get_entry(): retry search"); + search->may_retry_search=0; + if (do_retry_search(search)==LDAP_SUCCESS) + return myldap_get_entry(search,rcp); + } + myldap_search_close(search); + if (rcp!=NULL) + *rcp=LDAP_SERVER_DOWN; + return NULL; + } + /* set up a timelimit value for operations */ + if (nslcd_cfg->ldc_timelimit==LDAP_NO_LIMIT) + tvp=NULL; + else + { + tv.tv_sec=nslcd_cfg->ldc_timelimit; + tv.tv_usec=0; + tvp=&tv; + } + /* if we have an existing result entry, free it */ + if (search->entry!=NULL) + { + myldap_entry_free(search->entry); + search->entry=NULL; + } + /* try to parse results until we have a final error or ok */ + while (1) + { + /* free the previous message if there was any */ + if (search->msg!=NULL) + { + ldap_msgfree(search->msg); + search->msg=NULL; + } + /* get the next result */ + rc=ldap_result(search->session->ld,search->msgid,LDAP_MSG_ONE,tvp,&(search->msg)); + /* handle result */ + switch (rc) + { + case LDAP_RES_SEARCH_ENTRY: + /* we have a normal search entry, update timestamp and return result */ + time(&(search->session->lastactivity)); + search->entry=myldap_entry_new(search); + if (rcp!=NULL) + *rcp=LDAP_SUCCESS; + search->may_retry_search=0; + return search->entry; + case LDAP_RES_SEARCH_RESULT: + /* we have a search result, parse it */ + resultcontrols=NULL; + if (search->cookie!=NULL) + { + ber_bvfree(search->cookie); + search->cookie=NULL; + } + /* NB: this frees search->msg */ + parserc=ldap_parse_result(search->session->ld,search->msg,&rc,NULL, + NULL,NULL,&resultcontrols,1); + search->msg=NULL; + /* check for errors during parsing */ + if ((parserc!=LDAP_SUCCESS)&&(parserc!=LDAP_MORE_RESULTS_TO_RETURN)) + { + if (resultcontrols!=NULL) + ldap_controls_free(resultcontrols); + log_log(LOG_ERR,"ldap_parse_result() failed: %s",ldap_err2string(parserc)); + myldap_search_close(search); + if (rcp!=NULL) + *rcp=parserc; + return NULL; + } + /* check for errors in message */ + if ((rc!=LDAP_SUCCESS)&&(rc!=LDAP_MORE_RESULTS_TO_RETURN)) + { + if (resultcontrols!=NULL) + ldap_controls_free(resultcontrols); + log_log(LOG_ERR,"ldap_result() failed: %s",ldap_err2string(rc)); + /* close connection on connection problems */ + if ((rc==LDAP_UNAVAILABLE)||(rc==LDAP_SERVER_DOWN)) + do_close(search->session); + myldap_search_close(search); + if (rcp!=NULL) + *rcp=rc; + return NULL; + } + /* handle result controls */ + if (resultcontrols!=NULL) + { + /* see if there are any more pages to come */ + rc=ldap_parse_page_control(search->session->ld, + resultcontrols,&count, + &(search->cookie)); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_WARNING,"ldap_parse_page_control() failed: %s", + ldap_err2string(rc)); + /* clear error flag */ + rc=LDAP_SUCCESS; + ldap_set_option(search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc); + } + /* TODO: handle the above return code?? */ + ldap_controls_free(resultcontrols); + } + search->msgid=-1; + /* check if there are more pages to come */ + if ((search->cookie==NULL)||(search->cookie->bv_len==0)) + { + log_log(LOG_DEBUG,"ldap_result(): end of results"); + /* we are at the end of the search, no more results */ + myldap_search_close(search); + if (rcp!=NULL) + *rcp=LDAP_SUCCESS; + return NULL; + } + /* try the next page */ + serverctrls[0]=NULL; + serverctrls[1]=NULL; + rc=ldap_create_page_control(search->session->ld, + nslcd_cfg->ldc_pagesize, + search->cookie,0,&serverctrls[0]); + if (rc!=LDAP_SUCCESS) + { + if (serverctrls[0]!=NULL) + ldap_control_free(serverctrls[0]); + log_log(LOG_WARNING,"ldap_create_page_control() failed: %s", + ldap_err2string(rc)); + myldap_search_close(search); + if (rcp!=NULL) + *rcp=rc; + return NULL; + } + /* set up a new search for the next page */ + rc=ldap_search_ext(search->session->ld, + search->base,search->scope,search->filter, + search->attrs,0,serverctrls,NULL,NULL, + LDAP_NO_LIMIT,&msgid); + ldap_control_free(serverctrls[0]); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_WARNING,"ldap_search_ext() failed: %s", + ldap_err2string(rc)); + /* close connection on connection problems */ + if ((rc==LDAP_UNAVAILABLE)||(rc==LDAP_SERVER_DOWN)) + do_close(search->session); + myldap_search_close(search); + if (rcp!=NULL) + *rcp=rc; + return NULL; + } + search->msgid=msgid; + /* we continue with another pass */ + break; + case LDAP_RES_SEARCH_REFERENCE: + break; /* just ignore search references */ + default: + /* we have some error condition, find out which */ + switch (rc) + { + case -1: + /* try to get error code */ + if (ldap_get_option(search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc)!=LDAP_SUCCESS) + rc=LDAP_UNAVAILABLE; + log_log(LOG_ERR,"ldap_result() failed: %s",ldap_err2string(rc)); + break; + case 0: + /* the timeout expired */ + log_log(LOG_ERR,"ldap_result() timed out"); + rc=LDAP_TIMELIMIT_EXCEEDED; + break; + default: + /* unknown code */ + log_log(LOG_WARNING,"ldap_result() returned unexpected result type"); + rc=LDAP_PROTOCOL_ERROR; + } + /* close connection on some connection problems */ + if ((rc==LDAP_UNAVAILABLE)||(rc==LDAP_SERVER_DOWN)||(rc==LDAP_SUCCESS)|| + (rc==LDAP_TIMELIMIT_EXCEEDED)|(rc==LDAP_OPERATIONS_ERROR)|| + (rc==LDAP_PROTOCOL_ERROR)) + { + do_close(search->session); + /* retry once if no data has been received yet */ + if (search->may_retry_search) + { + log_log(LOG_DEBUG,"myldap_get_entry(): retry search"); + search->may_retry_search=0; + if (do_retry_search(search)==LDAP_SUCCESS) + return myldap_get_entry(search,rcp); + } + } + /* close search */ + myldap_search_close(search); + if (rcp!=NULL) + *rcp=rc; + return NULL; + } + } +} + +/* Get the DN from the entry. This function only returns NULL (and sets + errno) if an incorrect entry is passed. If the DN value cannot be + retreived "unknown" is returned instead. */ +const char *myldap_get_dn(MYLDAP_ENTRY *entry) +{ + int rc; + /* check parameters */ + if (!is_valid_entry(entry)) + { + log_log(LOG_ERR,"myldap_get_dn(): invalid result entry passed"); + errno=EINVAL; + return "unknown"; + } + /* if we don't have it yet, retreive it */ + if ((entry->dn==NULL)&&(entry->search->valid)) + { + entry->dn=ldap_get_dn(entry->search->session->ld,entry->search->msg); + if (entry->dn==NULL) + { + if (ldap_get_option(entry->search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc)!=LDAP_SUCCESS) + rc=LDAP_UNAVAILABLE; + log_log(LOG_WARNING,"ldap_get_dn() returned NULL: %s",ldap_err2string(rc)); + /* close connection on connection problems */ + if ((rc==LDAP_UNAVAILABLE)||(rc==LDAP_SERVER_DOWN)) + do_close(entry->search->session); + } + } + /* if we still don't have it, return unknown */ + if (entry->dn==NULL) + return "unknown"; + /* return it */ + return entry->dn; +} + +char *myldap_cpy_dn(MYLDAP_ENTRY *entry,char *buf,size_t buflen) +{ + const char *dn; + /* get the dn */ + dn=myldap_get_dn(entry); + /* copy into buffer */ + if (strlen(dn)search->session; + MYLDAP_SEARCH *search=NULL; + SET *set=NULL; + /* build the attribute name to find */ + if (mysnprintf(attbuf,sizeof(attbuf),"%s;range=0-*",attr)) + return NULL; + /* keep doing lookups untul we can't get any more results */ + while (1) + { + /* go over all attributes to find the ranged attribute */ + ber=NULL; + attn=ldap_first_attribute(entry->search->session->ld,entry->search->msg,&ber); + values=NULL; + while (attn!=NULL) + { + if (strncasecmp(attn,attbuf,strlen(attbuf)-1)==0) + { + log_log(LOG_DEBUG,"found ranged results %s",attn); + nxt=atoi(attn+strlen(attbuf)-1)+1; + values=ldap_get_values(entry->search->session->ld,entry->search->msg,attn); + ldap_memfree(attn); + break; + } + /* free old attribute name and get next one */ + ldap_memfree(attn); + attn=ldap_next_attribute(entry->search->session->ld,entry->search->msg,ber); + } + ber_free(ber,0); + /* see if we found any values */ + if ((values==NULL)||(*values==NULL)) + break; + /* allocate memory */ + if (set==NULL) + { + set=set_new(); + if (set==NULL) + { + ldap_value_free(values); + log_log(LOG_CRIT,"myldap_get_ranged_values(): set_new() failed to allocate memory"); + return NULL; + } + } + /* add to the set */ + for (i=0;values[i]!=NULL;i++) + set_add(set,values[i]); + /* free results */ + ldap_value_free(values); + /* check if we should start a new search */ + if (nxt<=startat) + break; + startat=nxt; + /* build attributes for a new search */ + if (mysnprintf(attbuf,sizeof(attbuf),"%s;range=%d-*",attr,startat)) + break; + attrs[0]=attbuf; + attrs[1]=NULL; + /* close the previous search, if any */ + if (search!=NULL) + myldap_search_close(search); + /* start the new search */ + search=myldap_search(session,dn,LDAP_SCOPE_BASE,"(objectClass=*)",attrs,NULL); + if (search==NULL) + break; + entry=myldap_get_entry(search,NULL); + if (entry==NULL) + break; + } + /* close any started searches */ + if (search!=NULL) + myldap_search_close(search); + /* return the contents of the set as a list */ + return set; +} + +/* Simple wrapper around ldap_get_values(). */ +const char **myldap_get_values(MYLDAP_ENTRY *entry,const char *attr) +{ + char **values; + int rc; + int i; + SET *set; + /* check parameters */ + if (!is_valid_entry(entry)) + { + log_log(LOG_ERR,"myldap_get_values(): invalid result entry passed"); + errno=EINVAL; + return NULL; + } + else if (attr==NULL) + { + log_log(LOG_ERR,"myldap_get_values(): invalid attribute name passed"); + errno=EINVAL; + return NULL; + } + if (!entry->search->valid) + return NULL; /* search has been stopped */ + /* get from LDAP */ + values=ldap_get_values(entry->search->session->ld,entry->search->msg,attr); + if (values==NULL) + { + if (ldap_get_option(entry->search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc)!=LDAP_SUCCESS) + rc=LDAP_UNAVAILABLE; + /* ignore decoding errors as they are just nonexisting attribute values */ + if (rc==LDAP_DECODING_ERROR) + { + rc=LDAP_SUCCESS; + ldap_set_option(entry->search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc); + } + else if (rc==LDAP_SUCCESS) + { + /* we have a success code but no values, let's try to get ranged + values */ + set=myldap_get_ranged_values(entry,attr); + if (set==NULL) + return NULL; + /* store values entry so we can free it later on */ + for (i=0;irangedattributevalues[i]==NULL) + { + entry->rangedattributevalues[i]=(char **)set_tolist(set); + set_free(set); + return (const char **)entry->rangedattributevalues[i]; + } + /* we found no room to store the values */ + log_log(LOG_ERR,"ldap_get_values() couldn't store results, increase MAX_RANGED_ATTRIBUTES_PER_ENTRY"); + set_free(set); + return NULL; + } + else + log_log(LOG_WARNING,"ldap_get_values() of attribute \"%s\" on entry \"%s\" returned NULL: %s", + attr,myldap_get_dn(entry),ldap_err2string(rc)); + return NULL; + } + /* store values entry so we can free it later on */ + for (i=0;iattributevalues[i]==NULL) + { + entry->attributevalues[i]=values; + return (const char **)values; + } + /* we found no room to store the entry */ + log_log(LOG_ERR,"ldap_get_values() couldn't store results, increase MAX_ATTRIBUTES_PER_ENTRY"); + ldap_value_free(values); + return NULL; +} + +/* Convert the bervalues to a simple list of strings that can be freed + with one call to free(). */ +static const char **bervalues_to_values(struct berval **bvalues) +{ + int num_values; + int i; + size_t sz; + char *buf; + char **values; + /* figure out how much memory to allocate */ + num_values=ldap_count_values_len(bvalues); + sz=(num_values+1)*sizeof(char *); + for (i=0;ibv_len+1; + /* allocate the needed memory */ + buf=(char *)malloc(sz); + if (buf==NULL) + { + log_log(LOG_CRIT,"myldap_get_values_len(): malloc() failed to allocate memory"); + ldap_value_free_len(bvalues); + return NULL; + } + values=(char **)buf; + buf+=(num_values+1)*sizeof(char *); + /* copy from bvalues */ + for (i=0;ibv_val,bvalues[i]->bv_len); + values[i][bvalues[i]->bv_len]='\0'; + buf+=bvalues[i]->bv_len+1; + } + values[i]=NULL; + return (const char **)values; +} + +/* Simple wrapper around ldap_get_values(). */ +const char **myldap_get_values_len(MYLDAP_ENTRY *entry,const char *attr) +{ + const char **values; + struct berval **bvalues; + int rc; + int i; + SET *set; + /* check parameters */ + if (!is_valid_entry(entry)) + { + log_log(LOG_ERR,"myldap_get_values_len(): invalid result entry passed"); + errno=EINVAL; + return NULL; + } + else if (attr==NULL) + { + log_log(LOG_ERR,"myldap_get_values_len(): invalid attribute name passed"); + errno=EINVAL; + return NULL; + } + if (!entry->search->valid) + return NULL; /* search has been stopped */ + /* get from LDAP */ + bvalues=ldap_get_values_len(entry->search->session->ld,entry->search->msg,attr); + if (bvalues==NULL) + { + if (ldap_get_option(entry->search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc)!=LDAP_SUCCESS) + rc=LDAP_UNAVAILABLE; + /* ignore decoding errors as they are just nonexisting attribute values */ + if (rc==LDAP_DECODING_ERROR) + { + rc=LDAP_SUCCESS; + ldap_set_option(entry->search->session->ld,LDAP_OPT_ERROR_NUMBER,&rc); + } + else if (rc==LDAP_SUCCESS) + { + /* we have a success code but no values, let's try to get ranged + values */ + set=myldap_get_ranged_values(entry,attr); + if (set==NULL) + return NULL; + values=set_tolist(set); + } + else + log_log(LOG_WARNING,"myldap_get_values_len() of attribute \"%s\" on entry \"%s\" returned NULL: %s", + attr,myldap_get_dn(entry),ldap_err2string(rc)); + return NULL; + } + else + { + values=bervalues_to_values(bvalues); + ldap_value_free_len(bvalues); + } + /* store values entry so we can free it later on */ + for (i=0;irangedattributevalues[i]==NULL) + { + entry->rangedattributevalues[i]=(char **)values; + return values; + } + /* we found no room to store the values */ + log_log(LOG_ERR,"myldap_get_values_len() couldn't store results, increase MAX_RANGED_ATTRIBUTES_PER_ENTRY"); + free(values); + return NULL; +} + +/* Go over the entries in exploded_rdn and see if any start with + the requested attribute. Return a reference to the value part of + the DN (does not modify exploded_rdn). */ +static const char *find_rdn_value(char **exploded_rdn,const char *attr) +{ + int i,j; + int l; + if (exploded_rdn==NULL) + return NULL; + /* go over all RDNs */ + l=strlen(attr); + for (i=0;exploded_rdn[i]!=NULL;i++) + { + /* check that RDN starts with attr */ + if (strncasecmp(exploded_rdn[i],attr,l)!=0) + continue; + j=l; + /* skip spaces */ + while (isspace(exploded_rdn[i][j])) j++; + /* ensure that we found an equals sign now */ + if (exploded_rdn[i][j]!='=') + continue; + j++; + /* skip more spaces */ + while (isspace(exploded_rdn[i][j])) j++; + /* ensure that we're not at the end of the string */ + if (exploded_rdn[i][j]=='\0') + continue; + /* we found our value */ + return exploded_rdn[i]+j; + } + /* fail */ + return NULL; +} + +/* explode the first part of DN into parts + (e.g. "cn=Test", "uid=test") + The returned value should be freed with ldap_value_free(). */ +static char **get_exploded_rdn(const char *dn) +{ + char **exploded_dn; + char **exploded_rdn; + /* check if we have a DN */ + if ((dn==NULL)||(strcasecmp(dn,"unknown")==0)) + return NULL; + /* explode dn into { "uid=test", "ou=people", ..., NULL } */ + exploded_dn=ldap_explode_dn(dn,0); + if ((exploded_dn==NULL)||(exploded_dn[0]==NULL)) + { + log_log(LOG_WARNING,"ldap_explode_dn(%s) returned NULL: %s", + dn,strerror(errno)); + return NULL; + } + /* explode rdn (first part of exploded_dn), + e.g. "cn=Test User+uid=testusr" into + { "cn=Test User", "uid=testusr", NULL } */ + errno=0; + exploded_rdn=ldap_explode_rdn(exploded_dn[0],0); + if ((exploded_rdn==NULL)||(exploded_rdn[0]==NULL)) + { + log_log(LOG_WARNING,"ldap_explode_rdn(%s) returned NULL: %s", + exploded_dn[0],strerror(errno)); + if (exploded_rdn!=NULL) + ldap_value_free(exploded_rdn); + ldap_value_free(exploded_dn); + return NULL; + } + ldap_value_free(exploded_dn); + return exploded_rdn; +} + +const char *myldap_get_rdn_value(MYLDAP_ENTRY *entry,const char *attr) +{ + /* check parameters */ + if (!is_valid_entry(entry)) + { + log_log(LOG_ERR,"myldap_get_rdn_value(): invalid result entry passed"); + errno=EINVAL; + return NULL; + } + else if (attr==NULL) + { + log_log(LOG_ERR,"myldap_get_rdn_value(): invalid attribute name passed"); + errno=EINVAL; + return NULL; + } + /* check if entry contains exploded_rdn */ + if (entry->exploded_rdn==NULL) + { + entry->exploded_rdn=get_exploded_rdn(myldap_get_dn(entry)); + if (entry->exploded_rdn==NULL) + return NULL; + } + /* find rnd value */ + return find_rdn_value(entry->exploded_rdn,attr); +} + +const char *myldap_cpy_rdn_value(const char *dn,const char *attr, + char *buf,size_t buflen) +{ + char **exploded_rdn; + const char *value; + /* explode dn into { "cn=Test", "uid=test", NULL } */ + exploded_rdn=get_exploded_rdn(dn); + if (exploded_rdn==NULL) + return NULL; + /* see if we have a match */ + value=find_rdn_value(exploded_rdn,attr); + /* if we have something store it in the buffer */ + if ((value!=NULL)&&(strlen(value)=buflen) + return -1; + /* do escaping for some characters */ + switch (*src) + { + case '*': + strcpy(buffer+pos,"\\2a"); + pos+=3; + break; + case '(': + strcpy(buffer+pos,"\\28"); + pos+=3; + break; + case ')': + strcpy(buffer+pos,"\\29"); + pos+=3; + break; + case '\\': + strcpy(buffer+pos,"\\5c"); + pos+=3; + break; + default: + /* just copy character */ + buffer[pos++]=*src; + break; + } + } + /* terminate destination string */ + buffer[pos]='\0'; + return 0; +} + +int myldap_set_debuglevel(int level) +{ + int i; + int rc; + /* turn on debugging */ + if (level>1) + { +#ifdef LBER_OPT_LOG_PRINT_FILE + log_log(LOG_DEBUG,"ber_set_option(LBER_OPT_LOG_PRINT_FILE)"); \ + rc=ber_set_option(NULL,LBER_OPT_LOG_PRINT_FILE,stderr); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_ERR,"ber_set_option(LBER_OPT_LOG_PRINT_FILE) failed: %s",ldap_err2string(rc)); + return rc; + } +#endif /* LBER_OPT_LOG_PRINT_FILE */ +#ifdef LBER_OPT_DEBUG_LEVEL + if (level>2) + { + i=-1; + log_log(LOG_DEBUG,"ber_set_option(LBER_OPT_DEBUG_LEVEL,-1)"); + rc=ber_set_option(NULL,LBER_OPT_DEBUG_LEVEL,&i); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_ERR,"ber_set_option(LBER_OPT_DEBUG_LEVEL) failed: %s",ldap_err2string(rc)); + return rc; + } + } +#endif /* LBER_OPT_DEBUG_LEVEL */ +#ifdef LDAP_OPT_DEBUG_LEVEL + i=-1; + log_log(LOG_DEBUG,"ldap_set_option(LDAP_OPT_DEBUG_LEVEL,-1)"); + rc=ldap_set_option(NULL,LDAP_OPT_DEBUG_LEVEL,&i); + if (rc!=LDAP_SUCCESS) + { + log_log(LOG_ERR,"ldap_set_option(LDAP_OPT_DEBUG_LEVEL) failed: %s",ldap_err2string(rc)); + return rc; + } +#endif /* LDAP_OPT_DEBUG_LEVEL */ + } + return LDAP_SUCCESS; +} + +int myldap_passwd( + MYLDAP_SESSION *session, + const char *userdn,const char *oldpassword,const char *newpasswd) +{ + int rc; + struct berval ber_userdn, ber_oldpassword, ber_newpassword, ber_retpassword; + /* check parameters */ + if (!is_valid_session(session)||(userdn==NULL)||(newpasswd==NULL)) + { + log_log(LOG_ERR,"myldap_passwd(): invalid parameter passed"); + errno=EINVAL; + return LDAP_OTHER; + } + /* log the call */ + log_log(LOG_DEBUG,"myldap_passwd(userdn=\"%s\",oldpasswd=%s,newpasswd=\"***\")", + userdn,oldpassword?"\"***\"":"NULL"); + /* translate to ber stuff */ + ber_userdn.bv_val=(char *)userdn; + ber_userdn.bv_len=strlen(userdn); + ber_newpassword.bv_val=(char *)newpasswd; + ber_newpassword.bv_len=strlen(newpasswd); + ber_retpassword.bv_val=NULL; + ber_retpassword.bv_len=0; + /* perform request */ + log_log(LOG_DEBUG,"myldap_passwd(): try ldap_passwd_s() without old password"); + rc=ldap_passwd_s(session->ld,&ber_userdn,NULL, + &ber_newpassword,&ber_retpassword,NULL,NULL); + if (rc!=LDAP_SUCCESS) + log_log(LOG_ERR,"ldap_passwd_s() without old password failed: %s",ldap_err2string(rc)); + /* free returned data if needed */ + if (ber_retpassword.bv_val!=NULL) + ldap_memfree(ber_retpassword.bv_val); + if ((rc!=LDAP_SUCCESS)&&(oldpassword!=NULL)) + { + /* retry with old password */ + log_log(LOG_DEBUG,"myldap_passwd(): try ldap_passwd_s() with old password"); + ber_oldpassword.bv_val=(char *)oldpassword; + ber_oldpassword.bv_len=strlen(oldpassword); + /* perform request */ + rc=ldap_passwd_s(session->ld,&ber_userdn,&ber_oldpassword, + &ber_newpassword,&ber_retpassword,NULL,NULL); + if (rc!=LDAP_SUCCESS) + log_log(LOG_ERR,"ldap_passwd_s() with old password failed: %s",ldap_err2string(rc)); + /* free returned data if needed */ + if (ber_retpassword.bv_val!=NULL) + ldap_memfree(ber_retpassword.bv_val); + } + return rc; +} + +int myldap_modify(MYLDAP_SESSION *session,const char *dn,LDAPMod *mods[]) +{ + if (!is_valid_session(session)||(dn==NULL)) + { + log_log(LOG_ERR,"myldap_passwd(): invalid parameter passed"); + errno=EINVAL; + return LDAP_OTHER; + } + return ldap_modify_ext_s(session->ld,dn,mods,NULL,NULL); +} diff --git a/nslcd/myldap.h b/nslcd/myldap.h new file mode 100644 index 0000000..f118f72 --- /dev/null +++ b/nslcd/myldap.h @@ -0,0 +1,154 @@ +/* + myldap.h - simple interface to do LDAP requests + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +/* + This file describes the API of the myldap module which takes the complexity + out of using the OpenLDAP library. Memory management, paging, reconnect + logic, idle timeout of connections, etc is taken care of by the module. + + Use of this module is very straightforeward. You first have to create a + session (with myldap_create_session()), with this session you can start + searches (with myldap_search()), from a search you can get entries (with + myldap_get_entry()) from the LDAP database and from these entries you can + get attribute values (with myldap_get_values()). +*/ + +#ifndef NSLCD__MYLDAP_H +#define NSLCD__MYLDAP_H + +/* for size_t */ +#include +/* for LDAP_SCOPE_* */ +#include +#include + +#include "compat/attrs.h" + +#ifndef LDAP_SCOPE_DEFAULT +#define LDAP_SCOPE_DEFAULT LDAP_SCOPE_SUBTREE +#endif /* not LDAP_SCOPE_DEFAULT */ + +/* This a a generic session handle. */ +typedef struct ldap_session MYLDAP_SESSION; + +/* Note that this session handle may be used within one thread only. No + locking is performed to prevent concurrent modifications. Most LDAP + libraries also are not thread-safe in that a single connection may be + shared by multiple threads. It seems however that OpenLDAP at least does + not have any problems with an LDAP *ld per thread. + http://www.openldap.org/lists/openldap-software/200606/msg00252.html */ + +/* A result set as returned by myldap_search(). */ +typedef struct myldap_search MYLDAP_SEARCH; + +/* A single entry from the LDAP database as returned by myldap_get_entry(). */ +typedef struct myldap_entry MYLDAP_ENTRY; + +/* Create a new session, this does not yet connect to the LDAP server. The + connection to the server is made on-demand when a search is performed. This + uses the configuration to find the URLs to attempt connections to. */ +MUST_USE MYLDAP_SESSION *myldap_create_session(void); + +/* Set alternative credentials for the session. */ +void myldap_set_credentials(MYLDAP_SESSION *session,const char *dn, + const char *password); + +/* Closes all pending searches and deallocates any memory that is allocated + with these searches. This does not close the session. */ +void myldap_session_cleanup(MYLDAP_SESSION *session); + +/* This checks the timeout value of the session and closes the connection + to the LDAP server if the timeout has expired and there are no pending + searches. */ +void myldap_session_check(MYLDAP_SESSION *session); + +/* Close the session and free all the resources allocated for the session. + After a call to this function the referenced handle is invalid. */ +void myldap_session_close(MYLDAP_SESSION *session); + +/* Do an LDAP search and return a reference to the results (returns NULL on + error). This function uses paging, and does reconnects to the configured + URLs transparently. The function returns an LDAP status code in the + location pointed to by rcp if it is non-NULL. */ +MUST_USE MYLDAP_SEARCH *myldap_search( + MYLDAP_SESSION *session, + const char *base,int scope,const char *filter,const char **attrs, + int *rcp); + +/* Close the specified search. This frees all the memory that was allocated + for the search and its results. */ +void myldap_search_close(MYLDAP_SEARCH *search); + +/* Get an entry from the result set, going over all results (returns NULL if + no more entries are available). Note that any memory allocated to return + information about the previous entry (e.g. with myldap_get_values()) is + freed with this call. The search is autoamtically closed when no more + results are available. The function returns an LDAP status code in the + location pointed to by rcp if it is non-NULL. */ +MUST_USE MYLDAP_ENTRY *myldap_get_entry(MYLDAP_SEARCH *search,int *rcp); + +/* Get the DN from the entry. This function does not return NULL (on error + "unknown" is returned). */ +MUST_USE const char *myldap_get_dn(MYLDAP_ENTRY *entry); + +/* Just like myldap_get_dn() but copies the result into the buffer. */ +char *myldap_cpy_dn(MYLDAP_ENTRY *entry,char *buf,size_t buflen); + +/* Get the attribute values from a certain entry as a NULL terminated list. + May return NULL or an empty array. */ +MUST_USE const char **myldap_get_values(MYLDAP_ENTRY *entry,const char *attr); + +/* Get the attribute values from a certain entry as a NULL terminated list. + May return NULL or an empty array. */ +MUST_USE const char **myldap_get_values_len(MYLDAP_ENTRY *entry,const char *attr); + +/* Checks to see if the entry has the specified object class. */ +MUST_USE int myldap_has_objectclass(MYLDAP_ENTRY *entry,const char *objectclass); + +/* Get the RDN's value: eg. if the DN was cn=lukeh, ou=People, dc=example, + dc=com getrdnvalue(entry,cn) would return lukeh. If the attribute was not + found in the DN or if some error occurs NULL is returned. This method may + be used to get the "most authorative" value for an attribute. */ +MUST_USE const char *myldap_get_rdn_value(MYLDAP_ENTRY *entry,const char *attr); + +/* Just like myldap_get_rdn_value() but use the supplied character sequence + and copies the result into the buffer. + Returns a pointer to the start of the string on success and NULL on + failure. */ +MUST_USE const char *myldap_cpy_rdn_value(const char *dn,const char *attr, + char *buf,size_t buflen); + +/* Escapes characters in a string for use in a search filter. */ +MUST_USE int myldap_escape(const char *src,char *buffer,size_t buflen); + +/* Set the debug level globally. Returns an LDAP status code. */ +int myldap_set_debuglevel(int level); + +/* Perform an EXOP password modification call. Returns an LDAP status code. */ +int myldap_passwd( + MYLDAP_SESSION *session, + const char *userdn,const char *oldpassword,const char *newpasswd); + +/* Perform an LDAP modification request. Returns an LDAP status code. */ +int myldap_modify(MYLDAP_SESSION *session,const char *dn,LDAPMod *mods[]); + +#endif /* not NSLCD__MYLDAP_H */ diff --git a/nslcd/netgroup.c b/nslcd/netgroup.c new file mode 100644 index 0000000..27bc531 --- /dev/null +++ b/nslcd/netgroup.c @@ -0,0 +1,249 @@ +/* + netgroup.c - netgroup lookup routines + Parts of this file were part of the nss_ldap library (as ldap-netgrp.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* ( nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL + * DESC 'Abstraction of a netgroup. May refer to other netgroups' + * MUST cn + * MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) + */ + +/* the search base for searches */ +const char *netgroup_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int netgroup_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *netgroup_filter = "(objectClass=nisNetgroup)"; + +/* the attributes to request with searches */ +const char *attmap_netgroup_cn = "cn"; +const char *attmap_netgroup_nisNetgroupTriple = "nisNetgroupTriple"; +const char *attmap_netgroup_memberNisNetgroup = "memberNisNetgroup"; + +/* the attribute list to request with searches */ +static const char *netgroup_attrs[4]; + +static int mkfilter_netgroup_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if (myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + netgroup_filter, + attmap_netgroup_cn,safename); +} + +void netgroup_init(void) +{ + int i; + /* set up search bases */ + if (netgroup_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (netgroup_scope==LDAP_SCOPE_DEFAULT) + netgroup_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + netgroup_attrs[0]=attmap_netgroup_cn; + netgroup_attrs[1]=attmap_netgroup_nisNetgroupTriple; + netgroup_attrs[2]=attmap_netgroup_memberNisNetgroup; + netgroup_attrs[3]=NULL; +} + +static int write_string_stripspace_len(TFILE *fp,const char *str,int len) +{ + int32_t tmpint32; + int i,j; + DEBUG_PRINT("WRITE_STRING: var="__STRING(str)" string=\"%s\"",str); + if (str==NULL) + { + WRITE_INT32(fp,0); + } + else + { + /* skip leading spaces */ + for (i=0;(str[i]!='\0')&&(isspace(str[i]));i++) + /* nothing else to do */ ; + /* skip trailing spaces */ + for (j=len;(j>i)&&(isspace(str[j-1]));j--) + /* nothing else to do */ ; + /* write length of string */ + WRITE_INT32(fp,j-i); + /* write string itself */ + if (j>i) + { + WRITE(fp,str+i,j-i); + } + } + /* we're done */ + return 0; +} + +#define WRITE_STRING_STRIPSPACE_LEN(fp,str,len) \ + if (write_string_stripspace_len(fp,str,len)) \ + return -1; + +#define WRITE_STRING_STRIPSPACE(fp,str) \ + WRITE_STRING_STRIPSPACE_LEN(fp,str,strlen(str)) + +static int write_netgroup_triple(TFILE *fp,const char *triple) +{ + int32_t tmpint32; + int i; + int hostb,hoste,userb,usere,domainb,domaine; + /* skip leading spaces */ + for (i=0;(triple[i]!='\0')&&(isspace(triple[i]));i++) + /* nothing else to do */ ; + /* we should have a bracket now */ + if (triple[i]!='(') + { + log_log(LOG_WARNING,"write_netgroup_triple(): entry does not begin with '(' (entry skipped)"); + return 0; + } + i++; + hostb=i; + /* find comma (end of host string) */ + for (;(triple[i]!='\0')&&(triple[i]!=',');i++) + /* nothing else to do */ ; + if (triple[i]!=',') + { + log_log(LOG_WARNING,"write_netgroup_triple(): missing ',' (entry skipped)"); + return 0; + } + hoste=i; + i++; + userb=i; + /* find comma (end of user string) */ + for (;(triple[i]!='\0')&&(triple[i]!=',');i++) + /* nothing else to do */ ; + if (triple[i]!=',') + { + log_log(LOG_WARNING,"write_netgroup_triple(): missing ',' (entry skipped)"); + return 0; + } + usere=i; + i++; + domainb=i; + /* find closing bracket (end of domain string) */ + for (;(triple[i]!='\0')&&(triple[i]!=')');i++) + /* nothing else to do */ ; + if (triple[i]!=')') + { + log_log(LOG_WARNING,"write_netgroup_triple(): missing ')' (entry skipped)"); + return 0; + } + domaine=i; + i++; + /* skip trailing spaces */ + for (;(triple[i]!='\0')&&(isspace(triple[i]));i++) + /* nothing else to do */ ; + /* if anything is left in the string we have a problem */ + if (triple[i]!='\0') + { + log_log(LOG_WARNING,"write_netgroup_triple(): string contains trailing data (entry skipped)"); + return 0; + } + /* write strings */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_INT32(fp,NSLCD_NETGROUP_TYPE_TRIPLE); + WRITE_STRING_STRIPSPACE_LEN(fp,triple+hostb,hoste-hostb) + WRITE_STRING_STRIPSPACE_LEN(fp,triple+userb,usere-userb) + WRITE_STRING_STRIPSPACE_LEN(fp,triple+domainb,domaine-domainb) + /* we're done */ + return 0; +} + +#define WRITE_NETGROUP_TRIPLE(fp,triple) \ + if (write_netgroup_triple(fp,triple)) \ + return -1; + +static int write_netgroup(TFILE *fp,MYLDAP_ENTRY *entry, const char *reqname) +{ + int32_t tmpint32; + int i; + const char **names; + const char **triples; + const char **members; + /* get the netgroup name */ + names=myldap_get_values(entry,attmap_netgroup_cn); + for (i=0;(names[i]!=NULL)&&(strcmp(reqname,names[i])!=0);i++) + /* nothing here */ ; + if (names[i]==NULL) + return 0; /* the name was not found */ + /* get the netgroup triples and member */ + triples=myldap_get_values(entry,attmap_netgroup_nisNetgroupTriple); + members=myldap_get_values(entry,attmap_netgroup_memberNisNetgroup); + /* write the netgroup triples */ + if (triples!=NULL) + for (i=0;triples[i]!=NULL;i++) + { + WRITE_NETGROUP_TRIPLE(fp,triples[i]); + } + /* write netgroup members */ + if (members!=NULL) + for (i=0;members[i]!=NULL;i++) + { + /* write the result code */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + /* write triple indicator */ + WRITE_INT32(fp,NSLCD_NETGROUP_TYPE_NETGROUP); + /* write netgroup name */ + WRITE_STRING_STRIPSPACE(fp,members[i]); + } + /* we're done */ + return 0; +} + +NSLCD_HANDLE( + netgroup,byname, + char name[256]; + char filter[1024]; + READ_STRING(fp,name); + log_setrequest("netgroup=\"%s\"",name);, + NSLCD_ACTION_NETGROUP_BYNAME, + mkfilter_netgroup_byname(name,filter,sizeof(filter)), + write_netgroup(fp,entry,name) +) diff --git a/nslcd/network.c b/nslcd/network.c new file mode 100644 index 0000000..39b0e3e --- /dev/null +++ b/nslcd/network.c @@ -0,0 +1,190 @@ +/* + network.c - network address entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-network.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* ( nisSchema.2.7 NAME 'ipNetwork' SUP top STRUCTURAL + * DESC 'Abstraction of a network. The distinguished value of + * MUST ( cn $ ipNetworkNumber ) + * MAY ( ipNetmaskNumber $ l $ description $ manager ) ) + */ + +/* the search base for searches */ +const char *network_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int network_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *network_filter = "(objectClass=ipNetwork)"; + +/* the attributes used in searches */ +const char *attmap_network_cn = "cn"; +const char *attmap_network_ipNetworkNumber = "ipNetworkNumber"; + +/* the attribute list to request with searches */ +static const char *network_attrs[3]; + +/* create a search filter for searching a network entry + by name, return -1 on errors */ +static int mkfilter_network_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[1024]; + /* escape attribute */ + if (myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + network_filter, + attmap_network_cn,safename); +} + +static int mkfilter_network_byaddr(const char *addrname, + char *buffer,size_t buflen) +{ + char safeaddr[64]; + /* escape attribute */ + if (myldap_escape(addrname,safeaddr,sizeof(safeaddr))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + network_filter, + attmap_network_ipNetworkNumber,safeaddr); +} + +void network_init(void) +{ + int i; + /* set up search bases */ + if (network_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (network_scope==LDAP_SCOPE_DEFAULT) + network_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + network_attrs[0]=attmap_network_cn; + network_attrs[1]=attmap_network_ipNetworkNumber; + network_attrs[2]=NULL; +} + +/* write a single network entry to the stream */ +static int write_network(TFILE *fp,MYLDAP_ENTRY *entry) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + int numaddr,i; + const char *networkname; + const char **networknames; + const char **addresses; + /* get the most canonical name */ + networkname=myldap_get_rdn_value(entry,attmap_network_cn); + /* get the other names for the network */ + networknames=myldap_get_values(entry,attmap_network_cn); + if ((networknames==NULL)||(networknames[0]==NULL)) + { + log_log(LOG_WARNING,"network entry %s does not contain %s value", + myldap_get_dn(entry),attmap_network_cn); + return 0; + } + /* if the networkname is not yet found, get the first entry from networknames */ + if (networkname==NULL) + networkname=networknames[0]; + /* get the addresses */ + addresses=myldap_get_values(entry,attmap_network_ipNetworkNumber); + if ((addresses==NULL)||(addresses[0]==NULL)) + { + log_log(LOG_WARNING,"network entry %s does not contain %s value", + myldap_get_dn(entry),attmap_network_ipNetworkNumber); + return 0; + } + /* write the entry */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,networkname); + WRITE_STRINGLIST_EXCEPT(fp,networknames,networkname); + for (numaddr=0;addresses[numaddr]!=NULL;numaddr++) + /*noting*/ ; + WRITE_INT32(fp,numaddr); + for (i=0;i +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ +#include +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif /* HAVE_GETOPT_H */ +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_GRP_H +#include +#endif /* HAVE_GRP_H */ +#ifdef HAVE_NSS_H +#include +#endif /* HAVE_NSS_H */ +#include +#ifndef HAVE_GETOPT_LONG +#include "compat/getopt_long.h" +#endif /* not HAVE_GETOPT_LONG */ +#include "compat/daemon.h" +#include +#include +#include + +#include "nslcd.h" +#include "log.h" +#include "cfg.h" +#include "common.h" +#include "compat/attrs.h" +#include "compat/getpeercred.h" + +/* buffer sizes for I/O */ +#define READBUFFER_MINSIZE 32 +#define READBUFFER_MAXSIZE 64 +#define WRITEBUFFER_MINSIZE 64 +#define WRITEBUFFER_MAXSIZE 1*1024*1024 + +/* flag to indictate if we are in debugging mode */ +static int nslcd_debugging=0; + +/* flag to indicate user requested the --check option */ +static int nslcd_checkonly=0; + +/* the exit flag to indicate that a signal was received */ +static volatile int nslcd_exitsignal=0; + +/* the server socket used for communication */ +static int nslcd_serversocket=-1; + +/* thread ids of all running threads */ +static pthread_t *nslcd_threads; + +/* if we don't have clearenv() we have to do this the hard way */ +#ifndef HAVE_CLEARENV + +/* the definition of the environment */ +extern char **environ; + +/* the environment we want to use */ +static char *sane_environment[] = { + "HOME=/", + "TMPDIR=/tmp", + "LDAPNOINIT=1", + NULL +}; + +#endif /* not HAVE_CLEARENV */ + +/* display version information */ +static void display_version(FILE *fp) +{ + fprintf(fp,"%s\n",PACKAGE_STRING); + fprintf(fp,"Written by Luke Howard and Arthur de Jong.\n\n"); + fprintf(fp,"Copyright (C) 1997-2011 Luke Howard, Arthur de Jong and West Consulting\n" + "This is free software; see the source for copying conditions. There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); +} + +/* display usage information */ +static void display_usage(FILE *fp,const char *program_name) +{ + fprintf(fp,"Usage: %s [OPTION]...\n",program_name); + fprintf(fp,"Name Service LDAP connection daemon.\n"); + fprintf(fp," -c, --check check if the daemon already is running\n"); + fprintf(fp," -d, --debug don't fork and print debugging to stderr\n"); + fprintf(fp," --help display this help and exit\n"); + fprintf(fp," --version output version information and exit\n"); + fprintf(fp,"\n" + "Report bugs to <%s>.\n",PACKAGE_BUGREPORT); +} + +/* the definition of options for getopt(). see getopt(2) */ +static struct option const nslcd_options[] = +{ + { "check", no_argument, NULL, 'c' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; +#define NSLCD_OPTIONSTRING "cdhV" + +/* parse command line options and save settings in struct */ +static void parse_cmdline(int argc,char *argv[]) +{ + int optc; + while ((optc=getopt_long(argc,argv,NSLCD_OPTIONSTRING,nslcd_options,NULL))!=-1) + { + switch (optc) + { + case 'c': /* -c, --check check if the daemon already is running */ + nslcd_checkonly=1; + break; + case 'd': /* -d, --debug don't fork and print debugging to stderr */ + nslcd_debugging++; + log_setdefaultloglevel(LOG_DEBUG); + break; + case 'h': /* --help display this help and exit */ + display_usage(stdout,argv[0]); + exit(EXIT_SUCCESS); + case 'V': /* --version output version information and exit */ + display_version(stdout); + exit(EXIT_SUCCESS); + case ':': /* missing required parameter */ + case '?': /* unknown option character or extraneous parameter */ + default: + fprintf(stderr,"Try '%s --help' for more information.\n", + argv[0]); + exit(EXIT_FAILURE); + } + } + /* check for remaining arguments */ + if (optind= 0) + { + if (close(nslcd_serversocket)) + log_log(LOG_WARNING,"problem closing server socket (ignored): %s",strerror(errno)); + } + /* remove existing named socket */ + if (unlink(NSLCD_SOCKET)<0) + { + log_log(LOG_DEBUG,"unlink() of "NSLCD_SOCKET" failed (ignored): %s", + strerror(errno)); + } + /* remove pidfile */ + if (unlink(NSLCD_PIDFILE)<0) + { + log_log(LOG_DEBUG,"unlink() of "NSLCD_PIDFILE" failed (ignored): %s", + strerror(errno)); + } + /* log exit */ + log_log(LOG_INFO,"version %s bailing out",VERSION); +} + +/* create the directory for the specified file to reside in */ +static void mkdirname(const char *filename) +{ + char *tmpname; + tmpname=strdup(filename); + if (tmpname==NULL) return; + (void)mkdir(dirname(tmpname),(mode_t)0755); + free(tmpname); +} + +/* returns a socket ready to answer requests from the client, + exit()s on error */ +static int create_socket(const char *filename) +{ + int sock; + int i; + struct sockaddr_un addr; + /* create a socket */ + if ( (sock=socket(PF_UNIX,SOCK_STREAM,0))<0 ) + { + log_log(LOG_ERR,"cannot create socket: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* remove existing named socket */ + if (unlink(filename)<0) + { + log_log(LOG_DEBUG,"unlink() of %s failed (ignored): %s", + filename,strerror(errno)); + } + /* do not block on accept() */ + if ((i=fcntl(sock,F_GETFL,0))<0) + { + log_log(LOG_ERR,"fctnl(F_GETFL) failed: %s",strerror(errno)); + if (close(sock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + if (fcntl(sock,F_SETFL,i|O_NONBLOCK)<0) + { + log_log(LOG_ERR,"fctnl(F_SETFL,O_NONBLOCK) failed: %s",strerror(errno)); + if (close(sock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* create the directory if needed */ + mkdirname(filename); + /* create socket address structure */ + memset(&addr,0,sizeof(struct sockaddr_un)); + addr.sun_family=AF_UNIX; + strncpy(addr.sun_path,filename,sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path)-1]='\0'; + /* bind to the named socket */ + if (bind(sock,(struct sockaddr *)&addr,(sizeof(addr.sun_family)+strlen(addr.sun_path)))) + { + log_log(LOG_ERR,"bind() to %s failed: %s",filename,strerror(errno)); + if (close(sock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* close the file descriptor on exit */ + if (fcntl(sock,F_SETFD,FD_CLOEXEC)<0) + { + log_log(LOG_ERR,"fctnl(F_SETFL,FD_CLOEXEC) failed: %s",strerror(errno)); + if (close(sock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* set permissions of socket so anybody can do requests */ + /* Note: we use chmod() here instead of fchmod() because + fchmod does not work on sockets + http://www.opengroup.org/onlinepubs/009695399/functions/fchmod.html + http://lkml.org/lkml/2005/5/16/11 */ + if (chmod(filename,(mode_t)0666)) + { + log_log(LOG_ERR,"chmod(0666) failed: %s",strerror(errno)); + if (close(sock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* start listening for connections */ + if (listen(sock,SOMAXCONN)<0) + { + log_log(LOG_ERR,"listen() failed: %s",strerror(errno)); + if (close(sock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* we're done */ + return sock; +} + +/* read the version information and action from the stream + this function returns the read action in location pointer to by action */ +static int read_header(TFILE *fp,int32_t *action) +{ + int32_t tmpint32; + /* read the protocol version */ + READ_TYPE(fp,tmpint32,int32_t); + if (tmpint32 != (int32_t)NSLCD_VERSION) + { + log_log(LOG_DEBUG,"wrong nslcd version id (%d)",(int)tmpint32); + return -1; + } + /* read the request type */ + READ(fp,action,sizeof(int32_t)); + return 0; +} + +/* read a request message, returns <0 in case of errors, + this function closes the socket */ +static void handleconnection(int sock,MYLDAP_SESSION *session) +{ + TFILE *fp; + int32_t action; + struct timeval readtimeout,writetimeout; + uid_t uid; + gid_t gid; + pid_t pid; + /* log connection */ + if (getpeercred(sock,&uid,&gid,&pid)) + log_log(LOG_DEBUG,"connection from unknown client: %s",strerror(errno)); + else + log_log(LOG_DEBUG,"connection from pid=%d uid=%d gid=%d", + (int)pid,(int)uid,(int)gid); + /* set the timeouts */ + readtimeout.tv_sec=0; /* clients should send their request quickly */ + readtimeout.tv_usec=500000; + writetimeout.tv_sec=60; /* clients could be taking some time to process the results */ + writetimeout.tv_usec=0; + /* create a stream object */ + if ((fp=tio_fdopen(sock,&readtimeout,&writetimeout, + READBUFFER_MINSIZE,READBUFFER_MAXSIZE, + WRITEBUFFER_MINSIZE,WRITEBUFFER_MAXSIZE))==NULL) + { + log_log(LOG_WARNING,"cannot create stream for writing: %s",strerror(errno)); + (void)close(sock); + return; + } + /* read request */ + if (read_header(fp,&action)) + { + (void)tio_close(fp); + return; + } + /* handle request */ + switch (action) + { + case NSLCD_ACTION_ALIAS_BYNAME: (void)nslcd_alias_byname(fp,session); break; + case NSLCD_ACTION_ALIAS_ALL: (void)nslcd_alias_all(fp,session); break; + case NSLCD_ACTION_ETHER_BYNAME: (void)nslcd_ether_byname(fp,session); break; + case NSLCD_ACTION_ETHER_BYETHER: (void)nslcd_ether_byether(fp,session); break; + case NSLCD_ACTION_ETHER_ALL: (void)nslcd_ether_all(fp,session); break; + case NSLCD_ACTION_GROUP_BYNAME: (void)nslcd_group_byname(fp,session); break; + case NSLCD_ACTION_GROUP_BYGID: (void)nslcd_group_bygid(fp,session); break; + case NSLCD_ACTION_GROUP_BYMEMBER: (void)nslcd_group_bymember(fp,session); break; + case NSLCD_ACTION_GROUP_ALL: (void)nslcd_group_all(fp,session); break; + case NSLCD_ACTION_HOST_BYNAME: (void)nslcd_host_byname(fp,session); break; + case NSLCD_ACTION_HOST_BYADDR: (void)nslcd_host_byaddr(fp,session); break; + case NSLCD_ACTION_HOST_ALL: (void)nslcd_host_all(fp,session); break; + case NSLCD_ACTION_NETGROUP_BYNAME: (void)nslcd_netgroup_byname(fp,session); break; + case NSLCD_ACTION_NETWORK_BYNAME: (void)nslcd_network_byname(fp,session); break; + case NSLCD_ACTION_NETWORK_BYADDR: (void)nslcd_network_byaddr(fp,session); break; + case NSLCD_ACTION_NETWORK_ALL: (void)nslcd_network_all(fp,session); break; + case NSLCD_ACTION_PASSWD_BYNAME: (void)nslcd_passwd_byname(fp,session,uid); break; + case NSLCD_ACTION_PASSWD_BYUID: (void)nslcd_passwd_byuid(fp,session,uid); break; + case NSLCD_ACTION_PASSWD_ALL: (void)nslcd_passwd_all(fp,session,uid); break; + case NSLCD_ACTION_PROTOCOL_BYNAME: (void)nslcd_protocol_byname(fp,session); break; + case NSLCD_ACTION_PROTOCOL_BYNUMBER:(void)nslcd_protocol_bynumber(fp,session); break; + case NSLCD_ACTION_PROTOCOL_ALL: (void)nslcd_protocol_all(fp,session); break; + case NSLCD_ACTION_RPC_BYNAME: (void)nslcd_rpc_byname(fp,session); break; + case NSLCD_ACTION_RPC_BYNUMBER: (void)nslcd_rpc_bynumber(fp,session); break; + case NSLCD_ACTION_RPC_ALL: (void)nslcd_rpc_all(fp,session); break; + case NSLCD_ACTION_SERVICE_BYNAME: (void)nslcd_service_byname(fp,session); break; + case NSLCD_ACTION_SERVICE_BYNUMBER: (void)nslcd_service_bynumber(fp,session); break; + case NSLCD_ACTION_SERVICE_ALL: (void)nslcd_service_all(fp,session); break; + case NSLCD_ACTION_SHADOW_BYNAME: if (uid==0) (void)nslcd_shadow_byname(fp,session); break; + case NSLCD_ACTION_SHADOW_ALL: if (uid==0) (void)nslcd_shadow_all(fp,session); break; + case NSLCD_ACTION_PAM_AUTHC: (void)nslcd_pam_authc(fp,session,uid); break; + case NSLCD_ACTION_PAM_AUTHZ: (void)nslcd_pam_authz(fp,session); break; + case NSLCD_ACTION_PAM_SESS_O: (void)nslcd_pam_sess_o(fp,session); break; + case NSLCD_ACTION_PAM_SESS_C: (void)nslcd_pam_sess_c(fp,session); break; + case NSLCD_ACTION_PAM_PWMOD: (void)nslcd_pam_pwmod(fp,session,uid); break; + default: + log_log(LOG_WARNING,"invalid request id: %d",(int)action); + break; + } + /* we're done with the request */ + myldap_session_cleanup(session); + (void)tio_close(fp); + return; +} + +/* test to see if we can lock the specified file */ +static int is_locked(const char* filename) +{ + int fd; + if (filename!=NULL) + { + errno=0; + if ((fd=open(filename,O_RDWR,0644))<0) + { + if (errno==ENOENT) + return 0; /* if file doesn't exist it cannot be locked */ + log_log(LOG_ERR,"cannot open lock file (%s): %s",filename,strerror(errno)); + exit(EXIT_FAILURE); + } + if (lockf(fd,F_TEST,0)<0) + { + close(fd); + return -1; + } + close(fd); + } + return 0; +} + +/* write the current process id to the specified file */ +static void create_pidfile(const char *filename) +{ + int fd; + char buffer[20]; + if (filename!=NULL) + { + mkdirname(filename); + if ((fd=open(filename,O_RDWR|O_CREAT,0644))<0) + { + log_log(LOG_ERR,"cannot create pid file (%s): %s",filename,strerror(errno)); + exit(EXIT_FAILURE); + } + if (lockf(fd,F_TLOCK,0)<0) + { + log_log(LOG_ERR,"cannot lock pid file (%s): %s",filename,strerror(errno)); + exit(EXIT_FAILURE); + } + ftruncate(fd,0); + mysnprintf(buffer,sizeof(buffer),"%d\n",(int)getpid()); + if (write(fd,buffer,strlen(buffer))!=(int)strlen(buffer)) + { + log_log(LOG_ERR,"error writing pid file (%s): %s",filename,strerror(errno)); + exit(EXIT_FAILURE); + } + /* we keep the pidfile open so the lock remains valid */ + } +} + +/* try to install signal handler and check result */ +static void install_sighandler(int signum,void (*handler) (int)) +{ + struct sigaction act; + memset(&act,0,sizeof(struct sigaction)); + act.sa_handler=handler; + sigemptyset(&act.sa_mask); + act.sa_flags=SA_RESTART|SA_NOCLDSTOP; + if (sigaction(signum,&act,NULL)!=0) + { + log_log(LOG_ERR,"error installing signal handler for '%s': %s",signame(signum),strerror(errno)); + exit(EXIT_FAILURE); + } +} + +static void worker_cleanup(void *arg) +{ + MYLDAP_SESSION *session=(MYLDAP_SESSION *)arg; + myldap_session_close(session); +} + +static void *worker(void UNUSED(*arg)) +{ + MYLDAP_SESSION *session; + int csock; + int j; + struct sockaddr_storage addr; + socklen_t alen; + fd_set fds; + struct timeval tv; + /* create a new LDAP session */ + session=myldap_create_session(); + /* clean up the session if we're done */ + pthread_cleanup_push(worker_cleanup,session); + /* start waiting for incoming connections */ + while (1) + { + /* time out connection to LDAP server if needed */ + myldap_session_check(session); + /* set up the set of fds to wait on */ + FD_ZERO(&fds); + FD_SET(nslcd_serversocket,&fds); + /* set up our timeout value */ + tv.tv_sec=nslcd_cfg->ldc_idle_timelimit; + tv.tv_usec=0; + /* wait for a new connection */ + j=select(nslcd_serversocket+1,&fds,NULL,NULL,nslcd_cfg->ldc_idle_timelimit>0?&tv:NULL); + /* check result of select() */ + if (j<0) + { + if (errno==EINTR) + log_log(LOG_DEBUG,"debug: select() failed (ignored): %s",strerror(errno)); + else + log_log(LOG_ERR,"select() failed: %s",strerror(errno)); + continue; + } + /* see if our file descriptor is actually ready */ + if (!FD_ISSET(nslcd_serversocket,&fds)) + continue; + /* wait for a new connection */ + alen=(socklen_t)sizeof(struct sockaddr_storage); + csock=accept(nslcd_serversocket,(struct sockaddr *)&addr,&alen); + if (csock<0) + { + if ((errno==EINTR)||(errno==EAGAIN)||(errno==EWOULDBLOCK)) + log_log(LOG_DEBUG,"accept() failed (ignored): %s",strerror(errno)); + else + log_log(LOG_ERR,"accept() failed: %s",strerror(errno)); + continue; + } + /* make sure O_NONBLOCK is not inherited */ + if ((j=fcntl(csock,F_GETFL,0))<0) + { + log_log(LOG_ERR,"fctnl(F_GETFL) failed: %s",strerror(errno)); + if (close(csock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + continue; + } + if (fcntl(csock,F_SETFL,j&~O_NONBLOCK)<0) + { + log_log(LOG_ERR,"fctnl(F_SETFL,~O_NONBLOCK) failed: %s",strerror(errno)); + if (close(csock)) + log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); + continue; + } + /* indicate new connection to logging module (genrates unique id) */ + log_newsession(); + /* handle the connection */ + handleconnection(csock,session); + /* indicate end of session in log messages */ + log_clearsession(); + } + pthread_cleanup_pop(1); + return NULL; +} + +/* function to disable lookups through the nss_ldap module to avoid lookup + loops */ +static void disable_nss_ldap(void) +{ + void *handle; + char *error; + int *enable_flag; + /* try to load the NSS module */ +#ifdef RTLD_NODELETE + handle=dlopen(NSS_LDAP_SONAME,RTLD_LAZY|RTLD_NODELETE); +#else /* not RTLD_NODELETE */ + handle=dlopen(NSS_LDAP_SONAME,RTLD_LAZY); +#endif /* RTLD_NODELETE */ + if (handle==NULL) + { + log_log(LOG_WARNING,"Warning: LDAP NSS module not loaded: %s",dlerror()); + return; + } + /* clear any existing errors */ + dlerror(); + /* try to look up the flag */ + enable_flag=(int *)dlsym(handle,"_nss_ldap_enablelookups"); + error=dlerror(); + if (error!=NULL) + { + log_log(LOG_WARNING,"Warning: %s (probably older NSS module loaded)",error); + /* fall back to changing the way host lookup is done */ +#ifdef HAVE___NSS_CONFIGURE_LOOKUP + if (__nss_configure_lookup("hosts","files dns")) + log_log(LOG_ERR,"unable to override hosts lookup method: %s",strerror(errno)); +#endif /* HAVE___NSS_CONFIGURE_LOOKUP */ + dlclose(handle); + return; + } + /* disable nss_ldap */ + *enable_flag=0; +#ifdef RTLD_NODELETE + /* only close the handle if RTLD_NODELETE was used */ + dlclose(handle); +#endif /* RTLD_NODELETE */ +} + +/* the main program... */ +int main(int argc,char *argv[]) +{ + int i; + sigset_t signalmask,oldmask; +#ifdef HAVE_PTHREAD_TIMEDJOIN_NP + struct timespec ts; +#endif /* HAVE_PTHREAD_TIMEDJOIN_NP */ + /* parse the command line */ + parse_cmdline(argc,argv); + /* clean the environment */ +#ifdef HAVE_CLEARENV + if ( clearenv() || + putenv("HOME=/") || + putenv("TMPDIR=/tmp") || + putenv("LDAPNOINIT=1") ) + { + log_log(LOG_ERR,"clearing environment failed"); + exit(EXIT_FAILURE); + } +#else /* not HAVE_CLEARENV */ + /* this is a bit ugly */ + environ=sane_environment; +#endif /* not HAVE_CLEARENV */ + /* disable the nss_ldap module for this process */ + disable_nss_ldap(); + /* set LDAP log level */ + if (myldap_set_debuglevel(nslcd_debugging)!=LDAP_SUCCESS) + exit(EXIT_FAILURE); + /* read configuration file */ + cfg_init(NSLCD_CONF_PATH); + /* set default mode for pidfile and socket */ + (void)umask((mode_t)0022); + /* see if someone already locked the pidfile + if --check option was given: + exit TRUE if daemon runs (pidfile locked), FALSE otherwise */ + if (nslcd_checkonly) + { + if (is_locked(NSLCD_PIDFILE)) + { + log_log(LOG_DEBUG,"pidfile (%s) is locked",NSLCD_PIDFILE); + exit(EXIT_SUCCESS); + } + else + { + log_log(LOG_DEBUG,"pidfile (%s) is not locked",NSLCD_PIDFILE); + exit(EXIT_FAILURE); + } + } + /* normal check for pidfile locked */ + if (is_locked(NSLCD_PIDFILE)) + { + log_log(LOG_ERR,"daemon may already be active, cannot acquire lock (%s): %s",NSLCD_PIDFILE,strerror(errno)); + exit(EXIT_FAILURE); + } + /* close all file descriptors (except stdin/out/err) */ + i=sysconf(_SC_OPEN_MAX); + /* if the system does not have OPEN_MAX just close the first 32 and + hope we closed enough */ + if (i<0) + i=32; + for (;i>3;i--) + close(i); + /* daemonize */ + if ((!nslcd_debugging)&&(daemon(0,0)<0)) + { + log_log(LOG_ERR,"unable to daemonize: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* intilialize logging */ + if (!nslcd_debugging) + log_startlogging(); + log_log(LOG_INFO,"version %s starting",VERSION); + /* write pidfile */ + create_pidfile(NSLCD_PIDFILE); + /* install handler to close stuff off on exit and log notice */ + if (atexit(exithandler)) + { + log_log(LOG_ERR,"atexit() failed: %s",strerror(errno)); + exit(EXIT_FAILURE); + } + /* create socket */ + nslcd_serversocket=create_socket(NSLCD_SOCKET); +#ifdef HAVE_SETGROUPS + /* drop all supplemental groups */ + if (setgroups(0,NULL)<0) + log_log(LOG_WARNING,"cannot setgroups(0,NULL) (ignored): %s",strerror(errno)); + else + log_log(LOG_DEBUG,"setgroups(0,NULL) done"); +#else /* HAVE_SETGROUPS */ + log_log(LOG_DEBUG,"setgroups() not available"); +#endif /* not HAVE_SETGROUPS */ + /* change to nslcd gid */ + if (nslcd_cfg->ldc_gid!=NOGID) + { + if (setgid(nslcd_cfg->ldc_gid)!=0) + { + log_log(LOG_ERR,"cannot setgid(%d): %s",(int)nslcd_cfg->ldc_gid,strerror(errno)); + exit(EXIT_FAILURE); + } + log_log(LOG_DEBUG,"setgid(%d) done",(int)nslcd_cfg->ldc_gid); + } + /* change to nslcd uid */ + if (nslcd_cfg->ldc_uid!=NOUID) + { + if (setuid(nslcd_cfg->ldc_uid)!=0) + { + log_log(LOG_ERR,"cannot setuid(%d): %s",(int)nslcd_cfg->ldc_uid,strerror(errno)); + exit(EXIT_FAILURE); + } + log_log(LOG_DEBUG,"setuid(%d) done",(int)nslcd_cfg->ldc_uid); + } + /* block all these signals so our worker threads won't handle them */ + sigemptyset(&signalmask); + sigaddset(&signalmask,SIGHUP); + sigaddset(&signalmask,SIGINT); + sigaddset(&signalmask,SIGQUIT); + sigaddset(&signalmask,SIGABRT); + sigaddset(&signalmask,SIGPIPE); + sigaddset(&signalmask,SIGTERM); + sigaddset(&signalmask,SIGUSR1); + sigaddset(&signalmask,SIGUSR2); + pthread_sigmask(SIG_BLOCK,&signalmask,&oldmask); + /* start worker threads */ + log_log(LOG_INFO,"accepting connections"); + nslcd_threads=(pthread_t *)malloc(nslcd_cfg->ldc_threads*sizeof(pthread_t)); + if (nslcd_threads==NULL) + { + log_log(LOG_CRIT,"main(): malloc() failed to allocate memory"); + exit(EXIT_FAILURE); + } + for (i=0;ildc_threads;i++) + { + if (pthread_create(&nslcd_threads[i],NULL,worker,NULL)) + { + log_log(LOG_ERR,"unable to start worker thread %d: %s",i,strerror(errno)); + exit(EXIT_FAILURE); + } + } + pthread_sigmask(SIG_SETMASK,&oldmask,NULL); + /* install signalhandlers for some signals */ + install_sighandler(SIGHUP, sigexit_handler); + install_sighandler(SIGINT, sigexit_handler); + install_sighandler(SIGQUIT,sigexit_handler); + install_sighandler(SIGABRT,sigexit_handler); + install_sighandler(SIGPIPE,SIG_IGN); + install_sighandler(SIGTERM,sigexit_handler); + install_sighandler(SIGUSR1,sigexit_handler); + install_sighandler(SIGUSR2,sigexit_handler); + /* wait until we received a signal */ + while (nslcd_exitsignal==0) + { + sleep(INT_MAX); /* sleep as long as we can or until we receive a signal */ + } + /* print something about received signal */ + log_log(LOG_INFO,"caught signal %s (%d), shutting down", + signame(nslcd_exitsignal),nslcd_exitsignal); + /* cancel all running threads */ + for (i=0;ildc_threads;i++) + if (pthread_cancel(nslcd_threads[i])) + log_log(LOG_WARNING,"failed to stop thread %d (ignored): %s",i,strerror(errno)); + /* close server socket to trigger failures in threads waiting on accept() */ + close(nslcd_serversocket); + nslcd_serversocket=-1; + /* if we can, wait a few seconds for the threads to finish */ +#ifdef HAVE_PTHREAD_TIMEDJOIN_NP + ts.tv_sec=time(NULL)+3; + ts.tv_nsec=0; +#endif /* HAVE_PTHREAD_TIMEDJOIN_NP */ + for (i=0;ildc_threads;i++) + { +#ifdef HAVE_PTHREAD_TIMEDJOIN_NP + pthread_timedjoin_np(nslcd_threads[i],NULL,&ts); +#endif /* HAVE_PTHREAD_TIMEDJOIN_NP */ + if (pthread_kill(nslcd_threads[i],0)==0) + log_log(LOG_ERR,"thread %d is still running, shutting down anyway",i); + } + /* we're done */ + return EXIT_FAILURE; +} diff --git a/nslcd/nsswitch.c b/nslcd/nsswitch.c new file mode 100644 index 0000000..13782c6 --- /dev/null +++ b/nslcd/nsswitch.c @@ -0,0 +1,116 @@ +/* + nsswitch.c - functions for parsing /etc/nsswitch.conf + + Copyright (C) 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include + +#include "log.h" + +/* the maximum line length supported of nsswitch.conf */ +#define MAX_LINE_LENGTH 4096 + + +/* TODO: store mtime of file and use it to check reparse */ +/* TODO: cache entries for x minutes */ + +/* see if the line is a service definition for db and return a pointer to + the beginning of the services list if it is */ +static const char *find_db(const char *line,const char *db) +{ + int i; + i=strlen(db); + /* the line should begin with the db we're looking for */ + if (strncmp(line,db,i)!=0) + return NULL; + /* followed by a : */ + while (isspace(line[i])) i++; + if (line[i]!=':') + return NULL; + i++; + while (isspace(line[i])) i++; + return line+i; +} + +/* check to see if the list of services contains the specified service */ +static int has_service(const char *services,const char *service, + const char *filename,int lnr) +{ + int i=0,l; + if (services==NULL) + return 0; + l=strlen(service); + while (services[i]!='\0') + { + /* skip spaces */ + while (isspace(services[i])) i++; + /* check if this is the service */ + if ((strncmp(services+i,service,l)==0)&&(!isalnum(services[i+l]))) + return 1; + /* skip service name and spaces */ + i++; + while (isalnum(services[i])) i++; + while (isspace(services[i])) i++; + /* skip action mappings */ + if (services[i]=='[') + { + i++; /* skip [ */ + while ((services[i]!=']')&&(services[i]!='\0')) i++; + if (services[i]!=']') + { + log_log(LOG_WARNING,"%s: error parsing line %d",filename,lnr); + return 0; /* parse error */ + } + i++; /* skip ] */ + } + } + return 0; +} + +int nsswitch_db_uses_ldap(const char *filename,const char *db) +{ + FILE *fp; + int lnr=0; + char linebuf[MAX_LINE_LENGTH]; + const char *services; + /* open config file */ + if ((fp=fopen(filename,"r"))==NULL) + { + log_log(LOG_ERR,"cannot open %s: %s",filename,strerror(errno)); + return 0; + } + /* read file and parse lines */ + while (fgets(linebuf,sizeof(linebuf),fp)!=NULL) + { + lnr++; + services=find_db(linebuf,db); + if ((services!=NULL)&&has_service(services,"ldap",filename,lnr)) + { + fclose(fp); + return 1; + } + } + fclose(fp); + return 0; +} diff --git a/nslcd/pam.c b/nslcd/pam.c new file mode 100644 index 0000000..dbdf0b5 --- /dev/null +++ b/nslcd/pam.c @@ -0,0 +1,676 @@ +/* + pam.c - pam processing routines + + Copyright (C) 2009 Howard Chu + Copyright (C) 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" +#include "common/dict.h" +#include "common/expr.h" + +/* set up a connection and try to bind with the specified DN and password, + returns an LDAP result code */ +static int try_bind(const char *userdn,const char *password) +{ + MYLDAP_SESSION *session; + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + static const char *attrs[2]; + int rc; + /* set up a new connection */ + session=myldap_create_session(); + if (session==NULL) + return LDAP_UNAVAILABLE; + /* set up credentials for the session */ + myldap_set_credentials(session,userdn,password); + /* perform search for own object (just to do any kind of search) */ + attrs[0]="dn"; + attrs[1]=NULL; + search=myldap_search(session,userdn,LDAP_SCOPE_BASE,"(objectClass=*)",attrs,&rc); + if ((search==NULL)||(rc!=LDAP_SUCCESS)) + { + if (rc==LDAP_SUCCESS) + rc=LDAP_LOCAL_ERROR; + log_log(LOG_WARNING,"lookup of %s failed: %s",userdn,ldap_err2string(rc)); + } + else + { + entry=myldap_get_entry(search,&rc); + if ((entry==NULL)||(rc!=LDAP_SUCCESS)) + { + if (rc==LDAP_SUCCESS) + rc=LDAP_NO_RESULTS_RETURNED; + log_log(LOG_WARNING,"lookup of %s failed: %s",userdn,ldap_err2string(rc)); + } + } + /* close the session */ + myldap_session_close(session); + /* return results */ + return rc; +} + +/* ensure that both userdn and username are filled in from the entry, + returns an LDAP result code */ +static MYLDAP_ENTRY *validate_user(MYLDAP_SESSION *session, + char *username,int *rcp) +{ + int rc; + MYLDAP_ENTRY *entry=NULL; + /* check username for validity */ + if (!isvalidname(username)) + { + log_log(LOG_WARNING,"\"%s\": name denied by validnames option",username); + *rcp=LDAP_NO_SUCH_OBJECT; + return NULL; + } + /* get the user entry based on the username */ + entry=uid2entry(session,username,&rc); + if (entry==NULL) + { + if (rc==LDAP_SUCCESS) + rc=LDAP_NO_SUCH_OBJECT; + log_log(LOG_WARNING,"\"%s\": user not found: %s",username,ldap_err2string(rc)); + *rcp=rc; + } + return entry; +} + +/* update the username value from the entry if needed */ +static void update_username(MYLDAP_ENTRY *entry,char *username,size_t username_len) +{ + const char **values; + const char *value; + /* get the "real" username */ + value=myldap_get_rdn_value(entry,attmap_passwd_uid); + if (value==NULL) + { + /* get the username from the uid attribute */ + values=myldap_get_values(entry,attmap_passwd_uid); + if ((values==NULL)||(values[0]==NULL)) + log_log(LOG_WARNING,"\"%s\": DN %s is missing a %s attribute", + username,myldap_get_dn(entry),attmap_passwd_uid); + value=values[0]; + } + /* check the username */ + if ((value==NULL)||!isvalidname(value)||strlen(value)>=username_len) + { + log_log(LOG_WARNING,"passwd entry %s name denied by validnames option: \"%s\"", + myldap_get_dn(entry),username); + return; + } + /* check if the username is different and update it if needed */ + if (strcmp(username,value)!=0) + { + log_log(LOG_INFO,"username changed from \"%s\" to \"%s\"",username,value); + strcpy(username,value); + } +} + +static int check_shadow(MYLDAP_SESSION *session,const char *username, + char *authzmsg,size_t authzmsgsz, + int check_maxdays,int check_mindays) +{ + MYLDAP_ENTRY *entry=NULL; + long today,lastchangedate,mindays,maxdays,warndays,inactdays,expiredate; + unsigned long flag; + long daysleft,inactleft; + /* get the shadow entry */ + entry=shadow_uid2entry(session,username,NULL); + if (entry==NULL) + return NSLCD_PAM_SUCCESS; /* no shadow entry found, nothing to check */ + /* get today's date */ + today=(long)(time(NULL)/(60*60*24)); + /* get shadown information */ + get_shadow_properties(entry,&lastchangedate,&mindays,&maxdays,&warndays, + &inactdays,&expiredate,&flag); + /* check account expiry date */ + if ((expiredate!=-1)&&(today>=expiredate)) + { + daysleft=today-expiredate; + mysnprintf(authzmsg,authzmsgsz-1,"account expired %ld days ago",daysleft); + log_log(LOG_WARNING,"%s: %s",myldap_get_dn(entry),authzmsg); + return NSLCD_PAM_ACCT_EXPIRED; + } + /* password expiration isn't interesting at this point because the user + may not have authenticated with a password and if he did that would be + checked in the authc phase */ + if (check_maxdays) + { + /* check lastchanged */ + if (lastchangedate==0) + { + mysnprintf(authzmsg,authzmsgsz-1,"need a new password"); + log_log(LOG_WARNING,"%s: %s",myldap_get_dn(entry),authzmsg); + return NSLCD_PAM_NEW_AUTHTOK_REQD; + } + else if (today0) + mysnprintf(authzmsg+strlen(authzmsg),authzmsgsz-strlen(authzmsg)-1, + ", account will be locked in %ld days",inactleft); + else + { + mysnprintf(authzmsg+strlen(authzmsg),authzmsgsz-strlen(authzmsg)-1, + ", account locked %ld days ago",-inactleft); + log_log(LOG_WARNING,"%s: %s",myldap_get_dn(entry),authzmsg); + return NSLCD_PAM_AUTHTOK_EXPIRED; + } + } + if (daysleft<=0) + { + /* log previously built message */ + log_log(LOG_WARNING,"%s: %s",myldap_get_dn(entry),authzmsg); + return NSLCD_PAM_NEW_AUTHTOK_REQD; + } + /* check warndays */ + if ((warndays>0)&&(daysleft<=warndays)) + { + mysnprintf(authzmsg,authzmsgsz-1,"password will expire in %ld days",daysleft); + log_log(LOG_WARNING,"%s: %s",myldap_get_dn(entry),authzmsg); + } + } + } + if (check_mindays) + { + daysleft=lastchangedate+mindays-today; + if ((mindays!=-1)&&(daysleft>0)) + { + mysnprintf(authzmsg,authzmsgsz-1,"password cannot be changed for another %ld days",daysleft); + log_log(LOG_WARNING,"%s: %s",myldap_get_dn(entry),authzmsg); + return NSLCD_PAM_AUTHTOK_ERR; + } + } + return NSLCD_PAM_SUCCESS; +} + +/* check authentication credentials of the user */ +int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid) +{ + int32_t tmpint32; + int rc; + char username[256]; + char servicename[64]; + char password[64]; + const char *userdn; + MYLDAP_ENTRY *entry; + int authzrc=NSLCD_PAM_SUCCESS; + char authzmsg[1024]; + authzmsg[0]='\0'; + /* read request parameters */ + READ_STRING(fp,username); + SKIP_STRING(fp); /* DN */ + READ_STRING(fp,servicename); + READ_STRING(fp,password); + /* log call */ + log_setrequest("authc=\"%s\"",username); + log_log(LOG_DEBUG,"nslcd_pam_authc(\"%s\",\"%s\",\"%s\")", + username,servicename,*password?"***":""); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHC); + /* if the username is blank and rootpwmoddn is configured, try to + authenticate as administrator, otherwise validate request as usual */ + if ((*username=='\0')&&(nslcd_cfg->ldc_rootpwmoddn!=NULL)) + { + userdn=nslcd_cfg->ldc_rootpwmoddn; + /* if the caller is root we will allow the use of the rootpwmodpw option */ + if ((*password=='\0')&&(calleruid==0)&&(nslcd_cfg->ldc_rootpwmodpw!=NULL)) + { + if (strlen(nslcd_cfg->ldc_rootpwmodpw)>=sizeof(password)) + { + log_log(LOG_ERR,"nslcd_pam_authc(): rootpwmodpw will not fit in password"); + return -1; + } + strcpy(password,nslcd_cfg->ldc_rootpwmodpw); + } + } + else + { + /* try normal authentication, lookup the user entry */ + entry=validate_user(session,username,&rc); + if (entry==NULL) + { + /* for user not found we just say no result */ + if (rc==LDAP_NO_SUCH_OBJECT) + { + WRITE_INT32(fp,NSLCD_RESULT_END); + } + return -1; + } + userdn=myldap_get_dn(entry); + update_username(entry,username,sizeof(username)); + } + /* try authentication */ + rc=try_bind(userdn,password); + if (rc==LDAP_SUCCESS) + log_log(LOG_DEBUG,"bind successful"); + /* map result code */ + switch (rc) + { + case LDAP_SUCCESS: rc=NSLCD_PAM_SUCCESS; break; + case LDAP_INVALID_CREDENTIALS: rc=NSLCD_PAM_AUTH_ERR; break; + default: rc=NSLCD_PAM_AUTH_ERR; + } + /* perform shadow attribute checks */ + if (*username!='\0') + authzrc=check_shadow(session,username,authzmsg,sizeof(authzmsg),1,0); + /* write response */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,username); + WRITE_STRING(fp,userdn); + WRITE_INT32(fp,rc); + WRITE_INT32(fp,authzrc); + WRITE_STRING(fp,authzmsg); + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; +} + +static void autzsearch_var_add(DICT *dict,const char *name,const char *value) +{ + size_t sz; + char *escaped_value; + /* allocate memory for escaped string */ + sz=((strlen(value)+8)*120)/100; + escaped_value=(char *)malloc(sz); + if (escaped_value==NULL) + { + log_log(LOG_CRIT,"autzsearch_var_add(): malloc() failed to allocate memory"); + return; + } + /* perform escaping of the value */ + if(myldap_escape(value,escaped_value,sz)) + { + log_log(LOG_CRIT,"autzsearch_var_add(): myldap_escape() failed to fit in buffer"); + return; + } + /* add to dict */ + dict_put(dict,name,escaped_value); +} + +static void autzsearch_vars_free(DICT *dict) +{ + int i; + const char **keys; + void *value; + /* go over all keys and free all the values + (they were allocated in autzsearch_var_add) */ + /* loop over dictionary contents */ + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++) + { + value=dict_get(dict,keys[i]); + if (value) + free(value); + } + free(keys); + /* after this values from the dict should obviously no longer be used */ +} + +static const char *autzsearch_var_get(const char *name,void *expander_attr) +{ + DICT *dict=(DICT *)expander_attr; + return (const char *)dict_get(dict,name); + /* TODO: if not set use entry to get attribute name (entry can be an + element in the dict) */ +} + +/* perform an authorisation search, returns an LDAP status code */ +static int try_autzsearch(MYLDAP_SESSION *session,const char *dn, + const char *username,const char *servicename, + const char *ruser,const char *rhost,const char *tty) +{ + char hostname[HOST_NAME_MAX+1]; + const char *fqdn; + DICT *dict; + char filter_buffer[1024]; + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + static const char *attrs[2]; + int rc; + const char *res; + /* check whether the search filter is configured at all */ + if (!nslcd_cfg->ldc_pam_authz_search) + return LDAP_SUCCESS; + /* build the dictionary with variables + NOTE: any variables added here also need to be added to + cfg.c:parse_pam_authz_search_statement() */ + dict=dict_new(); + autzsearch_var_add(dict,"username",username); + autzsearch_var_add(dict,"service",servicename); + autzsearch_var_add(dict,"ruser",ruser); + autzsearch_var_add(dict,"rhost",rhost); + autzsearch_var_add(dict,"tty",tty); + if (gethostname(hostname,sizeof(hostname))==0) + autzsearch_var_add(dict,"hostname",hostname); + if ((fqdn=getfqdn())!=NULL) + autzsearch_var_add(dict,"fqdn",fqdn); + autzsearch_var_add(dict,"dn",dn); + autzsearch_var_add(dict,"uid",username); + /* build the search filter */ + res=expr_parse(nslcd_cfg->ldc_pam_authz_search, + filter_buffer,sizeof(filter_buffer), + autzsearch_var_get,(void *)dict); + autzsearch_vars_free(dict); + dict_free(dict); + if (res==NULL) + { + log_log(LOG_ERR,"pam_authz_search \"%s\" is invalid",nslcd_cfg->ldc_pam_authz_search); + return LDAP_LOCAL_ERROR; + } + log_log(LOG_DEBUG,"trying pam_authz_search \"%s\"",filter_buffer); + /* perform the search */ + attrs[0]="dn"; + attrs[1]=NULL; + /* FIXME: this only searches the first base */ + search=myldap_search(session,nslcd_cfg->ldc_bases[0],LDAP_SCOPE_SUBTREE, + filter_buffer,attrs,&rc); + if (search==NULL) + { + log_log(LOG_ERR,"pam_authz_search \"%s\" failed: %s", + filter_buffer,ldap_err2string(rc)); + return rc; + } + /* try to get an entry */ + entry=myldap_get_entry(search,&rc); + if (entry==NULL) + { + log_log(LOG_ERR,"pam_authz_search \"%s\" found no matches",filter_buffer); + if (rc==LDAP_SUCCESS) + rc=LDAP_NO_SUCH_OBJECT; + return rc; + } + log_log(LOG_DEBUG,"pam_authz_search found \"%s\"",myldap_get_dn(entry)); + /* we've found an entry so it's OK */ + return LDAP_SUCCESS; +} + +/* check authorisation of the user */ +int nslcd_pam_authz(TFILE *fp,MYLDAP_SESSION *session) +{ + int32_t tmpint32; + int rc; + char username[256]; + char servicename[64]; + char ruser[256],rhost[HOST_NAME_MAX+1],tty[64]; + MYLDAP_ENTRY *entry; + char authzmsg[1024]; + authzmsg[0]='\0'; + /* read request parameters */ + READ_STRING(fp,username); + SKIP_STRING(fp); /* DN */ + READ_STRING(fp,servicename); + READ_STRING(fp,ruser); + READ_STRING(fp,rhost); + READ_STRING(fp,tty); + /* log call */ + log_setrequest("authz=\"%s\"",username); + log_log(LOG_DEBUG,"nslcd_pam_authz(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")", + username,servicename,ruser,rhost,tty); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHZ); + /* validate request */ + entry=validate_user(session,username,&rc); + if (entry==NULL) + { + /* for user not found we just say no result */ + if (rc==LDAP_NO_SUCH_OBJECT) + { + WRITE_INT32(fp,NSLCD_RESULT_END); + } + return -1; + } + /* check authorisation search */ + rc=try_autzsearch(session,myldap_get_dn(entry),username,servicename,ruser,rhost,tty); + if (rc!=LDAP_SUCCESS) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,username); + WRITE_STRING(fp,""); + WRITE_INT32(fp,NSLCD_PAM_PERM_DENIED); + WRITE_STRING(fp,"LDAP authorisation check failed"); + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; + } + /* perform shadow attribute checks */ + rc=check_shadow(session,username,authzmsg,sizeof(authzmsg),0,0); + /* write response */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,username); + WRITE_STRING(fp,myldap_get_dn(entry)); + WRITE_INT32(fp,rc); + WRITE_STRING(fp,authzmsg); + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; +} + +int nslcd_pam_sess_o(TFILE *fp,MYLDAP_SESSION *session) +{ + int32_t tmpint32; + char username[256]; + char servicename[64]; + char tty[64],rhost[HOST_NAME_MAX+1],ruser[256]; + int32_t sessionid; + /* read request parameters */ + READ_STRING(fp,username); + SKIP_STRING(fp); /* DN */ + READ_STRING(fp,servicename); + READ_STRING(fp,tty); + READ_STRING(fp,rhost); + READ_STRING(fp,ruser); + READ_INT32(fp,sessionid); + /* log call */ + log_setrequest("sess_o=\"%s\"",username); + log_log(LOG_DEBUG,"nslcd_pam_sess_o(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")", + username,servicename,tty,rhost,ruser); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_PAM_SESS_O); + /* write response */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_INT32(fp,12345); /* session id */ + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; +} + +int nslcd_pam_sess_c(TFILE *fp,MYLDAP_SESSION *session) +{ + int32_t tmpint32; + char username[256]; + char servicename[64]; + char tty[64],rhost[HOST_NAME_MAX+1],ruser[256]; + int32_t sessionid; + /* read request parameters */ + READ_STRING(fp,username); + SKIP_STRING(fp); /* DN */ + READ_STRING(fp,servicename); + READ_STRING(fp,tty); + READ_STRING(fp,rhost); + READ_STRING(fp,ruser); + READ_INT32(fp,sessionid); + /* log call */ + log_setrequest("sess_c=\"%s\"",username); + log_log(LOG_DEBUG,"nslcd_pam_sess_c(\"%s\",\"%s\",%d)", + username,servicename,(int)sessionid); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_PAM_SESS_C); + /* write response */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_INT32(fp,0); /* session id */ + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; +} + +/* perform an LDAP password modification, returns an LDAP status code */ +static int try_pwmod(const char *binddn,const char *userdn, + const char *oldpassword,const char *newpassword) +{ + MYLDAP_SESSION *session; + char buffer[256]; + int rc; + /* set up a new connection */ + session=myldap_create_session(); + if (session==NULL) + return LDAP_UNAVAILABLE; + /* set up credentials for the session */ + myldap_set_credentials(session,binddn,oldpassword); + /* perform search for own object (just to do any kind of search) */ + if ((lookup_dn2uid(session,userdn,&rc,buffer,sizeof(buffer))!=NULL)&&(rc==LDAP_SUCCESS)) + { + /* if doing password modification as admin, don't pass old password along */ + if ((nslcd_cfg->ldc_rootpwmoddn!=NULL)&&(strcmp(binddn,nslcd_cfg->ldc_rootpwmoddn)==0)) + oldpassword=NULL; + /* perform password modification */ + rc=myldap_passwd(session,userdn,oldpassword,newpassword); + if (rc==LDAP_SUCCESS) + { + /* try to update the shadowLastChange attribute */ + (void)update_lastchange(session,userdn); + } + } + /* close the session */ + myldap_session_close(session); + /* return */ + return rc; +} + +int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid) +{ + int32_t tmpint32; + int rc; + char username[256]; + char userdn[256]; + int asroot; + char servicename[64]; + char oldpassword[64]; + char newpassword[64]; + const char *binddn=NULL; /* the user performing the modification */ + MYLDAP_ENTRY *entry; + char authzmsg[1024]; + authzmsg[0]='\0'; + /* read request parameters */ + READ_STRING(fp,username); + READ_STRING(fp,userdn); /* we can't ignore userdn for now here because we + need it to determine the modify-as-root case */ + asroot=(nslcd_cfg->ldc_rootpwmoddn!=NULL)&&(strcmp(userdn,nslcd_cfg->ldc_rootpwmoddn)==0); + READ_STRING(fp,servicename); + READ_STRING(fp,oldpassword); + READ_STRING(fp,newpassword); + /* log call */ + log_setrequest("pwmod=\"%s\"",username); + log_log(LOG_DEBUG,"nslcd_pam_pwmod(\"%s\",%s,\"%s\",\"%s\",\"%s\")", + username,asroot?"asroot":"asuser",servicename,*oldpassword?"***":"", + *newpassword?"***":""); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_PAM_PWMOD); + /* validate request */ + entry=validate_user(session,username,&rc); + if (entry==NULL) + { + /* for user not found we just say no result */ + if (rc==LDAP_NO_SUCH_OBJECT) + { + WRITE_INT32(fp,NSLCD_RESULT_END); + } + return -1; + } + /* check if the the user passed the rootpwmoddn */ + if (asroot) + { + binddn=nslcd_cfg->ldc_rootpwmoddn; + /* check if rootpwmodpw should be used */ + if ((*oldpassword=='\0')&&(calleruid==0)&&(nslcd_cfg->ldc_rootpwmodpw!=NULL)) + { + if (strlen(nslcd_cfg->ldc_rootpwmodpw)>=sizeof(oldpassword)) + { + log_log(LOG_ERR,"nslcd_pam_pwmod(): rootpwmodpw will not fit in oldpassword"); + return -1; + } + strcpy(oldpassword,nslcd_cfg->ldc_rootpwmodpw); + } + } + else + { + binddn=myldap_get_dn(entry); + /* check whether shadow properties allow password change */ + rc=check_shadow(session,username,authzmsg,sizeof(authzmsg),0,1); + if (rc!=NSLCD_PAM_SUCCESS) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,username); + WRITE_STRING(fp,""); + WRITE_INT32(fp,rc); + WRITE_STRING(fp,authzmsg); + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; + } + } + /* perform password modification */ + rc=try_pwmod(binddn,myldap_get_dn(entry),oldpassword,newpassword); + if (rc!=LDAP_SUCCESS) + { + mysnprintf(authzmsg,sizeof(authzmsg)-1,"password change failed: %s",ldap_err2string(rc)); + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,username); + WRITE_STRING(fp,""); + WRITE_INT32(fp,NSLCD_PAM_PERM_DENIED); + WRITE_STRING(fp,authzmsg); + WRITE_INT32(fp,NSLCD_RESULT_END); + } + /* write response */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,username); + WRITE_STRING(fp,myldap_get_dn(entry)); + WRITE_INT32(fp,NSLCD_PAM_SUCCESS); + WRITE_STRING(fp,""); + WRITE_INT32(fp,NSLCD_RESULT_END); + return 0; +} diff --git a/nslcd/passwd.c b/nslcd/passwd.c new file mode 100644 index 0000000..06e33c2 --- /dev/null +++ b/nslcd/passwd.c @@ -0,0 +1,626 @@ +/* + passwd.c - password entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-pwd.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" +#include "common/dict.h" +#include "compat/strndup.h" + +/* ( nisSchema.2.0 NAME 'posixAccount' SUP top AUXILIARY + * DESC 'Abstraction of an account with POSIX attributes' + * MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) + * MAY ( userPassword $ loginShell $ gecos $ description ) ) + */ + +/* the search base for searches */ +const char *passwd_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int passwd_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *passwd_filter = "(objectClass=posixAccount)"; + +/* the attributes used in searches */ +const char *attmap_passwd_uid = "uid"; +const char *attmap_passwd_userPassword = "\"*\""; +const char *attmap_passwd_uidNumber = "uidNumber"; +const char *attmap_passwd_gidNumber = "gidNumber"; +const char *attmap_passwd_gecos = "\"${gecos:-$cn}\""; +const char *attmap_passwd_homeDirectory = "homeDirectory"; +const char *attmap_passwd_loginShell = "loginShell"; + +/* special properties for objectSid-based searches + (these are already LDAP-escaped strings) */ +static char *uidSid=NULL; +static char *gidSid=NULL; + +/* default values for attributes */ +static const char *default_passwd_userPassword = "*"; /* unmatchable */ + +/* Note that the resulting password value should be one of: + - no password set, allow login without password + * - often used to prevent logins + x - "valid" encrypted password that does not match any valid password + often used to indicate that the password is defined elsewhere + other - encrypted password, usually in crypt(3) format */ + +/* the attribute list to request with searches */ +static const char **passwd_attrs=NULL; + +/* create a search filter for searching a passwd entry + by name, return -1 on errors */ +static int mkfilter_passwd_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if(myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + passwd_filter, + attmap_passwd_uid,safename); +} + +/* create a search filter for searching a passwd entry + by uid, return -1 on errors */ +static int mkfilter_passwd_byuid(uid_t uid, + char *buffer,size_t buflen) +{ + if (uidSid!=NULL) + { + return mysnprintf(buffer,buflen, + "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))", + passwd_filter, + attmap_passwd_uidNumber,uidSid, + (int)(uid&0xff),(int)((uid>>8)&0xff), + (int)((uid>>16)&0xff),(int)((uid>>24)&0xff)); + } + else + { + return mysnprintf(buffer,buflen, + "(&%s(%s=%d))", + passwd_filter, + attmap_passwd_uidNumber,(int)uid); + } +} + +void passwd_init(void) +{ + int i; + SET *set; + /* set up search bases */ + if (passwd_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (passwd_scope==LDAP_SCOPE_DEFAULT) + passwd_scope=nslcd_cfg->ldc_scope; + /* special case when uidNumber or gidNumber reference objectSid */ + if (strncasecmp(attmap_passwd_uidNumber,"objectSid:",10)==0) + { + uidSid=sid2search(attmap_passwd_uidNumber+10); + attmap_passwd_uidNumber=strndup(attmap_passwd_uidNumber,9); + } + if (strncasecmp(attmap_passwd_gidNumber,"objectSid:",10)==0) + { + gidSid=sid2search(attmap_passwd_gidNumber+10); + attmap_passwd_gidNumber=strndup(attmap_passwd_gidNumber,9); + } + /* set up attribute list */ + set=set_new(); + attmap_add_attributes(set,"objectClass"); /* for testing shadowAccount */ + attmap_add_attributes(set,attmap_passwd_uid); + attmap_add_attributes(set,attmap_passwd_userPassword); + attmap_add_attributes(set,attmap_passwd_uidNumber); + attmap_add_attributes(set,attmap_passwd_gidNumber); + attmap_add_attributes(set,attmap_passwd_gecos); + attmap_add_attributes(set,attmap_passwd_homeDirectory); + attmap_add_attributes(set,attmap_passwd_loginShell); + passwd_attrs=set_tolist(set); + set_free(set); +} + +/* the cache that is used in dn2uid() */ +static pthread_mutex_t dn2uid_cache_mutex=PTHREAD_MUTEX_INITIALIZER; +static DICT *dn2uid_cache=NULL; +struct dn2uid_cache_entry +{ + time_t timestamp; + char *uid; +}; +#define DN2UID_CACHE_TIMEOUT (15*60) + +/* checks whether the entry has a valid uidNumber attribute + (>= nss_min_uid) */ +static int entry_has_valid_uid(MYLDAP_ENTRY *entry) +{ + int i; + const char **values; + char *tmp; + uid_t uid; + /* if min_uid is not set any entry should do */ + if (nslcd_cfg->ldc_nss_min_uid==0) + return 1; + /* get all uidNumber attributes */ + values=myldap_get_values_len(entry,attmap_passwd_uidNumber); + if ((values==NULL)||(values[0]==NULL)) + { + log_log(LOG_WARNING,"passwd entry %s does not contain %s value", + myldap_get_dn(entry),attmap_passwd_uidNumber); + return 0; + } + /* check if there is a uidNumber attributes >= min_uid */ + for (i=0;values[i]!=NULL;i++) + { + if (uidSid!=NULL) + uid=(uid_t)binsid2id(values[i]); + else + { + errno=0; + uid=strtouid(values[i],&tmp,0); + if ((*(values[i])=='\0')||(*tmp!='\0')) + { + log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value", + myldap_get_dn(entry),attmap_passwd_uidNumber); + continue; + } + else if (errno!=0) + { + log_log(LOG_WARNING,"passwd entry %s contains too large %s value", + myldap_get_dn(entry),attmap_passwd_uidNumber); + continue; + } + } + if (uid>=nslcd_cfg->ldc_nss_min_uid) + return 1; + } + /* nothing found */ + return 0; +} + +/* Perform an LDAP lookup to translate the DN into a uid. + This function either returns NULL or a strdup()ed string. */ +char *lookup_dn2uid(MYLDAP_SESSION *session,const char *dn,int *rcp,char *buf,size_t buflen) +{ + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + static const char *attrs[3]; + int rc=LDAP_SUCCESS; + const char **values; + char *uid=NULL; + if (rcp==NULL) + rcp=&rc; + /* we have to look up the entry */ + attrs[0]=attmap_passwd_uid; + attrs[1]=attmap_passwd_uidNumber; + attrs[2]=NULL; + search=myldap_search(session,dn,LDAP_SCOPE_BASE,passwd_filter,attrs,rcp); + if (search==NULL) + { + log_log(LOG_WARNING,"lookup of user %s failed: %s",dn,ldap_err2string(*rcp)); + return NULL; + } + entry=myldap_get_entry(search,rcp); + if (entry==NULL) + { + if (*rcp!=LDAP_SUCCESS) + log_log(LOG_WARNING,"lookup of user %s failed: %s",dn,ldap_err2string(*rcp)); + return NULL; + } + /* check the uidNumber attribute if min_uid is set */ + if (entry_has_valid_uid(entry)) + { + /* get uid (just use first one) */ + values=myldap_get_values(entry,attmap_passwd_uid); + /* check the result for presence and validity */ + if ((values!=NULL)&&(values[0]!=NULL)&&isvalidname(values[0])&&(strlen(values[0])timestamp+DN2UID_CACHE_TIMEOUT)) + { + if ((cacheentry->uid!=NULL)&&(strlen(cacheentry->uid)uid); + else + buf=NULL; + pthread_mutex_unlock(&dn2uid_cache_mutex); + return buf; + } + /* leave the entry intact, just replace the uid below */ + } + pthread_mutex_unlock(&dn2uid_cache_mutex); + /* look up the uid using an LDAP query */ + uid=lookup_dn2uid(session,dn,NULL,buf,buflen); + /* store the result in the cache */ + pthread_mutex_lock(&dn2uid_cache_mutex); + /* try to get the entry from the cache here again because it could have + changed in the meantime */ + cacheentry=dict_get(dn2uid_cache,dn); + if (cacheentry==NULL) + { + /* allocate a new entry in the cache */ + cacheentry=(struct dn2uid_cache_entry *)malloc(sizeof(struct dn2uid_cache_entry)); + if (cacheentry!=NULL) + { + cacheentry->uid=NULL; + dict_put(dn2uid_cache,dn,cacheentry); + } + } + /* update the cache entry */ + if (cacheentry!=NULL) + { + cacheentry->timestamp=time(NULL); + /* copy the uid if needed */ + if (cacheentry->uid==NULL) + cacheentry->uid=uid!=NULL?strdup(uid):NULL; + else if (strcmp(cacheentry->uid,uid)!=0) + { + free(cacheentry->uid); + cacheentry->uid=uid!=NULL?strdup(uid):NULL; + } + } + pthread_mutex_unlock(&dn2uid_cache_mutex); + /* copy the result into the buffer */ + return uid; +} + +MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *session,const char *uid,int *rcp) +{ + MYLDAP_SEARCH *search=NULL; + MYLDAP_ENTRY *entry=NULL; + const char *base; + int i; + static const char *attrs[3]; + char filter[1024]; + /* if it isn't a valid username, just bail out now */ + if (!isvalidname(uid)) + { + if (rcp!=NULL) + *rcp=LDAP_INVALID_SYNTAX; + return NULL; + } + /* set up attributes (we don't need much) */ + attrs[0]=attmap_passwd_uid; + attrs[1]=attmap_passwd_uidNumber; + attrs[2]=NULL; + /* we have to look up the entry */ + mkfilter_passwd_byname(uid,filter,sizeof(filter)); + for (i=0;(i (cached_shadow_lastcheck+CACHED_SHADOW_TIMEOUT))) + { + cached_shadow_lastcheck=t; + if (stat(NSSWITCH_FILE,&buf)) + { + log_log(LOG_ERR,"stat(%s) failed: %s",NSSWITCH_FILE,strerror(errno)); + /* trigger a recheck anyway */ + cached_shadow_uses_ldap=CACHED_UNKNOWN; + return; + } + /* trigger a recheck if file changed */ + if (buf.st_mtime!=nsswitch_mtime) + { + nsswitch_mtime=buf.st_mtime; + cached_shadow_uses_ldap=CACHED_UNKNOWN; + } + } +} + +/* check whether shadow lookups are configured to use ldap */ +static inline int shadow_uses_ldap(void) +{ + if (cached_shadow_uses_ldap==CACHED_UNKNOWN) + cached_shadow_uses_ldap=nsswitch_db_uses_ldap(NSSWITCH_FILE,"shadow"); + return cached_shadow_uses_ldap; +} + +/* the maximum number of uidNumber attributes per entry */ +#define MAXUIDS_PER_ENTRY 5 + +static int write_passwd(TFILE *fp,MYLDAP_ENTRY *entry,const char *requser, + const uid_t *requid,uid_t calleruid) +{ + int32_t tmpint32; + const char **tmpvalues; + char *tmp; + const char **usernames; + const char *passwd; + uid_t uids[MAXUIDS_PER_ENTRY]; + int numuids; + char gidbuf[32]; + gid_t gid; + char gecos[100]; + char homedir[100]; + char shell[100]; + char passbuffer[64]; + int i,j; + /* get the usernames for this entry */ + usernames=myldap_get_values(entry,attmap_passwd_uid); + if ((usernames==NULL)||(usernames[0]==NULL)) + { + log_log(LOG_WARNING,"passwd entry %s does not contain %s value", + myldap_get_dn(entry),attmap_passwd_uid); + return 0; + } + /* if we are using shadow maps and this entry looks like it would return + shadow information, make the passwd entry indicate it */ + if (myldap_has_objectclass(entry,"shadowAccount")&&shadow_uses_ldap()) + { + passwd="x"; + } + else + { + passwd=get_userpassword(entry,attmap_passwd_userPassword,passbuffer,sizeof(passbuffer)); + if ((passwd==NULL)||(calleruid!=0)) + passwd=default_passwd_userPassword; + } + /* get the uids for this entry */ + if (requid!=NULL) + { + uids[0]=*requid; + numuids=1; + } + else + { + tmpvalues=myldap_get_values_len(entry,attmap_passwd_uidNumber); + if ((tmpvalues==NULL)||(tmpvalues[0]==NULL)) + { + log_log(LOG_WARNING,"passwd entry %s does not contain %s value", + myldap_get_dn(entry),attmap_passwd_uidNumber); + return 0; + } + for (numuids=0;(numuids=nslcd_cfg->ldc_nss_min_uid) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,usernames[i]); + WRITE_STRING(fp,passwd); + WRITE_TYPE(fp,uids[j],uid_t); + WRITE_TYPE(fp,gid,gid_t); + WRITE_STRING(fp,gecos); + WRITE_STRING(fp,homedir); + WRITE_STRING(fp,shell); + } + } + } + } + return 0; +} + +NSLCD_HANDLE_UID( + passwd,byname, + char name[256]; + char filter[1024]; + READ_STRING(fp,name); + log_setrequest("passwd=\"%s\"",name); + if (!isvalidname(name)) { + log_log(LOG_WARNING,"\"%s\": name denied by validnames option",name); + return -1; + } + check_nsswitch_reload();, + NSLCD_ACTION_PASSWD_BYNAME, + mkfilter_passwd_byname(name,filter,sizeof(filter)), + write_passwd(fp,entry,name,NULL,calleruid) +) + +NSLCD_HANDLE_UID( + passwd,byuid, + uid_t uid; + char filter[1024]; + READ_TYPE(fp,uid,uid_t); + log_setrequest("passwd=%d",(int)uid); + if (uidldc_nss_min_uid) + { + /* return an empty result */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_PASSWD_BYUID); + WRITE_INT32(fp,NSLCD_RESULT_END); + } + check_nsswitch_reload();, + NSLCD_ACTION_PASSWD_BYUID, + mkfilter_passwd_byuid(uid,filter,sizeof(filter)), + write_passwd(fp,entry,NULL,&uid,calleruid) +) + +NSLCD_HANDLE_UID( + passwd,all, + const char *filter; + log_setrequest("passwd(all)"); + check_nsswitch_reload();, + NSLCD_ACTION_PASSWD_ALL, + (filter=passwd_filter,0), + write_passwd(fp,entry,NULL,NULL,calleruid) +) diff --git a/nslcd/protocol.c b/nslcd/protocol.c new file mode 100644 index 0000000..520f69d --- /dev/null +++ b/nslcd/protocol.c @@ -0,0 +1,197 @@ +/* + protocol.c - protocol name and number lookup routines + Parts of this file were part of the nss_ldap library (as ldap-proto.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* ( nisSchema.2.4 NAME 'ipProtocol' SUP top STRUCTURAL + * DESC 'Abstraction of an IP protocol. Maps a protocol number + * to one or more names. The distinguished value of the cn + * attribute denotes the protocol's canonical name' + * MUST ( cn $ ipProtocolNumber ) + * MAY description ) + */ + +/* the search base for searches */ +const char *protocol_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int protocol_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *protocol_filter = "(objectClass=ipProtocol)"; + +/* the attributes used in searches */ +const char *attmap_protocol_cn = "cn"; +const char *attmap_protocol_ipProtocolNumber = "ipProtocolNumber"; + +/* the attribute list to request with searches */ +static const char *protocol_attrs[3]; + +static int mkfilter_protocol_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if (myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + protocol_filter, + attmap_protocol_cn,safename); +} + +/* create a search filter for searching a protocol entry + by uid, return -1 on errors */ +static int mkfilter_protocol_bynumber(int protocol, + char *buffer,size_t buflen) +{ + return mysnprintf(buffer,buflen, + "(&%s(%s=%d))", + protocol_filter, + attmap_protocol_ipProtocolNumber,protocol); +} + +void protocol_init(void) +{ + int i; + /* set up search bases */ + if (protocol_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (protocol_scope==LDAP_SCOPE_DEFAULT) + protocol_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + protocol_attrs[0]=attmap_protocol_cn; + protocol_attrs[1]=attmap_protocol_ipProtocolNumber; + protocol_attrs[2]=NULL; +} + +static int write_protocol(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqname) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + const char *name; + const char **aliases; + const char **protos; + char *tmp; + int proto; + int i; + /* get the most canonical name */ + name=myldap_get_rdn_value(entry,attmap_protocol_cn); + /* get the other names for the protocol */ + aliases=myldap_get_values(entry,attmap_protocol_cn); + if ((aliases==NULL)||(aliases[0]==NULL)) + { + log_log(LOG_WARNING,"protocol entry %s does not contain %s value", + myldap_get_dn(entry),attmap_protocol_cn); + return 0; + } + /* if the protocol name is not yet found, get the first entry */ + if (name==NULL) + name=aliases[0]; + /* check case of returned protocol entry */ + if ((reqname!=NULL)&&(strcmp(reqname,name)!=0)) + { + for (i=0;(aliases[i]!=NULL)&&(strcmp(reqname,aliases[i])!=0);i++) + /* nothing here */ ; + if (aliases[i]==NULL) + return 0; /* neither the name nor any of the aliases matched */ + } + /* get the protocol number */ + protos=myldap_get_values(entry,attmap_protocol_ipProtocolNumber); + if ((protos==NULL)||(protos[0]==NULL)) + { + log_log(LOG_WARNING,"protocol entry %s does not contain %s value", + myldap_get_dn(entry),attmap_protocol_ipProtocolNumber); + return 0; + } + else if (protos[1]!=NULL) + { + log_log(LOG_WARNING,"protocol entry %s contains multiple %s values", + myldap_get_dn(entry),attmap_protocol_ipProtocolNumber); + } + errno=0; + proto=(int)strtol(protos[0],&tmp,0); + if ((*(protos[0])=='\0')||(*tmp!='\0')) + { + log_log(LOG_WARNING,"protocol entry %s contains non-numeric %s value", + myldap_get_dn(entry),attmap_protocol_ipProtocolNumber); + return 0; + } + else if (errno!=0) + { + log_log(LOG_WARNING,"protocol entry %s contains too large %s value", + myldap_get_dn(entry),attmap_protocol_ipProtocolNumber); + return 0; + } + /* write entry */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,name); + WRITE_STRINGLIST_EXCEPT(fp,aliases,name); + WRITE_INT32(fp,proto); + return 0; +} + +NSLCD_HANDLE( + protocol,byname, + char name[256]; + char filter[1024]; + READ_STRING(fp,name); + log_setrequest("protocol=\"%s\"",name);, + NSLCD_ACTION_PROTOCOL_BYNAME, + mkfilter_protocol_byname(name,filter,sizeof(filter)), + write_protocol(fp,entry,name) +) + +NSLCD_HANDLE( + protocol,bynumber, + int protocol; + char filter[1024]; + READ_INT32(fp,protocol); + log_setrequest("protocol=%d",protocol);, + NSLCD_ACTION_PROTOCOL_BYNUMBER, + mkfilter_protocol_bynumber(protocol,filter,sizeof(filter)), + write_protocol(fp,entry,NULL) +) + +NSLCD_HANDLE( + protocol,all, + const char *filter; + log_setrequest("protocol(all)");, + NSLCD_ACTION_PROTOCOL_ALL, + (filter=protocol_filter,0), + write_protocol(fp,entry,NULL) +) diff --git a/nslcd/rpc.c b/nslcd/rpc.c new file mode 100644 index 0000000..ae79a90 --- /dev/null +++ b/nslcd/rpc.c @@ -0,0 +1,198 @@ +/* + rpc.c - rpc name lookup routines + Parts of this file were part of the nss_ldap library (as ldap-rpc.c) which + has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* ( nisSchema.2.5 NAME 'oncRpc' SUP top STRUCTURAL + * DESC 'Abstraction of an Open Network Computing (ONC) + * [RFC1057] Remote Procedure Call (RPC) binding. + * This class maps an ONC RPC number to a name. + * The distinguished value of the cn attribute denotes + * the RPC service's canonical name' + * MUST ( cn $ oncRpcNumber ) + * MAY description ) + */ + +/* the search base for searches */ +const char *rpc_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int rpc_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *rpc_filter = "(objectClass=oncRpc)"; + +/* the attributes to request with searches */ +const char *attmap_rpc_cn = "cn"; +const char *attmap_rpc_oncRpcNumber = "oncRpcNumber"; + +/* the attribute list to request with searches */ +static const char *rpc_attrs[3]; + +static int mkfilter_rpc_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if (myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + rpc_filter, + attmap_rpc_cn,safename); +} + +static int mkfilter_rpc_bynumber(int number, + char *buffer,size_t buflen) +{ + return mysnprintf(buffer,buflen, + "(&%s(%s=%d))", + rpc_filter, + attmap_rpc_oncRpcNumber,number); +} + +void rpc_init(void) +{ + int i; + /* set up search bases */ + if (rpc_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (rpc_scope==LDAP_SCOPE_DEFAULT) + rpc_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + rpc_attrs[0]=attmap_rpc_cn; + rpc_attrs[1]=attmap_rpc_oncRpcNumber; + rpc_attrs[2]=NULL; +} + +/* write a single rpc entry to the stream */ +static int write_rpc(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqname) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + const char *name; + const char **aliases; + const char **numbers; + char *tmp; + int number; + int i; + /* get the most canonical name */ + name=myldap_get_rdn_value(entry,attmap_rpc_cn); + /* get the other names for the rpc entries */ + aliases=myldap_get_values(entry,attmap_rpc_cn); + if ((aliases==NULL)||(aliases[0]==NULL)) + { + log_log(LOG_WARNING,"rpc entry %s does not contain %s value", + myldap_get_dn(entry),attmap_rpc_cn); + return 0; + } + /* if the rpc name is not yet found, get the first entry */ + if (name==NULL) + name=aliases[0]; + /* check case of returned rpc entry */ + if ((reqname!=NULL)&&(strcmp(reqname,name)!=0)) + { + for (i=0;(aliases[i]!=NULL)&&(strcmp(reqname,aliases[i])!=0);i++) + /* nothing here */ ; + if (aliases[i]==NULL) + return 0; /* neither the name nor any of the aliases matched */ + } + /* get the rpc number */ + numbers=myldap_get_values(entry,attmap_rpc_oncRpcNumber); + if ((numbers==NULL)||(numbers[0]==NULL)) + { + log_log(LOG_WARNING,"rpc entry %s does not contain %s value", + myldap_get_dn(entry),attmap_rpc_oncRpcNumber); + return 0; + } + else if (numbers[1]!=NULL) + { + log_log(LOG_WARNING,"rpc entry %s contains multiple %s values", + myldap_get_dn(entry),attmap_rpc_oncRpcNumber); + } + errno=0; + number=(int)strtol(numbers[0],&tmp,0); + if ((*(numbers[0])=='\0')||(*tmp!='\0')) + { + log_log(LOG_WARNING,"rpc entry %s contains non-numeric %s value", + myldap_get_dn(entry),attmap_rpc_oncRpcNumber); + return 0; + } + else if (errno!=0) + { + log_log(LOG_WARNING,"rpc entry %s contains too large %s value", + myldap_get_dn(entry),attmap_rpc_oncRpcNumber); + return 0; + } + /* write the entry */ + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,name); + WRITE_STRINGLIST_EXCEPT(fp,aliases,name); + WRITE_INT32(fp,number); + return 0; +} + +NSLCD_HANDLE( + rpc,byname, + char name[256]; + char filter[1024]; + READ_STRING(fp,name); + log_setrequest("rpc=\"%s\"",name);, + NSLCD_ACTION_RPC_BYNAME, + mkfilter_rpc_byname(name,filter,sizeof(filter)), + write_rpc(fp,entry,name) +) + +NSLCD_HANDLE( + rpc,bynumber, + int number; + char filter[1024]; + READ_INT32(fp,number); + log_setrequest("rpc=%d",number);, + NSLCD_ACTION_RPC_BYNUMBER, + mkfilter_rpc_bynumber(number,filter,sizeof(filter)), + write_rpc(fp,entry,NULL) +) + +NSLCD_HANDLE( + rpc,all, + const char *filter; + log_setrequest("rpc(all)");, + NSLCD_ACTION_RPC_ALL, + (filter=rpc_filter,0), + write_rpc(fp,entry,NULL) +) diff --git a/nslcd/service.c b/nslcd/service.c new file mode 100644 index 0000000..4a43022 --- /dev/null +++ b/nslcd/service.c @@ -0,0 +1,243 @@ +/* + service.c - service entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-service.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* ( nisSchema.2.3 NAME 'ipService' SUP top STRUCTURAL + * DESC 'Abstraction an Internet Protocol service. + * Maps an IP port and protocol (such as tcp or udp) + * to one or more names; the distinguished value of + * the cn attribute denotes the service's canonical + * name' + * MUST ( cn $ ipServicePort $ ipServiceProtocol ) + * MAY ( description ) ) + */ + +/* the search base for searches */ +const char *service_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int service_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *service_filter = "(objectClass=ipService)"; + +/* the attributes to request with searches */ +const char *attmap_service_cn = "cn"; +const char *attmap_service_ipServicePort = "ipServicePort"; +const char *attmap_service_ipServiceProtocol = "ipServiceProtocol"; + +/* the attribute list to request with searches */ +static const char *service_attrs[4]; + +static int mkfilter_service_byname(const char *name, + const char *protocol, + char *buffer,size_t buflen) +{ + char safename[300],safeprotocol[300]; + /* escape attributes */ + if (myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + if (*protocol!='\0') + { + if (myldap_escape(protocol,safeprotocol,sizeof(safeprotocol))) + return -1; + return mysnprintf(buffer,buflen, + "(&%s(%s=%s)(%s=%s))", + service_filter, + attmap_service_cn,safename, + attmap_service_ipServiceProtocol,safeprotocol); + } + else + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + service_filter, + attmap_service_cn,safename); +} + +static int mkfilter_service_bynumber(int number, + const char *protocol, + char *buffer,size_t buflen) +{ + char safeprotocol[300]; + if (*protocol!='\0') + { + if (myldap_escape(protocol,safeprotocol,sizeof(safeprotocol))) + return -1; + return mysnprintf(buffer,buflen, + "(&%s(%s=%d)(%s=%s))", + service_filter, + attmap_service_ipServicePort,number, + attmap_service_ipServiceProtocol,safeprotocol); + } + else + return mysnprintf(buffer,buflen, + "(&%s(%s=%d))", + service_filter, + attmap_service_ipServicePort,number); +} + +void service_init(void) +{ + int i; + /* set up search bases */ + if (service_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (service_scope==LDAP_SCOPE_DEFAULT) + service_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + service_attrs[0]=attmap_service_cn; + service_attrs[1]=attmap_service_ipServicePort; + service_attrs[2]=attmap_service_ipServiceProtocol; + service_attrs[3]=NULL; +} + +static int write_service(TFILE *fp,MYLDAP_ENTRY *entry, + const char *reqname,const char *reqprotocol) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + const char *name; + const char **aliases; + const char **ports; + const char **protocols; + char *tmp; + int port; + int i; + /* get the most canonical name */ + name=myldap_get_rdn_value(entry,attmap_service_cn); + /* get the other names for the service entries */ + aliases=myldap_get_values(entry,attmap_service_cn); + if ((aliases==NULL)||(aliases[0]==NULL)) + { + log_log(LOG_WARNING,"service entry %s does not contain %s value", + myldap_get_dn(entry),attmap_service_cn); + return 0; + } + /* if the service name is not yet found, get the first entry */ + if (name==NULL) + name=aliases[0]; + /* check case of returned servies entry */ + if ((reqname!=NULL)&&(strcmp(reqname,name)!=0)) + { + for (i=0;(aliases[i]!=NULL)&&(strcmp(reqname,aliases[i])!=0);i++) + /* nothing here */ ; + if (aliases[i]==NULL) + return 0; /* neither the name nor any of the aliases matched */ + } + /* get the service number */ + ports=myldap_get_values(entry,attmap_service_ipServicePort); + if ((ports==NULL)||(ports[0]==NULL)) + { + log_log(LOG_WARNING,"service entry %s does not contain %s value", + myldap_get_dn(entry),attmap_service_ipServicePort); + return 0; + } + else if (ports[1]!=NULL) + { + log_log(LOG_WARNING,"service entry %s contains multiple %s values", + myldap_get_dn(entry),attmap_service_ipServicePort); + } + errno=0; + port=(int)strtol(ports[0],&tmp,0); + if ((*(ports[0])=='\0')||(*tmp!='\0')) + { + log_log(LOG_WARNING,"service entry %s contains non-numeric %s value", + myldap_get_dn(entry),attmap_service_ipServicePort); + return 0; + } + else if (errno!=0) + { + log_log(LOG_WARNING,"service entry %s contains too large %s value", + myldap_get_dn(entry),attmap_service_ipServicePort); + return 0; + } + /* get protocols */ + protocols=myldap_get_values(entry,attmap_service_ipServiceProtocol); + if ((protocols==NULL)||(protocols[0]==NULL)) + { + log_log(LOG_WARNING,"service entry %s does not contain %s value", + myldap_get_dn(entry),attmap_service_ipServiceProtocol); + return 0; + } + /* write the entries */ + for (i=0;protocols[i]!=NULL;i++) + if ((reqprotocol==NULL)||(*reqprotocol=='\0')||(strcmp(reqprotocol,protocols[i])==0)) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,name); + WRITE_STRINGLIST_EXCEPT(fp,aliases,name); + WRITE_INT32(fp,port); + WRITE_STRING(fp,protocols[i]); + } + return 0; +} + +NSLCD_HANDLE( + service,byname, + char name[256]; + char protocol[256]; + char filter[1024]; + READ_STRING(fp,name); + READ_STRING(fp,protocol); + log_setrequest("service=\"%s\"/%s",name,protocol);, + NSLCD_ACTION_SERVICE_BYNAME, + mkfilter_service_byname(name,protocol,filter,sizeof(filter)), + write_service(fp,entry,name,protocol) +) + +NSLCD_HANDLE( + service,bynumber, + int number; + char protocol[256]; + char filter[1024]; + READ_INT32(fp,number); + READ_STRING(fp,protocol); + log_setrequest("service=%d/%s",number,protocol);, + NSLCD_ACTION_SERVICE_BYNUMBER, + mkfilter_service_bynumber(number,protocol,filter,sizeof(filter)), + write_service(fp,entry,NULL,protocol) +) + +NSLCD_HANDLE( + service,all, + const char *filter; + log_setrequest("service(all)");, + NSLCD_ACTION_SERVICE_ALL, + (filter=service_filter,0), + write_service(fp,entry,NULL,NULL) +) diff --git a/nslcd/shadow.c b/nslcd/shadow.c new file mode 100644 index 0000000..61d9019 --- /dev/null +++ b/nslcd/shadow.c @@ -0,0 +1,378 @@ +/* + shadow.c - shadow entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-spwd.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" + +/* ( nisSchema.2.1 NAME 'shadowAccount' SUP top AUXILIARY + * DESC 'Additional attributes for shadow passwords' + * MUST uid + * MAY ( userPassword $ shadowLastChange $ shadowMin + * shadowMax $ shadowWarning $ shadowInactive $ + * shadowExpire $ shadowFlag $ description ) ) + */ + +/* the search base for searches */ +const char *shadow_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; + +/* the search scope for searches */ +int shadow_scope = LDAP_SCOPE_DEFAULT; + +/* the basic search filter for searches */ +const char *shadow_filter = "(objectClass=shadowAccount)"; + +/* the attributes to request with searches */ +const char *attmap_shadow_uid = "uid"; +const char *attmap_shadow_userPassword = "\"*\""; +const char *attmap_shadow_shadowLastChange = "\"${shadowLastChange:--1}\""; +const char *attmap_shadow_shadowMin = "\"${shadowMin:--1}\""; +const char *attmap_shadow_shadowMax = "\"${shadowMax:--1}\""; +const char *attmap_shadow_shadowWarning = "\"${shadowWarning:--1}\""; +const char *attmap_shadow_shadowInactive = "\"${shadowInactive:--1}\""; +const char *attmap_shadow_shadowExpire = "\"${shadowExpire:--1}\""; +const char *attmap_shadow_shadowFlag = "\"${shadowFlag:-0}\""; + +/* default values for attributes */ +static const char *default_shadow_userPassword = "*"; /* unmatchable */ + +/* the attribute list to request with searches */ +static const char **shadow_attrs=NULL; + +static int mkfilter_shadow_byname(const char *name, + char *buffer,size_t buflen) +{ + char safename[300]; + /* escape attribute */ + if(myldap_escape(name,safename,sizeof(safename))) + return -1; + /* build filter */ + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + shadow_filter, + attmap_shadow_uid,safename); +} + +void shadow_init(void) +{ + int i; + SET *set; + /* set up search bases */ + if (shadow_bases[0]==NULL) + for (i=0;ildc_bases[i]; + /* set up scope */ + if (shadow_scope==LDAP_SCOPE_DEFAULT) + shadow_scope=nslcd_cfg->ldc_scope; + /* set up attribute list */ + set=set_new(); + attmap_add_attributes(set,attmap_shadow_uid); + attmap_add_attributes(set,attmap_shadow_userPassword); + attmap_add_attributes(set,attmap_shadow_shadowLastChange); + attmap_add_attributes(set,attmap_shadow_shadowMax); + attmap_add_attributes(set,attmap_shadow_shadowMin); + attmap_add_attributes(set,attmap_shadow_shadowWarning); + attmap_add_attributes(set,attmap_shadow_shadowInactive); + attmap_add_attributes(set,attmap_shadow_shadowExpire); + attmap_add_attributes(set,attmap_shadow_shadowFlag); + shadow_attrs=set_tolist(set); + set_free(set); +} + +static long to_date(const char *date,const char *attr) +{ + char buffer[32]; + long value; + char *tmp; + size_t l; + /* do some special handling for date values on AD */ + if (strcasecmp(attr,"pwdLastSet")==0) + { + /* we expect an AD 64-bit datetime value; + we should do date=date/864000000000-134774 + but that causes problems on 32-bit platforms, + first we devide by 1000000000 by stripping the + last 9 digits from the string and going from there */ + l=strlen(date)-9; + if (l>(sizeof(buffer)-1)) + return -1; /* error */ + strncpy(buffer,date,l); + buffer[l]='\0'; + errno=0; + value=strtol(date,&tmp,0); + if ((*date=='\0')||(*tmp!='\0')) + { + log_log(LOG_WARNING,"shadow entry contains non-numeric %s value",attr); + return -1; + } + else if (errno!=0) + { + log_log(LOG_WARNING,"shadow entry contains too large %s value",attr); + return -1; + } + return value/864-134774; + /* note that AD does not have expiry dates but a lastchangeddate + and some value that needs to be added */ + } + errno=0; + value=strtol(date,&tmp,0); + if ((*date=='\0')||(*tmp!='\0')) + { + log_log(LOG_WARNING,"shadow entry contains non-numeric %s value",attr); + return -1; + } + else if (errno!=0) + { + log_log(LOG_WARNING,"shadow entry contains too large %s value",attr); + return -1; + } + return value; +} + +#ifndef UF_DONT_EXPIRE_PASSWD +#define UF_DONT_EXPIRE_PASSWD 0x10000 +#endif + +#define GET_OPTIONAL_LONG(var,att,fallback) \ + tmpvalue=attmap_get_value(entry,attmap_shadow_##att,buffer,sizeof(buffer)); \ + if (tmpvalue==NULL) \ + tmpvalue=""; \ + errno=0; \ + var=strtol(tmpvalue,&tmp,0); \ + if ((*(tmpvalue)=='\0')||(*tmp!='\0')) \ + { \ + log_log(LOG_WARNING,"shadow entry %s contains non-numeric %s value", \ + myldap_get_dn(entry),attmap_shadow_##att); \ + var=fallback; \ + } \ + else if (errno!=0) \ + { \ + log_log(LOG_WARNING,"shadow entry %s contains too large %s value", \ + myldap_get_dn(entry),attmap_shadow_##att); \ + var=fallback; \ + } + +void get_shadow_properties(MYLDAP_ENTRY *entry,long *lastchangedate, + long *mindays,long *maxdays,long *warndays, + long *inactdays,long *expiredate,unsigned long *flag) +{ + char buffer[64]; + const char *tmpvalue; + char *tmp; + /* get lastchange date */ + tmpvalue=attmap_get_value(entry,attmap_shadow_shadowLastChange,buffer,sizeof(buffer)); + if (tmpvalue==NULL) + tmpvalue=""; + *lastchangedate=to_date(tmpvalue,attmap_shadow_shadowLastChange); + /* get other shadow properties */ + GET_OPTIONAL_LONG(*mindays,shadowMin,-1); + GET_OPTIONAL_LONG(*maxdays,shadowMax,-1); + GET_OPTIONAL_LONG(*warndays,shadowWarning,-1); + GET_OPTIONAL_LONG(*inactdays,shadowInactive,-1); + GET_OPTIONAL_LONG(*expiredate,shadowExpire,-1); + GET_OPTIONAL_LONG(*flag,shadowFlag,0); + /* if we're using AD handle the flag specially */ + if (strcasecmp(attmap_shadow_shadowLastChange,"pwdLastSet")==0) + { + if (*flag&UF_DONT_EXPIRE_PASSWD) + *maxdays=-1; + *flag=0; + } +} + +/* try to update the shadowLastChange attribute of the entry if possible */ +int update_lastchange(MYLDAP_SESSION *session,const char *userdn) +{ + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + static const char *attrs[3]; + const char *attr; + int rc; + const char **values; + LDAPMod mod,*mods[2]; + char buffer[64],*strvals[2]; + /* find the name of the attribute to use */ + if ( (attmap_shadow_shadowLastChange==NULL) || (attmap_shadow_shadowLastChange[0]=='\0') ) + return LDAP_LOCAL_ERROR; /* attribute not mapped at all */ + else if (strcmp(attmap_shadow_shadowLastChange,"\"${shadowLastChange:--1}\"")==0) + attr="shadowLastChange"; + else if (attmap_shadow_shadowLastChange[0]=='\"') + return LDAP_LOCAL_ERROR; /* other expressions not supported for now */ + else + attr=attmap_shadow_shadowLastChange; + /* set up the attributes we need */ + attrs[0]=attmap_shadow_uid; + attrs[1]=attr; + attrs[2]=NULL; + /* find the entry to see if the attribute is present */ + search=myldap_search(session,userdn,LDAP_SCOPE_BASE,shadow_filter,attrs,&rc); + if (search==NULL) + return rc; + entry=myldap_get_entry(search,&rc); + if (entry==NULL) + return rc; + values=myldap_get_values(entry,attr); + if ((values==NULL)||(values[0]==NULL)||(values[0][0]=='\0')) + return LDAP_NO_SUCH_ATTRIBUTE; + /* build the value for the new attribute */ + if (strcasecmp(attr,"pwdLastSet")==0) + { + /* for AD we use another timestamp */ + if(mysnprintf(buffer,sizeof(buffer),"%ld000000000",((long int)time(NULL)/100L+(134774L*864L)))) + return LDAP_LOCAL_ERROR; + } + else + { + /* time in days since Jan 1, 1970 */ + if(mysnprintf(buffer,sizeof(buffer),"%ld",((long int)(time(NULL)/(long int)(60*60*24))))) + return LDAP_LOCAL_ERROR; + } + /* update the shadowLastChange attribute */ + strvals[0]=buffer; + strvals[1]=NULL; + mod.mod_op=LDAP_MOD_REPLACE; + mod.mod_type=(char *)attr; + mod.mod_values=strvals; + mods[0]=&mod; + mods[1]=NULL; + rc=myldap_modify(session,userdn,mods); + if (rc!=LDAP_SUCCESS) + log_log(LOG_WARNING,"modification of %s attribute of %s failed: %s", + attr,userdn,ldap_err2string(rc)); + else + log_log(LOG_DEBUG,"modification of %s attribute of %s succeeded", + attr,userdn); + return rc; +} + +static int write_shadow(TFILE *fp,MYLDAP_ENTRY *entry,const char *requser) +{ + int32_t tmpint32; + const char **usernames; + const char *passwd; + long lastchangedate; + long mindays; + long maxdays; + long warndays; + long inactdays; + long expiredate; + unsigned long flag; + int i; + char passbuffer[64]; + /* get username */ + usernames=myldap_get_values(entry,attmap_shadow_uid); + if ((usernames==NULL)||(usernames[0]==NULL)) + { + log_log(LOG_WARNING,"shadow entry %s does not contain %s value", + myldap_get_dn(entry),attmap_shadow_uid); + return 0; + } + /* get password */ + passwd=get_userpassword(entry,attmap_shadow_userPassword,passbuffer,sizeof(passbuffer)); + if (passwd==NULL) + passwd=default_shadow_userPassword; + /* get expiry properties */ + get_shadow_properties(entry,&lastchangedate,&mindays,&maxdays,&warndays, + &inactdays,&expiredate,&flag); + /* write the entries */ + for (i=0;usernames[i]!=NULL;i++) + if ((requser==NULL)||(strcmp(requser,usernames[i])==0)) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,usernames[i]); + WRITE_STRING(fp,passwd); + WRITE_INT32(fp,lastchangedate); + WRITE_INT32(fp,mindays); + WRITE_INT32(fp,maxdays); + WRITE_INT32(fp,warndays); + WRITE_INT32(fp,inactdays); + WRITE_INT32(fp,expiredate); + WRITE_INT32(fp,flag); + } + return 0; +} + +MYLDAP_ENTRY *shadow_uid2entry(MYLDAP_SESSION *session,const char *username,int *rcp) +{ + MYLDAP_SEARCH *search=NULL; + MYLDAP_ENTRY *entry=NULL; + const char *base; + char filter[1024]; + int i; + /* if it isn't a valid username, just bail out now */ + if (!isvalidname(username)) + { + if (rcp!=NULL) + *rcp=LDAP_INVALID_SYNTAX; + return NULL; + } + /* we have to look up the entry */ + mkfilter_shadow_byname(username,filter,sizeof(filter)); + for (i=0;(i +#include + +#include "prototypes.h" +#include "common.h" + +/* read an alias entry from the stream */ +static nss_status_t read_aliasent( + TFILE *fp,struct aliasent *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + size_t bufptr=0; + /* read the name of the alias */ + READ_BUF_STRING(fp,result->alias_name); + /* read the members */ + READ_BUF_STRINGLIST(fp,result->alias_members); + /* tmp3int32 holds the number of entries read */ + result->alias_members_len=tmp3int32; + /* fill in remaining gaps in struct */ + result->alias_local=0; + /* we're done */ + return NSS_STATUS_SUCCESS; +} + +/* get an alias entry by name */ +nss_status_t _nss_ldap_getaliasbyname_r( + const char *name,struct aliasent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYNAME(NSLCD_ACTION_ALIAS_BYNAME, + name, + read_aliasent(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *aliasentfp; + +/* start a request to read all aliases */ +nss_status_t _nss_ldap_setaliasent(void) +{ + NSS_SETENT(aliasentfp); +} + +/* read a single alias entry from the stream */ +nss_status_t _nss_ldap_getaliasent_r( + struct aliasent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(aliasentfp,NSLCD_ACTION_ALIAS_ALL, + read_aliasent(aliasentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened with setaliasent() above */ +nss_status_t _nss_ldap_endaliasent(void) +{ + NSS_ENDENT(aliasentfp); +} diff --git a/nss/bsdnss.c b/nss/bsdnss.c new file mode 100644 index 0000000..da862a5 --- /dev/null +++ b/nss/bsdnss.c @@ -0,0 +1,155 @@ +/* + bsdnss.c - BSD NSS functions + This file was part of the nss-pam-ldapd FreeBSD port and part of the + nss_ldap FreeBSD port before that. + + Copyright (C) 2003 Jacques Vidrine + Copyright (C) 2006 Artem Kazakov + Copyright (C) 2009 Alexander V. Chernikov + Copyright (C) 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "prototypes.h" + +#define BUFFER_SIZE 1024 + +NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r); +NSS_METHOD_PROTOTYPE(__nss_compat_setgrent); +NSS_METHOD_PROTOTYPE(__nss_compat_endgrent); + +NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r); +NSS_METHOD_PROTOTYPE(__nss_compat_setpwent); +NSS_METHOD_PROTOTYPE(__nss_compat_endpwent); + +NSS_METHOD_PROTOTYPE(__nss_compat_gethostbyname); +NSS_METHOD_PROTOTYPE(__nss_compat_gethostbyname2); +NSS_METHOD_PROTOTYPE(__nss_compat_gethostbyaddr); + +static ns_mtab methods[]={ + { NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_ldap_getgrnam_r }, + { NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, _nss_ldap_getgrgid_r }, + { NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_ldap_getgrent_r }, + { NSDB_GROUP, "setgrent", __nss_compat_setgrent, _nss_ldap_setgrent }, + { NSDB_GROUP, "endgrent", __nss_compat_endgrent, _nss_ldap_endgrent }, + + { NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_ldap_getpwnam_r }, + { NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_ldap_getpwuid_r }, + { NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, _nss_ldap_getpwent_r }, + { NSDB_PASSWD, "setpwent", __nss_compat_setpwent, _nss_ldap_setpwent }, + { NSDB_PASSWD, "endpwent", __nss_compat_endpwent, _nss_ldap_endpwent }, + + { NSDB_HOSTS, "gethostbyname", __nss_compat_gethostbyname, _nss_ldap_gethostbyname_r }, + { NSDB_HOSTS, "gethostbyaddr", __nss_compat_gethostbyaddr, _nss_ldap_gethostbyaddr_r }, + { NSDB_HOSTS, "gethostbyname2", __nss_compat_gethostbyname2, _nss_ldap_gethostbyname2_r }, + + { NSDB_GROUP_COMPAT, "getgrnam_r", __nss_compat_getgrnam_r, _nss_ldap_getgrnam_r }, + { NSDB_GROUP_COMPAT, "getgrgid_r", __nss_compat_getgrgid_r, _nss_ldap_getgrgid_r }, + { NSDB_GROUP_COMPAT, "getgrent_r", __nss_compat_getgrent_r, _nss_ldap_getgrent_r }, + { NSDB_GROUP_COMPAT, "setgrent", __nss_compat_setgrent, _nss_ldap_setgrent }, + { NSDB_GROUP_COMPAT, "endgrent", __nss_compat_endgrent, _nss_ldap_endgrent }, + + { NSDB_PASSWD_COMPAT, "getpwnam_r", __nss_compat_getpwnam_r, _nss_ldap_getpwnam_r }, + { NSDB_PASSWD_COMPAT, "getpwuid_r", __nss_compat_getpwuid_r, _nss_ldap_getpwuid_r }, + { NSDB_PASSWD_COMPAT, "getpwent_r", __nss_compat_getpwent_r, _nss_ldap_getpwent_r }, + { NSDB_PASSWD_COMPAT, "setpwent", __nss_compat_setpwent, _nss_ldap_setpwent }, + { NSDB_PASSWD_COMPAT, "endpwent", __nss_compat_endpwent, _nss_ldap_endpwent }, +}; + +int __nss_compat_gethostbyname(void *retval,void *mdata,va_list ap) +{ + nss_status_t (*fn)(const char *,struct hostent *,char *,size_t,int *,int *); + const char *name; + struct hostent *result; + char buffer[BUFFER_SIZE]; + int errnop; + int h_errnop; + int af; + nss_status_t status; + fn=mdata; + name=va_arg(ap,const char*); + af=va_arg(ap,int); + result=va_arg(ap,struct hostent *); + status=fn(name,result,buffer,sizeof(buffer),&errnop,&h_errnop); + status=__nss_compat_result(status,errnop); + h_errno=h_errnop; + return (status); +} + +int __nss_compat_gethostbyname2(void *retval,void *mdata,va_list ap) +{ + nss_status_t (*fn)(const char *,struct hostent *,char *,size_t,int *,int *); + const char *name; + struct hostent *result; + char buffer[BUFFER_SIZE]; + int errnop; + int h_errnop; + int af; + nss_status_t status; + fn=mdata; + name=va_arg(ap,const char*); + af=va_arg(ap,int); + result=va_arg(ap,struct hostent *); + status=fn(name,result,buffer,sizeof(buffer),&errnop,&h_errnop); + status=__nss_compat_result(status,errnop); + h_errno=h_errnop; + return (status); +} + +int __nss_compat_gethostbyaddr(void *retval,void *mdata,va_list ap) +{ + struct in_addr *addr; + int len; + int type; + struct hostent *result; + char buffer[BUFFER_SIZE]; + int errnop; + int h_errnop; + nss_status_t (*fn)(struct in_addr *,int,int,struct hostent *,char *,size_t,int *,int *); + nss_status_t status; + fn=mdata; + addr=va_arg(ap,struct in_addr*); + len=va_arg(ap,int); + type=va_arg(ap,int); + result=va_arg(ap,struct hostent*); + status=fn(addr,len,type,result,buffer,sizeof(buffer),&errnop,&h_errnop); + status=__nss_compat_result(status,errnop); + h_errno=h_errnop; + return (status); +} + +ns_mtab *nss_module_register(const char *source,unsigned int *mtabsize, + nss_module_unregister_fn *unreg) +{ + *mtabsize=sizeof(methods)/sizeof(methods[0]); + *unreg=NULL; + return (methods); +} diff --git a/nss/common.c b/nss/common.c new file mode 100644 index 0000000..20a3136 --- /dev/null +++ b/nss/common.c @@ -0,0 +1,22 @@ +/* + common.c - common definitions + + Copyright (C) 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +int _nss_ldap_enablelookups=1; diff --git a/nss/common.h b/nss/common.h new file mode 100644 index 0000000..8d8f3a8 --- /dev/null +++ b/nss/common.h @@ -0,0 +1,227 @@ +/* + common.h - common functions for NSS lookups + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef NSS__COMMON_H +#define NSS__COMMON_H 1 + +#include +#include + +#include "nslcd.h" +#include "common/nslcd-prot.h" +#include "compat/attrs.h" +#include "compat/nss_compat.h" + +/* These are macros for handling read and write problems, they are + NSS specific due to the return code so are defined here. They + genrally close the open file, set an error code and return with + an error status. */ + +/* Macro is called to handle errors in opening a client connection. */ +#define ERROR_OUT_OPENERROR \ + *errnop=ENOENT; \ + return (errno==EAGAIN)?NSS_STATUS_TRYAGAIN:NSS_STATUS_UNAVAIL; + +/* Macro is called to handle errors on read operations. */ +#define ERROR_OUT_READERROR(fp) \ + (void)tio_close(fp); \ + fp=NULL; \ + *errnop=ENOENT; \ + return NSS_STATUS_UNAVAIL; + +/* Macro is called to handle problems with too small a buffer. + This triggers the caller to call the function with a larger + buffer (see NSS_GETENT below). */ +#define ERROR_OUT_BUFERROR(fp) \ + *errnop=ERANGE; \ + return NSS_STATUS_TRYAGAIN; + +/* This macro is called if there was a problem with a write + operation. */ +#define ERROR_OUT_WRITEERROR(fp) \ + ERROR_OUT_READERROR(fp) + +/* This macro is called if the read status code is not + NSLCD_RESULT_BEGIN. */ +#define ERROR_OUT_NOSUCCESS(fp) \ + (void)tio_close(fp); \ + fp=NULL; \ + return NSS_STATUS_NOTFOUND; + +/* These are some general macros that are used to build parts of the + genral macros below. */ + +/* check to see if we should answer NSS requests */ +#define NSS_AVAILCHECK \ + if (!_nss_ldap_enablelookups) \ + return NSS_STATUS_UNAVAIL; + +#ifdef NSS_FLAVOUR_GLIBC + +/* extra definitions we need (nothing for Glibc) */ +#define NSS_EXTRA_DEFS ; + +/* check validity of passed buffer (Glibc flavour) */ +#define NSS_BUFCHECK \ + if ((buffer==NULL)||(buflen==0)) \ + { \ + *errnop=EINVAL; \ + return NSS_STATUS_UNAVAIL; \ + } + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +/* extra definitions we need (Solaris NSS functions don't pass errno) */ +#define NSS_EXTRA_DEFS \ + int *errnop=&(errno); + +/* check validity of passed buffer (Solaris flavour) */ +#define NSS_BUFCHECK \ + if ((NSS_ARGS(args)->buf.buffer==NULL)||(NSS_ARGS(args)->buf.buflen<=0)) \ + { \ + NSS_ARGS(args)->erange=1; \ + return NSS_STATUS_TRYAGAIN; \ + } + +/* this is the backend structure for Solaris */ +struct nss_ldap_backend +{ + nss_backend_op_t *ops; /* function-pointer table */ + int n_ops; /* number of function pointers */ + TFILE *fp; /* the file pointer for {set,get,end}ent() functions */ +}; + +/* constructor for LDAP backends */ +nss_backend_t *nss_ldap_constructor(nss_backend_op_t *ops,size_t sizeofops); + +/* destructor for LDAP backends */ +nss_status_t nss_ldap_destructor(nss_backend_t *be,void UNUSED(*args)); + +#endif /* NSS_FLAVOUR_SOLARIS */ + +/* The following macros to automatically generate get..byname(), + get..bynumber(), setent(), getent() and endent() function + bodies. These functions have very common code so this can + easily be reused. */ + +/* This is a generic get..by..() generation macro. The action + parameter is the NSLCD_ACTION_.. action, the writefn is the + operation for writing the parameters and readfn is the function + name for reading a single result entry. The function is assumed + to have result, buffer, buflen and errnop parameters that define + the result structure, the user buffer with length and the + errno to return. This macro should be called through some of + the customized ones below. */ +#define NSS_BYGEN(action,writefn,readfn) \ + TFILE *fp; \ + int32_t tmpint32; \ + nss_status_t retv; \ + NSS_EXTRA_DEFS; \ + NSS_AVAILCHECK; \ + NSS_BUFCHECK; \ + /* open socket and write request */ \ + NSLCD_REQUEST(fp,action,writefn); \ + /* read response */ \ + READ_RESPONSE_CODE(fp); \ + retv=readfn; \ + /* close socket and we're done */ \ + if ((retv==NSS_STATUS_SUCCESS)||(retv==NSS_STATUS_TRYAGAIN)) \ + (void)tio_close(fp); \ + return retv; + +/* This macro can be used to generate a get..byname() function + body. */ +#define NSS_BYNAME(action,name,readfn) \ + NSS_BYGEN(action,WRITE_STRING(fp,name),readfn) + +/* This macro can be used to generate a get..by..() function + body where the value that is the key has the specified type. */ +#define NSS_BYTYPE(action,val,type,readfn) \ + NSS_BYGEN(action,WRITE_TYPE(fp,val,type),readfn) + +/* This macro can be used to generate a get..by..() function + body where the value should be passed as an int32_t. */ +#define NSS_BYINT32(action,val,readfn) \ + NSS_BYGEN(action,WRITE_INT32(fp,val),readfn) + +/* This macro generates a simple setent() function body. This closes any + open streams so that NSS_GETENT() can open a new file. */ +#define NSS_SETENT(fp) \ + NSS_AVAILCHECK; \ + if (fp!=NULL) \ + { \ + (void)tio_close(fp); \ + fp=NULL; \ + } \ + return NSS_STATUS_SUCCESS; + +/* This macro generates a getent() function body. If the stream is not yet + open, a new one is opened, a request is written and a check is done for + a response header. A single entry is read with the readfn() function. */ +#define NSS_GETENT(fp,action,readfn) \ + int32_t tmpint32; \ + nss_status_t retv; \ + NSS_EXTRA_DEFS; \ + NSS_AVAILCHECK; \ + NSS_BUFCHECK; \ + /* check that we have a valid file descriptor */ \ + if (fp==NULL) \ + { \ + /* open a new stream and write the request */ \ + NSLCD_REQUEST(fp,action,/* no writefn */;); \ + } \ + /* prepare for buffer errors */ \ + tio_mark(fp); \ + /* read a response */ \ + READ_RESPONSE_CODE(fp); \ + retv=readfn; \ + /* check read result */ \ + if (retv==NSS_STATUS_TRYAGAIN) \ + { \ + /* if we have a full buffer try to reset the stream */ \ + if (tio_reset(fp)) \ + { \ + tio_close(fp); \ + fp=NULL; \ + /* fail with permanent error to prevent retries */ \ + *errnop=EINVAL; \ + return NSS_STATUS_UNAVAIL; \ + } \ + } \ + else if (retv!=NSS_STATUS_SUCCESS) \ + fp=NULL; /* file should be closed by now */ \ + return retv; + +/* This macro generates a endent() function body. This just closes + the stream. */ +#define NSS_ENDENT(fp) \ + NSS_AVAILCHECK; \ + if (fp!=NULL) \ + { \ + (void)tio_close(fp); \ + fp=NULL; \ + } \ + return NSS_STATUS_SUCCESS; + +#endif /* not NSS__COMMON_H */ diff --git a/nss/ethers.c b/nss/ethers.c new file mode 100644 index 0000000..a109cf3 --- /dev/null +++ b/nss/ethers.c @@ -0,0 +1,184 @@ +/* + ethers.c - NSS lookup functions for ethers database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* read an ethernet entry from the stream */ +static nss_status_t read_etherent( + TFILE *fp,struct etherent *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32; + size_t bufptr=0; + READ_BUF_STRING(fp,result->e_name); + READ_TYPE(fp,result->e_addr,uint8_t[6]); + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* map a hostname to the corresponding ethernet address */ +nss_status_t _nss_ldap_gethostton_r( + const char *name,struct etherent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYNAME(NSLCD_ACTION_ETHER_BYNAME, + name, + read_etherent(fp,result,buffer,buflen,errnop)); +} + +/* map an ethernet address to the corresponding hostname */ +nss_status_t _nss_ldap_getntohost_r( + const struct ether_addr *addr,struct etherent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYTYPE(NSLCD_ACTION_ETHER_BYETHER, + *addr,uint8_t[6], + read_etherent(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *etherentfp; + +/* open a connection to read all ether entries */ +nss_status_t _nss_ldap_setetherent(int UNUSED(stayopen)) +{ + NSS_SETENT(etherentfp); +} + +/* read a single ethernet entry from the stream */ +nss_status_t _nss_ldap_getetherent_r( + struct etherent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(etherentfp,NSLCD_ACTION_ETHER_ALL, + read_etherent(etherentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened with setetherent() above */ +nss_status_t _nss_ldap_endetherent(void) +{ + NSS_ENDENT(etherentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifndef NSS_BUFLEN_ETHERS +#define NSS_BUFLEN_ETHERS 1024 +#endif /* NSS_BUFLEN_ETHERS */ + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_etherstring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct etherent result; + nss_status_t retv; + char *buffer; + int res; + /* read the etherent into a temporary buffer */ + buffer=(char *)malloc(args->buf.buflen); + if (buffer==NULL) + return NSS_STATUS_UNAVAIL; + retv=read_etherent(fp,&result,buffer,args->buf.buflen,&errno); + if (retv!=NSS_STATUS_SUCCESS) + { + free(buffer); + return retv; + } + /* make a string representation */ + res=snprintf(args->buf.buffer,args->buf.buflen, + "%s %s",ether_ntoa(&result.e_addr),result.e_name); + free(buffer); + if ((res<0)||(res>=args->buf.buflen)) + return NSS_STATUS_TRYAGAIN; + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_etherent(fp,(struct etherent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno): \ + read_etherstring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_etherent(fp,(struct etherent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +/* map a hostname to the corresponding ethernet address */ +static nss_status_t ethers_gethostton(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_ETHER_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT(fp)); +} + +/* map an ethernet address to the corresponding hostname */ +static nss_status_t ethers_getntohost(nss_backend_t UNUSED(*be),void *args) +{ + struct ether_addr *addr=(struct ether_addr *)(NSS_ARGS(args)->key.ether); + NSS_BYTYPE(NSLCD_ACTION_ETHER_BYETHER, + *addr,uint8_t[6], + READ_RESULT(fp)); +} + +static nss_status_t ethers_destructor(nss_backend_t *be,void UNUSED(*args)) +{ + free(be); + return NSS_STATUS_SUCCESS; +} + +static nss_backend_op_t ethers_ops[]={ + ethers_destructor, + ethers_gethostton, + ethers_getntohost +}; + +nss_backend_t *_nss_ldap_ethers_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + nss_backend_t *be; + if (!(be=(nss_backend_t *)malloc(sizeof(*be)))) + return NULL; + be->ops=ethers_ops; + be->n_ops=sizeof(ethers_ops)/sizeof(nss_backend_op_t); + return be; +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/exports.freebsd b/nss/exports.freebsd new file mode 100644 index 0000000..b9cd773 --- /dev/null +++ b/nss/exports.freebsd @@ -0,0 +1,16 @@ +EXPORTED { + + # published NSS service functions + global: + + # flag to enable or disable lookups + _nss_ldap_enablelookups; + + # module init + nss_module_register; + + # everything else should not be exported + local: + *; + +}; diff --git a/nss/exports.glibc b/nss/exports.glibc new file mode 100644 index 0000000..0ed5ea2 --- /dev/null +++ b/nss/exports.glibc @@ -0,0 +1,88 @@ +EXPORTED { + + # published NSS service functions + global: + + # flag to enable or disable lookups + _nss_ldap_enablelookups; + + # aliases - mail aliases + _nss_ldap_getaliasbyname_r; + _nss_ldap_setaliasent; + _nss_ldap_getaliasent_r; + _nss_ldap_endaliasent; + + # ethers - ethernet numbers + _nss_ldap_gethostton_r; + _nss_ldap_getntohost_r; + _nss_ldap_setetherent; + _nss_ldap_getetherent_r; + _nss_ldap_endetherent; + + # group - groups of users + _nss_ldap_getgrnam_r; + _nss_ldap_getgrgid_r; + _nss_ldap_initgroups_dyn; + _nss_ldap_setgrent; + _nss_ldap_getgrent_r; + _nss_ldap_endgrent; + + # hosts - host names and numbers + _nss_ldap_gethostbyname_r; + _nss_ldap_gethostbyname2_r; + _nss_ldap_gethostbyaddr_r; + _nss_ldap_sethostent; + _nss_ldap_gethostent_r; + _nss_ldap_endhostent; + + # netgroup - list of host and users + _nss_ldap_setnetgrent; + _nss_ldap_getnetgrent_r; + _nss_ldap_endnetgrent; + + # networks - network names and numbers + _nss_ldap_getnetbyname_r; + _nss_ldap_getnetbyaddr_r; + _nss_ldap_setnetent; + _nss_ldap_getnetent_r; + _nss_ldap_endnetent; + + # passwd - user database and passwords + _nss_ldap_getpwnam_r; + _nss_ldap_getpwuid_r; + _nss_ldap_setpwent; + _nss_ldap_getpwent_r; + _nss_ldap_endpwent; + + # protocols - network protocols + _nss_ldap_getprotobyname_r; + _nss_ldap_getprotobynumber_r; + _nss_ldap_setprotoent; + _nss_ldap_getprotoent_r; + _nss_ldap_endprotoent; + + # rpc - remote procedure call names and numbers + _nss_ldap_getrpcbyname_r; + _nss_ldap_getrpcbynumber_r; + _nss_ldap_setrpcent; + _nss_ldap_getrpcent_r; + _nss_ldap_endrpcent; + + # services - network services + _nss_ldap_getservbyname_r; + _nss_ldap_getservbyport_r; + _nss_ldap_setservent; + _nss_ldap_getservent_r; + _nss_ldap_endservent; + + # shadow - extended user information + _nss_ldap_getspnam_r; + _nss_ldap_setspent; + _nss_ldap_getspent_r; + _nss_ldap_endspent; + + # everything else should not be exported + local: + *; + +}; diff --git a/nss/exports.solaris b/nss/exports.solaris new file mode 100644 index 0000000..be90512 --- /dev/null +++ b/nss/exports.solaris @@ -0,0 +1,25 @@ +nss_ldap.so.1 { + + # published NSS service functions + global: + + # flag to enable or disable lookups + _nss_ldap_enablelookups; + + # published NSS service module constructors + _nss_ldap_ethers_constr; + _nss_ldap_group_constr; + _nss_ldap_hosts_constr; + _nss_ldap_networks_constr; + _nss_ldap_protocols_constr; + _nss_ldap_passwd_constr; + _nss_ldap_rpc_constr; + _nss_ldap_services_constr; + _nss_ldap_shadow_constr; + _nss_ldap_netgroup_constr; + + # everything else should not be exported + local: + *; + +}; diff --git a/nss/group.c b/nss/group.c new file mode 100644 index 0000000..c20ac04 --- /dev/null +++ b/nss/group.c @@ -0,0 +1,303 @@ +/* + group.c - NSS lookup functions for group database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2009, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* read a single group entry from the stream */ +static nss_status_t read_group( + TFILE *fp,struct group *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + size_t bufptr=0; + READ_BUF_STRING(fp,result->gr_name); + READ_BUF_STRING(fp,result->gr_passwd); + READ_TYPE(fp,result->gr_gid,gid_t); + READ_BUF_STRINGLIST(fp,result->gr_mem); + return NSS_STATUS_SUCCESS; +} + +/* read all group entries from the stream and add + gids of these groups to the list */ +static nss_status_t read_gids( + TFILE *fp,gid_t skipgroup,long int *start,long int *size, + gid_t **groupsp,long int limit,int *errnop) +{ + int32_t res=(int32_t)NSLCD_RESULT_BEGIN; + int32_t tmpint32,tmp2int32,tmp3int32; + gid_t gid; +#ifdef NSS_FLAVOUR_GLIBC + gid_t *newgroups; + long int newsize; +#endif /* NSS_FLAVOUR_GLIBC */ + /* loop over results */ + while (res==(int32_t)NSLCD_RESULT_BEGIN) + { + /* skip group name */ + SKIP_STRING(fp); + /* skip passwd entry */ + SKIP_STRING(fp); + /* read gid */ + READ_TYPE(fp,gid,gid_t); + /* skip members */ + SKIP_STRINGLIST(fp); + /* only add the group to the list if it is not the specified group */ + if (gid!=skipgroup) + { + /* check if we reached the limit */ + if ( (limit>0) && (*start>=limit) ) + return NSS_STATUS_TRYAGAIN; + /* check if our buffer is large enough */ +#ifdef NSS_FLAVOUR_GLIBC + if ((*start)>=(*size)) + { + /* for some reason Glibc expects us to grow the array (completely + different from all other NSS functions) */ + /* calculate new size */ + newsize=2*(*size); + if ( (limit>0) && (*start>=limit) ) + newsize=limit; + /* allocate new memory */ + newgroups=realloc(*groupsp,newsize*sizeof(gid_t)); + if (newgroups==NULL) + return NSS_STATUS_TRYAGAIN; + *groupsp=newgroups; + *size=newsize; + } +#endif /* NSS_FLAVOUR_GLIBC */ + /* add gid to list */ + (*groupsp)[(*start)++]=gid; + } + /* read next response code + (don't bail out on not success since we just want to build + up a list) */ + READ_TYPE(fp,res,int32_t); + } + /* return the proper status code */ + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* get a group entry by name */ +nss_status_t _nss_ldap_getgrnam_r( + const char *name,struct group *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYNAME(NSLCD_ACTION_GROUP_BYNAME, + name, + read_group(fp,result,buffer,buflen,errnop)); +} + +/* get a group entry by numeric gid */ +nss_status_t _nss_ldap_getgrgid_r( + gid_t gid,struct group *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYTYPE(NSLCD_ACTION_GROUP_BYGID, + gid,gid_t, + read_group(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *grentfp; + +/* start a request to read all groups */ +nss_status_t _nss_ldap_setgrent(int UNUSED(stayopen)) +{ + NSS_SETENT(grentfp); +} + +/* read a single group from the stream */ +nss_status_t _nss_ldap_getgrent_r( + struct group *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(grentfp,NSLCD_ACTION_GROUP_ALL, + read_group(grentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened with setgrent() above */ +nss_status_t _nss_ldap_endgrent(void) +{ + NSS_ENDENT(grentfp); +} + +/* this function returns a list of groups, documentation for the + interface is scarce (any pointers are welcome) but this is + what is assumed the parameters mean: + + user IN - the user name to find groups for + skipgroup IN - a group to not include in the list + *start IN/OUT - where to write in the array, is incremented + *size IN/OUT - the size of the supplied array (gid_t entries, not bytes) + **groupsp IN/OUT - pointer to the array of returned groupids + limit IN - the maxium size of the array + *errnop OUT - for returning errno +*/ +nss_status_t _nss_ldap_initgroups_dyn( + const char *user,gid_t skipgroup,long int *start, + long int *size,gid_t **groupsp,long int limit,int *errnop) +{ +/* temporarily map the buffer and buflen names so the check in NSS_BYNAME + for validity of the buffer works (renaming the parameters may cause + confusion) */ +#define buffer groupsp +#define buflen *size + NSS_BYNAME(NSLCD_ACTION_GROUP_BYMEMBER, + user, + read_gids(fp,skipgroup,start,size,groupsp,limit,errnop)); +#undef buffer +#undef buflen +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_groupstring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct group result; + nss_status_t retv; + char *buffer; + size_t buflen; + int i; + /* read the group into a temporary buffer */ + buffer=(char *)malloc(args->buf.buflen); + if (buffer==NULL) + return NSS_STATUS_UNAVAIL; + retv=read_group(fp,&result,buffer,args->buf.buflen,&errno); + if (retv!=NSS_STATUS_SUCCESS) + { + free(buffer); + return retv; + } + /* make a string representation */ + snprintf(args->buf.buffer,args->buf.buflen, + "%s:%s:%d:",result.gr_name,result.gr_passwd,(int)result.gr_gid); + args->buf.buffer[args->buf.buflen-1]='\0'; + if (result.gr_mem) + for (i=0;result.gr_mem[i];i++) + { + if (i) + strncat(args->buf.buffer,args->buf.buflen-strlen(args->buf.buffer)-1,","); + strncat(args->buf.buffer,args->buf.buflen-strlen(args->buf.buffer)-1,result.gr_mem[i]); + } + free(buffer); + /* check if buffer overflowed */ + if (strlen(args->buf.buffer)>=args->buf.buffer-1) + return NSS_STATUS_TRYAGAIN; + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_group(fp,(struct group *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno): \ + read_groupstring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_group(fp,(struct group *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +static nss_status_t group_getgrnam(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_GROUP_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT(fp)); +} + +static nss_status_t group_getgrgid(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYTYPE(NSLCD_ACTION_GROUP_BYGID, + NSS_ARGS(args)->key.gid,gid_t, + READ_RESULT(fp)); +} + +static nss_status_t group_setgrent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +static nss_status_t group_getgrent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_GROUP_ALL, + READ_RESULT((LDAP_BE(be)->fp))); +} + +static nss_status_t group_endgrent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +/* +static nss_status_t get_initgroups_dyn( + const char *user,gid_t skipgroup,long int *start, + gid_t **groupsp,long int limit,int *errnop) +*/ +static nss_status_t group_getgroupsbymember(nss_backend_t UNUSED(*be),void *args) +{ + struct nss_groupsbymem *argp=(struct nss_groupsbymem *)args; + long int start=(long int)argp->numgids; + gid_t skipgroup=(start>0)?argp->gid_array[0]:(gid_t)-1; + NSS_BYNAME(NSLCD_ACTION_GROUP_BYMEMBER, + argp->username, + read_gids(fp,skipgroup,&start,NULL,(gid_t **)&argp->gid_array,argp->maxgids,&errno); + argp->numgids=(int)start;); +} + +static nss_backend_op_t group_ops[]={ + nss_ldap_destructor, + group_endgrent, + group_setgrent, + group_getgrent, + group_getgrnam, + group_getgrgid, + group_getgroupsbymember +}; + +nss_backend_t *_nss_ldap_group_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(group_ops,sizeof(group_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/hosts.c b/nss/hosts.c new file mode 100644 index 0000000..eda7dc5 --- /dev/null +++ b/nss/hosts.c @@ -0,0 +1,382 @@ +/* + hosts.c - NSS lookup functions for hosts database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* Redefine some ERROR_OUT macros as we also want to set h_errnop. */ + +#undef ERROR_OUT_OPENERROR +#define ERROR_OUT_OPENERROR \ + *errnop=ENOENT; \ + *h_errnop=HOST_NOT_FOUND; \ + return (errno==EAGAIN)?NSS_STATUS_TRYAGAIN:NSS_STATUS_UNAVAIL; + +#undef ERROR_OUT_READERROR +#define ERROR_OUT_READERROR(fp) \ + (void)tio_close(fp); \ + fp=NULL; \ + *errnop=ENOENT; \ + *h_errnop=NO_RECOVERY; \ + return NSS_STATUS_UNAVAIL; + +#undef ERROR_OUT_BUFERROR +#define ERROR_OUT_BUFERROR(fp) \ + (void)tio_close(fp); \ + fp=NULL; \ + *errnop=ERANGE; \ + *h_errnop=TRY_AGAIN; \ + return NSS_STATUS_TRYAGAIN; + +#undef ERROR_OUT_WRITEERROR +#define ERROR_OUT_WRITEERROR(fp) \ + ERROR_OUT_READERROR(fp) + +/* read a single host entry from the stream, filtering on the + specified address family, result is stored in result + it will an empty entry if no addresses in the address family + were available */ +static nss_status_t read_hostent( + TFILE *fp,int af,struct hostent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + int32_t numaddr; + int i; + int readaf; + size_t bufptr=0; + /* read the host entry */ + READ_BUF_STRING(fp,result->h_name); + READ_BUF_STRINGLIST(fp,result->h_aliases); + result->h_addrtype=af; + result->h_length=0; + /* read number of addresses to follow */ + READ_INT32(fp,numaddr); + /* allocate memory for array */ + /* Note: this may allocate too much memory (e.g. also for + address records of other address families) but + this is a simple way to do it */ + BUF_ALLOC(fp,result->h_addr_list,char *,numaddr+1); + /* go through the address list and filter on af */ + i=0; + while (--numaddr>=0) + { + /* read address family and size */ + READ_INT32(fp,readaf); + READ_INT32(fp,tmp2int32); + if (readaf==af) + { + /* read the address */ + result->h_length=tmp2int32; + READ_BUF(fp,result->h_addr_list[i++],tmp2int32); + } + else + { + SKIP(fp,tmpint32); + } + } + /* null-terminate address list */ + result->h_addr_list[i]=NULL; + return NSS_STATUS_SUCCESS; +} + +/* this is a wrapper around read_hostent() that does error handling + if the read address list does not contain any addresses for the + specified address familiy */ +static nss_status_t read_hostent_erronempty( + TFILE *fp,int af,struct hostent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + nss_status_t retv; + retv=read_hostent(fp,af,result,buffer,buflen,errnop,h_errnop); + /* check result */ + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* check empty address list + (note that we cannot do this in the read_hostent() function as closing + the socket there will cause problems with the {set,get,end}ent() functions + below) + */ + if (result->h_addr_list[0]==NULL) + { + *errnop=ENOENT; + *h_errnop=NO_ADDRESS; + (void)tio_close(fp); + return NSS_STATUS_NOTFOUND; + } + return NSS_STATUS_SUCCESS; +} + +/* this is a wrapper around read_hostent() that skips to the + next address if the address list does not contain any addresses for the + specified address familiy */ +static nss_status_t read_hostent_nextonempty( + TFILE *fp,int af,struct hostent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + int32_t tmpint32; + nss_status_t retv; + /* check until we read an non-empty entry */ + do + { + /* read a host entry */ + retv=read_hostent(fp,af,result,buffer,buflen,errnop,h_errnop); + /* check result */ + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* skip to the next entry if we read an empty address */ + if (result->h_addr_list[0]==NULL) + { + retv=NSS_STATUS_NOTFOUND; + READ_RESPONSE_CODE(fp); + } + /* do another loop run if we read an empty address */ + } + while (retv!=NSS_STATUS_SUCCESS); + return NSS_STATUS_SUCCESS; +} + +/* write an address value */ +#define WRITE_ADDRESS(fp,af,len,addr) \ + WRITE_INT32(fp,af); \ + WRITE_INT32(fp,len); \ + WRITE(fp,addr,len); + +#ifdef NSS_FLAVOUR_GLIBC + +/* this function looks up a single host entry and returns all the addresses + associated with the host in a single address familiy + name - IN - hostname to lookup + af - IN - address familty to present results for + result - OUT - entry found + buffer,buflen - OUT - buffer to store allocated stuff on + errnop,h_errnop - OUT - for reporting errors */ +nss_status_t _nss_ldap_gethostbyname2_r( + const char *name,int af,struct hostent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + NSS_BYNAME(NSLCD_ACTION_HOST_BYNAME, + name, + read_hostent_erronempty(fp,af,result,buffer,buflen,errnop,h_errnop)); +} + +/* this function just calls the gethostbyname2() variant with the address + familiy set */ +nss_status_t _nss_ldap_gethostbyname_r( + const char *name,struct hostent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + return _nss_ldap_gethostbyname2_r(name,AF_INET,result,buffer,buflen,errnop,h_errnop); +} + +/* this function looks up a single host entry and returns all the addresses + associated with the host in a single address familiy + addr - IN - the address to look up + len - IN - the size of the addr struct + af - IN - address familty the address is specified as + result - OUT - entry found + buffer,buflen - OUT - buffer to store allocated stuff on + errnop,h_errnop - OUT - for reporting errors */ +nss_status_t _nss_ldap_gethostbyaddr_r( + const void *addr,socklen_t len,int af,struct hostent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + NSS_BYGEN(NSLCD_ACTION_HOST_BYADDR, + WRITE_ADDRESS(fp,af,len,addr), + read_hostent_erronempty(fp,af,result,buffer,buflen,errnop,h_errnop)) +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *hostentfp; + +nss_status_t _nss_ldap_sethostent(int UNUSED(stayopen)) +{ + NSS_SETENT(hostentfp); +} + +/* this function only returns addresses of the AF_INET address family */ +nss_status_t _nss_ldap_gethostent_r( + struct hostent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + NSS_GETENT(hostentfp,NSLCD_ACTION_HOST_ALL, + read_hostent_nextonempty(hostentfp,AF_INET,result,buffer,buflen,errnop,h_errnop)); +} + +/* close the stream opened with sethostent() above */ +nss_status_t _nss_ldap_endhostent(void) +{ + NSS_ENDENT(hostentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +struct nss_ldap_hosts_backend +{ + nss_backend_op_t *ops; + int n_ops; + TFILE *fp; +}; + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_hoststring(TFILE *fp,nss_XbyY_args_t *args,int erronempty) +{ + struct hostent result; + nss_status_t retv; + char *buffer; + size_t buflen; + int i; + /* read the hostent */ + if (erronempty) + retv=read_hostent_erronempty(fp,NSS_ARGS(args)->key.hostaddr.type,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); + else + retv=read_hostent_nextonempty(fp,NSS_ARGS(args)->key.hostaddr.type,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* allocate a temporary buffer */ + buflen=args->buf.buflen; + buffer=(char *)malloc(buflen); + /* build the formatted string */ + /* FIXME: implement proper buffer size checking */ + if (result.h_addr_list) + { + struct in_addr in; + (void)memcpy(&in.s_addr,result.h_addr_list[0],sizeof(in.s_addr)); + sprintf(buffer,"%s %s",inet_ntoa(in),result.h_name); + if (result.h_aliases) + { + int j; + for (j=0;result.h_aliases[j];j++) + { + strcat(buffer," "); + strcat(buffer,result.h_aliases[j]); + } + } + for (i=1;result.h_addr_list[i];i++) + { + (void)memcpy(&in.s_addr,result.h_addr_list[i],sizeof(in.s_addr)); + strcat(buffer,"\n"); + strcat(buffer,inet_ntoa(in)); + strcat(buffer," "); + strcat(buffer,result.h_name); + /* TODO: aliases only supplied to the first address */ + /* need review */ + } + } + /* copy the result back to the result buffer and free the temporary one */ + strcpy(NSS_ARGS(args)->buf.buffer,buffer); + free(buffer); + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT_ERRONEMPTY(fp) \ + NSS_ARGS(args)->buf.result? \ + read_hostent_erronempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)): \ + read_hoststring(fp,args,1); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#define READ_RESULT_NEXTONEMPTY(fp) \ + NSS_ARGS(args)->buf.result? \ + read_hostent_nextonempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)): \ + read_hoststring(fp,args,0); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT_ERRONEMPTY(fp) \ + read_hostent_erronempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#define READ_RESULT_NEXTONEMPTY(fp) \ + read_hostent_nextonempty(fp,NSS_ARGS(args)->key.hostaddr.type,(struct hostent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +/* hack to set the correct errno and h_errno */ +#define h_errnop &(NSS_ARGS(args)->h_errno) + +static nss_status_t hosts_gethostbyname(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_HOST_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT_ERRONEMPTY(fp)); +} + +static nss_status_t hosts_gethostbyaddr(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYGEN(NSLCD_ACTION_HOST_BYADDR, + WRITE_ADDRESS(fp,NSS_ARGS(args)->key.hostaddr.type,NSS_ARGS(args)->key.hostaddr.len,NSS_ARGS(args)->key.hostaddr.addr), + READ_RESULT_ERRONEMPTY(fp)); +} + +static nss_status_t hosts_sethostent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +static nss_status_t hosts_gethostent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_HOST_ALL, + READ_RESULT_NEXTONEMPTY(LDAP_BE(be)->fp)); +} + +static nss_status_t hosts_endhostent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +static nss_backend_op_t hosts_ops[]={ + nss_ldap_destructor, + hosts_endhostent, + hosts_sethostent, + hosts_gethostent, + hosts_gethostbyname, + hosts_gethostbyaddr +}; + +nss_backend_t *_nss_ldap_hosts_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(hosts_ops,sizeof(hosts_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/netgroup.c b/nss/netgroup.c new file mode 100644 index 0000000..51baa7d --- /dev/null +++ b/nss/netgroup.c @@ -0,0 +1,332 @@ +/* + netgroup.c - NSS lookup functions for netgroup entries + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" +#include "common/set.h" + +/* we redefine this here because we need to return NSS_STATUS_RETURN + instead of NSS_STATUS_NOTFOUND */ +#undef ERROR_OUT_NOSUCCESS +#define ERROR_OUT_NOSUCCESS(fp) \ + (void)tio_close(fp); \ + fp=NULL; \ + return NSS_STATUS_RETURN; + +/* function for reading a single result entry */ +static nss_status_t read_netgrent( + TFILE *fp,struct __netgrent *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32; + int type; + size_t bufptr=0; + /* read netgroup type */ + READ_INT32(fp,type); + if (type==NSLCD_NETGROUP_TYPE_NETGROUP) + { + /* the response is a reference to another netgroup */ + result->type=group_val; + READ_BUF_STRING(fp,result->val.group); + } + else if (type==NSLCD_NETGROUP_TYPE_TRIPLE) + { + /* the response is a host/user/domain triple */ + result->type=triple_val; + /* read host and revert to NULL on empty string */ + READ_BUF_STRING(fp,result->val.triple.host); + if (result->val.triple.host[0]=='\0') + { + result->val.triple.host=NULL; + bufptr--; /* free unused space */ + } + /* read user and revert to NULL on empty string */ + READ_BUF_STRING(fp,result->val.triple.user); + if (result->val.triple.user[0]=='\0') + { + result->val.triple.user=NULL; + bufptr--; /* free unused space */ + } + /* read domain and revert to NULL on empty string */ + READ_BUF_STRING(fp,result->val.triple.domain); + if (result->val.triple.domain[0]=='\0') + { + result->val.triple.domain=NULL; + bufptr--; /* free unused space */ + } + } + else + return NSS_STATUS_UNAVAIL; + /* we're done */ + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *netgrentfp; + +/* start a request to get a netgroup by name */ +nss_status_t _nss_ldap_setnetgrent( + const char *group,struct __netgrent UNUSED(*result)) +{ + /* we cannot use NSS_SETENT() here because we have a parameter that is only + available in this function */ + int32_t tmpint32; + int errnocp; + int *errnop; + if (!_nss_ldap_enablelookups) + return NSS_STATUS_UNAVAIL; + errnop=&errnocp; + /* check parameter */ + if ((group==NULL)||(group[0]=='\0')) + return NSS_STATUS_UNAVAIL; + /* open a new stream and write the request */ + NSLCD_REQUEST(netgrentfp,NSLCD_ACTION_NETGROUP_BYNAME,WRITE_STRING(netgrentfp,group)); + return NSS_STATUS_SUCCESS; +} + +/* get a single netgroup tuple from the stream */ +nss_status_t _nss_ldap_getnetgrent_r( + struct __netgrent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(netgrentfp,NSLCD_ACTION_NETGROUP_BYNAME, + read_netgrent(netgrentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened with setnetgrent() above */ +nss_status_t _nss_ldap_endnetgrent(struct __netgrent UNUSED(*result)) +{ + NSS_ENDENT(netgrentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +/* this is the backend structure for the {set,get,end}ent() functions */ +struct setnetgrent_backend +{ + nss_backend_op_t *ops; /* function-pointer table */ + int n_ops; /* number of function pointers */ + TFILE *fp; /* the file pointer for {set,get,end}ent() functions */ + SET *seen_groups; /* netgroups seen, for loop detection */ + SET *unseen_groups; /* netgroups that need to be chased */ +}; + +/* easy way to get sets from back-end */ +#define NETGROUP_BE(be) ((struct setnetgrent_backend*)(be)) + +/* access arguments */ +#define SETNETGRENT_ARGS(args) ((struct nss_setnetgrent_args *)(args)) +#define GETNETGRENT_ARGS(args) ((struct nss_getnetgrent_args *)(args)) + +/* return a netgroup that has not been traversed */ +static char *find_unseen_netgroup(nss_backend_t *be) +{ + char *group; + while (1) + { + group=set_pop(NETGROUP_BE(be)->unseen_groups); + if (group==NULL) + return NULL; + if (!set_contains(NETGROUP_BE(be)->seen_groups,group)) + { + set_add(NETGROUP_BE(be)->seen_groups,group); + return group; + } + } +} + +static nss_status_t netgroup_nslcd_setnetgrent(nss_backend_t *be,const char *group) +{ + /* we cannot use NSS_SETENT() here because we have a parameter that is only + available in this function */ + int32_t tmpint32; + int errnocp; + int *errnop; + errnop=&errnocp; + /* check parameter */ + if ((group==NULL)||(group[0]=='\0')) + return NSS_STATUS_UNAVAIL; + /* open a new stream and write the request */ + NSLCD_REQUEST(NETGROUP_BE(be)->fp,NSLCD_ACTION_NETGROUP_BYNAME, + WRITE_STRING(NETGROUP_BE(be)->fp,group)); + return NSS_STATUS_SUCCESS; +} + +static nss_status_t netgroup_nslcd_getnetgrent(nss_backend_t *be,struct __netgrent *result,char *buffer,size_t buflen,void *args) +{ + NSS_GETENT(NETGROUP_BE(be)->fp,NSLCD_ACTION_NETGROUP_BYNAME, + read_netgrent(NETGROUP_BE(be)->fp,result,buffer,buflen,errnop)); +} + +static nss_status_t netgroup_setnetgrent_setnetgrent(nss_backend_t UNUSED(*be),void UNUSED(*args)) +{ + return NSS_STATUS_SUCCESS; +} + +static nss_status_t netgroup_setnetgrent_getnetgrent(nss_backend_t *be,void *args) +{ + struct __netgrent result; + char *group=NULL; + int done=0; + nss_status_t status,rc; + GETNETGRENT_ARGS(args)->status=NSS_NETGR_NO; + while (!done) + { + status=netgroup_nslcd_getnetgrent(be,&result,GETNETGRENT_ARGS(args)->buffer, + GETNETGRENT_ARGS(args)->buflen,args); + if (status!=NSS_STATUS_SUCCESS) + { + if (errno==ENOENT) + { + /* done with the current netgroup */ + /* explore nested netgroup,if any */ + int found=0; + while (!found) + { + /* find a nested netgroup to pursue further */ + group=find_unseen_netgroup(be); + if (group==NULL) + { + /* no more netgroup */ + found=1; done=1; + errno=ENOENT; + } + else + { + rc=netgroup_nslcd_setnetgrent(be,group); + if (rc==NSS_STATUS_SUCCESS) + found=1; + free(group); + group=NULL; + } + } /* while !found */ + } + else + { /* err!=ENOENT */ + done=1; + } + } + else + { /* status==NSS_STATUS_SUCCESS */ + if (result.type==group_val) + { + /* a netgroup nested within the current netgroup */ + set_add(NETGROUP_BE(be)->unseen_groups,result.val.group); + } + else if (result.type==triple_val) + { + GETNETGRENT_ARGS(args)->retp[NSS_NETGR_MACHINE]=result.val.triple.host; + GETNETGRENT_ARGS(args)->retp[NSS_NETGR_USER]=result.val.triple.user; + GETNETGRENT_ARGS(args)->retp[NSS_NETGR_DOMAIN]=result.val.triple.domain; + GETNETGRENT_ARGS(args)->status=NSS_NETGR_FOUND; + done=1; + } + else + { + /* NSS_STATUS_SUCCESS,but type is not group_val or triple_val */ + /* should not be here,log a message */ + status=NSS_STATUS_NOTFOUND; + done=1; + } + } + } /* while !done */ + return status; +} + +static nss_status_t netgroup_setnetgrent_endnetgrent(nss_backend_t UNUSED(*be),void UNUSED(*args)) +{ + NSS_ENDENT(NETGROUP_BE(be)->fp); +} + +static nss_status_t netgroup_setnetgrent_destructor(nss_backend_t *be,void *UNUSED(args)) +{ + struct setnetgrent_backend *ngbe=(struct setnetgrent_backend *)be; + if (ngbe->fp!=NULL) + (void)tio_close(ngbe->fp); + set_free(ngbe->seen_groups); + set_free(ngbe->unseen_groups); + free(ngbe); + return NSS_STATUS_SUCCESS; +} + +static nss_backend_op_t netgroup_setnetgrent_ops[]={ + netgroup_setnetgrent_destructor, + netgroup_setnetgrent_endnetgrent, + netgroup_setnetgrent_setnetgrent, + netgroup_setnetgrent_getnetgrent, +}; + +static nss_status_t netgroup_setnetgrent_constructor(nss_backend_t *be,void *args) +{ + struct setnetgrent_backend *ngbe; + nss_status_t retv; + NSS_AVAILCHECK; + SETNETGRENT_ARGS(args)->iterator=NULL; /* initialize */ + /* allocate a back-end specific to this request */ + ngbe=(struct setnetgrent_backend *)malloc(sizeof(struct setnetgrent_backend)); + if (ngbe==NULL) + return NSS_STATUS_UNAVAIL; + ngbe->ops=netgroup_setnetgrent_ops; + ngbe->n_ops=sizeof(netgroup_setnetgrent_ops)/sizeof(nss_backend_op_t); + ngbe->fp=NULL; + ngbe->seen_groups=set_new(); + ngbe->unseen_groups=set_new(); + /* start the first search */ + retv=netgroup_nslcd_setnetgrent(be,SETNETGRENT_ARGS(args)->netgroup); + if (retv!=NSS_STATUS_SUCCESS) + { + netgroup_setnetgrent_destructor(be,args); + return retv; + } + /* return the new back-end */ + SETNETGRENT_ARGS(args)->iterator=(nss_backend_t *)ngbe; + return NSS_STATUS_SUCCESS; +} + +static nss_backend_op_t netgroup_ops[]={ + nss_ldap_destructor, + NULL, + NULL, + NULL, + NULL,/* TODO:_nss_ldap_netgr_in,*/ + netgroup_setnetgrent_constructor +}; + +nss_backend_t *_nss_ldap_netgroup_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(netgroup_ops,sizeof(netgroup_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/networks.c b/nss/networks.c new file mode 100644 index 0000000..4237ab4 --- /dev/null +++ b/nss/networks.c @@ -0,0 +1,263 @@ +/* + networks.c - NSS lookup functions for networks database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010, 2011 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* Redefine some ERROR_OUT macros as we also want to set h_errnop. */ + +#undef ERROR_OUT_OPENERROR +#define ERROR_OUT_OPENERROR \ + *errnop=ENOENT; \ + *h_errnop=HOST_NOT_FOUND; \ + return (errno==EAGAIN)?NSS_STATUS_TRYAGAIN:NSS_STATUS_UNAVAIL; + +#undef ERROR_OUT_READERROR +#define ERROR_OUT_READERROR(fp) \ + (void)tio_close(fp); \ + fp=NULL; \ + *errnop=ENOENT; \ + *h_errnop=NO_RECOVERY; \ + return NSS_STATUS_UNAVAIL; + +#undef ERROR_OUT_BUFERROR +#define ERROR_OUT_BUFERROR(fp) \ + (void)tio_close(fp); \ + fp=NULL; \ + *errnop=ERANGE; \ + *h_errnop=TRY_AGAIN; \ + return NSS_STATUS_TRYAGAIN; + +#undef ERROR_OUT_WRITEERROR +#define ERROR_OUT_WRITEERROR(fp) \ + ERROR_OUT_READERROR(fp) + +/* read a single network entry from the stream, ignoring entries + that are not AF_INET (IPv4), result is stored in result */ +static nss_status_t read_netent( + TFILE *fp,struct netent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + int32_t numaddr; + int readaf; + size_t bufptr=0; + nss_status_t retv=NSS_STATUS_NOTFOUND; + /* read the network entry */ + READ_BUF_STRING(fp,result->n_name); + READ_BUF_STRINGLIST(fp,result->n_aliases); + result->n_addrtype=AF_INET; + /* read number of addresses to follow */ + READ_TYPE(fp,numaddr,int32_t); + /* go through the address list and filter on af */ + while (--numaddr>=0) + { + /* read address family and size */ + READ_INT32(fp,readaf); + READ_INT32(fp,tmp2int32); /* address length */ + if ((readaf==AF_INET)&&(tmp2int32==4)) + { + /* read address and translate to host byte order */ + READ_TYPE(fp,tmpint32,int32_t); + result->n_net=ntohl((uint32_t)tmpint32); + /* signal that we've read a proper entry */ + retv=NSS_STATUS_SUCCESS; + /* don't return here to not upset the stream */ + } + else + { + /* skip unsupported address families */ + SKIP(fp,tmpint32); + } + } + return retv; +} + +/* write an address value */ +/* version 2.10 of glibc changed the address from network to host order + (changelog entry 2009-07-01) */ +#define WRITE_ADDRESS(fp,addr) \ + WRITE_INT32(fp,AF_INET); \ + WRITE_INT32(fp,4); \ + WRITE_INT32(fp,htonl(addr)); + +#ifdef NSS_FLAVOUR_GLIBC + +/* get a network entry by name */ +nss_status_t _nss_ldap_getnetbyname_r( + const char *name,struct netent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + NSS_BYNAME(NSLCD_ACTION_NETWORK_BYNAME, + name, + read_netent(fp,result,buffer,buflen,errnop,h_errnop)); +} + +/* Note: the af parameter is ignored and is assumed to be AF_INET */ +/* TODO: implement handling of af parameter */ +nss_status_t _nss_ldap_getnetbyaddr_r( + uint32_t addr,int UNUSED(af),struct netent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + NSS_BYGEN(NSLCD_ACTION_NETWORK_BYADDR, + WRITE_ADDRESS(fp,addr), + read_netent(fp,result,buffer,buflen,errnop,h_errnop)) +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *netentfp; + +/* start a request to read all networks */ +nss_status_t _nss_ldap_setnetent(int UNUSED(stayopen)) +{ + NSS_SETENT(netentfp); +} + +/* get a single network entry from the stream */ +nss_status_t _nss_ldap_getnetent_r( + struct netent *result, + char *buffer,size_t buflen,int *errnop,int *h_errnop) +{ + NSS_GETENT(netentfp,NSLCD_ACTION_NETWORK_ALL, + read_netent(netentfp,result,buffer,buflen,errnop,h_errnop)); +} + +/* close the stream opened by setnetent() above */ +nss_status_t _nss_ldap_endnetent(void) +{ + NSS_ENDENT(netentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_netentstring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct netent result; + nss_status_t retv; + char *buffer; + size_t buflen; + int i; + struct in_addr priv_in_addr; + /* read the netent */ + retv=read_netent(fp,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* allocate a temporary buffer */ + buflen=args->buf.buflen; + buffer=(char *)malloc(buflen); + /* build the formatted string */ + /* FIXME: implement proper buffer size checking */ + priv_in_addr.s_addr = result.n_net; + sprintf(buffer,"%s %s",result.n_name,inet_ntoa(priv_in_addr)); /* ipNetworkNumber */ + if (result.n_aliases) + for (i=0;result.n_aliases[i];i++) + { + strcat(buffer," "); + strcat(buffer,result.n_aliases[i]); + } + /* copy the result back to the result buffer and free the temporary one */ + strcpy(NSS_ARGS(args)->buf.buffer,buffer); + free(buffer); + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_netent(fp,(struct netent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)): \ + read_netentstring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_netent(fp,(struct netent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno,&(NSS_ARGS(args)->h_errno)); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +/* more of a dirty hack */ +#define h_errnop (&(NSS_ARGS(args)->h_errno)) + +static nss_status_t networks_getnetbyname(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_NETWORK_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT(fp)); +} + +static nss_status_t networks_getnetbyaddr(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYGEN(NSLCD_ACTION_NETWORK_BYADDR, + WRITE_ADDRESS(fp,NSS_ARGS(args)->key.netaddr.net), + READ_RESULT(fp)); +} + +static nss_status_t networks_setnetent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +static nss_status_t networks_getnetent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_NETWORK_ALL, + READ_RESULT(LDAP_BE(be)->fp)); +} + +static nss_status_t networks_endnetent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +static nss_backend_op_t networks_ops[]={ + nss_ldap_destructor, + networks_endnetent, + networks_setnetent, + networks_getnetent, + networks_getnetbyname, + networks_getnetbyaddr +}; + +nss_backend_t *_nss_ldap_networks_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(networks_ops,sizeof(networks_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/passwd.c b/nss/passwd.c new file mode 100644 index 0000000..9681eb5 --- /dev/null +++ b/nss/passwd.c @@ -0,0 +1,192 @@ +/* + passwd.c - NSS lookup functions for passwd database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* read a passwd entry from the stream */ +static nss_status_t read_passwd( + TFILE *fp,struct passwd *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32; + size_t bufptr=0; + READ_BUF_STRING(fp,result->pw_name); + READ_BUF_STRING(fp,result->pw_passwd); + READ_TYPE(fp,result->pw_uid,uid_t); + READ_TYPE(fp,result->pw_gid,gid_t); + READ_BUF_STRING(fp,result->pw_gecos); + READ_BUF_STRING(fp,result->pw_dir); + READ_BUF_STRING(fp,result->pw_shell); + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* get a single passwd entry by name */ +nss_status_t _nss_ldap_getpwnam_r( + const char *name,struct passwd *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYNAME(NSLCD_ACTION_PASSWD_BYNAME, + name, + read_passwd(fp,result,buffer,buflen,errnop)); +} + +/* get a single passwd entry by uid */ +nss_status_t _nss_ldap_getpwuid_r( + uid_t uid,struct passwd *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYTYPE(NSLCD_ACTION_PASSWD_BYUID, + uid,uid_t, + read_passwd(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *pwentfp; + +/* open a connection to read all passwd entries */ +nss_status_t _nss_ldap_setpwent(int UNUSED(stayopen)) +{ + NSS_SETENT(pwentfp); +} + +/* read password data from an opened stream */ +nss_status_t _nss_ldap_getpwent_r( + struct passwd *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(pwentfp,NSLCD_ACTION_PASSWD_ALL, + read_passwd(pwentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened with setpwent() above */ +nss_status_t _nss_ldap_endpwent(void) +{ + NSS_ENDENT(pwentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_passwdstring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct passwd result; + nss_status_t retv; + char *buffer; + size_t buflen; + /* read the passwd */ + retv=read_passwd(fp,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno); + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* allocate a temporary buffer */ + buflen=args->buf.buflen; + buffer=(char *)malloc(buflen); + /* build the formatted string */ + /* FIXME: implement proper buffer size checking */ + sprintf(buffer,"%s:%s:%d:%d:%s:%s:%s", + result.pw_name,result.pw_passwd,(int)result.pw_uid,(int)result.pw_gid,result.pw_gecos, + result.pw_dir,result.pw_shell); + /* copy the result back to the result buffer and free the temporary one */ + strcpy(NSS_ARGS(args)->buf.buffer,buffer); + free(buffer); + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_passwd(fp,(struct passwd *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno): \ + read_passwdstring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_passwd(fp,(struct passwd *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +static nss_status_t passwd_getpwnam(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_PASSWD_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT(fp)); +} + +static nss_status_t passwd_getpwuid(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYTYPE(NSLCD_ACTION_PASSWD_BYUID, + NSS_ARGS(args)->key.uid,uid_t, + READ_RESULT(fp)); +} + +/* open a connection to the nslcd and write the request */ +static nss_status_t passwd_setpwent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +/* read password data from an opened stream */ +static nss_status_t passwd_getpwent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_PASSWD_ALL, + READ_RESULT(LDAP_BE(be)->fp)); +} + +/* close the stream opened with setpwent() above */ +static nss_status_t passwd_endpwent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +static nss_backend_op_t passwd_ops[]={ + nss_ldap_destructor, + passwd_endpwent, + passwd_setpwent, + passwd_getpwent, + passwd_getpwnam, + passwd_getpwuid +}; + +nss_backend_t *_nss_ldap_passwd_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(passwd_ops,sizeof(passwd_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/protocols.c b/nss/protocols.c new file mode 100644 index 0000000..c641eaa --- /dev/null +++ b/nss/protocols.c @@ -0,0 +1,190 @@ +/* + protocols.c - NSS lookup functions for protocol database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* read a single protocol entry from the stream */ +static nss_status_t read_protoent( + TFILE *fp,struct protoent *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + size_t bufptr=0; + READ_BUF_STRING(fp,result->p_name); + READ_BUF_STRINGLIST(fp,result->p_aliases); + READ_INT32(fp,result->p_proto); + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* get a protocol entry by name */ +nss_status_t _nss_ldap_getprotobyname_r( + const char *name,struct protoent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYNAME(NSLCD_ACTION_PROTOCOL_BYNAME, + name, + read_protoent(fp,result,buffer,buflen,errnop)); +} + +/* get a protocol entry by number */ +nss_status_t _nss_ldap_getprotobynumber_r( + int number,struct protoent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYINT32(NSLCD_ACTION_PROTOCOL_BYNUMBER, + number, + read_protoent(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *protoentfp; + +/* start a request to read all protocol entries */ +nss_status_t _nss_ldap_setprotoent(int UNUSED(stayopen)) +{ + NSS_SETENT(protoentfp); +} + +/* get a single protocol entry */ +nss_status_t _nss_ldap_getprotoent_r( + struct protoent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(protoentfp,NSLCD_ACTION_PROTOCOL_ALL, + read_protoent(protoentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened by setprotoent() above */ +nss_status_t _nss_ldap_endprotoent(void) +{ + NSS_ENDENT(protoentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_protostring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct protoent result; + nss_status_t retv; + char *buffer; + size_t buflen; + int i; + /* read the protoent */ + retv=read_protoent(fp,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno); + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* allocate a temporary buffer */ + buflen=args->buf.buflen; + buffer=(char *)malloc(buflen); + /* build the formatted string */ + /* FIXME: implement proper buffer size checking */ + sprintf(buffer,"%s\t\t%d",result.p_name,result.p_proto); + if (result.p_aliases) + for (i=0; result.p_aliases[i]; i++) + { + strcat(buffer," "); + strcat(buffer,result.p_aliases[i]); + } + /* copy the result back to the result buffer and free the temporary one */ + strcpy(NSS_ARGS(args)->buf.buffer,buffer); + free(buffer); + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_protoent(fp,(struct protoent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno): \ + read_protostring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_protoent(fp,(struct protoent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +static nss_status_t protocols_getprotobyname(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_PROTOCOL_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT(fp)); +} + +static nss_status_t protocols_getprotobynumber(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYINT32(NSLCD_ACTION_PROTOCOL_BYNUMBER, + NSS_ARGS(args)->key.number, + READ_RESULT(fp)); +} + +static nss_status_t protocols_setprotoent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +static nss_status_t protocols_getprotoent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_PROTOCOL_ALL, + READ_RESULT(LDAP_BE(be)->fp)); +} + +static nss_status_t protocols_endprotoent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +static nss_backend_op_t protocols_ops[]={ + nss_ldap_destructor, + protocols_endprotoent, + protocols_setprotoent, + protocols_getprotoent, + protocols_getprotobyname, + protocols_getprotobynumber +}; + +nss_backend_t *_nss_ldap_protocols_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(protocols_ops,sizeof(protocols_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/prototypes.h b/nss/prototypes.h new file mode 100644 index 0000000..ad38417 --- /dev/null +++ b/nss/prototypes.h @@ -0,0 +1,156 @@ +/* + prototypes.h - all functions exported by the NSS library + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2008, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef NSS__PROTOTYPES_H +#define NSS__PROTOTYPES_H 1 + +#include "compat/nss_compat.h" + +/* flag to gloabally disable lookups (all _nss_ldap_*() functions will return + NSS_STATUS_UNAVAIL */ +extern int _nss_ldap_enablelookups; + +#ifdef NSS_FLAVOUR_FREEBSD + +/* for FreeBSD we want the GlibC prototypes and functions to be built + (we provide some wrappers in bsdnss.c) */ +#define NSS_FLAVOUR_GLIBC 1 + +/* FreeBSD specific register function */ +ns_mtab *nss_module_register(const char *source, unsigned int *mtabsize, + nss_module_unregister_fn *unreg); + +#endif /* NSS_FLAVOUR_FREEBSD */ + +#ifdef NSS_FLAVOUR_GLIBC + +/* + These are prototypes for functions exported from the ldap NSS module. + For more complete definitions of these functions check the GLIBC + documentation. + + Other services than those mentioned here are currently not implemented. + + These definitions partially came from examining the GLIBC source code + as no complete documentation of the NSS interface is available. + This however is a useful pointer: + http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html +*/ + +/* aliases - mail aliases */ +nss_status_t _nss_ldap_getaliasbyname_r(const char *name,struct aliasent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_setaliasent(void); +nss_status_t _nss_ldap_getaliasent_r(struct aliasent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endaliasent(void); + +/* ethers - ethernet numbers */ +nss_status_t _nss_ldap_gethostton_r(const char *name,struct etherent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_getntohost_r(const struct ether_addr *addr,struct etherent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_setetherent(int stayopen); +nss_status_t _nss_ldap_getetherent_r(struct etherent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endetherent(void); + +/* group - groups of users */ +nss_status_t _nss_ldap_getgrnam_r(const char *name,struct group *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_getgrgid_r(gid_t gid,struct group *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_initgroups_dyn(const char *user,gid_t skipgroup,long int *start,long int *size,gid_t **groupsp,long int limit,int *errnop); +nss_status_t _nss_ldap_setgrent(int stayopen); +nss_status_t _nss_ldap_getgrent_r(struct group *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endgrent(void); + +/* hosts - host names and numbers */ +nss_status_t _nss_ldap_gethostbyname_r(const char *name,struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +nss_status_t _nss_ldap_gethostbyname2_r(const char *name,int af,struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +nss_status_t _nss_ldap_gethostbyaddr_r(const void *addr,socklen_t len,int af,struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +nss_status_t _nss_ldap_sethostent(int stayopen); +nss_status_t _nss_ldap_gethostent_r(struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +nss_status_t _nss_ldap_endhostent(void); + +/* netgroup - list of host and users */ +nss_status_t _nss_ldap_setnetgrent(const char *group,struct __netgrent *result); +nss_status_t _nss_ldap_getnetgrent_r(struct __netgrent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endnetgrent(struct __netgrent *result); + +/* networks - network names and numbers */ +nss_status_t _nss_ldap_getnetbyname_r(const char *name,struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +nss_status_t _nss_ldap_getnetbyaddr_r(uint32_t addr,int af,struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +nss_status_t _nss_ldap_setnetent(int stayopen); +nss_status_t _nss_ldap_getnetent_r(struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +nss_status_t _nss_ldap_endnetent(void); + +/* passwd - user database and passwords */ +nss_status_t _nss_ldap_getpwnam_r(const char *name,struct passwd *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_getpwuid_r(uid_t uid,struct passwd *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_setpwent(int stayopen); +nss_status_t _nss_ldap_getpwent_r(struct passwd *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endpwent(void); + +/* protocols - network protocols */ +nss_status_t _nss_ldap_getprotobyname_r(const char *name,struct protoent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_getprotobynumber_r(int number,struct protoent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_setprotoent(int stayopen); +nss_status_t _nss_ldap_getprotoent_r(struct protoent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endprotoent(void); + +/* rpc - remote procedure call names and numbers */ +nss_status_t _nss_ldap_getrpcbyname_r(const char *name,struct rpcent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_getrpcbynumber_r(int number,struct rpcent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_setrpcent(int stayopen); +nss_status_t _nss_ldap_getrpcent_r(struct rpcent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endrpcent(void); + +/* services - network services */ +nss_status_t _nss_ldap_getservbyname_r(const char *name,const char *protocol,struct servent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_getservbyport_r(int port,const char *protocol,struct servent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_setservent(int stayopen); +nss_status_t _nss_ldap_getservent_r(struct servent *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endservent(void); + +/* shadow - extended user information */ +nss_status_t _nss_ldap_getspnam_r(const char *name,struct spwd *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_setspent(int stayopen); +nss_status_t _nss_ldap_getspent_r(struct spwd *result,char *buffer,size_t buflen,int *errnop); +nss_status_t _nss_ldap_endspent(void); + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +/* helper marcos to do casts */ +#define NSS_ARGS(args) ((nss_XbyY_args_t *)args) +#define LDAP_BE(be) ((struct nss_ldap_backend*)(be)) + +/* these are the constructors we provide */ +nss_backend_t *_nss_ldap_ethers_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_group_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_hosts_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_netgroup_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_networks_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_passwd_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_protocols_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_rpc_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_services_constr(const char *db_name,const char *src_name,const char *cfg_args); +nss_backend_t *_nss_ldap_shadow_constr(const char *db_name,const char *src_name,const char *cfg_args); + +#endif /* NSS_FLAVOUR_SOLARIS */ + +#endif /* not NSS__PROTOTYPES_H */ diff --git a/nss/rpc.c b/nss/rpc.c new file mode 100644 index 0000000..cc1b12f --- /dev/null +++ b/nss/rpc.c @@ -0,0 +1,190 @@ +/* + rpc.c - NSS lookup functions for rpc database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* read a sinlge rpc entry from the stream */ +static nss_status_t read_rpcent( + TFILE *fp,struct rpcent *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + size_t bufptr=0; + READ_BUF_STRING(fp,result->r_name); + READ_BUF_STRINGLIST(fp,result->r_aliases); + READ_INT32(fp,result->r_number); + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* get a rpc entry by name */ +nss_status_t _nss_ldap_getrpcbyname_r( + const char *name,struct rpcent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYNAME(NSLCD_ACTION_RPC_BYNAME, + name, + read_rpcent(fp,result,buffer,buflen,errnop)); +} + +/* get a rpc entry by number */ +nss_status_t _nss_ldap_getrpcbynumber_r( + int number,struct rpcent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYINT32(NSLCD_ACTION_RPC_BYNUMBER, + number, + read_rpcent(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *rpcentfp; + +/* request a stream to list all rpc entries */ +nss_status_t _nss_ldap_setrpcent(int UNUSED(stayopen)) +{ + NSS_SETENT(rpcentfp); +} + +/* get an rpc entry from the list */ +nss_status_t _nss_ldap_getrpcent_r( + struct rpcent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(rpcentfp,NSLCD_ACTION_RPC_ALL, + read_rpcent(rpcentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened by setrpcent() above */ +nss_status_t _nss_ldap_endrpcent(void) +{ + NSS_ENDENT(rpcentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_rpcstring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct rpcent result; + nss_status_t retv; + char *buffer; + size_t buflen; + int i; + /* read the rpcent */ + retv=read_rpcent(fp,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno); + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* allocate a temporary buffer */ + buflen=args->buf.buflen; + buffer=(char *)malloc(buflen); + /* build the formatted string */ + /* FIXME: implement proper buffer size checking */ + sprintf(buffer,"%s %d",result.r_name,result.r_number); + if (result.r_aliases) + for (i=0; result.r_aliases[i]; i++) + { + strcat(buffer," "); + strcat(buffer,result.r_aliases[i]); + } + /* copy the result back to the result buffer and free the temporary one */ + strcpy(NSS_ARGS(args)->buf.buffer,buffer); + free(buffer); + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_rpcent(fp,(struct rpcent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno): \ + read_rpcstring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_rpcent(fp,(struct rpcent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +static nss_status_t rpc_getrpcbyname(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_RPC_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT(fp)); +} + +static nss_status_t rpc_getrpcbynumber(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYINT32(NSLCD_ACTION_RPC_BYNUMBER, + NSS_ARGS(args)->key.number, + READ_RESULT(fp)); +} + +static nss_status_t rpc_setrpcent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +static nss_status_t rpc_getrpcent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_RPC_ALL, + READ_RESULT(LDAP_BE(be)->fp)); +} + +static nss_status_t rpc_endrpcent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +static nss_backend_op_t rpc_ops[]={ + nss_ldap_destructor, + rpc_endrpcent, + rpc_setrpcent, + rpc_getrpcent, + rpc_getrpcbyname, + rpc_getrpcbynumber +}; + +nss_backend_t *_nss_ldap_rpc_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(rpc_ops,sizeof(rpc_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/services.c b/nss/services.c new file mode 100644 index 0000000..4d03d5c --- /dev/null +++ b/nss/services.c @@ -0,0 +1,196 @@ +/* + service.c - NSS lookup functions for services database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* read a single services result entry from the stream */ +static nss_status_t read_servent( + TFILE *fp,struct servent *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + size_t bufptr=0; + READ_BUF_STRING(fp,result->s_name); + READ_BUF_STRINGLIST(fp,result->s_aliases); + /* store port number in network byte order */ + READ_TYPE(fp,tmpint32,int32_t); + result->s_port=htons((uint16_t)tmpint32); + READ_BUF_STRING(fp,result->s_proto); + /* we're done */ + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* get a service entry by name and protocol */ +nss_status_t _nss_ldap_getservbyname_r( + const char *name,const char *protocol,struct servent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYGEN(NSLCD_ACTION_SERVICE_BYNAME, + WRITE_STRING(fp,name);WRITE_STRING(fp,protocol), + read_servent(fp,result,buffer,buflen,errnop)); +} + +/* get a service entry by port and protocol */ +nss_status_t _nss_ldap_getservbyport_r( + int port,const char *protocol,struct servent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYGEN(NSLCD_ACTION_SERVICE_BYNUMBER, + WRITE_INT32(fp,ntohs(port));WRITE_STRING(fp,protocol), + read_servent(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *serventfp; + +/* open request to get all services */ +nss_status_t _nss_ldap_setservent(int UNUSED(stayopen)) +{ + NSS_SETENT(serventfp); +} + +/* read a single returned service definition */ +nss_status_t _nss_ldap_getservent_r( + struct servent *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(serventfp,NSLCD_ACTION_SERVICE_ALL, + read_servent(serventfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened by setservent() above */ +nss_status_t _nss_ldap_endservent(void) +{ + NSS_ENDENT(serventfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_servstring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct servent result; + nss_status_t retv; + char *buffer; + size_t buflen; + int i; + /* read the servent */ + retv=read_servent(fp,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno); + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* allocate a temporary buffer */ + buflen=args->buf.buflen; + buffer=(char *)malloc(buflen); + /* build the formatted string */ + /* FIXME: implement proper buffer size checking */ + sprintf(buffer,"%s %d/%s",result.s_name,result.s_port,result.s_proto); + if (result.s_aliases) + for (i=0;result.s_aliases[i];i++) + { + strcat(buffer," "); + strcat(buffer,result.s_aliases[i]); + } + /* copy the result back to the result buffer and free the temporary one */ + strcpy(NSS_ARGS(args)->buf.buffer,buffer); + free(buffer); + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_servent(fp,(struct servent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno): \ + read_servstring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_servent(fp,(struct servent *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +static nss_status_t services_getservbyname(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYGEN(NSLCD_ACTION_SERVICE_BYNAME, + WRITE_STRING(fp,NSS_ARGS(args)->key.serv.serv.name); + WRITE_STRING(fp,NSS_ARGS(args)->key.serv.proto), + READ_RESULT(fp)); +} + +static nss_status_t services_getservbyport(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYGEN(NSLCD_ACTION_SERVICE_BYNUMBER, + WRITE_INT32(fp,ntohs(NSS_ARGS(args)->key.serv.serv.port)); + WRITE_STRING(fp,NSS_ARGS(args)->key.serv.proto), + READ_RESULT(fp)); +} + +static nss_status_t services_setservent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +static nss_status_t services_getservent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_SERVICE_ALL, + READ_RESULT(LDAP_BE(be)->fp)); +} + +static nss_status_t services_endservent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +static nss_backend_op_t services_ops[]={ + nss_ldap_destructor, + services_endservent, + services_setservent, + services_getservent, + services_getservbyname, + services_getservbyport +}; + +nss_backend_t *_nss_ldap_services_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(services_ops,sizeof(services_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/shadow.c b/nss/shadow.c new file mode 100644 index 0000000..d22af52 --- /dev/null +++ b/nss/shadow.c @@ -0,0 +1,207 @@ +/* + shadow.c - NSS lookup functions for shadow database + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2008, 2010 Arthur de Jong + Copyright (C) 2010 Symas Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +/* read a single shadow entry from the stream */ +static nss_status_t read_spwd( + TFILE *fp,struct spwd *result, + char *buffer,size_t buflen,int *errnop) +{ + int32_t tmpint32; + size_t bufptr=0; + READ_BUF_STRING(fp,result->sp_namp); + READ_BUF_STRING(fp,result->sp_pwdp); + READ_INT32(fp,result->sp_lstchg); + READ_INT32(fp,result->sp_min); + READ_INT32(fp,result->sp_max); + READ_INT32(fp,result->sp_warn); + READ_INT32(fp,result->sp_inact); + READ_INT32(fp,result->sp_expire); + READ_INT32(fp,result->sp_flag); + return NSS_STATUS_SUCCESS; +} + +#ifdef NSS_FLAVOUR_GLIBC + +/* get a shadow entry by name */ +nss_status_t _nss_ldap_getspnam_r( + const char *name,struct spwd *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_BYNAME(NSLCD_ACTION_SHADOW_BYNAME, + name, + read_spwd(fp,result,buffer,buflen,errnop)); +} + +/* thread-local file pointer to an ongoing request */ +static __thread TFILE *spentfp; + +/* start listing all shadow users */ +nss_status_t _nss_ldap_setspent(int UNUSED(stayopen)) +{ + NSS_SETENT(spentfp); +} + +/* return a single shadow entry read from the stream */ +nss_status_t _nss_ldap_getspent_r( + struct spwd *result, + char *buffer,size_t buflen,int *errnop) +{ + NSS_GETENT(spentfp,NSLCD_ACTION_SHADOW_ALL, + read_spwd(spentfp,result,buffer,buflen,errnop)); +} + +/* close the stream opened by setspent() above */ +nss_status_t _nss_ldap_endspent(void) +{ + NSS_ENDENT(spentfp); +} + +#endif /* NSS_FLAVOUR_GLIBC */ + +#ifdef NSS_FLAVOUR_SOLARIS + +#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN + +static nss_status_t read_spwdstring(TFILE *fp,nss_XbyY_args_t *args) +{ + struct spwd result; + nss_status_t retv; + char *buffer; + char field_buf[128]; + size_t buflen; + /* read the spwd */ + retv=read_spwd(fp,&result,NSS_ARGS(args)->buf.buffer,args->buf.buflen,&errno); + if (retv!=NSS_STATUS_SUCCESS) + return retv; + /* allocate a temporary buffer */ + buflen=args->buf.buflen; + buffer=(char *)malloc(buflen); + /* build the formatted string */ + /* FIXME: implement proper buffer size checking */ + sprintf(buffer,"%s:%s:",result.sp_namp,result.sp_pwdp); + if (result.sp_lstchg >= 0) + sprintf(field_buf,"%d:",result.sp_lstchg); + else + sprintf(field_buf,":"); + strcat(buffer,field_buf); + if (result.sp_min >= 0) + sprintf(field_buf,"%d:",result.sp_min); + else + sprintf(field_buf,":"); + strcat(buffer,field_buf); + if (result.sp_max >= 0) + sprintf(field_buf,"%d:",result.sp_max); + else + sprintf(field_buf,":"); + strcat(buffer,field_buf); + if (result.sp_warn >= 0) + sprintf(field_buf,"%d:",result.sp_warn); + else + sprintf(field_buf,":"); + strcat(buffer,field_buf); + if (result.sp_inact >= 0) + sprintf(field_buf,"%d:",result.sp_inact); + else + sprintf(field_buf,":"); + strcat(buffer,field_buf); + if (result.sp_expire >= 0) + sprintf(field_buf,"%d:",result.sp_expire); + else + sprintf(field_buf,":"); + strcat(buffer,field_buf); + if (result.sp_flag >= 0) + sprintf(field_buf,"%x",result.sp_flag); + else + sprintf(field_buf,":"); + strcat(buffer,field_buf); + /* copy the result back to the result buffer and free the temporary one */ + strcpy(NSS_ARGS(args)->buf.buffer,buffer); + free(buffer); + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.buffer; + NSS_ARGS(args)->returnlen=strlen(NSS_ARGS(args)->buf.buffer); + return NSS_STATUS_SUCCESS; +} + +#define READ_RESULT(fp) \ + NSS_ARGS(args)->buf.result? \ + read_spwd(fp,(struct spwd *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno): \ + read_spwdstring(fp,args); \ + if ((NSS_ARGS(args)->buf.result)&&(retv==NSS_STATUS_SUCCESS)) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#else /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +#define READ_RESULT(fp) \ + read_spwd(fp,(struct spwd *)NSS_ARGS(args)->buf.result,NSS_ARGS(args)->buf.buffer,NSS_ARGS(args)->buf.buflen,&errno); \ + if (retv==NSS_STATUS_SUCCESS) \ + NSS_ARGS(args)->returnval=NSS_ARGS(args)->buf.result; + +#endif /* not HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */ + +static nss_status_t shadow_getspnam(nss_backend_t UNUSED(*be),void *args) +{ + NSS_BYNAME(NSLCD_ACTION_SHADOW_BYNAME, + NSS_ARGS(args)->key.name, + READ_RESULT(fp)); +} + +static nss_status_t shadow_setspent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_SETENT(LDAP_BE(be)->fp); +} + +static nss_status_t shadow_getspent(nss_backend_t *be,void *args) +{ + NSS_GETENT(LDAP_BE(be)->fp,NSLCD_ACTION_SHADOW_ALL, + READ_RESULT(LDAP_BE(be)->fp)); +} + +static nss_status_t shadow_endspent(nss_backend_t *be,void UNUSED(*args)) +{ + NSS_ENDENT(LDAP_BE(be)->fp); +} + +static nss_backend_op_t shadow_ops[]={ + nss_ldap_destructor, + shadow_endspent, + shadow_setspent, + shadow_getspent, + shadow_getspnam +}; + +nss_backend_t *_nss_ldap_shadow_constr(const char UNUSED(*db_name), + const char UNUSED(*src_name),const char UNUSED(*cfg_args)) +{ + return nss_ldap_constructor(shadow_ops,sizeof(shadow_ops)); +} + +#endif /* NSS_FLAVOUR_SOLARIS */ diff --git a/nss/solnss.c b/nss/solnss.c new file mode 100644 index 0000000..5206e30 --- /dev/null +++ b/nss/solnss.c @@ -0,0 +1,49 @@ +/* + solnss.c - Solaris specific NSS interface functions + + Copyright (C) 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include + +#include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" + +nss_backend_t *nss_ldap_constructor(nss_backend_op_t *ops,size_t sizeofops) +{ + struct nss_ldap_backend *ldapbe; + ldapbe=(struct nss_ldap_backend *)malloc(sizeof(struct nss_ldap_backend)); + if (ldapbe==NULL) + return NULL; + ldapbe->ops=ops; + ldapbe->n_ops=sizeofops/sizeof(nss_backend_op_t); + ldapbe->fp=NULL; + return (nss_backend_t *)ldapbe; +} + +nss_status_t nss_ldap_destructor(nss_backend_t *be,void UNUSED(*args)) +{ + struct nss_ldap_backend *ldapbe=(struct nss_ldap_backend *)be; + if (ldapbe->fp!=NULL) + (void)tio_close(ldapbe->fp); + free(ldapbe); + return NSS_STATUS_SUCCESS; +} diff --git a/pam/Makefile.am b/pam/Makefile.am new file mode 100644 index 0000000..ce2fabf --- /dev/null +++ b/pam/Makefile.am @@ -0,0 +1,43 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2009, 2010, 2011 Arthur de Jong +# Copyright (C) 2010 Symas Corporation +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_PROGRAMS = pam_ldap.so + +AM_CPPFLAGS=-I$(top_srcdir) +AM_CFLAGS = -fPIC + +pam_ldap_so_SOURCES = ../nslcd.h ../common/nslcd-prot.h \ + ../compat/attrs.h pam.c common.h +pam_ldap_so_LDADD = ../common/libtio.a ../common/libprot.a \ + ../compat/libcompat.a \ + -lpam + +EXTRA_DIST = pam_ldap.map + +install-exec-local: install-pam_ldap_so +uninstall-local: uninstall-pam_ldap_so + +install-pam_ldap_so: pam_ldap.so + -rm -f $(DESTDIR)$(PAM_SECLIB_DIR)/$(PAM_LDAP_SONAME) + $(mkinstalldirs) $(DESTDIR)$(PAM_SECLIB_DIR) + $(INSTALL_PROGRAM) pam_ldap.so $(DESTDIR)$(PAM_SECLIB_DIR)/$(PAM_LDAP_SONAME) + +uninstall-pam_ldap_so: + -rm -f $(DESTDIR)$(PAM_SECLIB_DIR)/$(PAM_LDAP_SONAME) diff --git a/pam/common.h b/pam/common.h new file mode 100644 index 0000000..73b1df5 --- /dev/null +++ b/pam/common.h @@ -0,0 +1,100 @@ +/* + common.h - common functions for PAM lookups + + Copyright (C) 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef PAM__COMMON_H +#define PAM__COMMON_H 1 + +#include + +#include "nslcd.h" +#include "common/nslcd-prot.h" +#include "compat/attrs.h" + +/* These are macros for handling read and write problems, they are + PAM specific due to the return code so are defined here. They + genrally close the open file, set an error code and return with + an error status. */ + +/* Macro is called to handle errors in opening a client connection. */ +#define ERROR_OUT_OPENERROR \ + pam_syslog(pamh,LOG_ERR,"error opening connection to nslcd: %s",strerror(errno)); \ + return PAM_AUTHINFO_UNAVAIL; + +/* Macro is called to handle errors on read operations. */ +#define ERROR_OUT_READERROR(fp) \ + pam_syslog(pamh,LOG_ERR,"error reading from nslcd: %s",strerror(errno)); \ + (void)tio_close(fp); \ + return PAM_AUTHINFO_UNAVAIL; + +/* Macro is called to handle problems with too small a buffer. */ +#define ERROR_OUT_BUFERROR(fp) \ + pam_syslog(pamh,LOG_CRIT,"buffer %d bytes too small",tmpint32); \ + (void)tio_close(fp); \ + return PAM_SYSTEM_ERR; + +/* This macro is called if there was a problem with a write + operation. */ +#define ERROR_OUT_WRITEERROR(fp) \ + pam_syslog(pamh,LOG_ERR,"error writing to nslcd: %s",strerror(errno)); \ + (void)tio_close(fp); \ + return PAM_AUTHINFO_UNAVAIL; + +/* This macro is called if the read status code is not + NSLCD_RESULT_BEGIN. */ +#define ERROR_OUT_NOSUCCESS(fp) \ + (void)tio_close(fp); \ + if (cfg->debug) \ + pam_syslog(pamh,LOG_DEBUG,"user not handled by nslcd"); \ + return PAM_USER_UNKNOWN; + +/* This is a generic PAM request generation macro. The action + parameter is the NSLCD_ACTION_.. action, the writefn is the + operation for writing the parameter and readfn is the function + name for reading a single result entry. The function is assumed + to have result, buffer, buflen and errnop parameters that define + the result structure, the user buffer with length and the + errno to return. This macro should be called through some of + the customized ones below. */ +#define PAM_REQUEST(action,debuglog,writefn,readfn) \ + TFILE *fp; \ + int32_t tmpint32; \ + char *buffer=ctx->buf; \ + size_t buflen=sizeof(ctx->buf); \ + size_t bufptr=0; \ + if (cfg->debug) \ + debuglog; \ + /* open socket and write request */ \ + NSLCD_REQUEST(fp,action,writefn); \ + /* read response code */ \ + READ_RESPONSE_CODE(fp); \ + /* read the response */ \ + readfn; \ + /* close socket and we're done */ \ + (void)tio_close(fp); \ + return PAM_SUCCESS; + +/* helper macro to read PAM status code (auto-translated from NSLCD PAM + status code */ +#define READ_PAM_CODE(fp,i) \ + READ_TYPE(fp,tmpint32,int32_t); \ + i=nslcd2pam_rc(pamh,tmpint32); + +#endif /* not PAM__COMMON_H */ diff --git a/pam/pam.c b/pam/pam.c new file mode 100644 index 0000000..1cbc73f --- /dev/null +++ b/pam/pam.c @@ -0,0 +1,661 @@ +/* + pam.c - pam module functions + + Copyright (C) 2009 Howard Chu + Copyright (C) 2009, 2010, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +/* these are defined (before including pam_modules.h) for staticly linking */ +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD + +#include "common.h" +#include "compat/attrs.h" +#include "compat/pam_compat.h" + +#ifdef HAVE_SECURITY_PAM_APPL_H +#include +#endif /* HAVE_SECURITY_PAM_APPL_H */ +#ifndef HAVE_PAM_PAM_MODULES_H +#include +#ifdef HAVE_SECURITY_PAM_EXT_H +#include +#endif /* HAVE_SECURITY_PAM_EXT_H */ +#else /* not HAVE_PAM_PAM_MODULES_H */ +#include +#endif /* not HAVE_PAM_PAM_MODULES_H */ + +/* the name we store our context under */ +#define PLD_CTX "PAM_LDAPD_CTX" + + +/* this struct represents the context that the PAM module keeps + between calls */ +struct pld_ctx { + char *user; + char *dn; + char *tmpluser; + char *authzmsg; + char *oldpassword; + int authok; + int authz; + int sessid; + char buf[1024]; +}; + +/* clear the context to all empty values */ +static void ctx_clear(struct pld_ctx *ctx) +{ + if (ctx->user) + { + free(ctx->user); + ctx->user=NULL; + } + if (ctx->oldpassword) + { + memset(ctx->oldpassword,0,strlen(ctx->oldpassword)); + free(ctx->oldpassword); + ctx->oldpassword=NULL; + } + ctx->dn=NULL; + ctx->tmpluser=NULL; + ctx->authzmsg=NULL; + ctx->authok=0; + ctx->authz=0; +} + +/* free the context (this is installed as handler into PAM) */ +static void ctx_free(pam_handle_t UNUSED(*pamh),void *data,int UNUSED(err)) +{ + struct pld_ctx *ctx=data; + ctx_clear(ctx); + free(ctx); +} + +/* try to get the module's context, returns a PAM status code */ +static int ctx_get(pam_handle_t *pamh,const char *username,struct pld_ctx **pctx) +{ + struct pld_ctx *ctx=NULL; + int rc; + /* try to get the context from PAM */ + rc=pam_get_data(pamh,PLD_CTX,(const void **)&ctx); + if ((rc==PAM_SUCCESS)&&(ctx!=NULL)) + { + /* if the user is different clear the context */ + if ((ctx->user!=NULL)&&(strcmp(ctx->user,username)!=0)) + ctx_clear(ctx); + } + else + { + /* allocate a new context */ + ctx=calloc(1,sizeof(struct pld_ctx)); + if (ctx==NULL) + { + pam_syslog(pamh,LOG_CRIT,"calloc(): failed to allocate memory: %s",strerror(errno)); + return PAM_BUF_ERR; + } + ctx_clear(ctx); + /* store the new context with the handler to free it */ + rc=pam_set_data(pamh,PLD_CTX,ctx,ctx_free); + if (rc!=PAM_SUCCESS) + { + ctx_free(pamh,ctx,0); + pam_syslog(pamh,LOG_ERR,"failed to store context: %s",pam_strerror(pamh,rc)); + return rc; + } + } + /* return the context */ + *pctx=ctx; + return PAM_SUCCESS; +} + +/* our PAM module configuration */ +struct pld_cfg { + int nullok; + int no_warn; + int ignore_unknown_user; + int ignore_authinfo_unavail; + int debug; + uid_t minimum_uid; +}; + +static void cfg_init(pam_handle_t *pamh,int flags,int argc,const char **argv, + struct pld_cfg *cfg) +{ + int i; + /* initialise config with defaults */ + cfg->nullok=0; + cfg->no_warn=0; + cfg->ignore_unknown_user=0; + cfg->ignore_authinfo_unavail=0; + cfg->debug=0; + cfg->minimum_uid=0; + /* go over arguments */ + for (i=0;inullok=1; + else if (strcmp(argv[i],"use_authtok")==0) + /* ignore, this option is used by pam_get_authtok() internally */; + else if (strcmp(argv[i],"no_warn")==0) + cfg->no_warn=1; + else if (strcmp(argv[i],"ignore_unknown_user")==0) + cfg->ignore_unknown_user=1; + else if (strcmp(argv[i],"ignore_authinfo_unavail")==0) + cfg->ignore_authinfo_unavail=1; + else if (strcmp(argv[i],"debug")==0) + cfg->debug=1; + else if (strncmp(argv[i],"minimum_uid=",12) == 0) + cfg->minimum_uid=(uid_t)atoi(argv[i]+12); + else + pam_syslog(pamh,LOG_ERR,"unknown option: %s",argv[i]); + } + /* check flags */ + if (flags&PAM_SILENT) + cfg->no_warn=1; +} + +static int init(pam_handle_t *pamh,struct pld_cfg *cfg,struct pld_ctx **ctx, + const char **username,const char **service) +{ + int rc; + struct passwd *pwent; + /* get user name */ + rc=pam_get_user(pamh,username,NULL); + if (rc!=PAM_SUCCESS) + { + pam_syslog(pamh,LOG_ERR,"failed to get user name: %s",pam_strerror(pamh,rc)); + return rc; + } + if ((*username==NULL)||((*username)[0]=='\0')) + { + pam_syslog(pamh,LOG_ERR,"got empty user name"); + return PAM_USER_UNKNOWN; + } + /* check uid */ + if (cfg->minimum_uid>0) + { + pwent=pam_modutil_getpwnam(args->pamh,*username); + if ((pwent!=NULL)&&(pwent->pw_uidminimum_uid)) + { + if (cfg->debug) + pam_syslog(pamh,LOG_DEBUG,"uid below minimum_uid; user=%s uid=%ld",*username,(long)pwent->pw_uid); + return cfg->ignore_unknown_user?PAM_IGNORE:PAM_USER_UNKNOWN; + } + } + /* get our context */ + rc=ctx_get(pamh,*username,ctx); + if (rc!=PAM_SUCCESS) + return rc; + /* get service name */ + rc=pam_get_item(pamh,PAM_SERVICE,(const void **)service); + if (rc!=PAM_SUCCESS) + { + pam_syslog(pamh,LOG_ERR,"failed to get service name: %s",pam_strerror(pamh,rc)); + return rc; + } + return PAM_SUCCESS; +} + +/* map a NSLCD PAM status code to a PAM status code */ +static int nslcd2pam_rc(pam_handle_t *pamh,int rc) +{ +#define map(i) case NSLCD_##i: return i; + switch(rc) { + map(PAM_SUCCESS); + map(PAM_PERM_DENIED); + map(PAM_AUTH_ERR); + map(PAM_CRED_INSUFFICIENT); + map(PAM_AUTHINFO_UNAVAIL); + map(PAM_USER_UNKNOWN); + map(PAM_MAXTRIES); + map(PAM_NEW_AUTHTOK_REQD); + map(PAM_ACCT_EXPIRED); + map(PAM_SESSION_ERR); + map(PAM_AUTHTOK_ERR); + map(PAM_AUTHTOK_DISABLE_AGING); + map(PAM_IGNORE); + map(PAM_ABORT); + map(PAM_AUTHTOK_EXPIRED); + default: + pam_syslog(pamh,LOG_ERR,"unknown NSLCD_PAM_* code returned: %d",rc); + return PAM_ABORT; + } +} + +/* check whether the specified user is handled by nslcd */ +static int nslcd_request_exists(pam_handle_t *pamh,struct pld_ctx *ctx,struct pld_cfg *cfg, + const char *username) +{ + uid_t dummy_uid; + gid_t dummy_gid; + PAM_REQUEST(NSLCD_ACTION_PASSWD_BYNAME, + /* log debug message */ + pam_syslog(pamh,LOG_DEBUG,"nslcd account check; user=%s",username), + /* write the request parameters */ + WRITE_STRING(fp,username), + /* read the result entry */ + SKIP_STRING(fp); /* user name */ + SKIP_STRING(fp); /* passwd entry */ + READ_TYPE(fp,dummy_uid,uid_t); + READ_TYPE(fp,dummy_gid,gid_t); + SKIP_STRING(fp); /* gecos */ + SKIP_STRING(fp); /* home dir */ + SKIP_STRING(fp); /* shell */ + ) +} + +/* perform an authentication call over nslcd */ +static int nslcd_request_authc(pam_handle_t *pamh,struct pld_ctx *ctx,struct pld_cfg *cfg, + const char *username,const char *service, + const char *passwd) +{ + PAM_REQUEST(NSLCD_ACTION_PAM_AUTHC, + /* log debug message */ + pam_syslog(pamh,LOG_DEBUG,"nslcd authentication; user=%s",username), + /* write the request parameters */ + WRITE_STRING(fp,username); + WRITE_STRING(fp,ctx->dn); + WRITE_STRING(fp,service); + WRITE_STRING(fp,passwd), + /* read the result entry */ + READ_BUF_STRING(fp,ctx->tmpluser); + READ_BUF_STRING(fp,ctx->dn); + READ_PAM_CODE(fp,ctx->authok) + READ_PAM_CODE(fp,ctx->authz) + READ_BUF_STRING(fp,ctx->authzmsg);) +} + +/* perform an authorisation call over nslcd */ +static int nslcd_request_authz(pam_handle_t *pamh,struct pld_ctx *ctx,struct pld_cfg *cfg, + const char *username,const char *service, + const char *ruser,const char *rhost, + const char *tty) +{ + PAM_REQUEST(NSLCD_ACTION_PAM_AUTHZ, + /* log debug message */ + pam_syslog(pamh,LOG_DEBUG,"nslcd authorisation; user=%s",username), + /* write the request parameters */ + WRITE_STRING(fp,username); + WRITE_STRING(fp,ctx->dn); + WRITE_STRING(fp,service); + WRITE_STRING(fp,ruser); + WRITE_STRING(fp,rhost); + WRITE_STRING(fp,tty), + /* read the result entry */ + READ_BUF_STRING(fp,ctx->tmpluser); + READ_BUF_STRING(fp,ctx->dn); + READ_PAM_CODE(fp,ctx->authz); + READ_BUF_STRING(fp,ctx->authzmsg);) +} + +/* do a session nslcd request (open or close) */ +static int nslcd_request_sess(pam_handle_t *pamh,struct pld_ctx *ctx,struct pld_cfg *cfg,int action, + const char *username,const char *service, + const char *tty,const char *rhost, + const char *ruser) +{ + PAM_REQUEST(action, + /* log debug message */ + pam_syslog(pamh,LOG_DEBUG,"nslcd session %s; user=%s", + (action==NSLCD_ACTION_PAM_SESS_O)?"open":"close",username), + /* write the request parameters */ + WRITE_STRING(fp,username); + WRITE_STRING(fp,ctx->dn); + WRITE_STRING(fp,service); + WRITE_STRING(fp,tty); + WRITE_STRING(fp,rhost); + WRITE_STRING(fp,ruser); + WRITE_INT32(fp,ctx->sessid), + /* read the result entry */ + READ_INT32(fp,ctx->sessid)) +} + +/* do a password modification nslcd call */ +static int nslcd_request_pwmod(pam_handle_t *pamh,struct pld_ctx *ctx,struct pld_cfg *cfg, + const char *username,const char *service, + const char *oldpasswd,const char *newpasswd) +{ + PAM_REQUEST(NSLCD_ACTION_PAM_PWMOD, + /* log debug message */ + pam_syslog(pamh,LOG_DEBUG,"nslcd password modify; user=%s",username), + /* write the request parameters */ + WRITE_STRING(fp,username); + WRITE_STRING(fp,ctx->dn); + WRITE_STRING(fp,service); + WRITE_STRING(fp,oldpasswd); + WRITE_STRING(fp,newpasswd), + /* read the result entry */ + READ_BUF_STRING(fp,ctx->tmpluser); + READ_BUF_STRING(fp,ctx->dn); + READ_PAM_CODE(fp,ctx->authz); + READ_BUF_STRING(fp,ctx->authzmsg);) +} + +/* remap the return code based on the configuration */ +static int remap_pam_rc(int rc,struct pld_cfg *cfg) +{ + if ((rc==PAM_AUTHINFO_UNAVAIL)&&cfg->ignore_authinfo_unavail) + return PAM_IGNORE; + if ((rc==PAM_USER_UNKNOWN)&&cfg->ignore_unknown_user) + return PAM_IGNORE; + return rc; +} + +/* PAM authentication check */ +int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) +{ + int rc; + struct pld_cfg cfg; + struct pld_ctx *ctx; + const char *username,*service; + char *passwd=NULL; + /* set up configuration */ + cfg_init(pamh,flags,argc,argv,&cfg); + rc=init(pamh,&cfg,&ctx,&username,&service); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* get the password */ + rc=pam_get_authtok(pamh,PAM_AUTHTOK,(const char **)&passwd,NULL); + if (rc!=PAM_SUCCESS) + { + pam_syslog(pamh,LOG_ERR,"failed to get password: %s",pam_strerror(pamh,rc)); + return rc; + } + /* check password */ + if (!cfg.nullok&&((passwd==NULL)||(passwd[0]=='\0'))) + { + if (cfg.debug) + pam_syslog(pamh,LOG_DEBUG,"user has empty password, access denied"); + return PAM_AUTH_ERR; + } + /* do the nslcd request */ + rc=nslcd_request_authc(pamh,ctx,&cfg,username,service,passwd); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* check the authentication result */ + rc=ctx->authok; + if (rc!=PAM_SUCCESS) + { + pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",pam_strerror(pamh,rc),username); + return remap_pam_rc(rc,&cfg); + } + /* debug log */ + if (cfg.debug) + pam_syslog(pamh,LOG_DEBUG,"authentication succeeded"); + /* save username */ + ctx->user=strdup(username); + /* if password change is required, save old password in context */ + if (ctx->authz==PAM_NEW_AUTHTOK_REQD) + ctx->oldpassword=strdup(passwd); + /* update caller's idea of the user name */ + if ( ctx->tmpluser && ctx->tmpluser[0] && (strcmp(ctx->tmpluser,username)!=0) ) + { + pam_syslog(pamh,LOG_INFO,"username changed from %s to %s",username, + ctx->tmpluser); + rc=pam_set_item(pamh,PAM_USER,ctx->tmpluser); + } + return rc; +} + +/* called to update the authentication credentials */ +int pam_sm_setcred(pam_handle_t UNUSED(*pamh),int UNUSED(flags), + int UNUSED(argc),const char UNUSED(**argv)) +{ + /* we don't need to do anything here */ + return PAM_SUCCESS; +} + +/* PAM authorisation check */ +int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv) +{ + int rc; + struct pld_cfg cfg; + struct pld_ctx *ctx=NULL,ctx2; + const char *username,*service; + const char *ruser=NULL,*rhost=NULL,*tty=NULL; + /* set up configuration */ + cfg_init(pamh,flags,argc,argv,&cfg); + rc=init(pamh,&cfg,&ctx,&username,&service); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* get more PAM information */ + pam_get_item(pamh,PAM_RUSER,(const void **)&ruser); + pam_get_item(pamh,PAM_RHOST,(const void **)&rhost); + pam_get_item(pamh,PAM_TTY,(const void **)&tty); + /* call the function with a copy of the context to be able to keep the + original context */ + ctx2.dn=ctx->dn; + ctx2.user=ctx->user; + /* do the nslcd request */ + rc=nslcd_request_authz(pamh,&ctx2,&cfg,username,service,ruser,rhost,tty); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* check the returned authorisation value */ + if (ctx2.authz!=PAM_SUCCESS) + { + /* turn in to generic PAM error message if message is empty */ + if ((ctx2.authzmsg==NULL)||(ctx2.authzmsg[0]=='\0')) + ctx2.authzmsg=(char *)pam_strerror(pamh,ctx2.authz); + pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",ctx2.authzmsg,username); + rc=remap_pam_rc(ctx2.authz,&cfg); + if ((rc!=PAM_IGNORE)&&(!cfg.no_warn)) + pam_error(pamh,"%s",ctx2.authzmsg); + return rc; + } + /* check the original authorisation check from authentication */ + if (ctx->authz!=PAM_SUCCESS) + { + if ((ctx->authzmsg==NULL)||(ctx->authzmsg[0]=='\0')) + ctx->authzmsg=(char *)pam_strerror(pamh,ctx->authz); + pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",ctx->authzmsg,username); + rc=remap_pam_rc(ctx->authz,&cfg); + if ((rc!=PAM_IGNORE)&&(!cfg.no_warn)) + pam_error(pamh,"%s",ctx->authzmsg); + return rc; + } + if (cfg.debug) + pam_syslog(pamh,LOG_DEBUG,"authorization succeeded"); + /* present any informational messages to the user */ + if ((ctx2.authzmsg!=NULL)&&(ctx2.authzmsg[0]!='\0')&&(!cfg.no_warn)) + pam_info(pamh,"%s",ctx2.authzmsg); + if ((ctx->authzmsg!=NULL)&&(ctx->authzmsg[0]!='\0')&&(!cfg.no_warn)) + pam_info(pamh,"%s",ctx->authzmsg); + return PAM_SUCCESS; +} + +/* PAM session open/close calls */ +static int pam_sm_session(pam_handle_t *pamh,int flags,int argc, + const char **argv,int action) +{ + int rc; + struct pld_cfg cfg; + struct pld_ctx *ctx; + const char *username,*service; + const char *tty=NULL,*rhost=NULL,*ruser=NULL; + /* set up configuration */ + cfg_init(pamh,flags,argc,argv,&cfg); + rc=init(pamh,&cfg,&ctx,&username,&service); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* get more PAM information */ + pam_get_item(pamh,PAM_TTY,(const void **)&tty); + pam_get_item(pamh,PAM_RHOST,(const void **)&rhost); + pam_get_item(pamh,PAM_RUSER,(const void **)&ruser); + /* do the nslcd request */ + rc=nslcd_request_sess(pamh,ctx,&cfg,action,username,service,tty,rhost,ruser); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* debug log */ + if (cfg.debug) + pam_syslog(pamh,LOG_DEBUG,"session %s succeeded; session_id=%d", + (action==NSLCD_ACTION_PAM_SESS_O)?"open":"close",ctx->sessid); + return PAM_SUCCESS; +} + +/* PAM session open call */ +int pam_sm_open_session( + pam_handle_t *pamh,int flags,int argc,const char **argv) +{ + return pam_sm_session(pamh,flags,argc,argv,NSLCD_ACTION_PAM_SESS_O); +} + +/* PAM session close call */ +int pam_sm_close_session( + pam_handle_t *pamh,int flags,int argc,const char **argv) +{ + return pam_sm_session(pamh,flags,argc,argv,NSLCD_ACTION_PAM_SESS_C); +} + +/* Change the password of the user. This function is first called with + PAM_PRELIM_CHECK set in the flags and then without the flag. In the first + pass it is determined whether we can contact the LDAP server and the + provided old password is valid. In the second pass we get the new + password and actually modify the password. */ +int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) +{ + int rc; + struct pld_cfg cfg; + struct pld_ctx *ctx; + const char *username,*service; + const char *oldpassword=NULL,*newpassword=NULL; + struct passwd *pwent; + uid_t myuid; + /* set up configuration */ + cfg_init(pamh,flags,argc,argv,&cfg); + rc=init(pamh,&cfg,&ctx,&username,&service); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* see if we are dealing with an LDAP user first */ + if (ctx->dn==NULL) + { + rc=nslcd_request_exists(pamh,ctx,&cfg,username); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + } + /* prelimenary check, just see if we can connect to the LDAP server + and authenticate with the current password */ + if (flags&PAM_PRELIM_CHECK) + { + /* see if the user is trying to modify another user's password */ + pwent=getpwnam(username); + myuid=getuid(); + if ((pwent!=NULL)&&(pwent->pw_uid!=myuid)&&(!(flags&PAM_CHANGE_EXPIRED_AUTHTOK))) + { + /* we are root so we can test if nslcd will allow us to change the + user's password without the admin password */ + if (myuid==0) + { + rc=nslcd_request_authc(pamh,ctx,&cfg,"",service,""); + if ((rc==PAM_SUCCESS)&&(ctx->authok==PAM_SUCCESS)) + return pam_set_item(pamh,PAM_OLDAUTHTOK,""); + } + /* try to authenticate with the LDAP administrator password by passing + an empty username to the authc request */ + rc=pam_get_authtok(pamh,PAM_OLDAUTHTOK,&oldpassword,"LDAP administrator password: "); + if (rc!=PAM_SUCCESS) + return rc; + username=""; + } + else if ((ctx->oldpassword!=NULL)&&(*ctx->oldpassword!='\0')) + /* we already have an old password stored (from a previous + authentication phase) so we'll use that */ + oldpassword=ctx->oldpassword; + else + { + rc=pam_get_authtok(pamh,PAM_OLDAUTHTOK,(const char **)&oldpassword,"(current) LDAP Password: "); + if (rc!=PAM_SUCCESS) + return rc; + } + /* check for empty password */ + if (!cfg.nullok&&((oldpassword==NULL)||(oldpassword[0]=='\0'))) + { + if (cfg.debug) + pam_syslog(pamh,LOG_DEBUG,"user has empty password, access denied"); + return PAM_AUTH_ERR; + } + /* try authenticating */ + rc=nslcd_request_authc(pamh,ctx,&cfg,username,service,oldpassword); + if (rc!=PAM_SUCCESS) + return remap_pam_rc(rc,&cfg); + /* handle authentication result */ + if (ctx->authok!=PAM_SUCCESS) + pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",pam_strerror(pamh,ctx->authok),username); + else if (cfg.debug) + pam_syslog(pamh,LOG_DEBUG,"authentication succeeded"); + /* store password (needed if oldpassword was retreived from context) */ + if (rc==PAM_SUCCESS) + return pam_set_item(pamh,PAM_OLDAUTHTOK,oldpassword); + /* remap error code */ + return remap_pam_rc(ctx->authok,&cfg); + } + /* get the old password (from the previous call) */ + rc=pam_get_item(pamh,PAM_OLDAUTHTOK,(const void **)&oldpassword); + if (rc!=PAM_SUCCESS) + return rc; + /* get the new password */ + rc=pam_get_authtok(pamh,PAM_AUTHTOK,&newpassword,NULL); + if (rc!=PAM_SUCCESS) + return rc; + /* perform the password modification */ + rc=nslcd_request_pwmod(pamh,ctx,&cfg,username,service,oldpassword,newpassword); + if (rc==PAM_SUCCESS) + rc=ctx->authz; + else + ctx->authzmsg=(char *)pam_strerror(pamh,rc); + /* remap error code */ + rc=remap_pam_rc(rc,&cfg); + /* check the returned value */ + if (rc!=PAM_SUCCESS) + { + pam_syslog(pamh,LOG_NOTICE,"password change failed: %s; user=%s",ctx->authzmsg,username); + if ((rc!=PAM_IGNORE)&&(!cfg.no_warn)) + pam_error(pamh,"%s",ctx->authzmsg); + return rc; + } + pam_syslog(pamh,LOG_NOTICE,"password changed for %s",username); + return PAM_SUCCESS; +} + +#ifdef PAM_STATIC +struct pam_module _pam_ldap_modstruct={ + "pam_ldap", + pam_sm_authenticate, + pam_sm_setcred, + pam_sm_acct_mgmt, + pam_sm_open_session, + pam_sm_close_session, + pam_sm_chauthtok +}; +#endif /* PAM_STATIC */ diff --git a/pam/pam_ldap.map b/pam/pam_ldap.map new file mode 100644 index 0000000..21c98f8 --- /dev/null +++ b/pam/pam_ldap.map @@ -0,0 +1,16 @@ +EXPORTED { + + # published PAM service functions + global: + pam_sm_acct_mgmt; + pam_sm_authenticate; + pam_sm_chauthtok; + pam_sm_close_session; + pam_sm_open_session; + pam_sm_setcred; + + # everything else should not be exported + local: + *; + +}; diff --git a/py-compile b/py-compile new file mode 100755 index 0000000..3f9d05b --- /dev/null +++ b/py-compile @@ -0,0 +1,146 @@ +#!/bin/sh +# py-compile - Compile a Python program + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 2000, 2001, 2003, 2004, 2005, 2008, 2009 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, see . + +# 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. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if [ -z "$PYTHON" ]; then + PYTHON=python +fi + +basedir= +destdir= +files= +while test $# -ne 0; do + case "$1" in + --basedir) + basedir=$2 + if test -z "$basedir"; then + echo "$0: Missing argument to --basedir." 1>&2 + exit 1 + fi + shift + ;; + --destdir) + destdir=$2 + if test -z "$destdir"; then + echo "$0: Missing argument to --destdir." 1>&2 + exit 1 + fi + shift + ;; + -h|--h*) + cat <<\EOF +Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." + +Byte compile some python scripts FILES. Use --destdir to specify any +leading directory path to the FILES that you don't want to include in the +byte compiled file. Specify --basedir for any additional path information you +do want to be shown in the byte compiled file. + +Example: + py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py + +Report bugs to . +EOF + exit $? + ;; + -v|--v*) + echo "py-compile $scriptversion" + exit $? + ;; + *) + files="$files $1" + ;; + esac + shift +done + +if test -z "$files"; then + echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 + exit 1 +fi + +# if basedir was given, then it should be prepended to filenames before +# byte compilation. +if [ -z "$basedir" ]; then + pathtrans="path = file" +else + pathtrans="path = os.path.join('$basedir', file)" +fi + +# if destdir was given, then it needs to be prepended to the filename to +# byte compile but not go into the compiled file. +if [ -z "$destdir" ]; then + filetrans="filepath = path" +else + filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" +fi + +$PYTHON -c " +import sys, os, py_compile + +files = '''$files''' + +sys.stdout.write('Byte-compiling python modules...\n') +for file in files.split(): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + sys.stdout.write(file) + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'c', path) +sys.stdout.write('\n')" || exit $? + +# this will fail for python < 1.5, but that doesn't matter ... +$PYTHON -O -c " +import sys, os, py_compile + +files = '''$files''' +sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n') +for file in files.split(): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + sys.stdout.write(file) + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'o', path) +sys.stdout.write('\n')" 2>/dev/null || : + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/pynslcd/Makefile.am b/pynslcd/Makefile.am new file mode 100644 index 0000000..efe9788 --- /dev/null +++ b/pynslcd/Makefile.am @@ -0,0 +1,46 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +pynslcddir = $(datadir)/pynslcd + +pynslcd_PYTHON = pynslcd.py cfg.py common.py tio.py mypidfile.py \ + alias.py ether.py group.py host.py netgroup.py network.py \ + pam.py passwd.py shadow.py +nodist_pynslcd_PYTHON = constants.py config.py +CLEANFILES = $(nodist_pynslcd_PYTHON) + +all-local: $(nodist_pynslcd_PYTHON) + +# clean up locally created compiled Python files +clean-local: + rm -f *.pyc *.pyo + +# create a symbolic link for the pynslcd daemon and fix permissions +install-data-hook: + chmod a+rx $(DESTDIR)$(pynslcddir)/pynslcd.py + $(MKDIR_P) $(DESTDIR)$(sbindir) + [ -L $(DESTDIR)$(sbindir)/pynslcd ] || $(LN_S) $(pynslcddir)/pynslcd.py $(DESTDIR)$(sbindir)/pynslcd + +# generate constants module +constants.py: $(top_srcdir)/nslcd.h Makefile + ( echo "# This file is automatically generated from nslcd.h." ; \ + echo "# See that file for details." ; \ + echo "" ; \ + sed -n 's| */\*.*\*/ *||;s/^.define *\(NSLCD_[A-Z_]*\) */\1 = /p' \ + $< ) > $@ diff --git a/pynslcd/alias.py b/pynslcd/alias.py new file mode 100644 index 0000000..b35e009 --- /dev/null +++ b/pynslcd/alias.py @@ -0,0 +1,65 @@ + +# alias.py - lookup functions for aliasnet addresses +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging + +import constants +import common + + +attmap = common.Attributes(cn='cn', rfc822MailMember='rfc822MailMember') +filter = '(objectClass=nisMailAlias)' + + +class AliasRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get name and check against requested name + names = attributes['cn'] + if not names: + logging.error('Error: entry %s does not contain %s value', dn, attmap['cn']) + return + if 'cn' in parameters: + if parameters['cn'].lower() not in (x.lower() for x in names): + return + names = ( parameters['cn'], ) + # get the members of the alias + members = attributes['rfc822MailMember'] + if not members: + logging.error('Error: entry %s does not contain %s value', dn, attmap['rfc822MailMember']) + return + # write results + for name in names: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write_stringlist(members) + + +class AliasByNameRequest(AliasRequest): + + action = constants.NSLCD_ACTION_ALIAS_BYNAME + + def read_parameters(self, fp): + return dict(cn=fp.read_string()) + + +class AliasAllRequest(AliasRequest): + + action = constants.NSLCD_ACTION_ALIAS_ALL diff --git a/pynslcd/attmap.py b/pynslcd/attmap.py new file mode 100644 index 0000000..f72fa62 --- /dev/null +++ b/pynslcd/attmap.py @@ -0,0 +1,194 @@ + +# attributes.py - attribute mapping functions +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +"""Module for handling attribute mappings used for LDAP searches. + +>>> attrs = Attributes(uid='uid', +... userPassword='userPassword', +... uidNumber='uidNumber', +... gidNumber='gidNumber', +... gecos='"${gecos:-$cn}"', +... homeDirectory='homeDirectory', +... loginShell='loginShell') +>>> attrs.attributes() +('uid', 'userPassword', 'uidNumber', 'gidNumber', 'gecos', 'cn', 'homeDirectory', 'loginShell') +>>> attrs.value('gecos', {'cn': 'test'}) +['test'] +>>> attrs.search('uidNumber', 100) +'(uidNumber=100)' +>>> attrs['foo'] = '\"bar\"' +>>> attrs.get('foo', {}) +['bar'] +""" + +# exported names +__all__ = ( 'Attributes', ) + + +# FIXME: support multiple attribute values +# TODO: support objectSid attributes +# TODO: do more expression validity checking +# TODO: handle userPassword specially to do filtering of results + + +class MyIter(object): + """Custom iterator-like class with a back() method.""" + + def __init__(self, value): + self.value = value + self.pos = 0 + + def next(self): + self.pos += 1 + return self.value[self.pos-1] + + def back(self): + self.pos -= 1 + + def __iter__(self): + return self + + +class DollarExpression(object): + """Class for handling a variable $xxx ${xxx}, ${xxx:-yyy} or ${xxx:+yyy} + expression.""" + + def _parse_varname(self, value): + """Read a variable name from the value iterator.""" + name = '' + for c in value: + if not c.isalnum(): + value.back() + return name + name += c + + def __init__(self, value): + """Parse the expression as the start of a $-expression.""" + self.op = None + self.expr = None + c = value.next() + if c == '{': + self.name = self._parse_varname(value) + c = value.next() + if c == '}': + return + self.op = c + value.next() + self.expr = Expression(value, endat='}') + else: + value.back() + self.name = self._parse_varname(value) + + def value(self, variables): + """Expand the expression using the variables specified.""" + value = variables.get(self.name, [''])[0] + # FIXME: expand list + if self.op == ':-': + return value if value else self.expr.value(variables) + elif self.op == ':+': + return self.expr.value(variables) if value else '' + return value + + def variables(self, results): + """Add the variables used in the expression to results.""" + results.add(self.name) + if self.expr: + self.expr.variables(results) + + +class Expression(object): + """Class for parsing and expanding an expression.""" + + def __init__(self, value, endat=None): + """Parse the expression as a string.""" + if not isinstance(value, MyIter): + value = MyIter(value) + if not endat: + endat = value.next() # skip opening quote + expr = [] + literal = '' + c = value.next() + while c != endat: + if c == '$': + if literal: + expr.append(literal) + expr.append(DollarExpression(value)) + literal = '' + elif c == '\\': + literal += value.next() + else: + literal += c + c = value.next() + if literal: + expr.append(literal) + self.expr = expr + + def value(self, variables): + """Expand the expression using the variables specified.""" + res = '' + for x in self.expr: + if hasattr(x, 'value'): + res += x.value(variables) + else: + res += x + return res + + def variables(self, results=None): + """Return the variables defined in the expression.""" + if not results: + results = set() + for x in self.expr: + if hasattr(x, 'variables'): + x.variables(results) + return results + + +class Attributes(dict): + """Dictionary-like class for handling a list of attributes.""" + + def _prepare(self): + """Go over all values to parse any expressions.""" + updates = dict() + for k, v in self.iteritems(): + if isinstance(v, basestring) and v[0] == '"': + updates[k] = Expression(v) + self.update(updates) + + def attributes(self): + """Return a set of attributes that are referenced in this attribute + mapping.""" + self._prepare() + results = set() + for value in self.itervalues(): + if hasattr(value, 'variables'): + results.update(value.variables()) + else: + results.add(value) + return list(results) + + def mapped(self, variables): + """Return a dictionary with every attribute mapped to their value from + the specified variables.""" + results = dict() + for k, v in self.iteritems(): + if hasattr(v, 'value'): + results[k] = [v.value(variables)] + else: + results[k] = variables.get(v, []) + return results diff --git a/pynslcd/cfg.py b/pynslcd/cfg.py new file mode 100644 index 0000000..000e601 --- /dev/null +++ b/pynslcd/cfg.py @@ -0,0 +1,58 @@ + +# cfg.py - module for accessing configuration information +# +# Copyright (C) 2010 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import ldap + +# these values are defined here + +# the name of the program +program_name = 'pynslcd' +# the debugging level +debug = 0 +# whether the --check option was passed +check = False +# the number of threads to start +threads = 5 + +# the user id nslcd should be run as +uid = None +# the group id nslcd should be run as +gid = None + +# the LDAP server to use +# FIXME: support multiple servers and have a fail-over mechanism +ldap_uri = 'ldapi:///' + +# default search scope for searches +scope = ldap.SCOPE_SUBTREE + +# LDAP search bases to search +bases = ( 'dc=test, dc=tld', ) + +# the users for which no initgroups() searches should be done +nss_initgroups_ignoreusers = [] + +# the DN to use to perform password modifications as root +rootpwmoddn = 'cn=admin, dc=test, dc=tld' +rootpwmodpw = 'test' + +# FIXME: implement reading configuration from file +def read(cfgfile): + pass diff --git a/pynslcd/common.py b/pynslcd/common.py new file mode 100644 index 0000000..1f50584 --- /dev/null +++ b/pynslcd/common.py @@ -0,0 +1,134 @@ + +# common.py - functions that are used by different modules +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import re +import ldap +import ldap.dn +import sys + +import cfg +import constants +from attmap import Attributes + + +_validname_re = re.compile(r'^[a-z0-9._@$][a-z0-9._@$ \\~-]{0,98}[a-z0-9._@$~-]$', re.IGNORECASE) + +def isvalidname(name): + """Checks to see if the specified name seems to be a valid user or group + name. + + This test is based on the definition from POSIX (IEEE Std 1003.1, 2004, + 3.426 User Name, 3.189 Group Name and 3.276 Portable Filename Character Set): + http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_426 + http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_189 + http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_276 + + The standard defines user names valid if they contain characters from + the set [A-Za-z0-9._-] where the hyphen should not be used as first + character. As an extension this test allows some more characters.""" + return bool(_validname_re.match(name)) + +def validate_name(name): + """Checks to see if the specified name seems to be a valid user or group + name. See isvalidname().""" + if not _validname_re.match(name): + raise ValueError('%r: invalid user name' % name) + + +class Request(object): + """ + Request handler class. Subclasses are expected to handle actual requests + and should implement the following members: + + action: the NSLCD_ACTION_* action that should trigger this handler + read_parameters: a function that reads the request parameters of the + request stream + filter: LDAP search filter + mk_filter (optional): function that returns the LDAP search filter + write: function that writes a single LDAP entry to the result stream + """ + + def __init__(self, fp, conn, calleruid): + self.fp = fp + self.conn = conn + self.calleruid = calleruid + # load information from module that defines the class + module = sys.modules[self.__module__] + self.attmap = getattr(module, 'attmap', None) + self.filter = getattr(module, 'filter', None) + self.bases = getattr(module, 'bases', cfg.bases) + self.scope = getattr(module, 'scope', cfg.scope) + + def read_parameters(self, fp): + """This method should read the parameters from ths stream and + store them in self.""" + pass + + def attributes(self): + """Return the attributes that should be used in the LDAP search.""" + return self.attmap.attributes() + + def mk_filter(self, parameters): + """Return the active search filter (based on the read parameters).""" + if parameters: + return '(&%s(%s))' % ( self.filter, + ')('.join('%s=%s' % (self.attmap[attribute], + ldap.filter.escape_filter_chars(str(value))) + for attribute, value in parameters.items()) ) + return self.filter + + def handle_request(self, parameters): + """This method handles the request based on the parameters read + with read_parameters().""" + # get search results + for base in self.bases: + # do the LDAP search + try: + res = self.conn.search_s(base, self.scope, self.mk_filter(parameters), self.attributes()) + for entry in res: + if entry[0]: + self.write(entry[0], self.attmap.mapped(entry[1]), parameters) + except ldap.NO_SUCH_OBJECT: + # FIXME: log message + pass + # write the final result code + self.fp.write_int32(constants.NSLCD_RESULT_END) + + def __call__(self): + parameters = self.read_parameters(self.fp) or {} + # TODO: log call with parameters + self.fp.write_int32(constants.NSLCD_VERSION) + self.fp.write_int32(self.action) + self.handle_request(parameters) + + +def get_handlers(module): + """Return a dictionary mapping actions to Request classes.""" + import inspect + res = {} + if isinstance(module, basestring): + module = __import__(module, globals()) + for name, cls in inspect.getmembers(module, inspect.isclass): + if issubclass(cls, Request) and hasattr(cls, 'action'): + res[cls.action] = cls + return res + +def get_rdn_value(dn, attribute): + return dict((x, y) for x, y, z in ldap.dn.str2dn(dn)[0])[attribute] diff --git a/pynslcd/config.py.in b/pynslcd/config.py.in new file mode 100644 index 0000000..bab172e --- /dev/null +++ b/pynslcd/config.py.in @@ -0,0 +1,61 @@ + +# config.py.in - configured information, this file is processed by the +# configure script to produce config.py +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + + +# Name of package +PACKAGE = '''@PACKAGE@''' + +# Define to the address where bug reports for this package should be sent. +PACKAGE_BUGREPORT = '''@PACKAGE_BUGREPORT@''' + +# Define to the full name of this package. +PACKAGE_NAME = '''@PACKAGE_NAME@''' + +# Define to the full name and version of this package. +PACKAGE_STRING = '''@PACKAGE_STRING@''' + +# Define to the one symbol short name of this package. +PACKAGE_TARNAME = '''@PACKAGE_TARNAME@''' + +# Define to the home page for this package. +PACKAGE_URL = '''@PACKAGE_URL@''' + +# Define to the version of this package. +PACKAGE_VERSION = '''@PACKAGE_VERSION@''' + +# Version number of package +VERSION = '''@VERSION@''' + +# Whether to check configfile options. +ENABLE_CONFIGFILE_CHECKING = '''@ENABLE_CONFIGFILE_CHECKING@''' + +# Path to bindpw value. +NSLCD_BINDPW_PATH = '''@NSLCD_BINDPW_PATH@''' + +# Path to nslcd configuration file. +NSLCD_CONF_PATH = '''@NSLCD_CONF_PATH@''' + +# The location of the pidfile used for checking availability of the nslcd. +NSLCD_PIDFILE = '''@NSLCD_PIDFILE@''' + +# The location of the socket used for communicating. +NSLCD_SOCKET = '''@NSLCD_SOCKET@''' + +# The SONAME of the NSS library module. +NSS_LDAP_SONAME = '''@NSS_LDAP_SONAME@''' diff --git a/pynslcd/ether.py b/pynslcd/ether.py new file mode 100644 index 0000000..756e572 --- /dev/null +++ b/pynslcd/ether.py @@ -0,0 +1,86 @@ + +# ether.py - lookup functions for ethernet addresses +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import struct + +import constants +import common + + +def ether_aton(ether): + """Converst an ethernet address to binary form in network byte order.""" + return struct.pack('BBBBBB', *(int(x, 16) for x in ether.split(':'))) + +def ether_ntoa(ether): + """Conversts an ethernet address in network byte order to the string + representation.""" + return ':'.join('%x' % x for x in struct.unpack('6B', ether)) + + +attmap = common.Attributes(cn='cn', macAddress='macAddress') +filter = '(objectClass=ieee802Device)' + + +class EtherRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get name and check against requested name + names = attributes['cn'] + if not names: + print 'Error: entry %s does not contain %s value' % ( dn, attmap['cn']) + if 'cn' in parameters: + if parameters['cn'].lower() not in (x.lower() for x in names): + return # skip entry + names = ( parameters['cn'], ) + # get addresses and convert to binary form + addresses = [ether_aton(x) for x in attributes['macAddress']] + if not addresses: + print 'Error: entry %s does not contain %s value' % ( dn, attmap['macAddress']) + if 'macAddress' in parameters: + if ether_aton(parameters['macAddress']) not in addresses: + return + addresses = ( ether_aton(parameters['macAddress']), ) + # write results + for name in names: + for ether in addresses: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write(ether) + + +class EtherByNameRequest(EtherRequest): + + action = constants.NSLCD_ACTION_ETHER_BYNAME + + def read_parameters(self, fp): + return dict(cn=fp.read_string()) + + +class EtherByEtherRequest(EtherRequest): + + action = constants.NSLCD_ACTION_ETHER_BYETHER + + def read_parameters(self, fp): + return dict(macAddress=ether_ntoa(fp.read(6))) + + +class EtherAllRequest(EtherRequest): + + action = constants.NSLCD_ACTION_ETHER_ALL diff --git a/pynslcd/group.py b/pynslcd/group.py new file mode 100644 index 0000000..f3b91a5 --- /dev/null +++ b/pynslcd/group.py @@ -0,0 +1,137 @@ + +# group.py - group entry lookup routines +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging +import ldap.filter + +import constants +import common +from passwd import dn2uid, uid2dn + + +def clean(lst): + if lst: + for i in lst: + yield i.replace('\0', '') + + +attmap = common.Attributes(cn='cn', + userPassword='"*"', + gidNumber='gidNumber', + memberUid='memberUid', + member='member') +filter = '(|(objectClass=posixGroup)(objectClass=groupOfNames))' + + +class GroupRequest(common.Request): + + wantmembers = True + + def write(self, dn, attributes, parameters): + # get group names and check against requested group name + names = attributes['cn'] + if 'cn' in parameters: + if parameters['cn'] not in names: + return + names = ( parameters['cn'], ) + # get group group password + passwd = attributes['userPassword'][0] + # get group id(s) + gids = ( parameters['gidNumber'], ) if 'gidNumber' in parameters else attributes['gidNumber'] + gids = [ int(x) for x in gids ] + # build member list + members = set() + if self.wantmembers: + # add the memberUid values + for member in clean(attributes['memberUid']): + if common.isvalidname(member): + members.add(member) + # translate and add the member values + for memberdn in clean(attributes['member']): + member = dn2uid(self.conn, memberdn) + if member and common.isvalidname(member): + members.add(member) + # actually return the results + for name in names: + if not common.isvalidname(name): + print 'Warning: group entry %s contains invalid group name: "%s"' % ( dn, name ) + else: + for gid in gids: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write_string(passwd) + self.fp.write_gid_t(gid) + self.fp.write_stringlist(members) + + +class GroupByNameRequest(GroupRequest): + + action = constants.NSLCD_ACTION_GROUP_BYNAME + + def read_parameters(self, fp): + name = fp.read_string() + common.validate_name(name) + return dict(cn=name) + + +class GroupByGidRequest(GroupRequest): + + action = constants.NSLCD_ACTION_GROUP_BYGID + + def read_parameters(self, fp): + return dict(gidNumber=fp.read_gid_t()) + + +class GroupByMemberRequest(GroupRequest): + + action = constants.NSLCD_ACTION_GROUP_BYMEMBER + wantmembers = False + + def __init__(self, *args, **kwargs): + super(GroupByMemberRequest, self).__init__(*args, **kwargs) + # set up our own attributes that leave out membership attributes + self.attmap = common.Attributes(attmap) + del self.attmap['memberUid'] + del self.attmap['member'] + + def read_parameters(self, fp): + memberuid = fp.read_string() + common.validate_name(memberuid) + return dict(memberUid=memberuid) + + def attributes(self): + return self.attmap.attributes() + + def mk_filter(self, parameters): + # we still need a custom mk_filter because this is an | query + memberuid = parameters['memberUid'] + if attmap['member']: + dn = uid2dn(self.conn, memberuid) + if dn: + return '(&%s(|(%s=%s)(%s=%s)))' % ( self.filter, + attmap['memberUid'], ldap.filter.escape_filter_chars(memberuid), + attmap['member'], ldap.filter.escape_filter_chars(dn) ) + return '(&%s(%s=%s))' % ( self.filter, + attmap['memberUid'], ldap.filter.escape_filter_chars(memberuid) ) + + +class GroupAllRequest(GroupRequest): + + action = constants.NSLCD_ACTION_GROUP_ALL diff --git a/pynslcd/host.py b/pynslcd/host.py new file mode 100644 index 0000000..85e88a6 --- /dev/null +++ b/pynslcd/host.py @@ -0,0 +1,72 @@ + +# host.py - lookup functions for host names and addresses +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging + +import constants +import common + + +attmap = common.Attributes(cn='cn', ipHostNumber='ipHostNumber') +filter = '(objectClass=ipHost)' + + +class HostRequest(common.Request): + + def write(self, dn, attributes, parameters): + hostname = common.get_rdn_value(dn, attmap['cn']) + hostnames = attributes['cn'] + if not hostnames: + print 'Error: entry %s does not contain %s value' % ( dn, attmap['cn'] ) + if not hostname: + hostname = hostnames.pop(0) + elif hostname in hostnames: + hostnames.remove(hostname) + addresses = attributes['ipHostNumber'] + if not addresses: + print 'Error: entry %s does not contain %s value' % ( dn, attmap['ipHostNumber'] ) + # write result + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(hostname) + self.fp.write_stringlist(hostnames) + self.fp.write_int32(len(addresses)) + for address in addresses: + self.fp.write_address(address) + + +class HostByNameRequest(HostRequest): + + action = constants.NSLCD_ACTION_HOST_BYNAME + + def read_parameters(self, fp): + return dict(cn=fp.read_string()) + + +class HostByAddressRequest(HostRequest): + + action = constants.NSLCD_ACTION_HOST_BYADDR + + def read_parameters(self, fp): + return dict(ipHostNumber=fp.read_address()) + + +class HostAllRequest(HostRequest): + + action = constants.NSLCD_ACTION_HOST_ALL diff --git a/pynslcd/mypidfile.py b/pynslcd/mypidfile.py new file mode 100644 index 0000000..e179e16 --- /dev/null +++ b/pynslcd/mypidfile.py @@ -0,0 +1,71 @@ + +# mypidfile.py - functions for properly locking a PIDFile +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import fcntl +import errno +import os + + +class MyPIDLockFile(object): + """Implementation of a PIDFile fit for use with the daemon module + that locks the PIDFile with fcntl.lockf().""" + + def __init__(self, path): + self.path = path + + def __enter__(self): + """Lock the PID file and write the process ID to the file.""" + fd = os.open(self.path, os.O_RDWR | os.O_CREAT, 0644) + try: + fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + pidfile = os.fdopen(fd, 'w') + except: + os.close(fd) + raise + pidfile.write('%d\n' % os.getpid()) + pidfile.truncate() + pidfile.flush() + self.pidfile = pidfile + return self + + def __exit__(self, exc_type, exc_value, traceback): + """Release the lock (close the lockfile).""" + fcntl.lockf(self.pidfile.fileno(), fcntl.LOCK_UN) + self.pidfile.close() + del self.pidfile + + def is_locked(self): + """Check whether the file is already present and locked.""" + try: + fd = os.open(self.path, os.O_RDWR, 0644) + # Python doesn't seem to have F_TEST so we'll just try to lock + fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + # if we're here we must have aquired the lock + fcntl.lockf(fd, fcntl.LOCK_UN) + return False + except (IOError, OSError), e: + if e.errno == errno.ENOENT: + return False + if e.errno in (errno.EACCES, errno.EAGAIN): + return True + raise + finally: + if 'fd' in locals(): + os.close(fd) diff --git a/pynslcd/netgroup.py b/pynslcd/netgroup.py new file mode 100644 index 0000000..0f44660 --- /dev/null +++ b/pynslcd/netgroup.py @@ -0,0 +1,71 @@ + +# netgroup.py - lookup functions for netgroups +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging +import re + +import constants +import common + + +_netgroup_triple_re = re.compile(r'^\s*\(\s*(?P.*)\s*,\s*(?P.*)\s*,\s*(?P.*)\s*\)\s*$') + + +attmap = common.Attributes(cn='cn', + nisNetgroupTriple='nisNetgroupTriple', + memberNisNetgroup='memberNisNetgroup') +filter = '(objectClass=nisNetgroup)' + + +class NetgroupRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get names and check against requested user name + names = attributes['cn'] + if 'cn' in parameters: + if parameters['cn'] not in names: + return + names = ( parameters['cn'], ) + if not names: + print 'Error: entry %s does not contain %s value' % (dn, attmap['cn']) + # write the netgroup triples + for triple in attributes['nisNetgroupTriple']: + m = _netgroup_triple_re.match(triple) + if not m: + print 'Warning: entry %s contains invalid %s value: %r' % ( dn, attmap['nisNetgroupTriple'], triple) + else: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_int32(constants.NSLCD_NETGROUP_TYPE_TRIPLE) + self.fp.write_string(m.group('host')) + self.fp.write_string(m.group('user')) + self.fp.write_string(m.group('domain')) + # write netgroup members + for member in attributes['memberNisNetgroup']: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_int32(constants.NSLCD_NETGROUP_TYPE_NETGROUP) + self.fp.write_string(member) + + +class NetgroupByNameRequest(NetgroupRequest): + + action = constants.NSLCD_ACTION_NETGROUP_BYNAME + + def read_parameters(self, fp): + return dict(cn=fp.read_string()) diff --git a/pynslcd/network.py b/pynslcd/network.py new file mode 100644 index 0000000..dea01bd --- /dev/null +++ b/pynslcd/network.py @@ -0,0 +1,73 @@ + +# network.py - lookup functions for network names and addresses +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging + +import constants +import common + + +attmap = common.Attributes(cn='cn', + ipNetworkNumber='ipNetworkNumber') +filter = '(objectClass=ipNetwork)' + + +class NetworkRequest(common.Request): + + def write(self, dn, attributes, parameters): + networkname = common.get_rdn_value(dn, attmap['cn']) + networknames = attributes['cn'] + if not networknames: + print 'Error: entry %s does not contain %s value' % (dn, attmap['cn']) + if not networkname: + networkname = networknames.pop(0) + elif networkname in networknames: + networknames.remove(networkname) + addresses = attributes['ipNetworkNumber'] + if not addresses: + print 'Error: entry %s does not contain %s value' % (dn, attmap['ipNetworkNumber']) + # write result + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(networkname) + self.fp.write_stringlist(networknames) + self.fp.write_int32(len(addresses)) + for address in addresses: + self.fp.write_address(address) + + +class NetworkByNameRequest(NetworkRequest): + + action = constants.NSLCD_ACTION_NETWORK_BYNAME + + def read_parameters(self, fp): + return dict(cn=fp.read_string()) + + +class NetworkByAddressRequest(NetworkRequest): + + action = constants.NSLCD_ACTION_NETWORK_BYADDR + + def read_parameters(self, fp): + return dict(ipNetworkNumber=fp.read_address()) + + +class NetworkAllRequest(NetworkRequest): + + action = constants.NSLCD_ACTION_NETWORK_ALL diff --git a/pynslcd/pam.py b/pynslcd/pam.py new file mode 100644 index 0000000..316be96 --- /dev/null +++ b/pynslcd/pam.py @@ -0,0 +1,130 @@ + +# pam.py - functions authentication, authorisation and session handling +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging +import ldap + +import constants +import common +import cfg +import passwd + + +def try_bind(userdn, password): + # open a new connection + conn = ldap.initialize(cfg.ldap_uri) + # bind using the specified credentials + conn.simple_bind_s(userdn, password) + # perform search for own object (just to do any kind of search) + res = conn.search_s(userdn, ldap.SCOPE_BASE, '(objectClass=*)', [ 'dn', ]) + for entry in res: + if entry[0] == userdn: + return + raise ldap.NO_SUCH_OBJECT() + + +class PAMRequest(common.Request): + + def validate_request(self, parameters): + """This method checks the provided username for validity and fills + in the DN if needed.""" + # check username for validity + common.validate_name(parameters['username']) + # look up user DN if not known + if not parameters['userdn']: + entry = passwd.uid2entry(self.conn, parameters['username']) + if not entry: + raise ValueError('%r: user not found' % parameters['username']) + # save the DN + parameters['userdn'] = entry[0] + # get the "real" username + value = common.get_rdn_value(entry[0], passwd.attmap['uid']) + if not value: + # get the username from the uid attribute + values = myldap_get_values(entry, passwd.attmap['uid']) + if not values or not values[0]: + logging.warn('%s: is missing a %s attribute', dn, passwd.attmap['uid']) + value = values[0] + # check the username + if value and not common.isvalidname(value): + raise ValueError('%s: has invalid %s attribute', dn, passwd.attmap['uid']) + # check if the username is different and update it if needed + if value != parameters['username']: + logging.info('username changed from %r to %r', parameters['username'], value) + parameters['username'] = value + + +class PAMAuthenticationRequest(PAMRequest): + + action = constants.NSLCD_ACTION_PAM_AUTHC + + def read_parameters(self, fp): + return dict(username=fp.read_string(), + userdn=fp.read_string(), + servicename=fp.read_string(), + password=fp.read_string()) + #self.validate_request() + # TODO: log call with parameters + + def write(self, parameters, code=constants.NSLCD_PAM_SUCCESS, msg=''): + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(parameters['username']) + self.fp.write_string(parameters['userdn']) + self.fp.write_int32(code) # authc + self.fp.write_int32(constants.NSLCD_PAM_SUCCESS) # authz + self.fp.write_string(msg) # authzmsg + self.fp.write_int32(constants.NSLCD_RESULT_END) + + def handle_request(self, parameters): + # if the username is blank and rootpwmoddn is configured, try to + # authenticate as administrator, otherwise validate request as usual + if not parameters['username'] and cfg.rootpwmoddn: + # authenticate as rootpwmoddn + userdn = cfg.rootpwmoddn + # if the caller is root we will allow the use of rootpwmodpw + if not parameters['password'] and self.calleruid == 0 and cfg.rootpwmodpw: + password = cfg.rootpwmodpw + else: + self.validate_request(parameters) + userdn = parameters['userdn'] + password = parameters['password'] + # try authentication + try: + try_bind(userdn, password) + logging.debug('bind successful') + self.write(parameters) + except ldap.INVALID_CREDENTIALS, e: + try: + msg = e[0]['desc'] + except: + msg = str(e) + logging.debug('bind failed: %s', msg) + self.write(parameters, constants.NSLCD_PAM_AUTH_ERR, msg) + +#class PAMAuthorisationRequest(PAMRequest): + +# action = constants.NSLCD_ACTION_PAM_AUTHZ + +# def handle_request(self): + + +#NSLCD_ACTION_PAM_SESS_O +#NSLCD_ACTION_PAM_SESS_C +#NSLCD_ACTION_PAM_PWMOD diff --git a/pynslcd/passwd.py b/pynslcd/passwd.py new file mode 100644 index 0000000..cab2022 --- /dev/null +++ b/pynslcd/passwd.py @@ -0,0 +1,144 @@ + +# passwd.py - lookup functions for user account information +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import ldap +import ldap.filter + +import constants +import common + + +attmap = common.Attributes(uid='uid', + userPassword='"*"', + uidNumber='uidNumber', + gidNumber='gidNumber', + gecos='"${gecos:-$cn}"', + homeDirectory='homeDirectory', + loginShell='loginShell', + objectClass='objectClass') +filter = '(objectClass=posixAccount)' +bases = ( 'ou=people,dc=test,dc=tld', ) + + +class PasswdRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get uid attribute and check against requested user name + names = attributes['uid'] + if 'uid' in parameters: + if parameters['uid'] not in names: + return + names = ( parameters['uid'], ) + # get user password entry + if 'shadowAccount' in attributes['objectClass']: + passwd = 'x' + else: + passwd = attributes['userPassword'][0] + # get numeric user and group ids + uids = ( parameters['uidNumber'], ) if 'uidNumber' in parameters else attributes['uidNumber'] + uids = [ int(x) for x in uids ] + # get other passwd properties + gid = int(attributes['gidNumber'][0]) + gecos = attributes['gecos'][0] + home = attributes['homeDirectory'][0] + shell = attributes['loginShell'][0] + # write results + for name in names: + if not common.isvalidname(name): + print 'Warning: passwd entry %s contains invalid user name: "%s"' % ( dn, name ) + else: + for uid in uids: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write_string(passwd) + self.fp.write_uid_t(uid) + self.fp.write_gid_t(gid) + self.fp.write_string(gecos) + self.fp.write_string(home) + self.fp.write_string(shell) + + +class PasswdByNameRequest(PasswdRequest): + + action = constants.NSLCD_ACTION_PASSWD_BYNAME + + def read_parameters(self, fp): + name = fp.read_string() + common.validate_name(name) + return dict(uid=name) + + +class PasswdByUidRequest(PasswdRequest): + + action = constants.NSLCD_ACTION_PASSWD_BYUID + + def read_parameters(self, fp): + return dict(uidNumber=fp.read_uid_t()) + + +class PasswdAllRequest(PasswdRequest): + + action = constants.NSLCD_ACTION_PASSWD_ALL + + +# FIXME: have something in common that does this +def do_search(conn, flt=None, base=None): + mybases = ( base, ) if base else bases + flt = flt or filter + import cfg + # perform a search for each search base + for base in mybases: + # do the LDAP search + try: + scope = locals().get('scope', cfg.scope) + res = conn.search_s(base, scope, flt, [attmap['uid']]) + for entry in res: + if entry[0]: + yield entry + except ldap.NO_SUCH_OBJECT: + # FIXME: log message + pass + +def uid2entry(conn, uid): + """Look up the user by uid and return the LDAP entry or None if the user + was not found.""" + myfilter = '(&%s(%s=%s))' % ( filter, + attmap['uid'], ldap.filter.escape_filter_chars(uid) ) + for dn, attributes in do_search(conn, myfilter): + if uid in attributes[attmap['uid']]: + return dn, attributes + +def uid2dn(conn, uid): + """Look up the user by uid and return the DN or None if the user was + not found.""" + x = uid2entry(conn, uid) + if x is not None: + return x[0] + +# FIXME: use cache of dn2uid and try to use DN to get uid attribute + +def dn2uid(conn, dn): + """Look up the user by dn and return a uid or None if the user was + not found.""" + try: + for dn, attributes in do_search(conn, base=dn): + return attributes[attmap['uid']][0] + except ldap.NO_SUCH_OBJECT: + return None diff --git a/pynslcd/protocol.py b/pynslcd/protocol.py new file mode 100644 index 0000000..0e29f6b --- /dev/null +++ b/pynslcd/protocol.py @@ -0,0 +1,75 @@ + +# protocol.py - protocol name and number lookup routines +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging + +import constants +import common + + +attmap = common.Attributes(cn='cn', ipProtocolNumber='ipProtocolNumber') +filter = '(objectClass=ipProtocol)' + + +class ProtocolRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get name + name = common.get_rdn_value(dn, attmap['cn']) + names = attributes['cn'] + if not names: + print 'Error: entry %s does not contain %s value' % (dn, attmap['cn']) + if 'cn' in parameters and parameters['cn'] not in names: + return # case of result entry did not match + if not name: + name = names.pop(0) + elif name in names: + names.remove(name) + # get number + ( number, ) = attributes['ipProtocolNumber'] + if not number: + print 'Error: entry %s does not contain %s value' % (dn, attmap['ipProtocolNumber']) + number = int(number) + # write result + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write_stringlist(names) + self.fp.write_int32(number) + + +class ProtocolByNameRequest(ProtocolRequest): + + action = constants.NSLCD_ACTION_PROTOCOL_BYNAME + + def read_parameters(self, fp): + return dict(cn=fp.read_string()) + + +class ProtocolByNumberRequest(ProtocolRequest): + + action = constants.NSLCD_ACTION_PROTOCOL_BYNUMBER + + def read_parameters(self, fp): + return dict(ipProtocolNumber=fp.read_int32()) + + +class ProtocolAllRequest(ProtocolRequest): + + action = constants.NSLCD_ACTION_PROTOCOL_ALL diff --git a/pynslcd/pynslcd.py b/pynslcd/pynslcd.py new file mode 100755 index 0000000..8460c28 --- /dev/null +++ b/pynslcd/pynslcd.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python + +# pynslcd.py - main daemon module +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import os +import sys +import daemon +import mypidfile +import threading +import logging +import logging.handlers +import signal +import ldap + +import constants # from nslcd.h +import config # from configure +import cfg # from nslcd.conf +import common + +from tio import TIOStream + + +# configure logging +class MyFormatter(logging.Formatter): + def format(self, record): + msg = logging.Formatter.format(self, record) + if record.levelno == logging.DEBUG: + msg = 'DEBUG: %s' % msg + return msg +#logging.basicConfig(level=logging.INFO) +# , format='%(message)s' +formatter = MyFormatter('%(message)s') +stderrhandler = logging.StreamHandler(sys.stderr) +stderrhandler.setFormatter(formatter) +##sysloghandler = logging.handlers.SysLogHandler(address='/dev/log') +##sysloghandler.setFormatter(formatter) +#logging.getLogger().setFormatter(MyFormatter()) +logging.getLogger().addHandler(stderrhandler) + +#logger = logging.getLogger() +#logger.setLevel(logging.INFO) +#syslog = logging.handlers.SysLogHandler(address='/dev/log') +#formatter = logging.Formatter('%(name)s: %(levelname)s %(message)s') +#syslog.setFormatter(formatter) +#logger.addHandler(syslog) + +def display_version(fp): + fp.write('%(PACKAGE_STRING)s\n' + 'Written by Arthur de Jong.\n' + '\n' + 'Copyright (C) 2010, 2011 Arthur de Jong\n' + 'This is free software; see the source for copying conditions. There is NO\n' + 'warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n' + % { 'PACKAGE_STRING': config.PACKAGE_STRING, } ) + +def display_usage(fp): + fp.write("Usage: %(program_name)s [OPTION]...\n" + "Name Service LDAP connection daemon.\n" + " -c, --check check if the daemon already is running\n" + " -d, --debug don't fork and print debugging to stderr\n" + " --help display this help and exit\n" + " --version output version information and exit\n" + "\n" + "Report bugs to <%(PACKAGE_BUGREPORT)s>.\n" + % { 'program_name': cfg.program_name, + 'PACKAGE_BUGREPORT': config.PACKAGE_BUGREPORT, } ) + +def parse_cmdline(): + """Parse command-line arguments.""" + import getopt + cfg.program_name = sys.argv[0] or 'pynslcd' + try: + optlist, args = getopt.gnu_getopt(sys.argv[1:], + 'cdhV', ('check', 'debug', 'help', 'version', )) + for flag, arg in optlist: + if flag in ('-c', '--check'): + cfg.check = True + elif flag in ('-d', '--debug'): + cfg.debug += 1 + elif flag in ('-h', '--help'): + display_usage(sys.stdout) + sys.exit(0) + elif flag in ('-V', '--version'): + display_version(sys.stdout) + sys.exit(0) + if len(args): + raise getopt.GetoptError('unrecognized option \'%s\'' % args[0], args[0]) + except getopt.GetoptError, reason: + sys.stderr.write("%(program_name)s: %(reason)s\n" + "Try '%(program_name)s --help' for more information.\n" + % { 'program_name': cfg.program_name, + 'reason': reason, }) + sys.exit(1) + +def create_socket(): + """Returns a socket ready to answer requests from the client.""" + import socket + import fcntl + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + # remove existing named socket + try: + os.unlink(config.NSLCD_SOCKET) + except OSError: + pass # ignore any problems + # bind to named socket + sock.bind((config.NSLCD_SOCKET)) + # close the file descriptor on exit + fcntl.fcntl(sock, fcntl.F_SETFD, fcntl.FD_CLOEXEC) + # set permissions of socket so anybody can do requests + os.chmod(config.NSLCD_SOCKET, 0666) + # start listening for connections + sock.listen(socket.SOMAXCONN) + return sock + +def log_newsession(): + pass + # FIXME: implement + +def getpeercred(fd): + return (None, None, None) + # FIXME: implement and return uid, gid, pid + +handlers = {} +handlers.update(common.get_handlers('alias')) +handlers.update(common.get_handlers('ether')) +handlers.update(common.get_handlers('group')) +handlers.update(common.get_handlers('host')) +handlers.update(common.get_handlers('netgroup')) +handlers.update(common.get_handlers('network')) +handlers.update(common.get_handlers('pam')) +handlers.update(common.get_handlers('passwd')) +handlers.update(common.get_handlers('protocol')) +handlers.update(common.get_handlers('rpc')) +handlers.update(common.get_handlers('service')) +handlers.update(common.get_handlers('shadow')) + +def acceptconnection(session): + # accept a new connection + conn, addr = nslcd_serversocket.accept() + # See: http://docs.python.org/library/socket.html#socket.socket.settimeout + fp = None + try: + # probably use finally + # indicate new connection to logging module (genrates unique id) + log_newsession() + # log connection + try: + uid, gid, pid = getpeercred(conn) + logging.debug('connection from pid=%r uid=%r gid=%r', pid, uid, gid) + except: + raise # FIXME: handle exception gracefully + # create a stream object + fp = TIOStream(conn) + # read request + version = fp.read_int32() + if version != constants.NSLCD_VERSION: + logging.debug('wrong nslcd version id (%r)', version) + return + action = fp.read_int32() + try: + handler = handlers[action] + except KeyError: + logging.warn('invalid action id: %r', action) + return + handler(fp, session, uid)() + finally: + if fp: + fp.close() + +def disable_nss_ldap(): + """Disable the nss_ldap module to avoid lookup loops.""" + import ctypes + lib = ctypes.CDLL(config.NSS_LDAP_SONAME) + ctypes.c_int.in_dll(lib, '_nss_ldap_enablelookups').value = 0 + +def worker(): + # create a new LDAP session + #session = myldap_create_session() + session = ldap.initialize(cfg.ldap_uri) + # start waiting for incoming connections + while True: + # wait for a new connection + acceptconnection(session) + # FIXME: handle exceptions + +if __name__ == '__main__': + # parse options + parse_cmdline() + # clean the environment + os.environ.clear() + os.putenv('HOME', '/') + os.putenv('TMPDIR', '/tmp') + os.putenv('LDAPNOINIT', '1') + # disable ldap lookups of host names to avoid lookup loop + disable_nss_ldap() + # set log level + if cfg.debug: + logging.getLogger().setLevel(logging.DEBUG) + # FIXME: implement + #if myldap_set_debuglevel(cfg.debug) != LDAP_SUCCESS: + # sys.exit(1) + # read configuration file + cfg.read(config.NSLCD_CONF_PATH) + # set a default umask for the pidfile and socket + os.umask(0022) + # see if someone already locked the pidfile + pidfile = mypidfile.MyPIDLockFile(config.NSLCD_PIDFILE) + # see if --check option was given + if cfg.check: + if pidfile.is_locked(): + logging.debug('pidfile (%s) is locked', config.NSLCD_PIDFILE) + sys.exit(0) + else: + logging.debug('pidfile (%s) is not locked', config.NSLCD_PIDFILE) + sys.exit(1) + # normal check for pidfile locked + if pidfile.is_locked(): + logging.error('daemon may already be active, cannot acquire lock (%s)', config.NSLCD_PIDFILE) + sys.exit(1) + # daemonize + if cfg.debug: + daemon = pidfile + else: + daemon = daemon.DaemonContext( + pidfile=pidfile, + signal_map={ + signal.SIGTERM: 'terminate', + signal.SIGINT: 'terminate', + signal.SIGPIPE: None, + }) + # start daemon + with daemon: + # start normal logging + if not cfg.debug: + log_startlogging() + logging.info('version %s starting', config.VERSION) + # create socket + nslcd_serversocket = create_socket() + # drop all supplemental groups + try: + os.setgroups(()) + except OSError, e: + logging.warn('cannot setgroups(()) (ignored): %s', e) + # change to nslcd gid + if cfg.gid is not None: + import grp + os.setgid(grp.getgrnam(cfg.gid).gr_gid) + # change to nslcd uid + if cfg.uid is not None: + import pwd + u = pwd.getpwnam(cfg.uid) + os.setuid(u.pw_uid) + os.environ['HOME'] = u.pw_dir + logging.info('accepting connections') + # start worker threads + threads = [] + for i in range(cfg.threads): + thread = threading.Thread(target=worker, name='thread%d' % i) + thread.setDaemon(True) + thread.start() + logging.debug('started thread %s', thread.getName()) + threads.append(thread) + # wait for all threads to die + for thread in threads: + thread.join(10000) diff --git a/pynslcd/rpc.py b/pynslcd/rpc.py new file mode 100644 index 0000000..74a230d --- /dev/null +++ b/pynslcd/rpc.py @@ -0,0 +1,75 @@ + +# rpc.py - rpc name lookup routines +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging + +import constants +import common + + +attmap = common.Attributes(cn='cn', oncRpcNumber='oncRpcNumber') +filter = '(objectClass=oncRpc)' + + +class RpcRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get name + name = common.get_rdn_value(dn, attmap['cn']) + names = attributes['cn'] + if not names: + print 'Error: entry %s does not contain %s value' % ( dn, attmap['cn'] ) + if 'cn' in parameters and parameters['cn'] not in names: + return # case of result entry did not match + if not name: + name = names.pop(0) + elif name in names: + names.remove(name) + # get number + ( number, ) = attributes['oncRpcNumber'] + if not number: + print 'Error: entry %s does not contain %s value' % ( dn, attmap['oncRpcNumber']) + number = int(number) + # write result + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write_stringlist(names) + self.fp.write_int32(number) + + +class RpcByNameRequest(RpcRequest): + + action = constants.NSLCD_ACTION_RPC_BYNAME + + def read_parameters(self, fp): + return dict(cn=fp.read_string()) + + +class RpcByNumberRequest(RpcRequest): + + action = constants.NSLCD_ACTION_RPC_BYNUMBER + + def read_parameters(self, fp): + return dict(oncRpcNumber=fp.read_int32()) + + +class RpcAllRequest(RpcRequest): + + action = constants.NSLCD_ACTION_RPC_ALL diff --git a/pynslcd/service.py b/pynslcd/service.py new file mode 100644 index 0000000..08b0ebe --- /dev/null +++ b/pynslcd/service.py @@ -0,0 +1,96 @@ + +# service.py - service entry lookup routines +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging +import ldap.filter + +import constants +import common + + +attmap = common.Attributes(cn='cn', + ipServicePort='ipServicePort', + ipServiceProtocol='ipServiceProtocol') +filter = '(objectClass=ipService)' + + +class ServiceRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get name + name = common.get_rdn_value(dn, attmap['cn']) + names = attributes['cn'] + if not names: + print 'Error: entry %s does not contain %s value' % (dn, attmap['cn']) + if 'cn' in parameters and parameters['cn'] not in names + [ name, ]: + return # case of result entry did not match + if not name: + name = names.pop(0) + elif name in names: + names.remove(name) + # get port number + ( port, ) = attributes['ipServicePort'] + if not port: + print 'Error: entry %s does not contain %s value' % (dn, attmap['ipServicePort']) + port = int(port) + # get protocol + protocols = attributes['ipServiceProtocol'] + if 'ipServiceProtocol' in parameters: + if parameters['ipServiceProtocol'] not in protocols: + return + protocols = ( parameters['ipServiceProtocol'], ) + # write result + for protocol in protocols: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write_stringlist(names) + self.fp.write_int32(port) + self.fp.write_string(protocol) + + +class ServiceByNameRequest(ServiceRequest): + + action = constants.NSLCD_ACTION_SERVICE_BYNAME + + def read_parameters(self, fp): + name = fp.read_string() + protocol = fp.read_string() + if protocol: + return dict(cn=name, ipServiceProtocol=protocol) + else: + return dict(cn=name) + + +class ServiceByNumberRequest(ServiceRequest): + + action = constants.NSLCD_ACTION_SERVICE_BYNUMBER + + def read_parameters(self, fp): + number = fp.read_int32() + protocol = fp.read_string() + if protocol: + return dict(ipServicePort=number, ipServiceProtocol=protocol) + else: + return dict(ipServicePort=number) + + +class ServiceAllRequest(ServiceRequest): + + action = constants.NSLCD_ACTION_SERVICE_ALL diff --git a/pynslcd/shadow.py b/pynslcd/shadow.py new file mode 100644 index 0000000..34119b0 --- /dev/null +++ b/pynslcd/shadow.py @@ -0,0 +1,106 @@ + +# shadow.py - lookup functions for shadownet addresses +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import logging + +import constants +import common + + +attmap = common.Attributes(uid='uid', + userPassword='"*"', + shadowLastChange='"${shadowLastChange:--1}"', + shadowMin='"${shadowMin:--1}"', + shadowMax='"${shadowMax:--1}"', + shadowWarning='"${shadowWarning:--1}"', + shadowInactive='"${shadowInactive:--1}"', + shadowExpire='"${shadowExpire:--1}"', + shadowFlag='"${shadowFlag:-0}"') +filter = '(objectClass=shadowAccount)' +bases = ( 'ou=people,dc=test,dc=tld', ) + + +class ShadowRequest(common.Request): + + def write(self, dn, attributes, parameters): + # get name and check against requested name + names = attributes['uid'] + if not names: + print 'Error: entry %s does not contain %s value' % ( dn, attmap['uid'] ) + return + if 'uid' in parameters: + if parameters['uid'] not in names: + return + names = ( parameters['uid'], ) + # get password + (passwd, ) = attributes['userPassword'] + if not passwd or self.calleruid != 0: + passwd = '*' + # function for making an int + def mk_int(attr): + try: + return + except TypeError: + return None + # get lastchange date + lastchangedate = int(attributes.get('shadowLastChange', [0])[0]) + # we expect an AD 64-bit datetime value; + # we should do date=date/864000000000-134774 + # but that causes problems on 32-bit platforms, + # first we devide by 1000000000 by stripping the + # last 9 digits from the string and going from there */ + if attmap['shadowLastChange'] == 'pwdLastSet': + lastchangedate = ( lastchangedate / 864000000000 ) - 134774 + # get longs + mindays = int(attributes.get('shadowMin', [-1])[0]) + maxdays = int(attributes.get('shadowMax', [-1])[0]) + warndays = int(attributes.get('shadowWarning', [-1])[0]) + inactdays = int(attributes.get('shadowInactive', [-1])[0]) + expiredate = int(attributes.get('shadowExpire', [-1])[0]) + flag = int(attributes.get('shadowFlag', [0])[0]) + if attmap['shadowFlag'] == 'pwdLastSet': + if flag & 0x10000: + maxdays = -1 + flag = 0 + # write results + for name in names: + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_string(name) + self.fp.write_string(passwd) + self.fp.write_int32(lastchangedate) + self.fp.write_int32(mindays) + self.fp.write_int32(maxdays) + self.fp.write_int32(warndays) + self.fp.write_int32(inactdays) + self.fp.write_int32(expiredate) + self.fp.write_int32(flag) + + +class ShadowByNameRequest(ShadowRequest): + + action = constants.NSLCD_ACTION_SHADOW_BYNAME + + def read_parameters(self, fp): + return dict(uid=fp.read_string()) + + +class ShadowAllRequest(ShadowRequest): + + action = constants.NSLCD_ACTION_SHADOW_ALL diff --git a/pynslcd/tio.py b/pynslcd/tio.py new file mode 100644 index 0000000..f7091c5 --- /dev/null +++ b/pynslcd/tio.py @@ -0,0 +1,122 @@ + +# tio.py - I/O functions +# +# Copyright (C) 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +import struct +import os +import socket + + +# definition for reading and writing INT32 values +_int32 = struct.Struct('i') + +# FIXME: use something from config.py to determine the correct size +_uid_t = struct.Struct('i') + +# FIXME: use something from config.py to determine the correct size +_gid_t = struct.Struct('i') + +# FIXME: use something from config.py to determine the correct size +_struct_timeval = struct.Struct('ll') + +class TIOStreamError(Exception): + pass + +class TIOStream(object): + """File-like object that allows reading and writing nslcd-protocol + entities.""" + + def __init__(self, conn): + conn.setblocking(1) + conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, _struct_timeval.pack(0, 500000)) + conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, _struct_timeval.pack(60, 0)) + self.fp = os.fdopen(conn.fileno(), 'w+b', 1024*1024) + + def read(self, size): + return self.fp.read(size) + + def read_int32(self): + return _int32.unpack(self.read(_int32.size))[0] + + def read_uid_t(self): + return _uid_t.unpack(self.read(_uid_t.size))[0] + + def read_gid_t(self): + return _gid_t.unpack(self.read(_gid_t.size))[0] + + def read_string(self, maxsize=None): + len = self.read_int32() + if maxsize and len >= maxsize: + raise TIOStreamError() + return self.read(len) + + def read_address(self): + """Read an address (usually IPv4 or IPv6) from the stream and return + the address as a string representation.""" + af = self.read_int32() + return socket.inet_ntop(af, self.read_string(maxsize=64)) + + def write(self, value): + self.fp.write(value) + + def write_int32(self, value): + self.write(_int32.pack(value)) + + def write_uid_t(self, value): + self.write(_uid_t.pack(value)) + + def write_gid_t(self, value): + self.write(_gid_t.pack(value)) + + def write_string(self, value): + self.write_int32(len(value)) + self.write(value) + + def write_stringlist(self, value): + lst = tuple(value) + self.write_int32(len(lst)) + for string in lst: + self.write_string(string) + + @staticmethod + def _to_address(value): + # try IPv4 first + try: + return socket.AF_INET, socket.inet_pton(socket.AF_INET, value) + except socket.error: + pass # try the next one + # fall back to IPv6 + return socket.AF_INET6, socket.inet_pton(socket.AF_INET6, value) + + def write_address(self, value): + """Write an address (usually IPv4 or IPv6) in a string representation + to the stream.""" + # first try to make it into an IPv6 address + af, address = TIOStream._to_address(value) + self.write_int32(af) + self.write_string(address) + + def close(self): + try: + self.fp.close() + except IOError: + pass + + def __del__(self): + self.close() diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..328b181 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,74 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2006 West Consulting +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +TESTS = test_dict test_set test_tio test_expr test_getpeercred test_cfg \ + test_myldap.sh test_common test_nsscmds.sh test_pamcmds.sh + +check_PROGRAMS = test_dict test_set test_tio test_expr test_getpeercred \ + test_cfg test_myldap test_common + +EXTRA_DIST = nslcd-test.conf test_myldap.sh test_nsscmds.sh test_pamcmds.sh \ + in_testenv.sh test_pamcmds.expect usernames.txt + +CLEANFILES = $(EXTRA_PROGRAMS) + +AM_CPPFLAGS = -I$(top_srcdir) +AM_CFLAGS = $(PTHREAD_CFLAGS) -g + +# the following enables verbose protocol debugging information to be dumped +#AM_CPPFLAGS += -DDEBUG_PROT -DDEBUG_PROT_DUMP + +# the following enabled verbose tio stats logging +#AM_CPPFLAGS += -DDEBUG_TIO_STATS + +test_dict_SOURCES = test_dict.c ../common/dict.h ../common/dict.c +#test_dict_LDADD = ../common/dict.o + +test_set_SOURCES = test_set.c ../common/set.h +test_set_LDADD = ../common/libdict.a + +test_tio_SOURCES = test_tio.c common.h ../common/tio.h ../common/tio.c +test_tio_LDFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) + +test_expr_SOURCES = test_expr.c common.h +test_expr_LDADD = ../common/set.o ../common/dict.o + +test_getpeercred_SOURCES = test_getpeercred.c common.h +test_getpeercred_LDADD = ../compat/libcompat.a + +# common objects that are included for the tests of nslcd functionality +common_nslcd_LDADD = ../nslcd/log.o ../nslcd/common.o \ + ../nslcd/myldap.o ../nslcd/attmap.o ../nslcd/nsswitch.o \ + ../nslcd/alias.o ../nslcd/ether.o ../nslcd/group.o \ + ../nslcd/host.o ../nslcd/netgroup.o ../nslcd/network.o \ + ../nslcd/passwd.o ../nslcd/protocol.o ../nslcd/rpc.o \ + ../nslcd/service.o ../nslcd/shadow.o ../nslcd/pam.o \ + ../common/libtio.a ../common/libdict.a \ + ../common/libexpr.a ../compat/libcompat.a \ + @nslcd_LIBS@ @PTHREAD_LIBS@ + +test_cfg_SOURCES = test_cfg.c common.h +test_cfg_LDADD = $(common_nslcd_LDADD) + +test_myldap_SOURCES = test_myldap.c common.h +test_myldap_LDADD = ../nslcd/cfg.o $(common_nslcd_LDADD) + +test_common_SOURCES = test_common.c ../nslcd/common.h +test_common_LDADD = ../nslcd/cfg.o $(common_nslcd_LDADD) diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..c7894e4 --- /dev/null +++ b/tests/README @@ -0,0 +1,85 @@ + +This document tries to descrive the test in this directory. Most of these +tests should be self-explanitory as they should be simple unit tests of the +shipped modules (more unit tests are welcome). + +Since nss-pam-ldapd is meant for providing data from an LDAP server for some +tests you should have an LDAP server running and for even other tests you need +to have nslcd running. + +For this a test environment should be set up (the tests are ignored if no such +environment was detected). In my development environment I use a chroot jail +with Debian. The instructions in this document assume a similar environment. + + +TEST ENVIRONMENT +================ + +LDAP server configuration +------------------------- + +An LDAP server listening on ldap://localhost and ldapi:// is assumed. This is +acomplished on Debian by the following line in /etc/default/slapd: + SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///" + +Because there will be a lot of data in the database and to test paged results +you need the following in /etc/ldap/slapd.conf: + sizelimit size.prtotal=unlimited + +The LDAP server should be set up to service up the dc=test,dc=tld DN as base. + +A sample test.ldif file is also available in the SVN repository. Note that +this file is currently not shipped in the released tarballs because it is +quite large. Load the file into your LDAP server so that it can be served. + +Most of the names in the database have been randomly generated based on a +combination of name-lists that were found on the Internet. + + +nsswitch.conf +------------- + +The /etc/nsswitch.conf file is expected to contain something like the +following. All maps should be looked up through LDAP and some tests may expect +the LDAP lookup to come after the files lookup. + +passwd: files ldap +group: files ldap +shadow: files ldap +hosts: files ldap dns mdns +networks: files ldap +protocols: db files ldap +services: db files ldap +ethers: db files ldap +rpc: db files ldap +netgroup: files ldap +aliases: files ldap + +nslcd.conf +---------- + +The /etc/nslcd.conf file is expected to be configured like the following. + +uid nslcd +gid nslcd +uri ldapi:/// +base dc=test,dc=tld +#pagesize 100 # paging and referrals don't mix +timelimit 2 +bind_timelimit 4 +reconnect_sleeptime 4 +reconnect_retrytime 10 +filter group (|(objectClass=posixGroup)(objectClass=groupOfNames)) +base passwd ou=people,dc=test,dc=tld +base shadow ou=people,dc=test,dc=tld +base group ou=groups,dc=test,dc=tld +rootpwmoddn cn=admin,dc=test,dc=tld +rootpwmodpw test + + +OLD TESTS +========= + +There are also a lot of old test files in this directory. Those files are of +the form test_.c. These files call the NSS module functions directly. +These can probably all be removed and integrated into test_nsscmds.sh instead. diff --git a/tests/common.h b/tests/common.h new file mode 100644 index 0000000..68490e6 --- /dev/null +++ b/tests/common.h @@ -0,0 +1,69 @@ +/* + common.h - common test routines + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef TEST__COMMON_H +#define TEST__COMMON_H 1 + +#include + +#ifndef __ASSERT_FUNCTION +#define __ASSERT_FUNCTION "" +#endif /* not __ASSERT_FUNCTION */ + +/* try to find the actual assert function */ +#ifndef HAVE___ASSERT_FAIL +/* for Solaris: */ +#define __assert_fail(assertion,file,line,function) __assert(assertion,file,line) +#endif /* not HAVE___ASSERT_FAIL */ + +/* extra assertion function that epxects both strings to be the same + (special macro because strcmp() can be a macro that turns ugly in assert) */ +#define assertstreq(str1,str2) \ + (assertstreq_impl(str1,str2,"strcmp(" __STRING(str1) "," __STRING(str2) ")==0", \ + __FILE__, __LINE__, __ASSERT_FUNCTION)) + +static inline void assertstreq_impl(const char *str1,const char *str2, + const char *assertion,const char *file, + int line,const char *function) +{ + if (strcmp(str1,str2)!=0) + __assert_fail(assertion,file,line,function); +} + +/* extra assertion function that expects expr to be valid and prints an + error message that include errno otherwise */ +#define assertok(expr) \ + ((expr) \ + ? (void) (0) \ + : __assertok_fail(__STRING(expr),__FILE__,__LINE__,__ASSERT_FUNCTION)) + + +static inline void __assertok_fail(const char *expr,const char *file, + int line,const char *function) +{ + char msg[120]; + snprintf(msg,sizeof(msg),"%s (errno=\"%s\")",expr,strerror(errno)); + __assert_fail(msg,file,line,function); +} + + +#endif /* not TEST__COMMON_H */ diff --git a/tests/in_testenv.sh b/tests/in_testenv.sh new file mode 100755 index 0000000..5137140 --- /dev/null +++ b/tests/in_testenv.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# in_testenv.sh - script to check whether we are running in test environment +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +# This script expects to be run in an environment where nss-pam-ldapd +# is deployed with an LDAP server with the proper content (and nslcd running). +# It's probably best to run this in an environment without nscd (this breaks +# the services tests). + +# check if LDAP is configured correctly +cfgfile="/etc/nslcd.conf" +if [ -r "$cfgfile" ] +then + : +else + echo "$0: $cfgfile: not found" + exit 77 +fi + +uri=`sed -n 's/^uri *//p' "$cfgfile" | head -n 1` +base="dc=test,dc=tld" + +# try to fetch the base DN (fail with exit 77 to indicate problem) +ldapsearch -b "$base" -s base -x -H "$uri" > /dev/null 2>&1 || { + echo "$0: LDAP server $uri not available for $base" + exit 77 +} + +# basic check to see if nslcd is running +if [ -S /var/run/nslcd/socket ] && \ + [ -f /var/run/nslcd/nslcd.pid ] && \ + kill -s 0 `cat /var/run/nslcd/nslcd.pid` > /dev/null 2>&1 +then + : +else + echo "$0: nslcd not running" + exit 77 +fi + +# TODO: check if nscd is running + +# TODO: check if /etc/nsswitch.conf is correct + +echo "$0: using LDAP server $uri" diff --git a/tests/nslcd-test.conf b/tests/nslcd-test.conf new file mode 100644 index 0000000..d3430da --- /dev/null +++ b/tests/nslcd-test.conf @@ -0,0 +1,28 @@ +# nslcd-test.conf +# nslcd configuration file for test environment. +# See nslcd.conf(5) for details. + +# The location at which the LDAP server(s) should be reachable. +uri ldap://127.0.0.1/ + +# The search base that will be used for all queries. +base dc=test,dc=tld + +# The LDAP protocol version to use. +#ldap_version 3 + +# The DN to bind with for normal lookups. +#binddn cn=annonymous,dc=example,dc=net +#bindpw *removed* + +# The search scope. +#scope sub + +# The number of answers to request in a single search. +#pagesize 100 + +# The timeout for network operations. +timelimit 2 +bind_timelimit 4 +reconnect_sleeptime 4 +reconnect_retrytime 10 diff --git a/tests/test.ldif.gz b/tests/test.ldif.gz new file mode 100644 index 0000000000000000000000000000000000000000..1abcd0bf0eb9b0f5d590839a8fc566097c0b1bf5 GIT binary patch literal 182197 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
MVrl7{r*8J@*)>$+X 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%0A6&w%wA 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 +#include +#include + +#include "common.h" + +/* we include cfg.c because we want to test the static methods */ +#include "nslcd/cfg.c" + +static void test_xstrdup(void) +{ + static const char *foo="testString123"; + char *bar; + bar=xstrdup(foo); + /* we should have a new value */ + assert(bar!=NULL); + /* the contents should be the same */ + assertstreq(foo,bar); + /* but the pointer should be different */ + assert(foo!=bar); + /* free memory */ + free(bar); +} + +static void test_add_uris(void) +{ + static struct ldap_config cfg; + int i; + /* set up config */ + cfg_defaults(&cfg); + assert(cfg.ldc_uris[0].uri==NULL); + /* add a uri */ + add_uri(__FILE__,__LINE__,&cfg,"ldap://localhost"); + assert(cfg.ldc_uris[0].uri!=NULL); + assert(cfg.ldc_uris[1].uri==NULL); + /* add some more uris */ + for (i=1;i +#include + +#include "nslcd/common.h" +#include "nslcd/cfg.h" +#include "nslcd/log.h" + +static void test_isvalidname(void) +{ + assert(isvalidname("arthur")); + assert(!isvalidname("-arthur")); + assert(isvalidname("arthur-is-nice")); + assert(isvalidname("sambamachine$")); + assert(isvalidname("foo\\bar")); + assert(!isvalidname("\\foo\\bar")); + assert(!isvalidname("foo\\bar\\")); + assert(isvalidname("me")); /* try short name */ +} + +/* the main program... */ +int main(int UNUSED(argc),char UNUSED(*argv[])) +{ + char *srcdir; + char fname[100]; + /* build the name of the file */ + srcdir=getenv("srcdir"); + if (srcdir==NULL) + srcdir="."; + snprintf(fname,sizeof(fname),"%s/nslcd-test.conf",srcdir); + fname[sizeof(fname)-1]='\0'; + /* initialize configuration */ + cfg_init(fname); + /* partially initialize logging */ + log_setdefaultloglevel(LOG_DEBUG); + /* run the tests */ + test_isvalidname(); + return 0; +} diff --git a/tests/test_dict.c b/tests/test_dict.c new file mode 100644 index 0000000..05d54eb --- /dev/null +++ b/tests/test_dict.c @@ -0,0 +1,203 @@ +/* + test_dict.c - simple test for the dict module + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include + +#include "common/dict.h" +#include "compat/attrs.h" + +/* Simple test that adds a few key/value pairs to the dict and the does + most operations. */ +static void test_simple(void) +{ + DICT *dict; + void *val; + static char *value1="value1"; + static char *value2="value2"; + static char *replace2="replace2"; + const char **keys; + int i; + /* initialize */ + dict=dict_new(); + /* store some entries */ + dict_put(dict,"key1",value1); + dict_put(dict,"key2",value2); + dict_put(dict,"key3",dict); + dict_put(dict,"key2",replace2); + /* check dictionary contents */ + val=dict_get(dict,"key1"); + assert(val==value1); + val=dict_get(dict,"key2"); + assert(val==replace2); + val=dict_get(dict,"key3"); + assert(val==dict); + val=dict_get(dict,"key4"); + assert(val==NULL); + val=dict_get(dict,"KEY1"); + assert(val==NULL); + /* remove a key */ + dict_put(dict,"key3",NULL); + val=dict_get(dict,"key3"); + assert(val==NULL); + /* loop over dictionary contents */ + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++) + { + val=dict_get(dict,keys[i]); + assert(((val==value1)||(val==replace2))); + } + /* free stuff */ + dict_free(dict); + free(keys); +} + +/* Test to insert a large number of elements in the dict. */ +static void test_lotsofelements(void) +{ + DICT *dict; + char buf[80]; + int i,r; + void *val; + const char **keys; + /* initialize */ + dict=dict_new(); + /* insert a number of entries */ + for (i=0;i<1024;i++) + { + r=1+(int)(10000.0*(rand()/(RAND_MAX+1.0))); + sprintf(buf,"test%04d",r); + dict_put(dict,buf,&buf); + } + /* remove a number of entries */ + for (i=0;i<100;i++) + { + r=1+(int)(10000.0*(rand()/(RAND_MAX+1.0))); + sprintf(buf,"test%04d",r); + dict_put(dict,buf,NULL); + } + /* add some more entries */ + for (i=0;i<1024;i++) + { + r=1+(int)(10000.0*(rand()/(RAND_MAX+1.0))); + sprintf(buf,"test%04d",r); + dict_put(dict,buf,&buf); + } + /* loop over dictionary contents */ + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++) + { + val=dict_get(dict,keys[i]); + assert(val==buf); + } + /* free stuff */ + dict_free(dict); + free(keys); +} + +/* Test to insert a large number of elements in the dict. */ +static void test_readelements(const char *fname) +{ + DICT *dict; + char buf[80]; + FILE *fp; + void *val; + const char **keys; + int i; + /* initialize */ + dict=dict_new(); + /* read file and insert all entries */ + fp=fopen(fname,"r"); + assert(fp!=NULL); + while (fgets(buf,sizeof(buf),fp)!=NULL) + { + /* strip newline */ + buf[strlen(buf)-1]='\0'; + dict_put(dict,buf,&buf); + } + fclose(fp); + /* loop over dictionary contents */ + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++) + { + val=dict_get(dict,keys[i]); + assert(val==buf); + } + /* free stuff */ + dict_free(dict); + free(keys); +} + +static void test_countelements(int num) +{ + DICT *dict; + char buf[80]; + int i,r; + const char **keys; + /* initialize */ + dict=dict_new(); + /* insert a number of entries */ + for (i=0;i +#include +#include + +#include "common.h" + +/* we include expr.c because we want to test the static methods */ +#include "common/expr.c" + +static void test_parse_name(void) +{ + char buffer[20]; + int i; + i=0; + assert(parse_name("fooBar",&i,buffer,sizeof(buffer))!=NULL); + assert(i==6); + i=0; + assert(parse_name("nameThatWillNotFitInBuffer",&i,buffer,sizeof(buffer))==NULL); + i=0; + assert(parse_name("foo Bar",&i,buffer,sizeof(buffer))!=NULL); + assert(i==3); + assertstreq(buffer,"foo"); +} + +static const char *expanderfn(const char *name,void UNUSED(*expander_attr)) +{ + if (strcmp(name,"empty")==0) + return ""; + if (strcmp(name,"null")==0) + return NULL; + else + return "foobar"; +} + +static void test_expr_parse(void) +{ + char buffer[1024]; + assert(expr_parse("$test1",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"foobar"); + assert(expr_parse("\\$test1",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"$test1"); + assert(expr_parse("$empty",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,""); + assert(expr_parse("$foo1$empty-$foo2",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"foobar-foobar"); + assert(expr_parse("$foo1+$null+$foo2",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"foobar++foobar"); + assert(expr_parse("${test1}\\$",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"foobar$"); + assert(expr_parse("${test1:-default}",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"foobar"); + assert(expr_parse("${empty:-default}",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"default"); + assert(expr_parse("${test1:+setset}",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"setset"); + assert(expr_parse("${empty:+setset}",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,""); + assert(expr_parse("${empty:-$test1}",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"foobar"); + assert(expr_parse("a/$test1/b",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"a/foobar/b"); + assert(expr_parse("a/$empty/b",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"a//b"); + assert(expr_parse("a${test1}b",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"afoobarb"); + assert(expr_parse("a${test1}b${test2:+${test3:-d$test4}e}c",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"afoobarbfoobarec"); + assert(expr_parse("a${test1}b${test2:+${empty:-d$test4}e}c",buffer,sizeof(buffer),expanderfn,NULL)!=NULL); + assertstreq(buffer,"afoobarbdfoobarec"); + /* these are errors */ + assert(expr_parse("$&",buffer,sizeof(buffer),expanderfn,NULL)==NULL); + assert(expr_parse("${a",buffer,sizeof(buffer),expanderfn,NULL)==NULL); +} + +static void test_buffer_overflow(void) +{ + char buffer[10]; + assert(expr_parse("$test1$empty$test1",buffer,sizeof(buffer),expanderfn,NULL)==NULL); + assert(expr_parse("long test value",buffer,sizeof(buffer),expanderfn,NULL)==NULL); + assert(expr_parse("${test1:-long test value}",buffer,sizeof(buffer),expanderfn,NULL)==NULL); +} + +static void test_expr_vars(void) +{ + SET *set; + /* simple test */ + set=set_new(); + assert(expr_vars("$a",set)!=NULL); + assert(set_contains(set,"a")); + assert(!set_contains(set,"$a")); + set_free(set); + /* more elaborate test */ + set=set_new(); + assert(expr_vars("\"${gecos:-$cn}\"",set)!=NULL); + assert(set_contains(set,"gecos")); + assert(set_contains(set,"cn")); + set_free(set); + /* more elaborate test */ + set=set_new(); + assert(expr_vars("\"${homeDirectory:-/home/$uidNumber/$uid}\"",set)!=NULL); + assert(set_contains(set,"homeDirectory")); + assert(set_contains(set,"uidNumber")); + assert(set_contains(set,"uid")); + set_free(set); +} + +/* the main program... */ +int main(int UNUSED(argc),char UNUSED(*argv[])) +{ + test_parse_name(); + test_expr_parse(); + test_buffer_overflow(); + test_expr_vars(); + return EXIT_SUCCESS; +} diff --git a/tests/test_getpeercred.c b/tests/test_getpeercred.c new file mode 100644 index 0000000..57274b4 --- /dev/null +++ b/tests/test_getpeercred.c @@ -0,0 +1,132 @@ +/* + test_getpeercred.c - simple test for the peercred module + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2008, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_GRP_H +#include +#endif /* HAVE_GRP_H */ +#include + +#include "common.h" + +#include "compat/attrs.h" +#include "compat/getpeercred.h" + +/* create a named socket */ +static int create_socket(const char *name) +{ + int sock; + struct sockaddr_un addr; + /* create a socket */ + assertok((sock=socket(PF_UNIX,SOCK_STREAM,0))>=0); + /* remove existing named socket */ + unlink(name); + /* create socket address structure */ + memset(&addr,0,sizeof(struct sockaddr_un)); + addr.sun_family=AF_UNIX; + strncpy(addr.sun_path,name,sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path)-1]='\0'; + /* bind to the named socket */ + assertok(bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr_un))==0); + /* close the file descriptor on exit */ + assertok(fcntl(sock,F_SETFD,FD_CLOEXEC)>=0); + /* start listening for connections */ + assertok(listen(sock,SOMAXCONN)>=0); + /* we're done */ + return sock; +} + +/* accept a connection on the socket */ +static int acceptconnection(int sock) +{ + int csock; + int j; + struct sockaddr_storage addr; + socklen_t alen; + /* accept a new connection */ + alen=(socklen_t)sizeof(struct sockaddr_storage); + assertok((csock=accept(sock,(struct sockaddr *)&addr,&alen))>=0); + /* make sure O_NONBLOCK is not inherited */ + assertok((j=fcntl(csock,F_GETFL,0))>=0); + assertok(fcntl(csock,F_SETFL,j&~O_NONBLOCK)>=0); + /* return socket */ + return csock; +} + +/* open a connection to the named socket */ +static int open_socket(const char *name) +{ + int sock; + struct sockaddr_un addr; + /* create a socket */ + assertok((sock=socket(PF_UNIX,SOCK_STREAM,0))>=0); + /* create socket address structure */ + memset(&addr,0,sizeof(struct sockaddr_un)); + addr.sun_family=AF_UNIX; + strncpy(addr.sun_path,name,sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path)-1]='\0'; + /* connect to the socket */ + assertok(connect(sock,(struct sockaddr *)&addr,(socklen_t)sizeof(struct sockaddr_un))>=0); + /* return the socket */ + return sock; +} + +#define SOCKETNAME "/tmp/test_getpeercred.sock" + +#define assertwarn(assertion) \ + if (!(assertion)) \ + fprintf(stderr,"test_getpeercred: %s:%d: %s: Assertion `%s' failed\n", \ + __FILE__, __LINE__, __ASSERT_FUNCTION, __STRING(assertion)); + +/* the main program... */ +int main(int UNUSED(argc),char UNUSED(*argv[])) +{ + int ssock; + int csock; + int fsock; + uid_t uid; + gid_t gid; + pid_t pid; + /* create a socket to listen on */ + ssock=create_socket(SOCKETNAME); + /* open a connection to the socket */ + csock=open_socket(SOCKETNAME); + /* get a connection from the server socket */ + fsock=acceptconnection(ssock); + /* look up client information */ + assert(getpeercred(fsock,&uid,&gid,&pid)==0); + assert(uid==geteuid()); + assertwarn(gid==getegid()); + assertwarn(pid==getpid()); + /* remove the socket */ + unlink(SOCKETNAME); + return 0; +} diff --git a/tests/test_myldap.c b/tests/test_myldap.c new file mode 100644 index 0000000..5726d2e --- /dev/null +++ b/tests/test_myldap.c @@ -0,0 +1,431 @@ +/* + test_myldap.c - simple test for the myldap module + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2009, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#include "nslcd/log.h" +#include "nslcd/cfg.h" +#include "nslcd/myldap.h" + +struct worker_args { + int id; +}; + +/* the maxium number of results to print (all results are retrieved) */ +#define MAXRESULTS 10 + +/* This is a very basic search test, it performs a test to get certain + entries from the database. It currently just prints out the DNs for + the entries. */ +static void test_search(void) +{ + MYLDAP_SESSION *session; + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + const char *attrs[] = { "uid", "cn", "gid", NULL }; + int i; + int rc; + /* initialize session */ + printf("test_myldap: test_search(): getting session...\n"); + session=myldap_create_session(); + assert(session!=NULL); + /* perform search */ + printf("test_myldap: test_search(): doing search...\n"); + search=myldap_search(session,nslcd_cfg->ldc_bases[0], + LDAP_SCOPE_SUBTREE, + "(objectclass=posixAccount)", + attrs,NULL); + assert(search!=NULL); + /* go over results */ + printf("test_myldap: test_search(): get results...\n"); + for (i=0;(entry=myldap_get_entry(search,&rc))!=NULL;i++) + { + if (ildc_bases[0], + LDAP_SCOPE_SUBTREE, + "(objectclass=posixGroup)", + attrs,NULL); + assert(search!=NULL); + /* go over results */ + printf("test_myldap: test_search(): get results...\n"); + for (i=0;(entry=myldap_get_entry(search,&rc))!=NULL;i++) + { + if (ildc_bases[0], + LDAP_SCOPE_SUBTREE, + "(&(|(objectClass=posixGroup)(objectClass=groupOfNames))(cn=testgroup2))", + attrs1,NULL); + assert(search1!=NULL); + /* get one entry */ + entry=myldap_get_entry(search1,&rc); + assert(entry!=NULL); + printf("test_myldap: test_get(): got DN %s\n",myldap_get_dn(entry)); + /* get some attribute values */ + (void)myldap_get_values(entry,"gidNumber"); + (void)myldap_get_values(entry,"userPassword"); + (void)myldap_get_values(entry,"memberUid"); + (void)myldap_get_values(entry,"member"); + /* perform another search */ + printf("test_myldap: test_get(): doing get...\n"); + search2=myldap_search(session,"cn=Test User2,ou=people,dc=test,dc=tld", + LDAP_SCOPE_BASE, + "(objectclass=posixAccount)", + attrs2,NULL); + assert(search2!=NULL); + /* get one entry */ + entry=myldap_get_entry(search2,&rc); + assert(entry!=NULL); + printf("test_myldap: test_get(): got DN %s\n",myldap_get_dn(entry)); + /* test if searches are ok */ + assert(myldap_get_entry(search1,&rc)==NULL); + assert(myldap_get_entry(search2,&rc)==NULL); + /* clean up */ + myldap_session_close(session); +} + +/* This search prints a number of attributes from a search */ +static void test_get_values(void) +{ + MYLDAP_SESSION *session; + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + const char *attrs[] = { "uidNumber", "cn", "gidNumber", "uid", "objectClass", NULL }; + const char **vals; + const char *rdnval; + int i; + /* initialize session */ + printf("test_myldap: test_get_values(): getting session...\n"); + session=myldap_create_session(); + assert(session!=NULL); + /* perform search */ + search=myldap_search(session,nslcd_cfg->ldc_bases[0], + LDAP_SCOPE_SUBTREE, + "(&(objectClass=posixAccount)(uid=*))", + attrs,NULL); + assert(search!=NULL); + /* go over results */ + for (i=0;(entry=myldap_get_entry(search,NULL))!=NULL;i++) + { + if (ildc_bases[0], + LDAP_SCOPE_SUBTREE, + "(&(objectClass=posixAccount)(uid=*))", + attrs,NULL); + assert(search1!=NULL); + /* get a result from search1 */ + entry=myldap_get_entry(search1,NULL); + assert(entry!=NULL); + printf("test_myldap: test_two_searches(): [search1] DN %s\n",myldap_get_dn(entry)); + vals=myldap_get_values(entry,"cn"); + assert((vals!=NULL)&&(vals[0]!=NULL)); + printf("test_myldap: test_two_searches(): [search1] cn=%s\n",vals[0]); + /* start a second search */ + search2=myldap_search(session,nslcd_cfg->ldc_bases[0], + LDAP_SCOPE_SUBTREE, + "(&(objectclass=posixGroup)(gidNumber=*))", + attrs,NULL); + assert(search2!=NULL); + /* get a result from search2 */ + entry=myldap_get_entry(search2,NULL); + assert(entry!=NULL); + printf("test_myldap: test_two_searches(): [search2] DN %s\n",myldap_get_dn(entry)); + vals=myldap_get_values(entry,"cn"); + assert((vals!=NULL)&&(vals[0]!=NULL)); + printf("test_myldap: test_two_searches(): [search2] cn=%s\n",vals[0]); + /* get another result from search1 */ + entry=myldap_get_entry(search1,NULL); + assert(entry!=NULL); + printf("test_myldap: test_two_searches(): [search1] DN %s\n",myldap_get_dn(entry)); + vals=myldap_get_values(entry,"cn"); + assert((vals!=NULL)&&(vals[0]!=NULL)); + printf("test_myldap: test_two_searches(): [search1] cn=%s\n",vals[0]); + /* stop search1 */ + myldap_search_close(search1); + /* get another result from search2 */ + entry=myldap_get_entry(search2,NULL); + assert(entry!=NULL); + printf("test_myldap: test_two_searches(): [search2] DN %s\n",myldap_get_dn(entry)); + vals=myldap_get_values(entry,"cn"); + assert((vals!=NULL)&&(vals[0]!=NULL)); + printf("test_myldap: test_two_searches(): [search2] cn=%s\n",vals[0]); + /* clean up */ + myldap_session_close(session); +} + +/* perform a simple search */ +static void *worker(void *arg) +{ + MYLDAP_SESSION *session; + MYLDAP_SEARCH *search; + MYLDAP_ENTRY *entry; + const char *attrs[] = { "uid", "cn", "gid", NULL }; + struct worker_args *args=(struct worker_args *)arg; + int i; + int rc; + /* initialize session */ + session=myldap_create_session(); + assert(session!=NULL); + /* perform search */ + search=myldap_search(session,nslcd_cfg->ldc_bases[0], + LDAP_SCOPE_SUBTREE, + "(objectclass=posixAccount)", + attrs,NULL); + assert(search!=NULL); + /* go over results */ + for (i=0;(entry=myldap_get_entry(search,&rc))!=NULL;i++) + { + if (iid,i,myldap_get_dn(entry)); + else if (i==MAXRESULTS) + printf("test_myldap: test_threads(): [worker %d] ...\n",args->id); + } + printf("test_myldap: test_threads(): [worker %d] DONE: %s\n",args->id,ldap_err2string(rc)); + assert(rc==LDAP_SUCCESS); + /* clean up */ + myldap_session_close(session); + return 0; +} + +/* thread ids of all running threads */ +#define NUM_THREADS 5 +pthread_t my_threads[NUM_THREADS]; + +static void test_threads(void) +{ + int i; + struct worker_args args[NUM_THREADS]; + /* start worker threads */ + for (i=0;ildc_uris[i].uri; + nslcd_cfg->ldc_uris[i].uri=NULL; + } + /* set new URIs */ + i=0; + nslcd_cfg->ldc_uris[i++].uri="ldapi://%2fdev%2fnull/"; + nslcd_cfg->ldc_uris[i++].uri="ldap://10.10.10.10/"; + nslcd_cfg->ldc_uris[i++].uri="ldapi://%2fdev%2fnonexistent/"; + nslcd_cfg->ldc_uris[i++].uri="ldap://nosuchhost/"; + nslcd_cfg->ldc_uris[i++].uri=NULL; + /* initialize session */ + printf("test_myldap: test_connections(): getting session...\n"); + session=myldap_create_session(); + assert(session!=NULL); + /* perform search */ + printf("test_myldap: test_connections(): doing search...\n"); + search=myldap_search(session,nslcd_cfg->ldc_bases[0], + LDAP_SCOPE_SUBTREE, + "(objectclass=posixAccount)", + attrs,NULL); + assert(search==NULL); + /* clean up */ + myldap_session_close(session); + /* restore the old URIs */ + for (i=0;i<(NSS_LDAP_CONFIG_URI_MAX+1);i++) + nslcd_cfg->ldc_uris[i].uri=old_uris[i]; +} + +/* test whether myldap_escape() handles buffer overlows correctly */ +static void test_escape(void) +{ + char buffer[1024]; + assert(myldap_escape("test",buffer,4)!=0); + assert(myldap_escape("t*st",buffer,5)!=0); + assert(myldap_escape("t*st",buffer,20)==0); + assertstreq(buffer,"t\\2ast"); +} + +/* the main program... */ +int main(int argc,char *argv[]) +{ + char *srcdir; + char fname[100]; + struct sigaction act; + /* build the name of the file */ + srcdir=getenv("srcdir"); + if (srcdir==NULL) + srcdir="."; + snprintf(fname,sizeof(fname),"%s/nslcd-test.conf",srcdir); + fname[sizeof(fname)-1]='\0'; + /* initialize configuration */ + cfg_init(fname); + /* partially initialize logging */ + log_setdefaultloglevel(LOG_DEBUG); + /* ignore SIGPIPE */ + memset(&act,0,sizeof(struct sigaction)); + act.sa_handler=SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags=SA_RESTART|SA_NOCLDSTOP; + assert(sigaction(SIGPIPE,&act,NULL)==0); + /* do tests */ + test_search(); + test_get(); + test_get_values(); + test_get_rdnvalues(); + test_two_searches(); + test_threads(); + test_connections(); + test_escape(); + return 0; +} diff --git a/tests/test_myldap.sh b/tests/test_myldap.sh new file mode 100755 index 0000000..18b745a --- /dev/null +++ b/tests/test_myldap.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# test_myldap.sh - simple wrapper test script for test_myldap +# +# Copyright (C) 2007 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +# This script expects to be run in an environment where an LDAP server +# is available at the location specified in nslcd-test.conf in +# this directory. + +set -e + +# get LDAP config +srcdir="${srcdir-"."}" +cfgfile="$srcdir/nslcd-test.conf" +uri=`sed -n 's/^uri *//p' "$cfgfile" | head -n 1` +base="dc=test,dc=tld" + +# try to fetch the base DN (fail with exit 77 to indicate problem) +ldapsearch -b "$base" -s base -x -H "$uri" > /dev/null 2>&1 || { + echo "test_myldap.sh: LDAP server $uri not available for $base" + exit 77 +} +echo "test_myldap.sh: using LDAP server $uri" + +# just execute test_myldap +exec ./test_myldap diff --git a/tests/test_nsscmds.sh b/tests/test_nsscmds.sh new file mode 100755 index 0000000..fdca127 --- /dev/null +++ b/tests/test_nsscmds.sh @@ -0,0 +1,428 @@ +#!/bin/sh + +# test_nsscmds.sh - simple test script to check output of name lookup commands +# +# Copyright (C) 2007, 2008, 2009, 2010, 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +# This script expects to be run in an environment where nss-pam-ldapd +# is deployed with an LDAP server with the proper content (and nslcd running). +# It's probably best to run this in an environment without nscd (this breaks +# the services tests). + +set -e + +# find source directory +srcdir="${srcdir-`dirname "$0"`}" + +# ensure that we are running in the test environment +. "$srcdir/in_testenv.sh" + +# preload our own NSS module +LD_PRELOAD="$srcdir/../nss/nss_ldap.so" +export LD_PRELOAD + +# the total number of errors +FAIL=0 + +check() { + # the command to execute + cmd="$1" + # save the expected output + expectfile=`mktemp -t expected.XXXXXX 2> /dev/null || tempfile -s .expected 2> /dev/null` + cat > "$expectfile" + # run the command + echo 'test_nsscmds.sh: checking "'"$cmd"'"' + actualfile=`mktemp -t actual.XXXXXX 2> /dev/null || tempfile -s .actual 2> /dev/null` + eval "$cmd" > "$actualfile" 2>&1 || true + # check for differences + diff -Nauwi "$expectfile" "$actualfile" || FAIL=`expr $FAIL + 1` + # remove temporary files + rm "$expectfile" "$actualfile" +} + +########################################################################### + +echo "test_nsscmds.sh: testing aliases..." + +# note that this doesn't work if /etc/aliases contains anything + +# check all aliases +check "getent aliases|sort" << EOM +bar2: foobar@example.com +bar: foobar@example.com +foo: bar@example.com +EOM + +# get alias by name +check "getent aliases foo" << EOM +foo: bar@example.com +EOM + +# get alias by second name +check "getent aliases bar2" << EOM +bar2: foobar@example.com +EOM + +# get alias by different case +check "getent aliases FOO" << EOM +foo: bar@example.com +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing ether..." + +# get an entry by hostname +check "getent ethers testhost" << EOM +0:18:8a:54:1a:8e testhost +EOM + +# get an entry by alias name +check "getent ethers testhostalias" << EOM +0:18:8a:54:1a:8e testhostalias +EOM + +# get an entry by hostname with different case +check "getent ethers TESTHOST" << EOM +0:18:8a:54:1a:8e testhost +EOM + +# get an entry by ethernet address +check "getent ethers 0:18:8a:54:1a:8b" << EOM +0:18:8a:54:1a:8b testhost2 +EOM + +# get entry by ip address +# this does not currently work, but maybe it should +#check "getent ethers 10.0.0.1" << EOM +#0:18:8a:54:1a:8e testhost +#EOM + +# get all ethers (unsupported) +check "getent ethers" << EOM +Enumeration not supported on ethers +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing group..." + +# function to sort group members of a group +sortgroup() { + while read line + do + group="$(echo "$line" | sed 's/^\(.*:.*:.*:\).*/\1/')" + members="$(echo "$line" | sed 's/^.*:.*:.*://' | tr ',' '\n' | sort | tr '\n' ',' | sed 's/,$//')" + echo "${group}${members}" + done +} + +check "getent group testgroup | sortgroup" << EOM +testgroup:*:6100:arthur,test,testuser4 +EOM + +# this does not work because users is in /etc/group but it would +# be nice if libc supported this +#check "getent group users" << EOM +#users:*:100:arthur,test +#EOM + +# group with different case should not be found +check "getent group TESTGROUP" << EOM +EOM + +check "getent group 6100 | sortgroup" << EOM +testgroup:*:6100:arthur,test,testuser4 +EOM + +check "groups arthur | sed 's/^.*://'" << EOM +users testgroup testgroup2 grp4 grp5 grp6 grp7 grp8 grp9 grp10 grp11 grp12 grp13 grp14 grp15 grp16 grp17 grp18 +EOM + +check "groups testuser4 | sed 's/^.*://'" << EOM +users testgroup testgroup2 +EOM + +check "getent group | egrep '^(testgroup|users):' | sortgroup" << EOM +users:x:100: +testgroup:*:6100:arthur,test,testuser4 +users:*:100:arthur,test +EOM + +check "getent group | wc -l" << EOM +`grep -c : /etc/group | awk '{print $1 + 20}'` +EOM + +check "getent group | grep ^largegroup | sortgroup" << EOM +largegroup:*:1005:akraskouskas,alat,ameisinger,bdevera,behrke,bmoldan,btempel,cjody,clouder,cmanno,dbye,dciviello,dfirpo,dgivliani,dgosser,emcquiddy,enastasi,fcunard,gcubbison,gdaub,gdreitzler,ghanauer,gpomerance,gsusoev,gtinnel,gvollrath,gzuhlke,hgalavis,hhaffey,hhydrick,hmachesky,hpaek,hpolk,hsweezer,htomlinson,hzagami,igurwell,ihashbarger,jyeater,kbradbury,khathway,kklavetter,lbuchtel,lgandee,lkhubba,lmauracher,lseehafer,lvittum,mblanchet,mbodley,mciaccia,mjuris,ndipanfilo,nfilipek,nfunchess,ngata,ngullett,nkraker,nriofrio,nroepke,nrybij,oclunes,oebrani,okveton,osaines,otrevor,pdossous,phaye,psowa,purquilla,rkoonz,rlatessa,rworkowski,sdebry,sgurski,showe,slaforge,tabdelal,testusr2,testusr3,tfalconeri,tpaa,uschweyen,utrezize,vchevalier,vdelnegro,vleyton,vmedici,vmigliori,vpender,vwaltmann,wbrettschneide,wselim,wvalcin,wworf,yautin,ykisak,zgingrich,znightingale,zwinterbottom +EOM + +check "getent group largegroup | sortgroup" << EOM +largegroup:*:1005:akraskouskas,alat,ameisinger,bdevera,behrke,bmoldan,btempel,cjody,clouder,cmanno,dbye,dciviello,dfirpo,dgivliani,dgosser,emcquiddy,enastasi,fcunard,gcubbison,gdaub,gdreitzler,ghanauer,gpomerance,gsusoev,gtinnel,gvollrath,gzuhlke,hgalavis,hhaffey,hhydrick,hmachesky,hpaek,hpolk,hsweezer,htomlinson,hzagami,igurwell,ihashbarger,jyeater,kbradbury,khathway,kklavetter,lbuchtel,lgandee,lkhubba,lmauracher,lseehafer,lvittum,mblanchet,mbodley,mciaccia,mjuris,ndipanfilo,nfilipek,nfunchess,ngata,ngullett,nkraker,nriofrio,nroepke,nrybij,oclunes,oebrani,okveton,osaines,otrevor,pdossous,phaye,psowa,purquilla,rkoonz,rlatessa,rworkowski,sdebry,sgurski,showe,slaforge,tabdelal,testusr2,testusr3,tfalconeri,tpaa,uschweyen,utrezize,vchevalier,vdelnegro,vleyton,vmedici,vmigliori,vpender,vwaltmann,wbrettschneide,wselim,wvalcin,wworf,yautin,ykisak,zgingrich,znightingale,zwinterbottom +EOM + +check "getent group | grep ^hugegroup | sortgroup" << EOM +hugegroup:*:1006:ablackstock,abortignon,achhor,ademosthenes,adenicola,adishaw,aesbensen,aferge,afredin,afuchs,agarbett,agimm,agordner,ahandy,ajaquess,akertzman,akomsthoeft,akraskouskas,akravetz,alamour,alat,alienhard,amanganelli,amaslyn,amayorga,amccroskey,amcgraw,amckinney,ameisinger,aponcedeleon,apurdon,areid,arosel,ascheno,ascovel,asemons,ashuey,asivley,astrunk,atollefsrud,atonkin,awhitt,aziernicki,badair,baigner,bbeckfield,bbrenton,bcoletta,bcolorado,bdadds,bdaughenbaugh,bdevera,bdominga,behrke,beon,bfishbeck,bgavagan,bguthary,bharnois,bhelverson,bjolly,blovig,bluellen,bmadamba,bmarlin,bmarszalek,bmicklos,bmoling,bouten,bphou,bpinedo,brodgerson,broher,bromano,bscadden,bsibal,bstrede,bswantak,btempel,btheim,bveeneman,bwinterton,bwynes,cabare,carguellez,cbarlup,cbartnick,cbelardo,cbleimehl,cbotdorf,cbourek,cbrechbill,cbrom,ccyganiewicz,cdeckard,cdegravelle,cdickes,cdrumm,cfasone,cflenner,cfleurantin,cgaler,cgalinol,cgaudette,cghianni,charriman,cjody,cjuntunen,ckerska,ckistenmacher,cklem,ckodish,clapenta,clewicki,clouder,cmafnas,cmanno,cmcanulty,cmellberg,cmiramon,cnabzdyk,cnoriego,cpaccione,cpalmios,cparee,cpencil,cpentreath,cpinela,cpluid,critchie,cscullion,csever,csoomaroo,cspilis,cswigert,ctenny,ctetteh,ctuzzo,cwank,cweiss,dasiedu,daubert,dbarriball,dbertels,dblazejewski,dcaltabiano,dciullo,ddeguire,ddigerolamo,denriquez,deshmon,dfirpo,dflore,dfollman,dgiacomazzi,dgivliani,dgosser,dhammontree,dhendon,dhindsman,dholdaway,dlablue,dlanois,dlargo,dledenbach,dlongbotham,dloubier,dmahapatra,dmarchizano,dmcgillen,dminozzi,dnegri,dpebbles,draymundo,dscheurer,dsharr,dsherard,dsteever,dtashjian,dtornow,dtuholski,dwittlinger,dzurek,eaguire,eathey,ebattee,ebeachem,eberkman,ebusk,ecelestin,ecolden,ecordas,ediga,edrinkwater,edurick,egospatrick,egrago,ehathcock,ehindbaugh,ejeppesen,ekalfas,ekenady,ekeuper,eklein,eklunder,ekurter,emanikowski,emargulis,emcquiddy,emehta,eorsten,eparham,epeterson,epoinelli,erathert,erostad,eserrett,esheehan,esonia,esproull,esthill,estockwin,etunby,ewicks,ewilles,ewismer,ewuitschick,eyounglas,eziebert,fagro,faleo,farquette,fbeatrice,fberra,fberyman,fbielecki,fburrough,fcha,fcunard,ffigert,fgoben,fgrashot,fhain,fhalon,fkeef,fmarchi,fmilsaps,fnottage,fparness,fplayfair,fsapien,fsavela,fsirianni,fsplinter,fsunderland,fsymmonds,fthein,fvallian,fvascones,fverfaille,fvinal,fwidhalm,gallanson,gapkin,garchambeault,gbitar,gbolay,gcarlini,gcervantez,gchounlapane,gclapham,gcobane,gconver,gcukaj,gcummer,gcurnutt,gdaub,gdeblasio,gdeyarmond,gdrilling,gearnshaw,gfaire,gfedewa,ggehrke,ggillim,ghann,ghelderman,ghumbles,gishii,gjankowiak,gkerens,glafontaine,gloebs,gmackinder,gmassi,gmilian,gmings,gmoen,gparkersmith,gpomerance,gportolese,greiff,gsantella,gschaumburg,gshrode,gtinnel,guresti,gvollrath,gwaud,habby,hbastidos,hbetterman,hbickford,hbraim,hbrandow,hbrehmer,hbukovsky,hcafourek,hcarrizal,hchaviano,hcintron,hcowles,hcusta,hdoiel,hdyner,hfludd,hgalavis,hhaffey,hhagee,hhartranft,hholyfield,hhysong,hkarney,hkinderknecht,hkippes,hkohlmeyer,hlauchaire,hlemon,hlichota,hliverman,hloftis,hlynema,hmateer,hmatonak,hmiazga,hmogush,hmuscaro,hpalmquist,hpimpare,hpolintan,hrapisura,hrenart,hriech,hsabol,hschelb,hschoepfer,hspiry,hstreitnatter,hsweezer,htilzer,htomlinson,htsuha,hvannette,hveader,hwestermark,hwoodert,hzagami,hzinda,iambrosino,ibeto,ibreitbart,ibuzo,ibyles,ichewning,icoard,ideveyra,ienglert,igizzi,ihalford,ihanneman,ihegener,ihernan,iherrarte,ihimmelwright,ihoa,iiffert,ikadar,ikulbida,ilacourse,ilamberth,ilawbaugh,ileaman,ilevian,imarungo,imcbay,imensah,imicthell,imillin,imuehl,inarain,iogasawara,iroiger,iseipel,isowder,isplonskowski,istallcup,istarring,isteinlicht,ithum,ivanschaack,iweibe,iyorgey,iyorks,jamber,jappleyard,jbielicki,jbjorkman,jcaroll,jdodge,jeuresti,jeverton,jglotzbecker,jherkenratt,jholzmiller,jjumalon,jkimpton,jknight,jlebouf,jlunney,jmartha,jmarugg,jmatty,joligee,jquicksall,jrees,jreigh,jroman,jscheitlin,jseen,jsegundo,jsenavanh,jskafec,jspohn,jsweezy,jvillaire,jwinterton,jzych,kaanerud,kalguire,kbarnthouse,kbartolet,kbattershell,kbrevitz,kbrugal,kcofrancesco,kcomparoni,kconkey,kdevincent,kepps,kfaure,kfend,kgarced,kgremminger,khartness,kheadlon,khovanesian,kjoslyn,klitehiser,klundsten,klurie,kmallach,kmandolfo,kmarzili,kmayoras,kmcardle,kmcguire,kmedcaf,kmeester,kmisove,kmoesch,kmosko,kmuros,kolexa,kottomaniello,kpalka,kpannunzio,kpenale,kpuebla,krahman,kseisler,kshippy,ksiering,ksollitto,ksparling,kstachurski,kthede,ktoni,ktriblett,ktuccio,ktuner,kwidrick,kwinterling,kwirght,laksamit,lautovino,lbanco,lbassin,lbove,lbuchtel,lcanestrini,lcaudell,lcavez,lcocherell,lcoulon,lcremer,leberhardt,lfarraj,lfichtner,lgadomski,lgandee,lgradilla,lhuggler,limbrogno,ljomes,lkimel,llarmore,llasher,lmadruga,lmauracher,lmcgeary,lmichaud,lmuehlberger,lnormand,lparrish,lpeagler,lpintor,lpitek,lpondexter,lrandall,lringuette,lschenkelberg,lschnorbus,lschollmeier,lseabold,lseehafer,lshilling,lsivic,lsobrino,lsous,lspielvogel,lvaleriano,lvanconant,lwedner,lyoula,mallmand,maustine,mbeagley,mbodley,mbravata,mcampagnone,mcaram,mcashett,mcasida,mcoch,mcolehour,mcontreras,mdanos,mdecourcey,mdedon,mdickinson,mdimaio,mdoering,mdyce,meconomides,mespinel,mfaeth,mfeil,mferandez,mfitzherbert,mgavet,mgayden,mground,mheilbrun,mhollings,mjeon,mkibler,mkofoed,mlaverde,mlenning,mlinak,mlinardi,mmangiamele,mmattu,mmcchristian,mmerriwether,mmesidor,mneubacher,moller,moser,mpanahon,mpark,mpellew,mpilon,mpizzaro,mpytko,mquigg,mredd,mrizer,mruppel,mrydelek,mskeele,mstirn,mswogger,mtanzi,mtintle,mvanbergen,mvanpelt,mvas,mvedder,mviverette,myokoyama,nagerton,nasmar,nbuford,nbugtong,ncermeno,nchrisman,nciucci,ndesautels,ndrumgole,nedgin,nendicott,nerbach,nevan,nforti,nfunchess,ngiesler,nglathar,ngrowney,ngullett,nhayer,nhelfinstine,nhija,ninnella,njordon,nkempon,nkubley,nlainhart,nlatchaw,nlemma,nlinarez,nlohmiller,nmccolm,nmoren,nnamanworth,nnickel,nousdahl,nphan,nramones,nranck,nridinger,nriofrio,nrybij,nrysavy,nschmig,nsiemonsma,nslaby,nspolar,nvyhnal,nwescott,nwiker,oahyou,oalthouse,obeaufait,obenallack,obercier,obihl,ocalleo,ochasten,oclunes,oconerly,ocrabbs,oebrani,ofelcher,ohatto,ohearl,ohedlund,ohoffert,ohove,ojerabek,okave,okveton,omalvaez,omasone,omatula,omcdaid,oolivarez,oosterhouse,opeet,opizzuti,opoch,oport,opuglisi,oreiss,osaber,oscarpello,oshough,ovibbert,owhelchel,owhitelow,pahles,pbascom,pbeckerdite,pbiggart,pbondroff,pbrentano,pcaposole,pcornn,pdauterman,pdech,pdischinger,pduitscher,pdulac,pdurando,pfavolise,pgiegerich,pgreenier,pgrybel,phalkett,pheathcock,phyer,pmineo,pminnis,ppedraja,ppeper,pphuaphes,prepasky,prowena,psabado,psalesky,pschrayter,psharits,psiroky,psundeen,pthornberry,ptoenjes,ptraweek,purquilla,pvierthaler,pvirelli,pviviani,pwademan,pwashuk,pwetherwax,pwhitmire,pwohlenhaus,pwutzke,qhanly,ralspach,rbernhagen,rbillingsly,rbloomstrand,rbrisby,rcheshier,rchevrette,rdubs,rdubuisson,redling,rfassinger,rfauerbach,rfidel,rginer,rgoonez,rgramby,rgriffies,rguinane,rheinzmann,rkraszewski,rlambertus,rlatessa,rlosinger,rmandril,rmcstay,rnordby,rpastorin,rpikes,rpinilla,rpitter,rramirez,rrasual,rschkade,rtole,rtooker,saben,sackles,sarndt,saycock,sbemo,sbettridge,sbloise,sbonnie,sbrabyn,scocuzza,sdebry,senrico,sestergard,sgefroh,sgirsh,sgropper,sgunder,sgurski,shaith,sherzberg,showe,sjankauskas,skanjirathinga,skoegler,slaningham,slaudeman,slerew,smccaie,smillian,smullowney,snotari,spolmer,srees,srubenfield,sscheiern,sskone,sskyers,sspagnuolo,sstough,sstuemke,svandewalle,svielle,svogler,svongal,swoodie,tabdelal,tairth,tbagne,tbattista,tboxx,tcacal,tcossa,tcrissinger,tdonathan,teliades,tfalconeri,tfetherston,tgelen,tgindhart,tguinnip,tharr,thelfritz,thoch,thynson,tkeala,tkelly,tkhora,tlana,tlowers,tmalecki,tmarkus,tmccaffity,tmccamish,tmcmickle,tmelland,tmorr,tmurata,tmysinger,tnaillon,tnitzel,tpaa,tplatko,tredfearn,tsablea,tsann,tschnepel,tsearle,tsepulueda,tsowells,tstalworth,tvehrs,tvrooman,tyounglas,ualway,uazatyan,ubenken,ubieniek,ubynum,udatu,uednilao,ueriks,uflander,ugerpheide,ugreenberg,uhayakawa,uholecek,ulanigan,umarbury,umosser,upater,upellam,uransford,urosentrance,uschweyen,usevera,uslavinski,uspittler,uvanmatre,uwalpole,uweyand,vbaldasaro,vbigalow,vbonder,vburton,vchevalier,vcrofton,vdesir,vdolan,veisenhardt,vemily,venfort,vfeigel,vglidden,vkrug,vlubic,vmaynard,vmedici,vnazzal,vnery,vpeairs,vpender,vpiraino,vrodick,vrunyon,vsefcovic,vstirman,vtowell,vtresch,vtrumpp,vwabasha,vwaltmann,vwisinger,vwokwicz,wbrill,wclokecloak,wconces,wconstantino,wcreggett,wdagrella,wdevenish,wdovey,wenglander,werrick,wesguerra,wganther,wkhazaleh,wleiva,wlynch,wmailey,wmendell,wnunziata,wottesen,wselim,wstjean,wtruman,wvalcin,wvermeulen,xeppley,xlantey,xrahaim,yautin,ycerasoli,ycobetto,ycostaneda,yduft,yeven,yfrymoyer,ygockel,yhenriques,ykimbel,yolivier,yschmuff,ysnock,yvdberg,zanderlik,zborgmeyer,zbuscaglia,zculp,zfarler,zhaulk,zkutchera,zmeeker,zneeb,zratti,zscammahorn,zvagt,zwinterbottom +EOM + +check "getent group hugegroup | sortgroup" << EOM +hugegroup:*:1006:ablackstock,abortignon,achhor,ademosthenes,adenicola,adishaw,aesbensen,aferge,afredin,afuchs,agarbett,agimm,agordner,ahandy,ajaquess,akertzman,akomsthoeft,akraskouskas,akravetz,alamour,alat,alienhard,amanganelli,amaslyn,amayorga,amccroskey,amcgraw,amckinney,ameisinger,aponcedeleon,apurdon,areid,arosel,ascheno,ascovel,asemons,ashuey,asivley,astrunk,atollefsrud,atonkin,awhitt,aziernicki,badair,baigner,bbeckfield,bbrenton,bcoletta,bcolorado,bdadds,bdaughenbaugh,bdevera,bdominga,behrke,beon,bfishbeck,bgavagan,bguthary,bharnois,bhelverson,bjolly,blovig,bluellen,bmadamba,bmarlin,bmarszalek,bmicklos,bmoling,bouten,bphou,bpinedo,brodgerson,broher,bromano,bscadden,bsibal,bstrede,bswantak,btempel,btheim,bveeneman,bwinterton,bwynes,cabare,carguellez,cbarlup,cbartnick,cbelardo,cbleimehl,cbotdorf,cbourek,cbrechbill,cbrom,ccyganiewicz,cdeckard,cdegravelle,cdickes,cdrumm,cfasone,cflenner,cfleurantin,cgaler,cgalinol,cgaudette,cghianni,charriman,cjody,cjuntunen,ckerska,ckistenmacher,cklem,ckodish,clapenta,clewicki,clouder,cmafnas,cmanno,cmcanulty,cmellberg,cmiramon,cnabzdyk,cnoriego,cpaccione,cpalmios,cparee,cpencil,cpentreath,cpinela,cpluid,critchie,cscullion,csever,csoomaroo,cspilis,cswigert,ctenny,ctetteh,ctuzzo,cwank,cweiss,dasiedu,daubert,dbarriball,dbertels,dblazejewski,dcaltabiano,dciullo,ddeguire,ddigerolamo,denriquez,deshmon,dfirpo,dflore,dfollman,dgiacomazzi,dgivliani,dgosser,dhammontree,dhendon,dhindsman,dholdaway,dlablue,dlanois,dlargo,dledenbach,dlongbotham,dloubier,dmahapatra,dmarchizano,dmcgillen,dminozzi,dnegri,dpebbles,draymundo,dscheurer,dsharr,dsherard,dsteever,dtashjian,dtornow,dtuholski,dwittlinger,dzurek,eaguire,eathey,ebattee,ebeachem,eberkman,ebusk,ecelestin,ecolden,ecordas,ediga,edrinkwater,edurick,egospatrick,egrago,ehathcock,ehindbaugh,ejeppesen,ekalfas,ekenady,ekeuper,eklein,eklunder,ekurter,emanikowski,emargulis,emcquiddy,emehta,eorsten,eparham,epeterson,epoinelli,erathert,erostad,eserrett,esheehan,esonia,esproull,esthill,estockwin,etunby,ewicks,ewilles,ewismer,ewuitschick,eyounglas,eziebert,fagro,faleo,farquette,fbeatrice,fberra,fberyman,fbielecki,fburrough,fcha,fcunard,ffigert,fgoben,fgrashot,fhain,fhalon,fkeef,fmarchi,fmilsaps,fnottage,fparness,fplayfair,fsapien,fsavela,fsirianni,fsplinter,fsunderland,fsymmonds,fthein,fvallian,fvascones,fverfaille,fvinal,fwidhalm,gallanson,gapkin,garchambeault,gbitar,gbolay,gcarlini,gcervantez,gchounlapane,gclapham,gcobane,gconver,gcukaj,gcummer,gcurnutt,gdaub,gdeblasio,gdeyarmond,gdrilling,gearnshaw,gfaire,gfedewa,ggehrke,ggillim,ghann,ghelderman,ghumbles,gishii,gjankowiak,gkerens,glafontaine,gloebs,gmackinder,gmassi,gmilian,gmings,gmoen,gparkersmith,gpomerance,gportolese,greiff,gsantella,gschaumburg,gshrode,gtinnel,guresti,gvollrath,gwaud,habby,hbastidos,hbetterman,hbickford,hbraim,hbrandow,hbrehmer,hbukovsky,hcafourek,hcarrizal,hchaviano,hcintron,hcowles,hcusta,hdoiel,hdyner,hfludd,hgalavis,hhaffey,hhagee,hhartranft,hholyfield,hhysong,hkarney,hkinderknecht,hkippes,hkohlmeyer,hlauchaire,hlemon,hlichota,hliverman,hloftis,hlynema,hmateer,hmatonak,hmiazga,hmogush,hmuscaro,hpalmquist,hpimpare,hpolintan,hrapisura,hrenart,hriech,hsabol,hschelb,hschoepfer,hspiry,hstreitnatter,hsweezer,htilzer,htomlinson,htsuha,hvannette,hveader,hwestermark,hwoodert,hzagami,hzinda,iambrosino,ibeto,ibreitbart,ibuzo,ibyles,ichewning,icoard,ideveyra,ienglert,igizzi,ihalford,ihanneman,ihegener,ihernan,iherrarte,ihimmelwright,ihoa,iiffert,ikadar,ikulbida,ilacourse,ilamberth,ilawbaugh,ileaman,ilevian,imarungo,imcbay,imensah,imicthell,imillin,imuehl,inarain,iogasawara,iroiger,iseipel,isowder,isplonskowski,istallcup,istarring,isteinlicht,ithum,ivanschaack,iweibe,iyorgey,iyorks,jamber,jappleyard,jbielicki,jbjorkman,jcaroll,jdodge,jeuresti,jeverton,jglotzbecker,jherkenratt,jholzmiller,jjumalon,jkimpton,jknight,jlebouf,jlunney,jmartha,jmarugg,jmatty,joligee,jquicksall,jrees,jreigh,jroman,jscheitlin,jseen,jsegundo,jsenavanh,jskafec,jspohn,jsweezy,jvillaire,jwinterton,jzych,kaanerud,kalguire,kbarnthouse,kbartolet,kbattershell,kbrevitz,kbrugal,kcofrancesco,kcomparoni,kconkey,kdevincent,kepps,kfaure,kfend,kgarced,kgremminger,khartness,kheadlon,khovanesian,kjoslyn,klitehiser,klundsten,klurie,kmallach,kmandolfo,kmarzili,kmayoras,kmcardle,kmcguire,kmedcaf,kmeester,kmisove,kmoesch,kmosko,kmuros,kolexa,kottomaniello,kpalka,kpannunzio,kpenale,kpuebla,krahman,kseisler,kshippy,ksiering,ksollitto,ksparling,kstachurski,kthede,ktoni,ktriblett,ktuccio,ktuner,kwidrick,kwinterling,kwirght,laksamit,lautovino,lbanco,lbassin,lbove,lbuchtel,lcanestrini,lcaudell,lcavez,lcocherell,lcoulon,lcremer,leberhardt,lfarraj,lfichtner,lgadomski,lgandee,lgradilla,lhuggler,limbrogno,ljomes,lkimel,llarmore,llasher,lmadruga,lmauracher,lmcgeary,lmichaud,lmuehlberger,lnormand,lparrish,lpeagler,lpintor,lpitek,lpondexter,lrandall,lringuette,lschenkelberg,lschnorbus,lschollmeier,lseabold,lseehafer,lshilling,lsivic,lsobrino,lsous,lspielvogel,lvaleriano,lvanconant,lwedner,lyoula,mallmand,maustine,mbeagley,mbodley,mbravata,mcampagnone,mcaram,mcashett,mcasida,mcoch,mcolehour,mcontreras,mdanos,mdecourcey,mdedon,mdickinson,mdimaio,mdoering,mdyce,meconomides,mespinel,mfaeth,mfeil,mferandez,mfitzherbert,mgavet,mgayden,mground,mheilbrun,mhollings,mjeon,mkibler,mkofoed,mlaverde,mlenning,mlinak,mlinardi,mmangiamele,mmattu,mmcchristian,mmerriwether,mmesidor,mneubacher,moller,moser,mpanahon,mpark,mpellew,mpilon,mpizzaro,mpytko,mquigg,mredd,mrizer,mruppel,mrydelek,mskeele,mstirn,mswogger,mtanzi,mtintle,mvanbergen,mvanpelt,mvas,mvedder,mviverette,myokoyama,nagerton,nasmar,nbuford,nbugtong,ncermeno,nchrisman,nciucci,ndesautels,ndrumgole,nedgin,nendicott,nerbach,nevan,nforti,nfunchess,ngiesler,nglathar,ngrowney,ngullett,nhayer,nhelfinstine,nhija,ninnella,njordon,nkempon,nkubley,nlainhart,nlatchaw,nlemma,nlinarez,nlohmiller,nmccolm,nmoren,nnamanworth,nnickel,nousdahl,nphan,nramones,nranck,nridinger,nriofrio,nrybij,nrysavy,nschmig,nsiemonsma,nslaby,nspolar,nvyhnal,nwescott,nwiker,oahyou,oalthouse,obeaufait,obenallack,obercier,obihl,ocalleo,ochasten,oclunes,oconerly,ocrabbs,oebrani,ofelcher,ohatto,ohearl,ohedlund,ohoffert,ohove,ojerabek,okave,okveton,omalvaez,omasone,omatula,omcdaid,oolivarez,oosterhouse,opeet,opizzuti,opoch,oport,opuglisi,oreiss,osaber,oscarpello,oshough,ovibbert,owhelchel,owhitelow,pahles,pbascom,pbeckerdite,pbiggart,pbondroff,pbrentano,pcaposole,pcornn,pdauterman,pdech,pdischinger,pduitscher,pdulac,pdurando,pfavolise,pgiegerich,pgreenier,pgrybel,phalkett,pheathcock,phyer,pmineo,pminnis,ppedraja,ppeper,pphuaphes,prepasky,prowena,psabado,psalesky,pschrayter,psharits,psiroky,psundeen,pthornberry,ptoenjes,ptraweek,purquilla,pvierthaler,pvirelli,pviviani,pwademan,pwashuk,pwetherwax,pwhitmire,pwohlenhaus,pwutzke,qhanly,ralspach,rbernhagen,rbillingsly,rbloomstrand,rbrisby,rcheshier,rchevrette,rdubs,rdubuisson,redling,rfassinger,rfauerbach,rfidel,rginer,rgoonez,rgramby,rgriffies,rguinane,rheinzmann,rkraszewski,rlambertus,rlatessa,rlosinger,rmandril,rmcstay,rnordby,rpastorin,rpikes,rpinilla,rpitter,rramirez,rrasual,rschkade,rtole,rtooker,saben,sackles,sarndt,saycock,sbemo,sbettridge,sbloise,sbonnie,sbrabyn,scocuzza,sdebry,senrico,sestergard,sgefroh,sgirsh,sgropper,sgunder,sgurski,shaith,sherzberg,showe,sjankauskas,skanjirathinga,skoegler,slaningham,slaudeman,slerew,smccaie,smillian,smullowney,snotari,spolmer,srees,srubenfield,sscheiern,sskone,sskyers,sspagnuolo,sstough,sstuemke,svandewalle,svielle,svogler,svongal,swoodie,tabdelal,tairth,tbagne,tbattista,tboxx,tcacal,tcossa,tcrissinger,tdonathan,teliades,tfalconeri,tfetherston,tgelen,tgindhart,tguinnip,tharr,thelfritz,thoch,thynson,tkeala,tkelly,tkhora,tlana,tlowers,tmalecki,tmarkus,tmccaffity,tmccamish,tmcmickle,tmelland,tmorr,tmurata,tmysinger,tnaillon,tnitzel,tpaa,tplatko,tredfearn,tsablea,tsann,tschnepel,tsearle,tsepulueda,tsowells,tstalworth,tvehrs,tvrooman,tyounglas,ualway,uazatyan,ubenken,ubieniek,ubynum,udatu,uednilao,ueriks,uflander,ugerpheide,ugreenberg,uhayakawa,uholecek,ulanigan,umarbury,umosser,upater,upellam,uransford,urosentrance,uschweyen,usevera,uslavinski,uspittler,uvanmatre,uwalpole,uweyand,vbaldasaro,vbigalow,vbonder,vburton,vchevalier,vcrofton,vdesir,vdolan,veisenhardt,vemily,venfort,vfeigel,vglidden,vkrug,vlubic,vmaynard,vmedici,vnazzal,vnery,vpeairs,vpender,vpiraino,vrodick,vrunyon,vsefcovic,vstirman,vtowell,vtresch,vtrumpp,vwabasha,vwaltmann,vwisinger,vwokwicz,wbrill,wclokecloak,wconces,wconstantino,wcreggett,wdagrella,wdevenish,wdovey,wenglander,werrick,wesguerra,wganther,wkhazaleh,wleiva,wlynch,wmailey,wmendell,wnunziata,wottesen,wselim,wstjean,wtruman,wvalcin,wvermeulen,xeppley,xlantey,xrahaim,yautin,ycerasoli,ycobetto,ycostaneda,yduft,yeven,yfrymoyer,ygockel,yhenriques,ykimbel,yolivier,yschmuff,ysnock,yvdberg,zanderlik,zborgmeyer,zbuscaglia,zculp,zfarler,zhaulk,zkutchera,zmeeker,zneeb,zratti,zscammahorn,zvagt,zwinterbottom +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing hosts..." + +check "getent hosts testhost" << EOM +10.0.0.1 testhost testhostalias +EOM + +check "getent hosts testhostalias" << EOM +10.0.0.1 testhost testhostalias +EOM + +# check hostname with different case +check "getent hosts TESTHOST" << EOM +10.0.0.1 testhost testhostalias +EOM + +check "getent hosts 10.0.0.1" << EOM +10.0.0.1 testhost testhostalias +EOM + +check "getent hosts | grep testhost" << EOM +10.0.0.1 testhost testhostalias +EOM + +# TODO: add more tests for IPv6 support + +########################################################################### + +echo "test_nsscmds.sh: testing netgroup..." + +# check netgroup lookup of test netgroup +check "getent netgroup tstnetgroup" << EOM +tstnetgroup ( , arthur, ) (noot, , ) +EOM + +# check netgroup lookup with different case +# Note: this should return nothing at all (this is a bug) +check "getent netgroup TSTNETGROUP" << EOM +TSTNETGROUP +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing networks..." + +check "getent networks testnet" << EOM +testnet 10.0.0.0 +EOM + +# check network name with different case +check "getent networks TESTNET" << EOM +testnet 10.0.0.0 +EOM + +check "getent networks 10.0.0.0" << EOM +testnet 10.0.0.0 +EOM + +check "getent networks | grep testnet" << EOM +testnet 10.0.0.0 +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing passwd..." + +check "getent passwd ecolden" << EOM +ecolden:x:5972:1000:Estelle Colden:/home/ecolden:/bin/bash +EOM + +check "getent passwd arthur" << EOM +arthur:x:1000:100:Arthur de Jong:/home/arthur:/bin/bash +EOM + +# check username with different case +check "getent passwd ARTHUR" << EOM +EOM + +check "getent passwd 4089" << EOM +jguzzetta:x:4089:1000:Josephine Guzzetta:/home/jguzzetta:/bin/bash +EOM + +# count the number of passwd entries in the 4000-5999 range +check "getent passwd | grep -c ':x:[45][0-9][0-9][0-9]:'" << EOM +2000 +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing protocols..." + +check "getent protocols protfoo" << EOM +protfoo 253 protfooalias +EOM + +check "getent protocols protfooalias" << EOM +protfoo 253 protfooalias +EOM + +# check protocol with different case +check "getent protocols PROTFOO" << EOM +EOM + +# test protocol alias with different case +check "getent protocols PROTFOOALIAS" << EOM +EOM + +check "getent protocols 253" << EOM +protfoo 253 protfooalias +EOM + +check "getent protocols icmp" << EOM +icmp 1 ICMP +EOM + +check "getent protocols | grep protfoo" << EOM +protfoo 253 protfooalias +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing rpc..." + +check "getent rpc rpcfoo" << EOM +rpcfoo 160002 rpcfooalias +EOM + +check "getent rpc rpcfooalias" << EOM +rpcfoo 160002 rpcfooalias +EOM + +# test rpc name with different case +check "getent rpc RPCFOO" << EOM +EOM + +check "getent rpc 160002" << EOM +rpcfoo 160002 rpcfooalias +EOM + +check "getent rpc | grep rpcfoo" << EOM +rpcfoo 160002 rpcfooalias +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing services..." + +check "getent services foosrv" << EOM +foosrv 15349/tcp +EOM + +check "getent services foosrv/tcp" << EOM +foosrv 15349/tcp +EOM + +check "getent services foosrv/udp" << EOM +EOM + +# check with different case +check "getent services FOOSRV" << EOM +EOM + +# check protocol name case sensitivity (TCP is commonly an alias) +check "getent services foosrv/tCp" << EOM +EOM + +check "getent services 15349/tcp" << EOM +foosrv 15349/tcp +EOM + +check "getent services 15349/udp" << EOM +EOM + +check "getent services barsrv" << EOM +barsrv 15350/tcp +EOM + +check "getent services barsrv/tcp" << EOM +barsrv 15350/tcp +EOM + +check "getent services barsrv/udp" << EOM +barsrv 15350/udp +EOM + +check "getent services | egrep '(foo|bar)srv' | sort" << EOM +barsrv 15350/tcp +barsrv 15350/udp +foosrv 15349/tcp +EOM + +check "getent services sssin" << EOM +sssin 5000/tcp SSSIN +EOM + +check "getent services SSSIN" << EOM +sssin 5000/tcp SSSIN +EOM + +check "getent services | wc -l" << EOM +`grep -c '^[^#].' /etc/services | awk '{print $1 + 4}'` +EOM + +########################################################################### + +echo "test_nsscmds.sh: testing shadow..." + +# NOTE: the output of this should depend on whether we are root or not + +check "getent shadow ecordas" << EOM +ecordas:*::::7:2::0 +EOM + +check "getent shadow adishaw" << EOM +adishaw:*:12302:::7:2::0 +EOM + +# check case-sensitivity +check "getent shadow ADISHAW" << EOM +EOM + +# check if the number of passwd entries matches the number of shadow entries +check "getent shadow | wc -l" << EOM +`getent passwd | wc -l` +EOM + +# check if the names of users match between passwd and shadow +getent passwd | sed 's/:.*//' | sort | \ + check "getent shadow | sed 's/:.*//' | sort" + +########################################################################### +# determine the result + +if [ $FAIL -eq 0 ] +then + echo "test_nsscmds.sh: all tests passed" + exit 0 +else + echo "test_nsscmds.sh: $FAIL TESTS FAILED" + exit 1 +fi diff --git a/tests/test_pamcmds.expect b/tests/test_pamcmds.expect new file mode 100644 index 0000000..f897e16 --- /dev/null +++ b/tests/test_pamcmds.expect @@ -0,0 +1,204 @@ +#!/usr/bin/expect -- + +# test_pamcmds.expect - test script to check output of PAM commands +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +# basic configuration +set timeout 5 +log_file -a -noappend test_pamcmds.log +log_user 0 + +# basic error handling +proc abort {} { + global expect_out + send_user "\n\ntest_pamcmds.expect: ERROR found:\n" + send_user "$expect_out(buffer)\n" + exit 1 +} + +# function for resetting the password +proc reset_password {} { + global expect_out + send_user "test_pamcmds.expect: resetting passwd...\n" + spawn passwd arthur + expect { + "LDAP administrator password" { send "test\r"; exp_continue } + -regexp "(New|Retype new) password:" { send "test\r"; exp_continue } + "password updated successfully" {} + "Invalid credentials" abort + "Authentication token manipulation error" abort + default abort + } + #close +} + +# find source directory +if { ! [info exists ::env(srcdir) ] } { + set env(srcdir) "." +} +# ensure that we are running as root +if { [exec id -u] != "0" } { + send_user "test_pamcmds.expect: not running as root\n" + exit 77 +} +# ensure that we are running in the test environment +spawn $env(srcdir)/in_testenv.sh +expect { + "in_testenv.sh: using LDAP server" { expect eof } + eof { + send_user "test_pamcmds.expect: not running in test environment\n" + exit 77 + } +} + +# ensure that a correct password is set +reset_password + +# start a shell as nobody +send_user "test_pamcmds.expect: start shell...\n" +spawn su - nobody -s /bin/sh +expect "\$ " + +# function to do login, expecting OK result +proc test_login_ok {uid passwd} { + send "su - $uid -s /bin/sh\r" + expect "Password:" + send "$passwd\r" + expect { + "\$ " {} + "su: " abort + default abort + } + # test whether we are really logged in + send "id\r" + expect { + -regexp "uid=\[0-9\]*\\($uid\\)" {} + "\$ " abort + default abort + } + expect "\$ " +} + +# function to do login, expecting FAIL result +proc test_login_authfail {uid passwd} { + send "su - $uid -s /bin/sh\r" + expect "Password:" + send "$passwd\r" + expect { + "su: Authentication failure" {} + "\$ " abort + default abort + } + expect "\$ " +} + +# function to do login, expecting FAIL result +proc test_login_unknown {uid passwd} { + send "su - $uid -s /bin/sh\r" + expect { + "Password:" { send "$passwd\r"; exp_continue } + "Unknown id" {} + "\$ " abort + default abort + } + expect "\$ " +} + +# test incorrect password +send_user "test_pamcmds.expect: testing incorrect password...\n" +test_login_authfail arthur wrongpassword + +# test correct password +send_user "test_pamcmds.expect: testing correct password...\n" +test_login_ok arthur test + +# change password using incorrect old password +send_user "test_pamcmds.expect: testing password change with incorrect password...\n" +send "passwd\r" +expect { + -nocase "password:" { send "wrongpassword\r" } + "\$ " abort + default abort +} +expect { + -regexp "(New|Retype new) password:" { send "newpassword\r"; exp_continue } + "password changed" abort + "Invalid credentials" {} + "Authentication token manipulation error" {} + "\$ " abort +} +expect "\$ " + +# change the password using the correct old password +send_user "test_pamcmds.expect: testing password change with correct password...\n" +send "passwd\r" +expect { + -nocase "password:" { send "test\r" } + "\$ " abort + default abort +} +expect { + -regexp "(New|Retype new) password:" { send "newpassword\r"; exp_continue } + "password updated successfully" {} + "Invalid credentials" abort + "Authentication token manipulation error" abort + "\$ " abort +} +expect "\$ " + +# exist shell (back to nobody) +send "exit\r" +expect "\$ " + +# logging in with the old password should fail now +send_user "test_pamcmds.expect: testing old password...\n" +test_login_authfail arthur test + +# test correct password +send_user "test_pamcmds.expect: testing new password...\n" +test_login_ok arthur newpassword + +# test invalid username +send_user "test_pamcmds.expect: testing with unknown username...\n" +test_login_unknown foo anypassword + +# test login as root with incorrect password +send_user "test_pamcmds.expect: testing with root...\n" +test_login_authfail root anypassword + +# test login as nobody with incorrect password +send_user "test_pamcmds.expect: testing with nobody...\n" +test_login_authfail nobody anypassword + +# close the shell (first log of arthur) +send "exit\r" +expect "\$ " +send "exit\r" +expect { + eof {} + "\$ " abort + timeout abort +} + +# ensure that a correct password is set +reset_password + +send_user "test_pamcmds.expect: everyting OK\n" + +exit 0 diff --git a/tests/test_pamcmds.sh b/tests/test_pamcmds.sh new file mode 100755 index 0000000..798cafd --- /dev/null +++ b/tests/test_pamcmds.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# test_pamcmds.sh - test script to start test_pamcmds.expect +# +# Copyright (C) 2011 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +set -e + +# find source directory +srcdir="${srcdir-`dirname "$0"`}" + +# ensure that we are running in the test environment +. "$srcdir/in_testenv.sh" + +# check if we have expect installed +EXPECT="$(which expect 2> /dev/null || true)" +if ! [ -x "$EXPECT" ] +then + echo "$0: expect not found, not running tests" + exit 77 +fi + +export srcdir +"$EXPECT" "$srcdir/test_pamcmds.expect" diff --git a/tests/test_set.c b/tests/test_set.c new file mode 100644 index 0000000..6f72b4d --- /dev/null +++ b/tests/test_set.c @@ -0,0 +1,82 @@ +/* + test_set.c - simple test for the set module + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2008, 2009, 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include + +#include "common/set.h" +#include "compat/attrs.h" + +static int isknownvalue(const char *value) +{ + return value!=NULL && ( + (strcmp(value,"key1")==0) || + (strcmp(value,"key2")==0) || + (strcmp(value,"key3")==0) ); +} + +/* the main program... */ +int main(int UNUSED(argc),char UNUSED(*argv[])) +{ + SET *set; + const char **list; + int i; + + /* initialize */ + set=set_new(); + + /* store some entries */ + set_add(set,"key1"); + set_add(set,"key2"); + set_add(set,"key3"); + set_add(set,"key2"); + + /* check set contents */ + assert(set_contains(set,"key1")); + assert(set_contains(set,"key2")); + assert(set_contains(set,"key3")); + assert(!set_contains(set,"key4")); + assert(!set_contains(set,"KEY1")); + + /* loop over set contents */ + list=set_tolist(set); + for (i=0;list[i]!=NULL;i++) + { + assert(isknownvalue(list[i])); + } + + /* remove keys from the set */ + assert(isknownvalue(set_pop(set))); + assert(isknownvalue(set_pop(set))); + assert(isknownvalue(set_pop(set))); + assert(set_pop(set)==NULL); + + /* free set */ + set_free(set); + free(list); + + return 0; +} diff --git a/tests/test_tio.c b/tests/test_tio.c new file mode 100644 index 0000000..b71fb7b --- /dev/null +++ b/tests/test_tio.c @@ -0,0 +1,358 @@ +/* + test_tio.c - simple test for the tio module + This file is part of the nss-pam-ldapd library. + + Copyright (C) 2007, 2008, 2011 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif /* HAVE_STDINT_H */ +#include +#include +#include +#include + +#include "common.h" + +#include "common/tio.h" + +/* structure for passing arguments to helper (is a thread) */ +struct helper_args { + int fd; + size_t blocksize; + size_t blocks; + int timeout; +}; + +static void *help_tiowriter(void *arg) +{ + TFILE *fp; + struct timeval timeout; + size_t i,j,k; + uint8_t *buf; + struct helper_args *hargs=(struct helper_args *)arg; + /* allocate the buffer */ + buf=(uint8_t *)malloc(hargs->blocksize); + assert(buf!=NULL); + /* set the timeout */ + timeout.tv_sec=hargs->timeout; + timeout.tv_usec=0; + /* open the file */ + fp=tio_fdopen(hargs->fd,&timeout,&timeout,4*1024,8*1024,4*1024,8*1024); + assertok(fp!=NULL); + /* write the blocks */ + i=0; + for (k=0;kblocks;k++) + { + /* fill the buffer */ + for (j=0;jblocksize;j++) + buf[j]=i++; + assertok(tio_write(fp,buf,hargs->blocksize)==0); + } + /* close the file flushing the buffer */ + assertok(tio_close(fp)==0); + /* we're done */ + free(buf); + return NULL; +} + +static void *help_tioreader(void *arg) +{ + TFILE *fp; + struct timeval timeout; + size_t i,j,k; + uint8_t *buf; + struct helper_args *hargs=(struct helper_args *)arg; + /* allocate the buffer */ + buf=(uint8_t *)malloc(hargs->blocksize); + assert(buf!=NULL); + /* set the timeout */ + timeout.tv_sec=hargs->timeout; + timeout.tv_usec=0; + /* open the file */ + fp=tio_fdopen(hargs->fd,&timeout,&timeout,4*1024,8*1024,4*1024,8*1024); + assertok(fp!=NULL); + /* read the blocks */ + i=0; + for (k=0;kblocks;k++) + { + assertok(tio_read(fp,buf,hargs->blocksize)==0); + /* check the buffer */ + for (j=0;jblocksize;j++) + assert(buf[j]==(uint8_t)(i++)); + } + /* close the file */ + assertok(tio_close(fp)==0); + /* we're done */ + free(buf); + return NULL; +} + +static void *help_normwriter(void *arg) +{ + FILE *fp; + size_t i,j,k; + uint8_t *buf; + struct helper_args *hargs=(struct helper_args *)arg; + /* allocate the buffer */ + buf=(uint8_t *)malloc(hargs->blocksize); + assert(buf!=NULL); + /* open the file */ + fp=fdopen(hargs->fd,"wb"); + assertok(fp!=NULL); + /* write the blocks */ + i=0; + for (k=0;kblocks;k++) + { + /* fill the buffer */ + for (j=0;jblocksize;j++) + buf[j]=i++; + assertok(fwrite(buf,hargs->blocksize,1,fp)==1); + } + /* close the file flushing the buffer */ + assertok(fclose(fp)==0); + /* we're done */ + free(buf); + return NULL; +} + +static void *help_normreader(void *arg) +{ + FILE *fp; + size_t i,j,k; + struct helper_args *hargs=(struct helper_args *)arg; + /* open the file */ + fp=fdopen(hargs->fd,"rb"); + assertok(fp!=NULL); + /* read the blocks */ + i=0; + for (k=0;kblocks;k++) + { + /* check the buffer */ + for (j=0;jblocksize;j++) + assertok(fgetc(fp)==(uint8_t)(i++)); + } + /* close the file */ + assertok(fclose(fp)==0); + return NULL; +} + +/* +TODO: test timeout +TODO: test whether a simple request/response works +*/ + +static int test_blocks(size_t wbs, size_t wbl, size_t rbs, size_t rbl) +{ + int sp[2]; + pthread_t wthread, rthread; + struct helper_args wargs,rargs; + /* set up the socket pair */ + assertok(socketpair(AF_UNIX,SOCK_STREAM,0,sp)==0); + /* log */ + printf("test_tio: writing %d blocks of %d bytes (%d total)\n",(int)wbl,(int)wbs,(int)(wbl*wbs)); + printf("test_tio: reading %d blocks of %d bytes (%d total)\n",(int)rbl,(int)rbs,(int)(rbl*rbs)); + /* start the writer thread */ + wargs.fd=sp[0]; + wargs.blocksize=wbs; + wargs.blocks=wbl; + wargs.timeout=2; + assertok(pthread_create(&wthread,NULL,help_tiowriter,&wargs)==0); +/* sleep(1); */ + /* start the reader thread */ + rargs.fd=sp[1]; + rargs.blocksize=rbs; + rargs.blocks=rbl; + rargs.timeout=2; + assertok(pthread_create(&rthread,NULL,help_tioreader,&rargs)==0); + /* wait for all threads to die */ + assertok(pthread_join(wthread,NULL)==0); + assertok(pthread_join(rthread,NULL)==0); + /* we're done */ + return 0; +} + +static void test_reset(void) +{ + int sp[2]; + pthread_t wthread; + struct helper_args wargs; + TFILE *fp; + struct timeval timeout; + size_t i,j,k,save; + uint8_t buf[20]; + /* set up the socket pair */ + assertok(socketpair(AF_UNIX,SOCK_STREAM,0,sp)==0); + /* start the writer thread */ + wargs.fd=sp[0]; + wargs.blocksize=4*1024; + wargs.blocks=10; + wargs.timeout=2; + assertok(pthread_create(&wthread,NULL,help_normwriter,&wargs)==0); + /* set up read handle */ + timeout.tv_sec=2; + timeout.tv_usec=0; + fp=tio_fdopen(sp[1],&timeout,&timeout,2*1024,4*1024,2*1024,4*1024); + assertok(fp!=NULL); + /* perform 20 reads */ + i=0; + for (k=0;k<20;k++) + { + assertok(tio_read(fp,buf,sizeof(buf))==0); + /* check the buffer */ + for (j=0;jstart); + /* close the files */ + assertok(tio_close(rfp)==0); + assertok(fclose(wfp)==0); +} + +/* this test starts a writer and an idle reader */ +static void test_timeout_writer(void) +{ + int sp[2]; + FILE *rfp; + TFILE *wfp; + int i; + struct timeval timeout; + uint8_t buf[20]; + time_t start,end; + /* set up the socket pair */ + assertok(socketpair(AF_UNIX,SOCK_STREAM,0,sp)==0); + /* open the reader */ + assertok((rfp=fdopen(sp[0],"rb"))!=NULL); + /* open the writer */ + timeout.tv_sec=1; + timeout.tv_usec=100000; + assertok((wfp=tio_fdopen(sp[1],&timeout,&timeout,2*1024,4*1024,2*20,4*20+1))!=NULL); + /* perform a few write (these should be OK because they fill the buffer) */ + assertok(tio_write(wfp,buf,sizeof(buf))==0); + assertok(tio_write(wfp,buf,sizeof(buf))==0); + assertok(tio_write(wfp,buf,sizeof(buf))==0); + assertok(tio_write(wfp,buf,sizeof(buf))==0); + /* one of these should fail but it depends on OS buffers */ + start=time(NULL); + for (i=0;(i<10000)&&(tio_write(wfp,buf,sizeof(buf))==0);i++); + assert(i<10000); + end=time(NULL); + assert(end>start); + /* close the files */ + assertok(tio_close(wfp)!=0); /* fails because of bufferred data */ + assertok(fclose(rfp)==0); +} + +/* the main program... */ +int main(int UNUSED(argc),char UNUSED(*argv[])) +{ + /* normal read-writes */ + test_blocks(400,11,11,400); + test_blocks(10*1024,11,10*11,1024); + test_blocks(5*1023,20,20*1023,5); + /* reader closes file sooner */ +/* test_blocks(2*6*1023,20,20*1023,5); */ +/* test_blocks(10,10,10,9); */ + /* writer closes file sooner */ +/* test_blocks(4*1023,20,20*1023,5); */ +/* test_blocks(10,9,10,10); */ + /* set tio_mark() and tio_reset() functions */ + test_reset(); + /* test timeout functionality */ + test_timeout_reader(); + test_timeout_writer(); + return 0; +} diff --git a/tests/usernames.txt b/tests/usernames.txt new file mode 100644 index 0000000..a948983 --- /dev/null +++ b/tests/usernames.txt @@ -0,0 +1,2500 @@ +wworf +kwinterling +timbier +nroh +bmatrejek +scombass +dstubby +prigney +iherrarte +imayette +oport +waristizabal +etunby +wschmeisser +cpinela +ascheno +lcavez +skuntz +rmcghay +cdrumm +sguenison +fculleton +cbarlup +vglow +greiff +gmoen +nfrancesconi +apastor +hmagsby +ocornelison +tmalecki +obailly +ygoldson +uhuysman +dcaltabiano +aschmider +yureta +fgrashot +rramirez +pwutzke +kfetters +redling +rworkowski +istruzik +ktriblett +atollefsrud +phalter +wvakil +jarango +apliska +cbambace +ipaquette +nvantassel +adesgroseillie +psundeen +puzzell +ihernan +clarusso +jvillaire +ndepina +fbalagtas +mcattrell +jscavotto +emehta +wprosienski +ideveyra +ncermeno +eengelman +istarring +mautullo +osaber +osarao +tplatko +npopwell +mkoelle +hmaresco +uhayakawa +vlajoie +umenlove +mwalkington +pvlcek +skever +ndelmore +htsuha +ctenny +fmahler +jherkenratt +emargulis +lnagata +uchalender +ihudspeth +crieck +enuffer +hriech +ikacher +cdudziak +eflury +riler +ncradduck +fmarchi +lvaleriano +hsadiq +fnader +mcattrell +igrimmer +mswogger +fsplinter +zwoolfrey +bphou +ikuboushek +leberhardt +vhargers +omarples +fgeris +vhaverill +ogoldthwaite +ckondo +dfollman +floparco +xlantey +tethelbert +dlanois +amccroskey +kseisler +gfaire +pahles +hsalvucci +xrahaim +alienhard +lpitek +kgiacalone +pquanstrum +gthorson +mtelford +tvehrs +mkibler +ivanschaack +lbruscino +gdreitzler +vhaverill +bmadamba +mjeon +nmastronardi +dcarsey +ykimbel +dasiedu +pgaudet +cduba +saycock +vwokwicz +wcreggett +vmalandrino +fbeatrice +svogler +ipen +wmendell +gmassi +yszumigala +dmellady +smccaie +wconstantino +phalkett +rgriffies +gsantella +canichini +lnooman +ndesautels +vlajoie +rbillingsly +szachariades +gwaldbauer +dciviello +bkoopmann +mredd +pfertitta +lchaudoin +inobrega +vcrofton +lchaudoin +mdedon +ktuner +bwiggins +opizzuti +fvinal +bdominga +lbenito +aarellano +inarain +ucarlino +nsnaders +zpoirier +ndrumgole +gspicer +kvanderbie +kbramblett +apastor +opuglisi +hcrowden +dgiacomazzi +wbrettschneide +vpridgeon +ktorrent +dsmykowski +pbeckerdite +tsepulueda +rgrigorov +fsunderland +ccuozzo +ofugere +malleruzzo +ckurkjian +faleo +esodachanh +kcomparoni +utircuit +vrodick +emcindoe +zkurokawa +wborde +agordner +lcarratala +pbrentano +mconsolini +wclokecloak +pdossous +yvdberg +shoitt +wganther +tquilindrino +jbjorkman +jgobble +pkoblick +broher +myokoyama +dcaltabiano +obenton +werrick +iyorgey +psabado +xdittrick +ykriegel +isowder +rgothro +nciucci +cfleurantin +gwethern +cmanno +imakofsky +dloubier +umosser +hsadiq +cpentreath +ojerabek +tmelland +ktapanes +mcasida +mvanpelt +fthein +jhenkensiefken +ubrumett +ysturino +ilamberth +tpaa +yolivier +rfangman +tguinnip +hhagee +ibyles +lsingletary +vpoitevin +kmcardle +gettl +vmaynard +mrydelek +hhardan +dwittlinger +lmuehlberger +cpencil +lhutsler +jguzzetta +tmurata +nreistetter +rgothro +ysantoscoy +llarmore +pbrohawn +hwoodert +gdeyarmond +mallmand +rcabler +gmackinder +bconour +ycerasoli +jskafec +bmarszalek +dphou +sdebry +nwehnes +psiroky +dgreenlun +gdaub +dnoneman +iambrosino +tmalecki +hskowronek +fkeef +jjumalon +gvollrath +kbrancati +rcabler +dsumaran +jmingo +lcoulon +emele +chosteller +dpallesen +emongelli +zcervenak +nvyhnal +xlantey +hhydrick +mfitzherbert +dsteever +rhujer +cpatrich +mstoffey +khartness +iquero +rpitter +oosterhouse +hfiebig +kmallach +ieagon +cwinney +thynson +fsavela +leberhardt +aponcedeleon +sshearon +cdewoody +olincicum +lgutenberg +hkarney +pminnis +ksparling +ajaquess +ttorregrossa +mleggio +vfohl +kgiacalone +uransford +fbeatrice +wtumaneng +kfend +udatu +dprestia +vkilburn +ncapuchin +cdonnick +nrabsatt +cchriswell +omullner +charriman +sskyers +ndesautels +bamaker +iroiger +dnegri +hrenart +odarity +dflore +gkerens +mfeil +svongal +tsteve +jreigh +achhor +cbandel +mpizzaro +satkins +asivley +phyers +gclapham +tmccaffity +prowena +cpentreath +zinsko +kgiacalone +mkarels +ocrabbs +mrydelek +zkeitsock +cgaudette +emathwich +ndepina +lemling +ibowdle +dledenbach +tbattista +ssarabando +ugreenberg +bfishbeck +wmellott +eberkman +alamour +mtelford +ugerpheide +hschoepfer +draymundo +moller +aborycz +rainsley +wenglander +lspielvogel +jbergseng +gbareis +nrufus +fagro +ibuzo +gmings +uwalpole +tvrooman +jwinterton +ilacourse +htomlinson +ihaub +fgoben +ekeuper +klurie +dbissen +fkrasnow +jbielicki +ascheno +nwatkinson +ljomes +asellberg +rboelk +qhanly +alat +lcanestrini +cdonnick +lgab +pslisz +wgidaro +ovasiliou +hbukovsky +joligee +uholecek +rtooker +atimenez +mwatt +twillets +vwabasha +hschoepfer +barenales +hmaly +salexandria +ecolden +dlablue +ewismer +kschlicker +jarango +mbaldyga +hhagee +cbartnick +ubuscombe +cbrunsting +yverbeke +ckistenmacher +amusemeche +fmilsaps +ghermie +esproull +laksamit +cklem +nmesser +psalesky +ckleis +omounts +gmings +xcilva +jyeater +omontross +daubert +dmccoyle +tguinnip +ddeguire +kottomaniello +mlenning +hsabol +nhayer +lpavick +gcukaj +isteinlicht +pwhitmire +nchrisman +sgefroh +trofkahr +kkennett +hmatonak +ecelestin +vfeigel +mtintle +plabrum +svandewalle +ikrise +mciaccia +dbye +zwoolfrey +iracey +szachariades +bleaks +wdovey +dgivliani +mdoering +vgaseoma +aarietta +ofelcher +ishuckhart +cflenner +wleiva +fplayfair +dgiacomazzi +npremer +jappleyard +poakland +wcagney +hchaviano +psharits +oshough +vwisinger +kmeester +swoodie +hgreuel +dnoneman +kconkey +gbumpaus +pshina +mhowat +cpaccione +ithum +dmccoyle +lkonicki +edack +ysnock +edufford +vlubic +ihimmelwright +ccrape +bhelverson +dscheurer +kkarmo +swolfertz +epeterson +lpondexter +dcoffer +ileaman +nfilipek +purquilla +cmcanulty +iaskin +sbrabyn +ekurter +saben +pgreviston +vdains +mzoulek +bzieba +plenix +kcofrancesco +lmcgeary +mbosten +gradish +hgranelli +lhenrey +cheinecke +wboroff +dflore +joconor +iiffert +ploegering +kdecock +jmatty +tcampman +sherzberg +lautovino +rginer +kalguire +ktaus +kmisove +aduffie +gmilian +dsmykowski +tcuenca +gbrihm +dpintor +aantuna +hlindemann +rsimonton +wdagrella +hseidt +gchounlapane +sstough +cnagode +ptoenjes +fmeola +bgavagan +bguthary +akraskouskas +mtuma +gdeadwyler +ehathcock +gjundt +lhuggler +wkhazaleh +jeidem +ohove +badair +sgraney +obache +ssorce +rkraszewski +moser +ecordas +aesbensen +bcuez +bwaymon +dpfeiffer +tkhora +tsingeltary +lbuchtel +smccastle +testusr2 +nrybij +lmohn +isuro +bdurkins +pkillingworth +lgadomski +jyslava +ebascle +kgarced +akrishna +cbelardo +dtashjian +nramones +sdefrain +epoinelli +imatherly +gstorrer +venfort +ikadar +eselvig +rcianciolo +cpaccione +bouten +mbrannin +ekenady +pschrayter +hsumrell +tmarcom +hlemon +fblow +dfirpo +nasmar +ewilund +stiry +hwestermark +dgorka +rdubs +tnaillon +nnocella +igurwell +mcook +fsinkovich +amanganelli +rcheshier +stiry +vhussien +sspagnuolo +nkempon +ssarabando +jholzmiller +omatula +glablanc +ghelderman +vtresch +nschmig +obirkline +kcofrancesco +tcrissinger +vexler +charriman +pvirelli +limbrogno +obenallack +pthornberry +mstirn +zosollo +lcallender +vnery +pquiller +tlietzke +pbenik +dbarretto +hgalavis +pshumski +cmiramon +lhutsler +zculp +hkohlmeyer +wbarcellos +gtkach +djosselyn +wharpel +rgoonez +ichewning +nchafins +ivoetmann +ekurter +bnicoletti +mberson +cabare +hbinker +teliades +hschlesser +nbuford +ncrissler +skuang +kadamczyk +planzi +rpastorin +dbarriball +dkopczyk +estockwin +ldettmann +ipaquette +zgitlewski +gvachula +sjankauskas +ywhittingham +dsantander +wschemm +jpidcock +ugowans +hpenick +cbrunsting +adesgroseillie +cweiss +oduba +gmackinder +lcorbridge +bmoling +gbolay +ninnella +kbrevitz +kdomke +bflexer +djosselyn +farquette +nquann +otanon +pdech +okave +cbotdorf +jcurson +zanderlik +cereth +ycobetto +lhurtado +tmontesi +rlambertus +mvedder +ktopoian +bwinterton +vmcilwraith +fdivers +rfassinger +ohoffert +dciullo +nreistetter +glemler +tsenemounnarat +zvagt +elozier +aspiess +ediga +gdrilling +baigner +iogasawara +ienglert +wpander +phyer +yversluis +ihalford +mespinel +zratti +vdolan +mfritsche +mjeon +ddeguire +bgjelaj +wrott +nkubley +lleagjeld +agarbett +xmcnerney +tgelen +kganesvoort +mwaltemath +tlietzke +ralspach +dpallesen +jfay +ncaballero +nspolar +uvanmatre +vareias +ikulbida +jschedler +mkumar +pgrybel +emiss +meconomides +cmiramon +nspolar +tlana +gishii +zboulding +vnooman +sherzberg +fkrasnow +gcubbison +cdeckard +nrajewski +hmagsby +pgermershausen +yeike +akrishna +lmccosh +phaye +lpaglialunga +ebattee +jmcgartland +mvas +cdegravelle +moller +tmorr +hhires +yfrymoyer +njordon +thaycraft +bluellen +sgurski +hvannette +nobregon +zneeb +hhysong +fnottage +ahandy +wzausch +lfichtner +yautin +fdechellis +sgarriss +garchambeault +bouten +wselim +kswirsky +fspiess +eziebert +gjundt +gdusen +jquicksall +sgunder +isorhaindo +lkimel +uneice +ebusk +gclapham +eshanon +wpoudrier +zborgmeyer +kwinterling +gcrossfield +jlianes +ctenny +bbeckfield +hfenk +creins +olilyblade +choeger +pzaccaria +ltegtmeier +ycerasoli +jcourtwright +kgillim +ycurtis +tfalconeri +faquilar +jeuresti +sstazenski +gpomerance +pmineo +ocornelison +hschrank +kfetters +wmolin +akravetz +hmachesky +shaith +ppeper +ldreckman +lbartimeus +tpin +dlongbotham +oclunes +vbaldasaro +bmatrejek +pcornn +nroepke +myokoyama +cbelardo +rsilberman +bpinedo +gdeblasio +nphan +istarring +sstuemke +tmagel +mcidre +pphuaphes +jwatah +ipeick +khembrey +hgreuel +nkempon +shoitt +slaudeman +hcalvaruso +hdumpert +nbugtong +hsweezer +cmcgoey +ngata +bcolorado +vballina +tmurata +sjarvi +esonia +ycostaneda +hriech +kmandolfo +ghumbles +ngrowney +ipuccio +ssilbert +hrapisura +mdanos +teliades +hmitchusson +ckugler +lmadruga +psantorella +ggillim +dstreich +emiss +ksoberanes +lshilling +ohearl +fberra +hderrig +nevan +xdittrick +obeaufait +mfinigan +fsirianni +bhelscher +fberyman +sgropper +mcashett +ecordts +bharnois +gkirchberg +wcarthon +dmccoyle +cnoriego +mblanchet +dhendon +kshippy +emori +mgoodenough +testusr3 +sdenina +lhutsler +uednilao +omcdaid +afeinen +tsearle +lnagata +aziernicki +jmarugg +sscheiern +hpaek +panello +fsapien +ykisak +msweezer +cheinecke +dhannam +maustine +vrapin +svielle +rcandy +tmysinger +hpalmquist +swilken +jnehls +ckondo +uweyand +ewuitschick +wschmuck +mlinak +pzutell +vchevalier +tabelman +cbrunsting +xmcnerney +tliekhus +klundsten +slaningham +deshmon +nmoren +askimehorn +rpinilla +mcaram +thoofard +dprestia +iquero +nrysavy +mvanbergen +ascheno +ulanigan +jeidem +gloebs +mdellavalle +tsingeltary +lwedner +mcoch +mneubacher +khathway +syurkovich +psherfy +fvallian +jlunney +wdovey +jjumalon +umcsparin +zfarler +bdevera +zeddins +mbroglie +adurol +dcastillion +ncaver +naquas +cmellberg +mswed +bluellen +rtrichell +cfasone +hderrig +hstanczyk +enastasi +adevenney +gcobane +psemple +ggehrke +mberson +ndrumgole +khoffstetter +ggase +iromie +mquigg +iyorgey +emargulis +imarungo +lrandall +kmalas +tvisitacion +imcbay +hbraskey +ymudie +tkuchem +rfauerbach +ctewari +gstallion +hcianciolo +jsegundo +tfetherston +mjuris +ualway +ideshon +lmadruga +aashbach +erostad +hludeman +wconces +tmarkus +eturpiano +pcaposole +lburmester +mcook +osarao +spolmer +isalm +gshelhorse +iwoldt +pvlcek +arosel +obache +jseen +kjhonson +vdesir +rrodberg +wtruman +mfornes +mfaruolo +iyorks +tairth +cstidstone +cfilippello +vwaltmann +pbenik +fhalon +ctetteh +hzagami +pheisdorffer +lelsaesser +ghann +fcunard +afallert +efobes +srees +sackles +uspittler +mcampagnone +gfaire +dhannam +kgleichweit +rmcdonnel +akomsthoeft +gjankowiak +glafontaine +mmylott +kgourd +lbatra +lparrish +snotari +oreiss +lringuette +ymursko +ekonick +rmandril +cfredericksen +fminecci +lbassin +mgavet +gshadle +cpalmios +vrunyon +cpalmios +ueriks +kstraughn +gconver +vburton +fplayfair +opeet +bwalega +mkonow +lschenkelberg +creddrick +ubieniek +wgwaltney +sanderegg +jchancy +ibyles +klover +hbickford +fsymmonds +nlemma +pgaudet +lparrish +rpenhale +fwidhalm +mvas +rlatessa +oscarpello +pzaccaria +zclendennen +seastridge +iweibe +wmenucci +pfreiberger +cswayze +fmulac +mviverette +tvallow +wborenstein +lhoerr +sstuemke +mconsolini +ndashem +lmauracher +mpark +thelfritz +ckehl +tbagne +jamber +walbrecht +diller +zgingrich +dzurek +nllewlyn +sbloise +lyoula +vkouns +dblazejewski +ashuey +eathey +kdevincent +kwidrick +mmcchristian +ebeachem +ckugler +tfowlkes +lnorseworthy +nerbach +phyer +gfedewa +ngrowney +pwademan +lkhubba +ktoni +craddle +rhickok +smarksberry +bwynes +bromano +dmarchizano +ewall +mxiong +fratner +tstalworth +omounts +vpender +tpownell +osaines +jlebouf +szachariades +omatice +nspanbauer +sdaignault +svielle +blovig +nlaizure +lsous +ademosthenes +speppin +mmangiamele +kmoesch +nhuckstadt +isudweeks +hsnarr +abeen +amccroskey +nkraker +rcandy +ocalleo +owhitelow +mrizer +cmafnas +jzych +tsann +abortignon +prowena +mfaeth +nridinger +ctuzzo +rcheshier +gshrode +vstirman +pheathcock +bdevera +mdimaio +pbeckerdite +amcgraw +nousdahl +zbuscaglia +ldettmann +ihegener +hbetterman +dlargo +ewilles +ngaler +ptomopoulos +lvanconant +jbiber +vglidden +nmajera +vnery +lseehafer +hiddings +kwirght +imensah +dmahapatra +osanthuff +mmanozca +hbrandow +zbracamonte +gguardia +lschenkelberg +ymichna +klover +hliverman +tmccannon +hnoblitt +pbascom +dherard +jscheitlin +lgadomski +mpilon +mstirn +fwollner +ashrigley +dlanois +seroh +vschaedler +mherlihy +vbonder +okveton +gmalave +hhardan +fkosiba +ccyganiewicz +vemily +omasone +cgalinol +jrees +tmcmickle +akertzman +ngoshen +tkeala +hpimpare +dtornow +jdodge +ldigman +vrunyon +jenfort +akilburn +lchaudoin +clapenta +kmedcaf +fparness +owhelchel +egalleta +yeven +bhaislett +critchie +lbramel +ppiccillo +ahalleck +gearnshaw +nhelfinstine +hhaffey +eyounglas +ksharma +gwethern +fhovermale +eklunder +emottillo +mdanos +isuro +pphuaphes +wvalcin +pduitscher +yhenriques +mjeon +areid +gbrimmer +rdubuisson +mvanpelt +dstubby +ksauler +cmiramon +cbrom +gparkersmith +gdivalerio +awhitt +slerew +mpanahon +kmanin +igeltz +awoytowich +llampier +lslavis +hsweezer +cbarrigan +afredin +slaforge +ycostaneda +hsabol +bhelscher +cnabzdyk +wharpel +cbrom +hbarrale +tmoskos +lnibler +mkassabian +saben +twedel +eleyton +mpark +mferandez +utrezize +ihanneman +behrke +tarre +hhartranft +eyounglas +ehindbaugh +ichewning +smayorca +pcorson +bcuez +isplonskowski +ediga +ivanschaack +ewicks +icalamari +bmicklos +lgandee +iwininger +pmurdoch +gkrasner +uazatyan +kbordwine +speppin +hwoodert +mmoskop +mferrier +ygoldson +cpatrich +ktuccio +vchevalier +cduffer +lringrose +dhomma +prepasky +mmattu +rbillingsly +kepps +fcha +lgodlove +rasrari +hpolich +garchambeault +nwrobbel +lsobrino +aagel +eneighbor +hbuttolph +umcsparin +oconerly +sschoeman +mtanzi +usoltes +skuntz +fhain +smullowney +okveton +showe +vrunyon +fschafer +yschmuff +olilyblade +hlynema +xhorvitz +hschrank +jsweezy +jrimando +dpintor +gshelhorse +dsharr +hmuscaro +ihashbarger +kmalas +mdyce +kschlicker +svielle +pwetherwax +tgraen +ecathers +fwaychowsky +mgoldhahn +tblackgoat +uoblinski +gwachowiak +thoch +bwiggins +tdonathan +dpfeiffer +arthur +mfaeth +bscadden +eorofino +imariello +hcouillard +uslavinski +guresti +bzaeske +rmagnone +rbloomstrand +klurie +csteinbrecher +tbattista +gpiatt +pspradling +ckerska +obercier +mdecourcey +senrico +rheinzmann +eprosper +jsenavanh +cklem +fcarvosso +pdziuban +gdrilling +vdelnegro +lschollmeier +mpatty +gapkin +eshurtliff +ghaworth +cdrumm +zpero +psharits +smillian +tnaillon +mdoering +mmedlar +fvascones +kmoesch +akravetz +ilacourse +umanske +cgalinol +kaanerud +tmcmickle +pcassaro +kkinnick +adesgroseillie +ssilbert +kleardi +pfloerke +hfiebig +greagey +wpeckler +ckreidler +vtrumpp +imillin +kkozik +bstrede +txayavong +aferge +kgarced +ycerasoli +dblazejewski +usherraden +vbigalow +khinckson +gallanson +pmalachi +cbrechbill +rfauerbach +jglotzbecker +chuxman +skoegler +lbartimeus +hstreitnatter +mviverette +emottillo +hbukovsky +edurick +pbiggart +sshilo +bsibal +pzieglen +bhelscher +kshippy +gcacatian +puniacke +nlatchaw +ohatto +rhollmann +sansari +swallberg +gportolese +plabrum +obenton +mbumbalough +ckleis +rschkade +fverfaille +ukins +bwhang +tmohmed +krahman +nlinarez +nwiker +gcarlini +sarndt +cmafnas +dgosser +phyers +hspackman +ireeser +bjolly +mhollings +ctenny +uschweyen +cgaler +zkampmann +svielle +kwidrick +omalvaez +aminari +khathway +mdickinson +kbradbury +cvote +cspilis +cschimke +ibreitbart +imcconkey +amayorga +gmeece +iroiger +wmailey +kthede +testusr2 +hbraim +eklunder +fgarron +cklem +kbarnthouse +khovanesian +cwank +dwideman +istoff +dlancey +mlinardi +tlorona +yeike +dfirpo +mcontreras +mlantieri +wschmeisser +dhammontree +hmogush +kfetters +achhor +bgjelaj +lsivic +eparham +nradican +thomme +lcoller +ncermeno +zkutchera +lgradilla +pvlcek +cdouthett +znightingale +jkimpton +owager +zbains +slaudeman +sczubia +jcaroll +pslisz +fdarakjian +dhindsman +zhaulk +mground +mkoelle +mmatise +gzuhlke +cjuntunen +mferandez +uholecek +tnitzel +fsumrall +jmartha +hboreland +eserrett +csalkeld +fburrough +jchipp +lfelan +hpotucek +pheathcock +dsgambati +kpuebla +agimm +csarjeant +fvinal +nglathar +beon +bsteinbrecher +rchevrette +cbleimehl +dminozzi +hfludd +wworf +jbjorkman +bzaeske +nglaspy +gdamour +etunby +hcintron +sdrawec +dtuholski +ochasten +pvierthaler +ekalfas +rzilahi +joligee +rhoffschneider +ckistenmacher +ksparling +zmeeker +asabin +mkrauser +umarbury +dpallesen +nblum +showe +fberyman +phardung +hkinderknecht +dgreenlun +gsusoev +tdembinski +lseabold +hbastidos +ohoffert +aesbensen +tmill +sbonnie +ohedlund +ewilund +tsowells +ilevian +btheim +wschemm +csoomaroo +ilawbaugh +jdeaville +lswanton +faleo +mcrise +fblow +amckinney +eklein +rginer +ndepina +vtowell +ploegering +lpintor +jfreuden +cjuntunen +lmichaud +hzinda +mwesberry +wsteinkuehler +mwalkington +nendicott +brodgerson +opoch +nnickel +rwinchell +ibeto +cboecker +lcocherell +fbakaler +wottesen +cbelardo +skanjirathinga +dsahota +nedgin +nhija +sestergard +imicthell +upater +sskone +ncrafford +gmalekan +dbertels +kbartolet +fsaeli +vbon +usoltes +vdelnegro +lversage +bvanscooter +ppedraja +clouder +bveeneman +hspiry +ckodish +hmatonak +owager +lgunnett +mfritsche +espangenberg +zvanwagoner +bswantak +lcoy +dciviello +bnibbs +esheehan +ptraweek +hdyner +wstjean +kmosko +nrajewski +brepka +hmerle +loganyan +hholyfield +nhayer +npopwell +rfassinger +sbettridge +tvrooman +ddobrowski +mjacox +enicoles +emanikowski +iseipel +emargulis +kgremminger +dauer +wgwaltney +ebascle +nnamanworth +mtoves +jlathen +lpeagler +mprim +wdelbalso +tabdelal +yhahne +uvazzana +csever +fbuzzi +nscharler +tchemin +kfaure +dpolashek +jcourtwright +sdehoyos +mlaverde +owero +bbabst +ewilles +ablackstock +kthornes +cbourek +tnitzel +pcoburn +redling +lfarraj +gwaud +sgraney +hmateer +csever +jchipp +klitehiser +oalthouse +hsabol +sduplechain +mdoering +wbryar +lbarban +hcusta +glebold +nmoren +cfronduti +pwohlenhaus +mpilbin +jgobble +nbolon +emanikowski +sdenina +mdoering +ilambino +vmigliori +kklavetter +krahman +eyslava +hschelb +adishaw +ghiland +nmccolm +zgingrich +rkraszewski +lsobrino +habby +mmuscarella +vnazzal +wzappa +pgreenier +phyer +pziesmer +cmundel +enuffer +vpiraino +kordahl +bmoldan +mgayden +craddle +jspohn +nhattman +iyorks +hloftis +lcarratala +ncermeno +mkawai +ascovel +hkohlmeyer +mvashaw +vrunyon +ihegener +srubenfield +rmagnone +ikaus +ngiesler +jknight +hhamburg +vlajoie +kheadlon +dpallesen +wdeluccia +vgieringer +hpascarella +egrago +aramsdale +hdula +hwoodert +rdubuisson +upellam +sratledge +rmcstay +hkippes +kgelhar +vmedici +gdeyarmond +zwinterbottom +htilzer +apancoast +yszumigala +mmatise +zscammahorn +jroman +pzorens +pfertitta +vkilburn +ngullett +gbueche +rrasual +mmerriwether +wcolbenson +splumlee +egospatrick +ykello +ejuedes +nsiemonsma +cnabzdyk +cpalmios +mruppel +cpentreath +vpeairs +cghianni +ohatto +kbattershell +pfavolise +kmcguire +nagerton +lseabold +jherkenratt +brucky +wboylston +mpatty +dnoneman +lnormand +miglesia +ieckhardt +lschnorbus +kgumbs +gcervantez +rkoonz +wkappen +wvermeulen +lcremer +kmayoras +gbitar +atonkin +dbissett +canichini +swolfertz +mhack +mskeele +hlemon +denriquez +fhalon +lkahre +eneighbor +dsherard +wmenucci +oreynero +imillin +smosses +uhayakawa +ilacourse +ahalcom +bdadds +tronald +carguellez +mstorto +isteinlicht +esonia +fberyman +fbielecki +rguinane +wtio +istallcup +bmednick +sscheiern +uwalpole +ipeick +icoard +amaslyn +rpikes +ebumbrey +gnordmark +wbillotte +jeverton +vweissmann +wlucken +ewicks +mcolehour +dslade +dhomma +pzorens +hyuscak +wkirkegaard +atilley +zrenderos +efudala +nforti +ubynum +ihashbarger +ganes +tredfearn +jwatah +wdevenish +apurdon +satkins +eorsten +zkeitsock +uazatyan +tcacal +wknipe +hcarrizal +dscialpi +jspohn +hpolk +lbanco +vemily +huber +oolivarez +ggaytan +dclardy +mpellew +bkiang +ksheeler +atopick +tgraen +cjody +ovibbert +ideveyra +eshurtliff +mtintle +clewicki +cdarensbourg +hdula +oduba +espyies +bmooe +emoradian +kpalka +rpinilla +xeppley +tgindhart +rlosinger +hdecristofaro +ycobetto +pdischinger +cwank +rtrichell +asivley +kjoslyn +hcafourek +gkerens +emcquiddy +crile +asticher +spolfer +mjennings +hskowronek +ddobrowski +ueriks +wgorton +mallmand +btempel +tcossa +jspeh +tboxx +nchrisman +ppeper +mpester +asundholm +kgiacalone +nlainhart +nslaby +ekalil +gpelyo +dliehr +eengelman +pdauterman +ddigerolamo +lvittum +tharr +bdaughenbaugh +tpownell +enastasi +dlancey +hcowles +amozier +pdulac +rfidel +klape +cswigert +nlohmiller +smazzara +hharian +llarmore +kcheyney +wbryar +cscullion +tmelland +flehenbauer +nwescott +pvierthaler +enoguera +jasplund +ploegering +tsowells +hpolintan +ahalcom +nscharler +bsolecki +yduft +obihl +lbove +ikulbida +volejarski +dfacenda +kwirght +dsherard +istruzik +sfaure +smosakowski +vkrug +oosterhouse +pquiller +msweezer +ecann +imuehl +xlantey +fpybus +mfornes +ssandine +ulanigan +bjolly +rtole +mkofoed +mkarels +xstrawbridge +dmcgillen +esonia +llaneaux +nbethany +rbernhagen +bwoolever +mbeagley +peickhorst +pwashuk +ktolontino +njordon +pquiller +glocascio +ashrigley +eyslava +tmagel +lvanconant +ghanauer +ajudkins +rcolindres +tfowlkes +kmarzili +llasher +ejeppesen +irenick +vsefcovic +uflander +uschweyen +esthill +ebartylla +udelashmit +pziesmer +rhollmann +dholdaway +irenick +hlemon +gjankowiak +gportolese +osanthuff +lkimel +fcoak +nchafins +ecolden +daveado +pzaccaria +wlynch +tmorr +mluft +ztukuafa +igeltz +ksiering +nfunchess +hboyette +qaloan +mbixby +werrick +nblum +mbodley +wnunziata +jarango +ipaquette +ocalleo +planzi +pbondroff +ofelcher +seroh +cpaccione +moser +bbrenton +gschaumburg +ugammell +cpluid +mgoldhahn +tboock +dphou +usevera +tmusemeche +ktriblett +gcurnutt +ischnitzer +bbertao +jwelliver +dborneman +eflanner +dtryba +hmiazga +pgiegerich +fcopley +zkampmann +vleyton +vbracey +oahyou +ihoa +amccolgan +hbrehmer +nherschelman +bbuhoveckey +pmailhiot +pgrybel +vbonder +nranck +cmiramon +zweide +bluppino +nschiele +hdoiel +dsmykowski +rgramby +mweiss +afuchs +kkottenstette +dtornow +fmcnaught +swallberg +cparee +kpenale +alichtenwalter +frumbo +kolexa +rkrallis +hkinderknecht +fburrough +cpinela +tsablea +msturrup +fluthe +igizzi +ksiering +wesguerra +tdonathan +kmisove +nriofrio +bnicoletti +ameisinger +hdohring +hstoute +nbouras +cdegravelle +ashrigley +rborjas +mheilbrun +trofkahr +cblumstein +swede +bmarlin +maustine +lgadomski +nmajette +kpannunzio +rlagrone +hstoute +kgillim +istruzik +wottesen +erathert +ygockel +ibyles +wcreggett +vmaynard +sestabillo +egivliani +mbravata +wtruman +jmarugg +oellerbee +pdauterman +pzutell +kbrugal +cordorica +wclokecloak +blittman +habby +scocuzza +ptomopoulos +hloftis +mjacox +lcaudell +ffigert +msweezer +sgirsh +hveader +wbarcellos +pirby +rnordby +mpytko +dpebbles +otrevor +nforti +dpintor +mdedon +svincenzo +pbrohawn +blatona +tlowers +hharian +mground +akraskouskas +lwedner +kvidra +nsilveria +cbandel +hkohlmeyer +sbemo +oebrani +waustad +asemons +ndipanfilo +adenicola +tstokey +mdecourcey +mruppel +kmuros +rbrisby +hgoodin +mkeedah +kpantoja +myokoyama +jkopko +gcummer +telman +mbrar +fprado +mdoering +owhelchel +bcoletta +hlauchaire +gvollrath +wstjean +rmarsee +fparness +zgitlewski +ipiontek +tyounglas +bcatholic +lgutenberg +mzoulek +fnollora +vduffel +mgolder +kgelhar +edrinkwater +tkelly +mmesidor +lloukota +pviviani +ihudspeth +obelloso +wkahoun +cdickes +jroden +zwoolfrey +sansari +tmccamish +jtetzlaff +hlichota +urosentrance +vglow +ubenken +mpizzaro +nsytsma +psowa +hboreland +astrunk +pdurando +nquann +aspiess +ikacher +wbrill +senrico +ishuckhart +hzinda +mpanahon +veisenhardt +eaguire +jkressin +pcourneya +tschnepel +osaines +dciullo +gtinnel +walbrecht +ksollitto +kstachurski +nbugtong +mdimaio +bdominga +farquette