diff options
-rw-r--r-- | .cvsignore | 7 | ||||
-rw-r--r-- | ANNOUNCE | 125 | ||||
-rw-r--r-- | AUTHORS | 70 | ||||
-rw-r--r-- | COPYING | 481 | ||||
-rw-r--r-- | CVSVersionInfo.txt | 13 | ||||
-rw-r--r-- | ChangeLog | 1520 | ||||
-rw-r--r-- | INSTALL | 182 | ||||
-rw-r--r-- | Makefile.am | 103 | ||||
-rw-r--r-- | Makefile.in | 513 | ||||
-rw-r--r-- | NEWS | 149 | ||||
-rw-r--r-- | README | 169 | ||||
-rw-r--r-- | acconfig.h | 54 | ||||
-rw-r--r-- | aclocal.m4 | 140 | ||||
-rw-r--r-- | aix_authmeth.c | 1023 | ||||
-rwxr-xr-x | autogen.sh | 5 | ||||
-rwxr-xr-x | certutil | 263 | ||||
-rwxr-xr-x | config.guess | 1334 | ||||
-rwxr-xr-x | config.h.in | 316 | ||||
-rwxr-xr-x | config.sub | 1457 | ||||
-rwxr-xr-x | configure | 5058 | ||||
-rw-r--r-- | configure.in | 321 | ||||
-rw-r--r-- | depcomp | 411 | ||||
-rw-r--r-- | dnsconfig.c | 192 | ||||
-rw-r--r-- | dnsconfig.h | 33 | ||||
-rw-r--r-- | doc/README.AIX | 141 | ||||
-rw-r--r-- | doc/README.HPUX | 6 | ||||
-rw-r--r-- | doc/README.IRS | 314 | ||||
-rw-r--r-- | doc/README.SFU | 164 | ||||
-rw-r--r-- | doc/README.paged | 53 | ||||
-rw-r--r-- | doc/SolarisInstallNotes.txt | 198 | ||||
-rw-r--r-- | doc/autofs-4.1.3-lookup-nssldap.patch | 401 | ||||
-rw-r--r-- | doc/lookup_nssldap.c | 335 | ||||
-rw-r--r-- | exports.aix | 64 | ||||
-rw-r--r-- | exports.hpux | 1 | ||||
-rw-r--r-- | exports.linux | 65 | ||||
-rw-r--r-- | exports.solaris | 30 | ||||
-rwxr-xr-x | install-sh | 251 | ||||
-rw-r--r-- | irs-grp.c | 125 | ||||
-rw-r--r-- | irs-hosts.c | 201 | ||||
-rw-r--r-- | irs-netgrp.c | 191 | ||||
-rw-r--r-- | irs-network.c | 213 | ||||
-rw-r--r-- | irs-nss.c | 90 | ||||
-rw-r--r-- | irs-nss.h | 60 | ||||
-rw-r--r-- | irs-proto.c | 120 | ||||
-rw-r--r-- | irs-pwd.c | 120 | ||||
-rw-r--r-- | irs-service.c | 161 | ||||
-rw-r--r-- | irs.h | 330 | ||||
-rw-r--r-- | ldap-alias.c | 113 | ||||
-rw-r--r-- | ldap-alias.h | 48 | ||||
-rw-r--r-- | ldap-automount.c | 400 | ||||
-rw-r--r-- | ldap-automount.h | 54 | ||||
-rw-r--r-- | ldap-bp.c | 136 | ||||
-rw-r--r-- | ldap-bp.h | 57 | ||||
-rw-r--r-- | ldap-ethers.c | 352 | ||||
-rw-r--r-- | ldap-ethers.h | 73 | ||||
-rw-r--r-- | ldap-grp.c | 1297 | ||||
-rw-r--r-- | ldap-grp.h | 43 | ||||
-rw-r--r-- | ldap-hosts.c | 484 | ||||
-rw-r--r-- | ldap-hosts.h | 59 | ||||
-rw-r--r-- | ldap-netgrp.c | 993 | ||||
-rw-r--r-- | ldap-netgrp.h | 45 | ||||
-rw-r--r-- | ldap-network.c | 372 | ||||
-rw-r--r-- | ldap-network.h | 47 | ||||
-rw-r--r-- | ldap-nss.c | 4251 | ||||
-rw-r--r-- | ldap-nss.h | 903 | ||||
-rw-r--r-- | ldap-parse.h | 202 | ||||
-rw-r--r-- | ldap-proto.c | 218 | ||||
-rw-r--r-- | ldap-proto.h | 55 | ||||
-rw-r--r-- | ldap-pwd.c | 325 | ||||
-rw-r--r-- | ldap-pwd.h | 43 | ||||
-rw-r--r-- | ldap-rpc.c | 222 | ||||
-rw-r--r-- | ldap-rpc.h | 53 | ||||
-rw-r--r-- | ldap-schema.c | 499 | ||||
-rw-r--r-- | ldap-schema.h | 317 | ||||
-rw-r--r-- | ldap-service.c | 368 | ||||
-rw-r--r-- | ldap-service.h | 56 | ||||
-rw-r--r-- | ldap-sldap.c | 1320 | ||||
-rw-r--r-- | ldap-sldap.h | 172 | ||||
-rw-r--r-- | ldap-spwd.c | 220 | ||||
-rw-r--r-- | ldap-spwd.h | 42 | ||||
-rw-r--r-- | ldap.conf | 313 | ||||
-rw-r--r-- | ltf.c | 355 | ||||
-rw-r--r-- | ltf.h | 29 | ||||
-rwxr-xr-x | missing | 283 | ||||
-rwxr-xr-x | mkinstalldirs | 40 | ||||
-rw-r--r-- | nss_common.h | 50 | ||||
-rw-r--r-- | nss_dbdefs.h | 134 | ||||
-rw-r--r-- | nss_ldap.5 | 460 | ||||
-rw-r--r-- | nss_ldap.spec | 161 | ||||
-rw-r--r-- | nsswitch.ldap | 39 | ||||
-rw-r--r-- | pagectrl.c | 226 | ||||
-rw-r--r-- | pagectrl.h | 44 | ||||
-rw-r--r-- | resolve.c | 369 | ||||
-rw-r--r-- | resolve.h | 123 | ||||
-rw-r--r-- | snprintf.c | 374 | ||||
-rw-r--r-- | snprintf.h | 52 | ||||
-rw-r--r-- | stamp-h.in | 1 | ||||
-rw-r--r-- | tests/ldaptest.pl | 101 | ||||
-rw-r--r-- | tests/nsswitch.test | 40 | ||||
-rw-r--r-- | tests/testd.c | 41 | ||||
-rw-r--r-- | tests/testgr.c | 71 | ||||
-rw-r--r-- | tests/testpw.c | 151 | ||||
-rw-r--r-- | tests/testpw3.c | 48 | ||||
-rw-r--r-- | tests/testpw4.c | 77 | ||||
-rw-r--r-- | tests/testpw5.c | 127 | ||||
-rw-r--r-- | tests/testpw6.c | 187 | ||||
-rw-r--r-- | util.c | 1584 | ||||
-rw-r--r-- | util.h | 216 |
108 files changed, 37108 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..a18eb2a --- /dev/null +++ b/.cvsignore @@ -0,0 +1,7 @@ +config.log +config.h +config.cache +config.status +stamp-h +Makefile +NSS_LDAP diff --git a/ANNOUNCE b/ANNOUNCE new file mode 100644 index 0000000..6936a45 --- /dev/null +++ b/ANNOUNCE @@ -0,0 +1,125 @@ + + ANNOUNCING NSS_LDAP + =================== + +1. What is nss_ldap? +-------------------- + +nss_ldap is a set of C library extensions which allows X.500 and LDAP +directory servers to be used as a primary source of aliases, ethers, +groups, hosts, networks, protocol, users, RPCs, services and shadow +passwords (instead of or in addition to using flat files or NIS). + +nss_ldap nominally supports the following operating system libraries: + + o the Nameservice Switch in Solaris 2.4 to 9 + o the Nameservice Switch in HP-UX 11 + o the Nameservice Switch in the GNU C Library 2.1 (as + in libc.so.6 under Linux) + o the Nameservice Switch in FreeBSD 5.x + o the Information Retrieval Service (IRS) in BIND + o the Information Retrieval Service (IRS) and proprietary + authentication and identity interface in AIX 4.3.3 + +nss_ldap is an implementation of the schema specified in RFC 2307 +and is compatible with that used in PADL Software Pty Ltd's +NIS/LDAP gateway (ypldapd), and current versions of Solaris, +HP-UX and MacOS X. + +2. What can it do for me? +------------------------- + +nss_ldap lets you use LDAP servers, like Netscape's Directory Server, +to distribute users, hosts, groups and other like information throughout +an organization. Because LDAP is a hierarchical directory service, +you can distribute the information in a manner which reflects an +organizational 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. + +nss_ldap will work alongside your existing NIS, NIS+, DNS and flat file +name services. More importantly, because it builds as a shared library, +you don't have to recompile any of your applications to take advantage +of LDAP. When used with a directory server under NT, it may be helpful +in synchronizing Unix and NT accounts. + +3. What are its limitations? +---------------------------- + +Currently, some "maps" (like bootparams) are not supported. It's also +alpha software, so use it at your own risk. This should be considered +with respect to the fact the nss_ldap is loaded into the address space +of *every* process which uses the C library's resolver functions and +has LDAP in its search order. (This isn't entirely true under Solaris, +but the implications are similar.) + +Finally, it only supports Linux and Solaris (and some versions of +BSD). You might want to look at ypldapd (see below) if you need to +support NIS clients. + +4. How much does it cost? +------------------------- + +It's free, and distributed under the GNU General Library Public +Licence (LGPL). Please read the file COPYING.LIB For more information. + +5. Where do I get it? +--------------------- + +nss_ldap is available from: + + <URL:http://www.padl.com/download/nss_ldap.tgz> + <URL:ftp://ftp.padl.com/pub/nss_ldap.tgz> + +We have also made available some Perl scripts for populating LDAP +databases from existing flat files, NIS and/or NetInfo data. + + <URL:http://www.padl.com/download/MigrationTools.tgz> + <URL:ftp://www.padl.com/pub/MigrationTools.tgz> + +You'll need to compile a position-independent LDAP client library +(libldap). You can either get the entire LDAP package from the University +of Michigan (see below) and add "-fPIC" (if you're using gcc) to the +C compiler flags; download the Mozilla SDK from www.mozilla.org; +download the prebuilt Netscape LDAP SDK from developer.netscape.com; +or download OpenLDAP from www.openldap.org. + +6. Where can I get more information? +------------------------------------ + +To discuss nss_ldap, ypldapd, and related technologies, you may subscribe +to the following mailing list: + + <URL:mailto:ldap-nis-request@padl.com> + +Send an electronic mail message with "subscribe" in the message body to +join the list. + +To contact the developers, email: + + <URL:mailto:dev@padl.com> + +Note that PADL offer commercial support on a per-incident basis. The +support@padl.com is for commercial support customers only. + +For more information on using LDAP for name resolution, and related software, +see: + + <URL:http://www.padl.com> + +And if you need an LDAP server, or some general information on LDAP, +see: + + <URL:http://www.openldap.org> + +7. Who wrote it? +---------------- + +nss_ldap was written by PADL Software Pty Ltd <dev@padl.com>. Many +others have contributed, see the file AUTHORS in this directory. + +Please read the following document before submitting any +contributions: + + <URL:http://www.padl.com/Articles/GuidelinesforContributing.html> + @@ -0,0 +1,70 @@ + +nss_ldap was written by Luke Howard <lukeh@padl.com>. + +Development commenced in mid-1997 and continues to this day. + +Special thanks go to people who have volunteered their time, effort, +and ideas to make this software available. + +Please note that unless specifically indicated otherwise, +Luke Howard retains copyright in all contributed code. + + Steven Barrus <sbarrus@eng.utah.edu> + David Begley <david@avarice.nepean.uws.edu.au> + Maxim Batourine <Batourine_M@ald.utoronto.ca> + Michael Brownea <mbrown@fensystems.co.uk> + Max Caines <Max.Caines@wlv.ac.uk> + Carlos Celso <carlos.celso@embraer.com.br> + Peter Cherny <peterc@luddite.com.au> + Howard Chu <hyc@symas.com> + Ben Collins <bcollins@debian.org> + Stephan Cremer <scremer@dohle.com> + Alejandro Forero Cuervo <azul@freaks-unidos.net> + Guenther Deschner <gd@samba.org> + Luca Filipozzi <lucaf+nssldap@ece.ubc.ca> + Andrew Findlay <Andrew.Findlay@skills-1st.co.uk> + Cristian Gafton <gafton@redhat.com> + Gabor Gombas <gombasg@inf.elte.hu> + DJ Gregor <dj@gregor.com> + Bob Guo <bob@mail.ied.ac.cn> + Daniel Hanks <hanksdc@plug.org> + Leif Hedstrom <leif@ogre.com> + Emile Heitor <eheitor@isdnet.net> + Geert Jansen <undisclosed> + Szymon Juraszczyk <szymon@ssk.pl> + Anselm Kruis <kruis@till-photonics.com> + Thorsten Kukuk <kukuk@suse.de> + Steve Langasek <vorlon@netexpress.net> + Joe Little <jlittle@open-it.org> + Phillip Liu <phillip@loudcloud.com> + Larry Lile <llile@dreamworks.com> + Jeff Mandel <jeff.mandel@probes.com> + Peter Marschall <peter@adpm.de> + Michael Mattice <mike@bmisystems.com> + Dejan Muhamedagic <dejan.muhamedagic@at.ibm.com> + Doug Nazar <nazard@dragoninc.on.ca> + Frode Nordahl <frode@nordahl.net> + Lars Oergel <lars.oergel@innominate.de> + Fredrik Ohrn <ohrn@chl.chalmers.se> + Rakesh Patel <rpatel@globix.com> + Nathan Hawkins <Nathan.Hawkins@FMR.COM> + Andrew Rechenberg <ARechenberg@shermanfinancialgroup.com> + Greg Retowski <greg@rage.net> + Alain Richard <alain.richard@equation.fr> + Michael Shuey <shuey@ecn.purdue.edu> + Oliver Schulze L. <oliver@samera.com.py> + Alexander Spannagel <spannagel@jobpilot.com> + Scott M. Stone <sstone@foo3.com> + Gero Treuner <gero@faveve.uni-stuttgart.de> + Jarkko Turkulainen <jt@wapit.com> + Stein Vrale <stein@terminator.net> + Simon Wilkinson <sxw@sxw.org.uk> + +If I've forgotton anyone, please let me know. + +Contributors should appraise themselves of the document at +http://www.padl.com/Articles/GuidelinesforContributing.html. + +-- +Luke Howard <lukeh@padl.com> + @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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 library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + 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 Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the 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 a program 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. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + 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, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +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 compile 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) 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. + + c) 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. + + d) 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 source code 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 to +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 Library 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 + + Appendix: 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. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/CVSVersionInfo.txt b/CVSVersionInfo.txt new file mode 100644 index 0000000..c279132 --- /dev/null +++ b/CVSVersionInfo.txt @@ -0,0 +1,13 @@ +# Created and modified by checkpoint; do not edit +# $Id: CVSVersionInfo.txt,v 2.293 2006/06/22 02:39:11 lukeh Exp $ +# $Name: nss_ldap-251 $ +ProjectName: nss_ldap +ProjectVersion: 251 +ProjectMaintainer: lukeh +# +# run this before building in RC. @@@PLATFORM@@@ is +# substituted for our platform names (linux, solaris etc) +PreBuild: configure --with-ldap-lib=netscape4 --with-ldap-dir=/usr/local/ldapsdk4 --enable-rfc2307bis --disable-ssl +PostBuild: make distclean +# binaries to ship (although we don't do that at the moment) +Shippables: nss_ldap.so diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..37a62f4 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,1520 @@ +$Id: ChangeLog,v 2.374 2006/05/15 08:13:44 lukeh Exp $ +=============================================================== + +251 Luke Howard <lukeh@padl.com> + + * remove doc/rfc2307.txt, it is available from + http://www.ietf.org/rfc/rfc2307.txt + * make objectClass a mappable attribute + +250 Luke Howard <lukeh@padl.com> + + * 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 + +249 Luke Howard <lukeh@padl.com> + + * fix for BUG#253: build broken on AIX + * fix for BUG#255: deadlock in initgroups + +248 Luke Howard <lukeh@padl.com> + + * fix regression in per-objectclass attribute mapping + introduced in nss_ldap-246 + +247 Luke Howard <lukeh@padl.com> + + * double-check *ld != NULL even if mapped eror return + from ldap_initialize() returns NSS_SUCCESS + +246 Luke Howard <lukeh@padl.com> + + * 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 <rhafer@suse.de>: + 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 + +245 Luke Howard <lukeh@padl.com> + + * 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 <dean@interdynamix.com>: + build with Netscape 5 library on Solaris + * patch from Ralf Haferkamp <rhafer@suse.de>: + manual page fix to bind_policy + +244 Luke Howard <lukeh@padl.com> + + * patch from Ralf Haferkamp <rhafer@suse.de>: + enusre bytesleft macro does not return values < 0 + * include <sys/param.h> in ldap-nss.c + +243 Luke Howard <lukeh@padl.com> + + * fix for BUG#225: invalid pointer dereferencing when + reading rootpw + +242 Luke Howard <lukeh@padl.com> + + * fixes for compiling on Solaris 10 + +241 Luke Howard <lukeh@padl.com> + + * 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 + +240 Luke Howard <lukeh@padl.com> + + * 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 + +239 Luke Howard <lukeh@padl.com> + + * 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 <peter@adpm.de>: + revert the deletion of blanks/tabs in ldap.conf that + happened between 235 and 238 + * from Peter Marschall <peter@adpm.de>: + 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). + +238 Luke Howard <lukeh@padl.com> + + * more manual page updates + +237 Luke Howard <lukeh@padl.com> + + * more manual page updates + +236 Luke Howard <lukeh@padl.com> + + * fix for BUG#201: typo in ldap-schema.c causing build + to fail + * add manual page for nss_ldap + +235 Luke Howard <lukeh@padl.com> + + * fix for BUG#198: make pagesize configurable + * fix for BUG#199: correct fix for BUG#138 + (blind last char remove in ldap.secret) + +234 Luke Howard <lukeh@padl.com> + + * 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". + +233 Luke Howard <lukeh@padl.com> + + * 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) + +232 Luke Howard <lukeh@padl.com> + + * fix for BUG#138 (blind last char remove in ldap.secret) + +230 Luke Howard <lukeh@padl.com> + + * don't free gss_krb5_ccache_name() output (Heimdal) + +229 Luke Howard <lukeh@padl.com> + + * 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 + +228 Luke Howard <lukeh@padl.com> + + * 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 + +227 Luke Howard <lukeh@padl.com> + + * 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 + behaviour 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 + +226 Luke Howard <lukeh@padl.com> + + * make LDAP_NSS_NGROUPS configurable with + --with-ngroups (experts only) option + +225 Luke Howard <lukeh@padl.com> + + * make LDAP_NSS_NGROUPS 64 - better choice for + small directories + +224 Luke Howard <lukeh@padl.com> + + * 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 + +223 Luke Howard <lukeh@padl.com> + + * allow empty lines in /etc/ldap.conf + * do loop detection in nested groups + * fixes for building with IRS on FreeBSD 4.10 + +222 Luke Howard <lukeh@padl.com> + + * fix deadlock in _nss_ldap_getentry() + * support more AIX usersec attributes + * more AIX porting fixes + * support Heimdal as well as MIT Kerberos + +221 Luke Howard <lukeh@padl.com> + + * AIX fix from <carlos.celso@embraer.com.br> + 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 + +220 Luke Howard <lukeh@padl.com> + + * 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 + +218 Luke Howard <lukeh@padl.com> + + * fix for BUG#168: set errnop to ENOENT if not found + * check for -lgssapi before -lgssapi_krb5 + +217 Luke Howard <lukeh@padl.com> + + * fix for BUG#167: compilation fails on Solaris + +216 Luke Howard <lukeh@padl.com> + + * 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) + +215 Luke Howard <lukeh@padl.com> + + * choose between using native GSS-API and putenv() + for setting ccache path + * per-map attribute mapping for attributes that + appear in multiple maps + +214 Luke Howard <lukeh@padl.com> + + * define LDAP_DEPRECATED for compiling against + OpenLDAP 2.2 + +213 Luke Howard <lukeh@padl.com> + + * 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 + +212 Luke Howard <lukeh@padl.com> + + * 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 + +211 Luke Howard <lukeh@padl.com> + + * 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! + +210 Luke Howard <lukeh@padl.com> + + * initialize DBT structures + * fix SASL crasher + +209 Luke Howard <lukeh@padl.com> + + * fix SASL breakage + +208 Luke Howard <lukeh@padl.com> + + * 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 + +207 Luke Howard <lukeh@padl.com> + + * work without LDAP_OPT_X_TLS_RANDOM_FILE + * fix schema mapping regression from nss_ldap-205; + attribute mapping now works again + +205 Luke Howard <lukeh@padl.com> + + * build with Sleepycat DB without db185 compat layer + (tested with 4.x; needs testing on 3.x) + +204 Luke Howard <lukeh@padl.com> + + * Linux netgroup implementation from Larry Lile + * Multiple service search descriptor support from + Symas + * IPv6 patch from Thorsten Kukuk at SuSE + +203 Luke Howard <lukeh@padl.com> + + * fix for BUG#115 + * fix for BUG#121 + +202 Luke Howard <lukeh@padl.com> + + * getsockname() fixes from Howard Chu + * configuration parser crasher fix + +201 Luke Howard <lukeh@padl.com> + + * Berkeley DB fixes from Howard Chu + * Netscape client library build fix + +200 Luke Howard <lukeh@padl.com> + + * use sigprocmask() if available to block SIGPIPE + * fix build breakage with OpenLDAP HEAD + +199 Luke Howard <lukeh@padl.com> + + * 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) + +198 Luke Howard <lukeh@padl.com> + + * 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 + +197 Luke Howard <lukeh@padl.com> + + * improved AIX documentation from Dejan Muhamedagic + * define LDAP_OPT_SSL for Solaris 9 + +196 Luke Howard <lukeh@padl.com> + + * 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 + +195 Luke Howard <lukeh@padl.com> + + * fixed BUG#98: large groups cause buffer length + wraparound with rfc2307bis + +194 Luke Howard <lukeh@padl.com> + + * bugfix for Debian Bug report #147553: lack of global + mutex use in initgroups() + +193 Luke Howard <lukeh@padl.com> + + * support for PADL GSS-SASL client library + +192 Luke Howard <lukeh@padl.com> + + * more carefully compare cached socket and peer + addresses + +191 Luke Howard <lukeh@padl.com> + + * added configurable [hard|soft] reconnect, see the + bind_policy parameter in ldap.conf. + +190 Luke Howard <lukeh@padl.com> + + * check for Netscape 4 SDK without SSL; don't require + pthreads for these + +189 Luke Howard <lukeh@padl.com> + + * patch for building on OpenLDAP 1.x from Nalin + at RedHat + +188 Luke Howard <lukeh@padl.com> + + * specify runtime path for LDAP library correctly to + native Solaris linker + * check for gcc correctly + * use native linker on Solaris and AIX + +187 Luke Howard <lukeh@padl.com> + + * 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 + +186 Luke Howard <lukeh@padl.com> + + * 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. + +185 Luke Howard <lukeh@padl.com> + + * updated copyrights + * fix for BUG#82: set close on exec (Debian bug 136953) + +184 Luke Howard <lukeh@padl.com> + + * return NSS_TRYAGAIN if no buffer space in ldap-grp.c + +183 Luke Howard <lukeh@padl.com> + + * return error strings in AIX authentication routine + * initialise schema in getgroupsbymember() + * fix for tls_checkpeer; pass NULL session in to + set global option + * BUG#77: configurable config file locations + +181 Luke Howard <lukeh@padl.com> + + * 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 + +180 Luke Howard <lukeh@padl.com> + + * pull in libpthreads on AIX + +179 Luke Howard <lukeh@padl.com> + + * a couple more patches for AIX + +178 Luke Howard <lukeh@padl.com> + + * 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 + +177 Luke Howard <lukeh@padl.com> + + * 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 + +176 Luke Howard <lukeh@padl.com> + + * fixed bug in SASL patch which had required + OpenLDAP headers + +175 Luke Howard <lukeh@padl.com> + + * incorporated GSS-API SASL patches + * rebind to server on LDAP_LOCAL_ERROR + +174 Luke Howard <lukeh@padl.com> + + * added patches from Maxim Batourine for compiling + with Sun workshop compiler + * added notes re: 64-bit compile on Solaris from + above source + +173 Luke Howard <lukeh@padl.com> + + * notes on IRS in doc/README.IRS + * added irs.h for AIX compat + * patch from Bob Guo for stripping trailing + spaces in ldap.conf. + +172 Luke Howard <lukeh@padl.com> + + * 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! + +171 Luke Howard <lukeh@padl.com> + + * added ldap.conf stanza for AIX + * workaround for schema mapping bug. + +170 Luke Howard <lukeh@padl.com> + + * use _nss_ldap_getrdnvalue() for determining canonical + group name + +169 Luke Howard <lukeh@padl.com> + + * fixed typo in ldap-service.c; prefix filters now + with _nss_ldap + +168 Luke Howard <lukeh@padl.com> + + * 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 + +167 Luke Howard <lukeh@padl.com> + + * support for new OpenLDAP rebind proc prototype + * in rebind function, respect timeout + * fix for PADL Release Control + +166 Luke Howard <lukeh@padl.com> + + * corrected small typos + +165 Luke Howard <lukeh@padl.com> + + * posixMember is a distinguished name, don't pretend it + is a login name + * cleaned up code referencing different member syntaxes + +164 Luke Howard <lukeh@padl.com> + + * removed IDS_UID code, never worked properly + +163 Luke Howard <lukeh@padl.com> + + * removed context_free function, usage confusing + +162 Luke Howard <lukeh@padl.com> + + * in reconnect harness, do not treat entry not found + errors as requiring a reconnect + +161 Luke Howard <lukeh@padl.com> + + * hopefully fixed use of synchronous searches in + _nss_ldap_getbyname() + +160 Luke Howard <lukeh@padl.com> + + * patch from RedHat to check for DB3, override + install user/group optionally + * use synchoronous searches for _nss_ldap_getbyname() + * only set SSL options if we have values for those + options + +159 Luke Howard <lukeh@padl.com> + + * make do_ssl_options() take a config parameter; + avoid segfault with SSL? + +158 Luke Howard <lukeh@padl.com> + + * 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. + +157 Luke Howard <lukeh@padl.com> + + * for MSSFU, use posixMember for group memberships + rather than member (reported by Andy Rechenberg) + * ignore SIGPIPE before calling do_close() for + idle_timeout + +156 Luke Howard <lukeh@padl.com> + + * 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 + +155 Luke Howard <lukeh@padl.com> + + * do not use private API when setting OpenLDAP TLS + options (do_ssl_options()) + +154 Luke Howard <lukeh@padl.com> + + * notes from Scott M. Stone <sstone@foo3.com> + * idle timeout patch from Steve Barrus + +153 Luke Howard <lukeh@padl.com> + + * SSL fix + +152 Luke Howard <lukeh@padl.com> + + * further patch from Jarkko for TLS/SSL auth: + support for LDAPS/cipher suite selection/ + client key/cert authentication + +151 Luke Howard <lukeh@padl.com> + + * patch from Andrew Rechenberg for Active + Directory schema support + * patch from Jarkko Turkulainen <jt@wapit.com> for + peer certificate support with OpenLDAP + +150 Luke Howard <lukeh@padl.com> + + * patch from Anselm Kruis for URI support + +149 Luke Howard <lukeh@padl.com> + + * fixed compile on Solaris, broken in 145 by + malformed Linux patch + +148 Luke Howard <lukeh@padl.com> + + * check for HAVE_LDAP_SET_OPTION always + +147 Luke Howard <lukeh@padl.com> + + * check for ldap_set_option(), as LDAP_OPT_REFERRALS + is defined for OpenLDAP 1.x but without the + ldap_set_option() function + +146 Luke Howard <lukeh@padl.com> + + * mass reindentation, GNU style + * patch from Simon Wilkinson <sxw@sxw.org.uk> + for compatibility with old initgroups entry + point + * request authPassword attribute if + --enable-authpassword + * authPassword support in ldap-spwd.c (shadow) + +145 Luke Howard <lukeh@padl.com> + + * preliminary support for authPassword attribute + * updated COPYING + * patch from Szymon Juraszczyk to suppot + _nss_ldap_initgroups_dyn prototype + +144 Luke Howard <lukeh@padl.com> + + * when specifying filters with nss_base_XXX, + only escape the filter argument not the entire + filter + +143 Luke Howard <lukeh@padl.com> + + * 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. + +142 Luke Howard <lukeh@padl.com> + + * patch from Simon Wilkinson <sxw@sxw.org.uk> + for memory leak in ldap-service.c + +141 Luke Howard <lukeh@padl.com> + + * fix for BUG#54 (AIX detection broken) + * use -rpath on all platforms except Solaris, + not just Linux + +140 Luke Howard <lukeh@padl.com> + + * 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 + +139 Luke Howard <lukeh@padl.com> + + * updated INSTALL file with boilerplate + * fixed pointer error in ldap-nss.c + +138 Luke Howard <lukeh@padl.com> + + * 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. + +137.1 Luke Howard <lukeh@padl.com> + + * 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. + +137 Gabor Gombas <gombasg@inf.elte.hu> + + * build nss_ldap as a loadable module on AIX + * doco on AIX + +136 Luke Howard <lukeh@padl.com> + + * define -DPIC for FreeBSD + * link with -shared not --shared + * fixes for AIX + +135 Luke Howard <lukeh@padl.com> + + * merged ldap.conf + * fixed bug in concatenating relative search + bases in ldap-nss.c (profile support) + +134 Luke Howard <lukeh@padl.com> + + * fixed Makefile.am + * reordered DB search order in util.c + +133 Luke Howard <lukeh@padl.com> + + * make /usr/lib directory in Makefile.am + * new spec file from Joe Little + +132 Luke Howard <lukeh@padl.com> + + * fixed rebind preprocessor logic + +131 Luke Howard <lukeh@padl.com> + + * created files for automake happiness + +130 Luke Howard <lukeh@padl.com> + + * fixed typo preventing build with Netscape + client library + +129 Luke Howard <lukeh@padl.com> + + * updated version number + * fixed build bug on Solaris + +128 Luke Howard <lukeh@padl.com> + + * fixed logic bug in util.c introduced in + nss_ldap-127 + +127 Luke Howard <lukeh@padl.com> + + * 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 + +126 Luke Howard <lukeh@padl.com> + +125 Luke Howard <lukeh@padl.com> + + * fixed up Linux Makefiles to build libnss_ldap + +124 Luke Howard <lukeh@padl.com> + + * patch from nalin@redhat.com for StartTLS + * fixed up indenting + +123 Luke Howard <lukeh@padl.com> + + * rolled in BUG#52 branch with fixes for AIX + +122.BZ52.2 Luke Howard <lukeh@padl.com> + + * included ldap-schema.c; omitted from previous + checkpoint + +122.BZ52.1 Luke Howard <lukeh@padl.com> + + * preliminary fix for BUG#52 (support for different + naming contexts for each map) + * fixed bug in enumerating services map + +122 Luke Howard <lukeh@padl.com> + + * fixed BUG#50 (check return value of ldap_simple_bind()) + +121 Luke Howard <lukeh@padl.com> + + * fixed BUG#49 (fix acknowledged race condition) + +120 Luke Howard <lukeh@padl.com> + + * added Makefile.aix and exports.aix (forgot) + +119 Luke Howard <lukeh@padl.com> + + * patch from Gabor Gombas <gombasg@inf.elte.hu> + to support AIX implementation of BIND IRS + +118 Luke Howard <lukeh@padl.com> + + * Makefile.RPM.openldap2 from Joe Little + +117 Luke Howard <lukeh@padl.com> + + * permanently ignore SIGPIPE when using SSL. This + bug should be fixed properly. + +116 Luke Howard <lukeh@padl.com> + + * added irs-nss.diff and README.IRS from Emile + Heitor + +115 Luke Howard <lukeh@padl.com> + + * 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 + +113 Luke Howard <lukeh@padl.com> + + * patch from Ben Collins to escape '*' in filters + +110 Luke Howrad <lukeh@padl.com> + + * patch from Phlilip Liu for async binds + +109 Luke Howard <lukeh@padl.com> + + * omit socket check for -DSSL; it doesn't work + * updated CONTRIBUTORS + * updated README re HAVE_LDAP_LD_FREE + +108 Luke Howard <lukeh@padl.com> + + * included "deref" option in /etc/ldap.conf, compatible + with OpenLDAP syntax. Patch from Michael Mattice. + +107 Luke Howard <lukeh@padl.com> + + * fixed argument to _nss_ldap_getent() in ldap-ethers.c + +106.2 Luke Howard <lukeh@padl.com> + + * if root, use rootbinddn/rootbindpw in rebind proc + * include objectClass in pwd required attributes + +106.1 Luke Howard <lukeh@padl.com> + + * 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() + +105 Luke Howard <lukeh@padl.com> + + * incorporated patch for deadlock under Solaris (from + Dave Begley) + +104 Luke Howard <lukeh@padl.com> + + * new spec file + +103 Luke Howard <lukeh@padl.com> + + * don't call ldap_parse_result() with V2 API + +102 Luke Howard <lukeh@padl.com> + + * added defines for LDAP_MSG_ONE et al if not in ldap.h + * removed LDAP_MORE_RESULTS_TO_RETURN test + +101 Luke Howard <lukeh@padl.com> + + * fixed spec file + +100 Luke Howard <lukeh@padl.com> + + * support for asynchronous search API! + * added some contributors + * notes about ldap_ld_free() + * merged in ChangeLog + +99 Luke Howard <lukeh@padl.com> + + * added some netgroup implementation tips + * do_close_no_unbind() cleanup + +98 Luke Howard <lukeh@padl.com> + + * /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 + +97 Luke Howard <lukeh@padl.com> + + * #ifndef HAVE_LDAP_LD_FREE, still call ldap_unbind(), + but having closed the descriptor. + +96 Luke Howard <lukeh@padl.com> + + * re-orged + +95 Luke Howard <lukeh@padl.com> + + * disable SO_KEEPALIVE on socket rather than blocking + SIGPIPE. Need to figure out the right way to do this. + +94 Luke Howard <lukeh@padl.com> + + * 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. + +93 Luke Howard <lukeh@padl.com> + + * 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. + +92 Luke Howard <lukeh@padl.com> + + * signal handling fix: don't restore handler + unnecessarily. + * don't open nss_ldap.secret unless a root pw + is specified in ldap.conf + +91 Luke Howard <lukeh@padl.com> + + * reorganized SIGPIPE blocking code + * added SSL support + +90 Luke Howard <lukeh@padl.com> + + * only reconnect if we've changed to/from root + +89 Luke Howard <lukeh@padl.com> + + * cleaned up a few things + +88 Luke Howard <lukeh@padl.com> + + * 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. + +87 Luke Howard <lukeh@padl.com> + + * fixed looking up DN-membered groups by member. Thanks + to Jeff Mandel for spotting this hard to find bug. + +86 Luke Howard <lukeh@padl.com> + + * member for NDS vs uniqueMember (needs further + investigation; -DNDS) + +85 Luke Howard <lukeh@padl.com> + + * check non-NULLity of userdn before freeing + * use AT(uid) for groupsbymember filter + +84 Luke Howard <lukeh@padl.com> + + * implemented _nss_ldap_initgroups() + +81 Luke Howard <lukeh@padl.com> + + * removed extraneous do_sleep() code + * updated spec file + +80 Luke Howard <lukeh@padl.com> + + * (really 2.80) changed version number a la Solaris 7! + * cleaned up schema stuff into ldap-schema.h + +2.79 Luke Howard <lukeh@padl.com> + + * implemented exponential backoff reconnect logic + +2.78 Luke Howard <lukeh@padl.com> + + * removed ldap.conf.ragenet from lineup + * removed spurious do_close() + +2.76 Luke Howard <lukeh@padl.com> + + * added -lresolv to Solaris makefiles + +2.75 Luke Howard <lukeh@padl.com> + + * incorporated RPM patches from stein@terminator.net + +2.72 Luke Howard <lukeh@padl.com> + + * implemented getgroupsbymember() for Solaris. + Supplementary groups should be initialized now. + (NB: doesn't appear to be quite working for + RFC2307bis yet.) + * GNU indent-ified + +2.71 Luke Howard <lukeh@padl.com> + + * removed -DDEBUG as default build flag + +2.70 Luke Howard <lukeh@padl.com> + + * put /usr/ucblib back into linker search path for + Solaris. + +2.69 Luke Howard <lukeh@padl.com> + + * added timeout, unavailable, and server busy + conditions to rebind logic + * indent -gnu all source files + +2.68 Luke Howard <lukeh@padl.com> + + * mods for glibc 2.1 (__set_errno is obselete it seems) + +2.65 Luke Howard <lukeh@padl.com> + + * mods to compile with OpenLDAP 2 + +2.64 Luke Howard <lukeh@padl.com> + + * changed alias schema to Sun SDS nisMailAlias schema + * updated TODO list to reflect Bugzilla entries + * restored capitalization of attributes for "niceness" + +2.63 Luke Howard <lukeh@padl.com> + + * added patch from gero@faveve.uni-stuttgart.de for + parsing of ldap.conf with tabs + * some fixes for BSDI BSD/OS IRS + +2.62 Luke Howard <lukeh@padl.com> + + * added experimental support for DN-membered groups; + to enable, define RFC2307BIS + * fixed align bug (where buflen wasn't being + decremented after pointer alignment) + +2.61 Luke Howard <lukeh@padl.com> + + * added warning about compiling with DS 4.1 LDAP SDK + +2.60 Luke Howard <lukeh@padl.com> + + * fixed missing close brace + +2.59 Luke Howard <lukeh@padl.com> + + * pw_comment field defaults to pw_gecos (Solaris only) + +2.56 Luke Howard <lukeh@padl.com> + + * fixed Makefile.linux.mozilla NSSLIBVER + +2.55 Luke Howard <lukeh@padl.com> + + * merged in glibc-2.1 branch + +2.54.6 Luke Howard <lukeh@padl.com> + + * misc fixes. + +2.54.5 Luke Howard <lukeh@padl.com> + + * misc fixes. + +2.54.4 Luke Howard <lukeh@padl.com> + + * glibc-2.1 patches from bcollins@debian.org + +2.54.3 Luke Howard <lukeh@padl.com> + + * glibc-2.1 support. (Recall #93) + * set erange correctly on Solaris (related to above) + +2.51 Luke Howaed <lukeh@padl.com> + + * added rebind function + +2.51 Luke Howard <lukeh@padl.com> + + * added stuff for RC + +2.49 Luke Howard <lukeh@padl.com> + + * configuration file is now case insensitive + +2.47 Luke Howard <lukeh@xedoc.com> + + * RFC2052BIS (_ldap._tcp) support + +2.45 Luke Howard <lukeh@xedoc.com> + + * added #include <stdlib.h> to globals.c + +2.44 Luke Howard <lukeh@xedoc.com> + + * NULL search base allowed (omit basedn from config file) + +2.42 Luke Howard <lukeh@xedoc.com> + + * 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(). + +2.39 Luke Howard <lukeh@xedoc.com> + + * fixed warning in ldap-ethers.c (removed const from + struct ether) + * added ldap_version keyword to ldap.conf for parity with + pam_ldap + +2.38 Luke Howard <lukeh@xedoc.com> + + * 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. + +2.37 Luke Howard <lukeh@xedoc.com> + + * moved to CVS repository and Linux as development + environment + * incorporated ldap-service.c fix from Greg + +2.36 Luke Howard <lukeh@xedoc.com> + + * util.c: will use ldap_explode_rdn() if it exists + +2.35 Luke Howard <lukeh@xedoc.com> + + * made util.c compile again. Silly me. + +2.34 Luke Howard <lukeh@xedoc.com> + + * 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 + +2.33 Luke Howard <lukeh@xedoc.com> + + * 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 + +2.32 Luke Howard <lukeh@xedoc.com> + + * moved Makefile to Makefile.solaris + * cleaned up mutex code for Linux, hopefully + +2.31 Luke Howard <lukeh@xedoc.com> + + * 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 + +2.30 Luke Howard <lukeh@xedoc.com> + + * synced into DevMan repository again + * RFC 2307 is the one! + +2.29e Luke Howard <lhoward@apple.com> + + * util.c: fixed memory leak (call to ldap_value_free()) + +2.29d Luke Howard <lhoward@apple.com> + + * ldap-ethers.c: fixed to use HOSTNAME attribute + +2.29c Luke Howard <lhoward@apple.com> + + * ieee8022Device -> ieee802Device + +2.29b Luke Howard <lhoward@apple.com> + + * added ieee8022Device and bootableDevice classes, + at Sun's request. + +2.29a Luke Howard <lhoward@apple.com> + + * dc -> cn + +2.29 Luke Howard <lukeh@xedoc.com> + + * changed host/network/ethers naming schema + see the -02 draft revision for more info + +2.28 Luke Howard <lukeh@xedoc.com> + + * ldap-pwd.c, ldap-spwd.c: fixed tmpbuf stuff. Yuck. + +2.27 Luke Howard <lukeh@xedoc.com> + + * 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) + +2.26 Luke Howard <lukeh@xedoc.com> + + * 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. + +2.25 Luke Howard <lukeh@xedoc.com> + + * 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) + +2.24 Luke Howard <lukeh@xedoc.com> + + * 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 + +2.23 Luke Howard <lukeh@xedoc.com> + + * 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. + +2.22 Luke Howard <lukeh@xedoc.com> + + * 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 + +2.21 Luke Howard <lukeh@xedoc.com> + + * 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. :-) + +2.20 Luke Howard <lukeh@xedoc.com> + + * Makefile.*: ensured resolve.[ch] and dnsconfig.[ch] were there. + * Makefile: should link now with gcc -shared instead of requiring + cc. + +2.19 Luke Howard <lukeh@xedoc.com> + + * 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 + +2.18 Luke Howard <lukeh@xedoc.com> + + * 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. + +2.17 Luke Howard <lukeh@xedoc.com> + + * Cleaned up documentation and testpw4.c + * dnsconfig.c: Fixed strtok() bug which was clobbering domain + +2.16 Luke Howard <lukeh@xedoc.com> + + * util.c (_nss_ldap_readconfig) fixed strtok() typo + +2.15 Luke Howard <lukeh@xedoc.com> + + * dnsconfig.c: got DNS SRV support working under NEXTSTEP + * util.c: (_nss_ldap_getdomainname) made host and network DN parsing + compliant with current draft + +2.2 - 2.14 Luke Howard <lukeh@xedoc.com> + + * 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. + +2.1 Luke Howard <lukeh@xedoc.com> + + * merged in old RCS tree (now nss_ldap 0.2) + +1.x Luke Howard <lukeh@xedoc.com> + + * old RCS repository (corresponds to nss_ldap 0.1) + @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' 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. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. 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. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..92f3fa6 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,103 @@ +if AIX +authmod = NSS_LDAP +else +authmod = +endif + +noinst_PROGRAMS = nss_ldap.so $(authmod) +INST_UID=root +if AIX +INST_GID=system +else +INST_GID=root +endif + +EXTRA_DIST = CVSVersionInfo.txt ChangeLog \ + AUTHORS ANNOUNCE NEWS INSTALL README LICENSE.OpenLDAP COPYING\ + ldap.conf nss_ldap.spec nsswitch.ldap + +man_MANS = nss_ldap.5 + +nss_ldap_so_SOURCES = ldap-nss.c ldap-pwd.c ldap-grp.c ldap-netgrp.c ldap-rpc.c \ + ldap-hosts.c ldap-network.c ldap-proto.c ldap-spwd.c \ + ldap-alias.c ldap-service.c ldap-schema.c ldap-ethers.c \ + ldap-bp.c ldap-automount.c util.c ltf.c snprintf.c resolve.c \ + dnsconfig.c irs-nss.c pagectrl.c ldap-sldap.c + +nss_ldap_so_LDFLAGS = @nss_ldap_so_LDFLAGS@ + +NSS_LDAP_PATH_CONF = @NSS_LDAP_PATH_CONF@ +NSS_LDAP_PATH_ROOTPASSWD = @NSS_LDAP_PATH_ROOTPASSWD@ + +NSS_LDAP_SOURCES = ldap-nss.c ldap-grp.c ldap-pwd.c ldap-netgrp.c ldap-schema.c \ + util.c ltf.c snprintf.c resolve.c dnsconfig.c \ + irs-nss.c pagectrl.c aix_authmeth.c + +NSS_LDAP_LDFLAGS = @NSS_LDAP_LDFLAGS@ +DEFS = @DEFS@ +#INCLUDES = -I$(top_builddir) -I$(srcdir) + +if GLIBC +LIBC_VERS = `ls /lib/libc-*.so | tail -n 1 |sed -e 's/\/lib\/libc-\(.*\)\.so/\1/'` +NSS_LDAP_LIBC_VERSIONED = libnss_ldap-$(LIBC_VERS).so + +NSS_VERS = $(shell ls /lib/libnss_files.so.? | tail -n 1 | sed -e 's/\/lib\/libnss_files\.so\.\(.*\)/\1/') +NSS_LDAP_NSS_VERSIONED = libnss_ldap.so.$(NSS_VERS) +endif + +if USE_NATIVE_LINKER +NATIVE_LINK = $(nss_ldap_so_LD) $(AM_LDFLAGS) -o $@ +else +GNU_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +endif + +# This is horrible but appears to be the only way to work with +# recent versions of automake. Any better ideas, let me know. +LINK = $(NATIVE_LINK) $(GNU_LINK) + +if AIX + +# AIX install instructions per doc/README.AIX + +install-exec-local: nss_ldap.so NSS_LDAP + $(mkinstalldirs) $(DESTDIR)$(libdir)/netsvc/dynload + $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/netsvc/dynload/nss_ldap.so + $(mkinstalldirs) $(DESTDIR)$(libdir)/security + $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) NSS_LDAP $(DESTDIR)$(libdir)/security/NSS_LDAP + +else + +# Linux, Solaris, other platform install instructions + +install-exec-local: nss_ldap.so + @$(NORMAL_INSTALL) +if GLIBC + -rm -f $(DESTDIR)$(libdir)/$(NSS_LDAP_LIBC_VERSIONED) + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/$(NSS_LDAP_LIBC_VERSIONED) + (cd $(DESTDIR)$(libdir); ln -sf $(NSS_LDAP_LIBC_VERSIONED) $(NSS_LDAP_NSS_VERSIONED)) + $(mkinstalldirs) $(DESTDIR)/usr$(libdir) + (cd $(DESTDIR)/usr$(libdir); ln -sf ../..$(libdir)/$(NSS_LDAP_NSS_VERSIONED) .) +else + $(mkinstalldirs) $(DESTDIR)$(libdir) +if HPUX + $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/libnss_ldap.1 +else + $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/nss_ldap.so.1 + (cd $(DESTDIR)$(libdir); rm -f nss_ldap.so; ln -s nss_ldap.so.1 nss_ldap.so) +endif +endif + +endif + +install-data-local: + @$(NORMAL_INSTALL) + @if test ! -f $(DESTDIR)$(NSS_LDAP_PATH_CONF); then \ + $(mkinstalldirs) $(DESTDIR)$(dir $(NSS_LDAP_PATH_CONF)); \ + $(INSTALL_DATA) -o $(INST_UID) -g $(INST_GID) $(srcdir)/ldap.conf $(DESTDIR)$(NSS_LDAP_PATH_CONF); \ + fi + $(INSTALL_DATA) -o $(INST_UID) -g $(INST_GID) $(srcdir)/nsswitch.ldap $(DESTDIR)$(sysconfdir)/nsswitch.ldap; + +uninstall-local: + @$(NORMAL_UNINSTALL) + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..08a99a6 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,513 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +CC = @CC@ +CPP = @CPP@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +nss_ldap_so_LD = @nss_ldap_so_LD@ +@AIX_TRUE@authmod = NSS_LDAP +@AIX_FALSE@authmod = + +noinst_PROGRAMS = nss_ldap.so $(authmod) +INST_UID = root +@AIX_TRUE@INST_GID = system +@AIX_FALSE@INST_GID = root + +EXTRA_DIST = CVSVersionInfo.txt ChangeLog AUTHORS ANNOUNCE NEWS INSTALL README LICENSE.OpenLDAP COPYING ldap.conf nss_ldap.spec nsswitch.ldap + + +man_MANS = nss_ldap.5 + +nss_ldap_so_SOURCES = ldap-nss.c ldap-pwd.c ldap-grp.c ldap-netgrp.c ldap-rpc.c ldap-hosts.c ldap-network.c ldap-proto.c ldap-spwd.c ldap-alias.c ldap-service.c ldap-schema.c ldap-ethers.c ldap-bp.c ldap-automount.c util.c ltf.c snprintf.c resolve.c dnsconfig.c irs-nss.c pagectrl.c ldap-sldap.c + + +nss_ldap_so_LDFLAGS = @nss_ldap_so_LDFLAGS@ + +NSS_LDAP_PATH_CONF = @NSS_LDAP_PATH_CONF@ +NSS_LDAP_PATH_ROOTPASSWD = @NSS_LDAP_PATH_ROOTPASSWD@ + +NSS_LDAP_SOURCES = ldap-nss.c ldap-grp.c ldap-pwd.c ldap-netgrp.c ldap-schema.c util.c ltf.c snprintf.c resolve.c dnsconfig.c irs-nss.c pagectrl.c aix_authmeth.c + + +NSS_LDAP_LDFLAGS = @NSS_LDAP_LDFLAGS@ +DEFS = @DEFS@ +#INCLUDES = -I$(top_builddir) -I$(srcdir) + +@GLIBC_TRUE@LIBC_VERS = `ls /lib/libc-*.so | tail -n 1 |sed -e 's/\/lib\/libc-\(.*\)\.so/\1/'` +@GLIBC_TRUE@NSS_LDAP_LIBC_VERSIONED = libnss_ldap-$(LIBC_VERS).so + +@GLIBC_TRUE@NSS_VERS = $(shell ls /lib/libnss_files.so.? | tail -n 1 | sed -e 's/\/lib\/libnss_files\.so\.\(.*\)/\1/') +@GLIBC_TRUE@NSS_LDAP_NSS_VERSIONED = libnss_ldap.so.$(NSS_VERS) + +@USE_NATIVE_LINKER_TRUE@NATIVE_LINK = $(nss_ldap_so_LD) $(AM_LDFLAGS) -o $@ +@USE_NATIVE_LINKER_FALSE@GNU_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + +# This is horrible but appears to be the only way to work with +# recent versions of automake. Any better ideas, let me know. +LINK = $(NATIVE_LINK) $(GNU_LINK) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) + +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +nss_ldap_so_OBJECTS = ldap-nss.o ldap-pwd.o ldap-grp.o ldap-netgrp.o \ +ldap-rpc.o ldap-hosts.o ldap-network.o ldap-proto.o ldap-spwd.o \ +ldap-alias.o ldap-service.o ldap-schema.o ldap-ethers.o ldap-bp.o \ +ldap-automount.o util.o ltf.o snprintf.o resolve.o dnsconfig.o \ +irs-nss.o pagectrl.o ldap-sldap.o +nss_ldap_so_LDADD = $(LDADD) +nss_ldap_so_DEPENDENCIES = +NSS_LDAP_OBJECTS = ldap-nss.o ldap-grp.o ldap-pwd.o ldap-netgrp.o \ +ldap-schema.o util.o ltf.o snprintf.o resolve.o dnsconfig.o irs-nss.o \ +pagectrl.o aix_authmeth.o +NSS_LDAP_LDADD = $(LDADD) +NSS_LDAP_DEPENDENCIES = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +man5dir = $(mandir)/man5 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \ +Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 config.guess \ +config.h.in config.sub configure configure.in install-sh missing \ +mkinstalldirs + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +DEP_FILES = .deps/aix_authmeth.P .deps/dnsconfig.P .deps/irs-nss.P \ +.deps/ldap-alias.P .deps/ldap-automount.P .deps/ldap-bp.P \ +.deps/ldap-ethers.P .deps/ldap-grp.P .deps/ldap-hosts.P \ +.deps/ldap-netgrp.P .deps/ldap-network.P .deps/ldap-nss.P \ +.deps/ldap-proto.P .deps/ldap-pwd.P .deps/ldap-rpc.P \ +.deps/ldap-schema.P .deps/ldap-service.P .deps/ldap-sldap.P \ +.deps/ldap-spwd.P .deps/ltf.P .deps/pagectrl.P .deps/resolve.P \ +.deps/snprintf.P .deps/util.P +SOURCES = $(nss_ldap_so_SOURCES) $(NSS_LDAP_SOURCES) +OBJECTS = $(nss_ldap_so_OBJECTS) $(NSS_LDAP_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.h.in: $(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +nss_ldap.so: $(nss_ldap_so_OBJECTS) $(nss_ldap_so_DEPENDENCIES) + @rm -f nss_ldap.so + $(LINK) $(nss_ldap_so_LDFLAGS) $(nss_ldap_so_OBJECTS) $(nss_ldap_so_LDADD) $(LIBS) + +NSS_LDAP: $(NSS_LDAP_OBJECTS) $(NSS_LDAP_DEPENDENCIES) + @rm -f NSS_LDAP + $(LINK) $(NSS_LDAP_LDFLAGS) $(NSS_LDAP_OBJECTS) $(NSS_LDAP_LDADD) $(LIBS) + +install-man5: + $(mkinstalldirs) $(DESTDIR)$(man5dir) + @list='$(man5_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.5*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \ + done + +uninstall-man5: + @list='$(man5_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.5*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \ + rm -f $(DESTDIR)$(man5dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man5 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man5 + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: install-exec-local +install-exec: install-exec-am + +install-data-am: install-man install-data-local +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-man uninstall-local +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(MANS) config.h +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(mandir)/man5 + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-hdr mostlyclean-noinstPROGRAMS \ + mostlyclean-compile mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-hdr clean-noinstPROGRAMS clean-compile clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-hdr distclean-noinstPROGRAMS distclean-compile \ + distclean-tags distclean-depend distclean-generic \ + clean-am + +distclean: distclean-am + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr \ + maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile install-man5 uninstall-man5 install-man \ +uninstall-man tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir mostlyclean-depend distclean-depend \ +clean-depend maintainer-clean-depend info-am info dvi-am dvi check \ +check-am installcheck-am installcheck all-recursive-am \ +install-exec-local install-exec-am install-exec install-data-local \ +install-data-am install-data install-am install uninstall-local \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# AIX install instructions per doc/README.AIX + +@AIX_TRUE@install-exec-local: nss_ldap.so NSS_LDAP +@AIX_TRUE@ $(mkinstalldirs) $(DESTDIR)$(libdir)/netsvc/dynload +@AIX_TRUE@ $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/netsvc/dynload/nss_ldap.so +@AIX_TRUE@ $(mkinstalldirs) $(DESTDIR)$(libdir)/security +@AIX_TRUE@ $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) NSS_LDAP $(DESTDIR)$(libdir)/security/NSS_LDAP + +# Linux, Solaris, other platform install instructions + +@AIX_FALSE@install-exec-local: nss_ldap.so +@AIX_FALSE@ @$(NORMAL_INSTALL) +@AIX_FALSE@@GLIBC_TRUE@ -rm -f $(DESTDIR)$(libdir)/$(NSS_LDAP_LIBC_VERSIONED) +@AIX_FALSE@@GLIBC_TRUE@ $(mkinstalldirs) $(DESTDIR)$(libdir) +@AIX_FALSE@@GLIBC_TRUE@ $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/$(NSS_LDAP_LIBC_VERSIONED) +@AIX_FALSE@@GLIBC_TRUE@ (cd $(DESTDIR)$(libdir); ln -sf $(NSS_LDAP_LIBC_VERSIONED) $(NSS_LDAP_NSS_VERSIONED)) +@AIX_FALSE@@GLIBC_TRUE@ $(mkinstalldirs) $(DESTDIR)/usr$(libdir) +@AIX_FALSE@@GLIBC_TRUE@ (cd $(DESTDIR)/usr$(libdir); ln -sf ../..$(libdir)/$(NSS_LDAP_NSS_VERSIONED) .) +@AIX_FALSE@@GLIBC_FALSE@ $(mkinstalldirs) $(DESTDIR)$(libdir) +@AIX_FALSE@@GLIBC_FALSE@@HPUX_TRUE@ $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/libnss_ldap.1 +@AIX_FALSE@@GLIBC_FALSE@@HPUX_FALSE@ $(INSTALL_PROGRAM) -o $(INST_UID) -g $(INST_GID) nss_ldap.so $(DESTDIR)$(libdir)/nss_ldap.so.1 +@AIX_FALSE@@GLIBC_FALSE@@HPUX_FALSE@ (cd $(DESTDIR)$(libdir); rm -f nss_ldap.so; ln -s nss_ldap.so.1 nss_ldap.so) + +install-data-local: + @$(NORMAL_INSTALL) + @if test ! -f $(DESTDIR)$(NSS_LDAP_PATH_CONF); then \ + $(mkinstalldirs) $(DESTDIR)$(dir $(NSS_LDAP_PATH_CONF)); \ + $(INSTALL_DATA) -o $(INST_UID) -g $(INST_GID) $(srcdir)/ldap.conf $(DESTDIR)$(NSS_LDAP_PATH_CONF); \ + fi + $(INSTALL_DATA) -o $(INST_UID) -g $(INST_GID) $(srcdir)/nsswitch.ldap $(DESTDIR)$(sysconfdir)/nsswitch.ldap; + +uninstall-local: + @$(NORMAL_UNINSTALL) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: @@ -0,0 +1,149 @@ +#ident $Id: NEWS,v 2.5 2004/06/19 05:23:05 lukeh Exp $ + +Please contact PADL Software Development Support <dev@padl.com> +if you wish to contribute. + +Please see http://bugzilla.padl.com for more information! + +BUGZILLA BUGS: +============== + +BUGS 18, 19, 20, 34 would be good to fix soon. + +[BUG#12] +- we should probably put the session, under Solaris, in the backend. + We need to do so in a way that remains compatible with the GNU NSS, + where I expect we need to open a connection for every lookup. + In nscd, where the backends are cached, it doesn't make sense to keep + opening and closing sockets to the LDAP server, particularly as the + rebinding logic was put there to *allow* the connection to be long + lived (marked RESOLVED LATER; a single connection is now used per + process) + +[BUG#12] +- ditto for IRS: the private data should contain the session and be long + lived. + +[BUG#13] +- we could clean up the text segment a bit by generating filters on the + fly from object classes and attributes, instead of storing them. This + seems to be important under Solaris as the linker doesn't intern strings (?) + All that filter-constructing stuff in the ldap-*.h headers is UGLY. + (marked RESOLVED LATER) + +[BUG#14] +- infinite recursion is host lookup -- libldap uses gethostbyname(). Perhaps + we should link with a custom gethostbyname() which uses DNS only??? (This + is nominally the LDAP client library's problem but we could short-circuit + by resolving the IP addresses ourselves). (marked RESOLVED INVALID) + +[BUG#16] +- finish implementing dl-*.c (LOW priority). In fact I'm tempted to remove + this from the line up: SGI have their own LDAP C library support, and + so do DEC (with SIA). (removed dl-*.c; marked RESOLVED WONTFIX) + +[BUG#17] +- implement gethostbyname2() and + debug IPv6 support in ldap-hosts.c (and ldap-network.c?) (Uli?) + +[BUG#19] +- add support for DHCP and coldstart configuration. Coldstart should + update /etc/ldap.conf (/var/ldap/LDAP_CLIENT_CACHE?). Should probably + add support for the HP/Sun server profile schema (marked RESOLVED + LATER) + +[BUG#21] +- write testsuite (marked RESOLVED LATER) + +[BUG#22] +- support for bootparams map (marked RESOLVED LATER) + +[BUG#34] +- shells hang on Solaris for LDAP users (marked RESOLVED LATER; +Solaris 7 users get patch cluster 106541-12) + +[BUG#49] +- race condition in ldap-nss.c (FIXED in nss_ldap-121) + +[BUG#50] +- check return value of ldap_simple_bind() (FIXED in nss_ldap-122) + +[BUG#63] +- integrate support for runtime schema mapping (FIXED in nss_ldap-168) + +To: linux-ldap@rage.net +Cc: ldap-nis@padl.com +Subject: Re: Netgroups [in nss_ldap] +Fcc: +outgoing +Reply-To: lukeh@padl.com + +[ ldap-nis readers may find this interesting. ] + +Matt, + +>Ok, i am going to see if I can do something with netgroups. Which of +>the services would be best to model ldap-netgrp.c after? +> +>I am not familiar with adding a new service to nss_ldap. What is +>involved? Do you think you could give a general overview of what has +>to happen to get the netgroup service doing SOMETHING? + +First, you need to familiarize yourself with the netgroup resolution +APIs. It's important that you implement something that works for both +Solaris and the GNU C Library (and, possibly, the BIND IRS, although +no one seems to be particularly interested in that switch). I haven't +looked into them in great detail. You'll need to create ldap-netgrp.c +(rip off ldap-pwd.c for starters). and implement the following: + +Linux +===== + +NSS_STATUS +_nss_ldap_setnetgrent(const char *group, struct __netgrent *result); + +NSS_STATUS +_nss_ldap_endnetgrent(struct __netgrent *result); + +NSS_STATUS +_nss_ldap_getnetgrent_r(struct __netgrent *result, char *buffer, + size_t buflen, int *errnop); + +Because netgroups are just triples in LDAP, you should be able to avail +yourself of the _nss_netgroup_parseline() helper function. (Having +the glibc source handy would be helpful.) Call this from the parser +(see below) for values of the "nisNetgroupTriple" attribute. + +Solaris +======= + +Check out /usr/include/nss_dbdefs.h. It looks pretty hairy: +FYI, let's look at how a user is resolved: + +NSS_STATUS +_nss_ldap_getpwnam_r ( + const char *name, + struct passwd * result, + char *buffer, + size_t buflen, + int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, filt_getpwnam, pw_attributes, _nss_ldap_parse_pw); +} + +The LOOKUP_NAME macro marshalls arguments to pass to +_nss_ldap_getbyname(), which is responsible for searching in the +directory. If the search is successful, this function will call +the parser (_nss_ldap_parse_pw()) with the LDAP result, and +the buffers supplied by the user. The parser is responsible +for mapping the LDAP entry into a struct pwent or whatever. +There are helper functions provided for doing such, for example +_nss_ldap_assign_attrval(): + + stat = _nss_ldap_assign_attrval (ld, e, LDAP_ATTR_USERNAME, &pw->pw_name, &buffer, &buflen); + if (stat != NSS_SUCCESS) + +This model works well when there is a 1:1 mapping between LDAP +entries and entities that the host API is responsible for. Things +get a bit trickier for things like getgroupsbymember(). Hope +this helps. Note that for Solaris, each backend has a dispatch +table, a "constructor" (_nss_ldap_passwd_constr, for example). @@ -0,0 +1,169 @@ + +LDAP NAMESERVICE SWITCH LIBRARY +=============================== + +This is the nss_ldap library, an LDAP module for the Solaris Nameservice +Switch (NSS), the GNU libc NSS, and the ISC BIND IRS (used on BSDI +and IRS). + +The LDAP schema used is described in RFC 2307 + +Insert this: + +passwd: files nis ldap +group: files nis ldap + +or something similar in /etc/nsswitch.conf. + +The source code is distributed under the GNU General Library Public Licence +(see COPYING.LIB). + +Platforms this has been built under: + + o Linux 2.x + o Solaris 2.4, 2.6, 7, 8 + o FreeBSD BIND 8.x (not useful unless you recompile libc) + o AIX 4.3.3 with IRS + +If you are willing to use an older, and possibly buggy, version +of nss_ldap, you *might* find patches to get it to work with the +"real" FreeBSD nsswitch at http://www.nectar.com/freebsd/nsswitch. + +To install: + +% ./configure +% make +% make install + +NB: you need to use GNU make! (often called gmake or gnumake) + +1. Installation +--------------- + +You need to ensure libnss_ldap.so.1 (or nss_ldap.so.1, for Solaris) is in +/usr/lib. + +2. Building shared LDAP client libraries +---------------------------------------- + +You can build a position independent LDAP client library by compiling +-fPIC and linking with -shared, or downloading the Mozilla or Netscape +LDAP SDKs. Note that OpenLDAP only appears to build shared libraries +on some platforms (apparently not Solaris?). To build these, configure +with --enable-shared. + +Q: Using the Netscape LDAP library with pam_ldap on Solaris 8 +- aka Solaris 2.8 - fails to link properly! David Begley writes: + +There are two releases of the Netscape LDAP library, one marked +for Solaris 8 and the other marked for Solaris 2.6 - the additional +catch is that the Solaris 8 library is a 64-bit library (this is marked +on Netscape's site) whilst the other is a 32-bit library. + +It doesn't matter if you have a 64-bit UltraSPARC processor running +the 64-bit Solaris kernel, if your compiler only works with 32-bit +objects then it won't successfully link the 64-bit Solaris 8 +Netscape LDAP library. + +GCC (up to version 2.95.2) does not work properly with 64-bit objects +under Solaris, so just use the Solaris 2.6 (32-bit) Netscape LDAP +library and everything should be fine. + +Q: Can I use a third-party client LDAP library (such as Netscape's) +on Solaris 7? David Begley writes: + +Yes, but if you have the Solaris 7 LDAP library installed (package +SUNWlldap or SUNWldapx) configure will find it before the third-party +library - in this case, you can't rely on the auto-lib-type detection of +configure and must use the "--with-ldap-lib=" parameter. + +Q: Why does linking fail on Solaris 2.6 (complaining about +relocations remaining against libcrypt)? David Begley +writes: + +In short, the problem is that GCC is looking for a shared libcrypt +(in response to the "--shared" parameter) which doesn't exist on +Solaris 2.6 (but does on Solaris 7). The fix is quite simple, use +"-G" instead of "--shared" (could this be a GCC bug?). This change +should already be included in newer versions of pam_ldap. + +It doesn't look like libcrypt is even needed if you're using the +Netscape LDAP client library (maybe it's required for OpenLDAP?). + +Scott M. Stone <sstone@foo3.com> writes: +Your openldap libs *and* your SSL/RSAREF libs must be DYNAMIC LIBRARIES +or neither nss_ldap nor pam_ldap will work. + +3. glibc 2.0 compatibility +-------------------------- + +Current versions of the nss_ldap library are designed to work with +glibc 2.1, not glibc 2.0. They _may_ work with glibc 2.0. YMMV. + +4. RFC2307BIS +------------- + +Compiling with -DRFC2307BIS adds rfc2307bis support, which at the +moment just gets you support for groups with distinguished name +members (instead of login names). A posixGroup can thus have the +both memberUid and uniqueMember attributes. + +5. Building under FreeBSD +------------------------- + +Here's what I do to build it under FreeBSD. You will need to +link it into libbind.a for it actually to be useful. + +CPPFLAGS="-I/usr/local/include -I/usr/local/include/bind -DPIC" +export CPPFLAGS +CFLAGS=$CPPFLAGS # this is weird +export CFLAGS +LDFLAGS="-L/usr/local/lib" +LIBS="-lbind_r -lgnuregex -lsasl -lkrb" +export LDFLAGS LIBS +./configure +make + +6. Solaris, shadowAccount +------------------------- + +Joerg Paysen notes: + +> I think its extremly important that you have a +> /etc/shadow file so that an ObjectClass shadowAccount +> will be created in the ldap database. My experience is +> that without shadowAccount nss_ldap does not work on +> solaris!! + +7. Secret file +-------------- + +If using /etc/ldap.secret, it must have a newline at the end +of the secret. + +8. Mailing lists +---------------- + +To discuss nss_ldap and related technologies, you may +subscribe to the following mailing lists: + + <URL:mailto:nssldap-request@padl.com> +and + <URL:mailto:ldap-nis-request@padl.com> + +Send an electronic mail message with "subscribe" in the +message body to join the list. + +9. Commercial support +--------------------- + +Note that PADL now offer commercial support on a +per-incident basis. + +To request a support incident, send email to: nssldap-support@padl.com + +-- +PADL Software Pty Ltd +nssldap-support@padl.com +http://www.padl.com/ + diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 0000000..7bf3d26 --- /dev/null +++ b/acconfig.h @@ -0,0 +1,54 @@ +/* Define to the number of arguments to ldap_set_rebindproc */ +#undef LDAP_SET_REBIND_PROC_ARGS + +/* define to the number of args to gethostbyname_r */ +#undef GETHOSTBYNAME_R_ARGS + +/* define to set RFC2307BIS support */ +#undef RFC2307BIS + +/* define to enable debug code */ +#undef DEBUG + +/* define to enable attribute/objectclass mapping */ +#undef AT_OC_MAP + +/* define to enable proxy authentication for AIX */ +#undef PROXY_AUTH + +/* define to enable paged results control */ +#undef PAGE_RESULTS + +/* define to enable configurable Kerberos credentials cache */ +#undef CONFIGURE_KRB5_CCNAME + +/* define to enable configurable Kerberos credentials cache (putenv method) */ +#undef CONFIGURE_KRB5_CCNAME_ENV + +/* define to enable configurable Kerberos credentials cache (gssapi method) */ +#undef CONFIGURE_KRB5_CCNAME_GSSAPI + +/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_KRB5_H + +/* define to enable struct ether_addr definition */ +#undef HAVE_STRUCT_ETHER_ADDR + +/* define to enable socklen_t definition */ +#undef HAVE_SOCKLEN_T + +/* define if struct passwd has a pw_change member */ +#undef HAVE_PASSWD_PW_CHANGE + +/* define if struct passwd has a pw_expire member */ +#undef HAVE_PASSWD_PW_EXPIRE + +/* path to LDAP configuration file */ +#define NSS_LDAP_PATH_CONF "/etc/ldap.conf" + +/* path to LDAP root secret file */ +#define NSS_LDAP_PATH_ROOTPASSWD "/etc/ldap.secret" + +/* maximum number of group members in static buffer */ +#define LDAP_NSS_NGROUPS 64 + diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..4f9ffe8 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,140 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<<am_indx=1 +for am_file in <<$1>>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# Define a conditional. + +AC_DEFUN([AM_CONDITIONAL], +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + diff --git a/aix_authmeth.c b/aix_authmeth.c new file mode 100644 index 0000000..19b9e35 --- /dev/null +++ b/aix_authmeth.c @@ -0,0 +1,1023 @@ +/* Copyright (C) 2002-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 2002. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/* + * Shim to support AIX loadable authentication modules + */ + +#include "config.h" + +static char rcsId[] = + "$Id: aix_authmeth.c,v 2.31 2006/02/24 01:28:59 lukeh Exp $"; + +#ifdef HAVE_USERSEC_H + +#include <stdlib.h> +#include <string.h> +#include <usersec.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "util.h" + +#define TABLE_KEY_ALL "ALL" +#define TABLE_USER "user" +#define TABLE_GROUP "group" + +#define S_LDAPDN "ldapdn" + +static struct irs_gr *uess_gr_be = NULL; +static struct irs_pw *uess_pw_be = NULL; + +extern void *gr_pvtinit (void); /* irs-grp.c */ +extern void *pw_pvtinit (void); /* irs-pwd.c */ + +/* from ldap-grp.c */ +extern char *_nss_ldap_getgrset (char *user); + +/* search arguments for getentry method */ +typedef struct ldap_uess_args +{ + /* argument block */ + const char *lua_key; + const char *lua_table; + char **lua_attributes; + attrval_t *lua_results; + int lua_size; + + /* private */ + ldap_map_selector_t lua_map; + size_t lua__bufsiz; + size_t lua__buflen; + char *lua__buffer; + const char *lua_naming_attribute; +} +ldap_uess_args_t; + +static NSS_STATUS uess_get_char (LDAPMessage * e, ldap_uess_args_t * arg, int index); +static NSS_STATUS uess_get_char_ex (LDAPMessage * e, ldap_uess_args_t * arg, int index, const char *attribute); +static NSS_STATUS uess_get_int (LDAPMessage * e, ldap_uess_args_t * arg, int index); +static NSS_STATUS uess_get_pgrp (LDAPMessage * e, ldap_uess_args_t * arg, int index); +static NSS_STATUS uess_get_groupsids (LDAPMessage * e, ldap_uess_args_t * arg, int index); +static NSS_STATUS uess_get_gecos (LDAPMessage * e, ldap_uess_args_t * arg, int index); +static NSS_STATUS uess_get_pwd (LDAPMessage * e, ldap_uess_args_t * arg, int index); +static NSS_STATUS uess_get_dn (LDAPMessage * e, ldap_uess_args_t * arg, int index); + +/* dispatch table for retrieving UESS attribute from an LDAP entry */ +struct ldap_uess_fn +{ + const char *luf_attribute; + NSS_STATUS (*luf_translator) (LDAPMessage * e, + ldap_uess_args_t *, int); +} +ldap_uess_fn_t; + +static struct ldap_uess_fn __uess_fns[] = { + {S_GECOS, uess_get_gecos}, + {S_GROUPSIDS, uess_get_groupsids}, + {S_HOME, uess_get_char}, + {S_ID, uess_get_int}, + {S_PWD, uess_get_pwd}, + {S_SHELL, uess_get_char}, + {S_PGRP, uess_get_pgrp}, + {SEC_PASSWD, uess_get_char}, + {SEC_LASTUP, uess_get_int}, + {S_MAXAGE, uess_get_int}, + {S_MINAGE, uess_get_int}, + {S_MAXEXPIRED, uess_get_int}, + {S_PWDWARNTIME, uess_get_int}, + /* add additional attributes we know about here */ + {S_LDAPDN, uess_get_dn}, + {NULL, NULL} +}; + +#define GR_PVTINIT() do { \ + if (uess_gr_be == NULL) { \ + uess_gr_be = (struct irs_gr *) gr_pvtinit (); \ + if (uess_gr_be == NULL) \ + return NULL; \ + } \ + } while (0) + +#define PW_PVTINIT() do { \ + if (uess_pw_be == NULL) { \ + uess_pw_be = (struct irs_pw *) pw_pvtinit (); \ + if (uess_pw_be == NULL) \ + return NULL; \ + } \ + } while (0) + +static void * +_nss_ldap_uess_open (const char *name, const char *domain, + const int mode, char *options) +{ + /* Currently we do not use the above parameters */ + GR_PVTINIT(); + PW_PVTINIT(); + + return NULL; +} + +static void +_nss_ldap_uess_close (void *token) +{ + if (uess_gr_be != NULL) + { + (uess_gr_be->close) (uess_gr_be); + uess_gr_be = NULL; + } + + if (uess_pw_be != NULL) + { + (uess_pw_be->close) (uess_pw_be); + uess_pw_be = NULL; + } +} + +static struct group * +_nss_ldap_getgrgid (gid_t gid) +{ + GR_PVTINIT (); + + return (uess_gr_be->bygid) (uess_gr_be, gid); +} + +static struct group * +_nss_ldap_getgrnam (const char *name) +{ + GR_PVTINIT (); + + return (uess_gr_be->byname) (uess_gr_be, name); +} + +static struct passwd * +_nss_ldap_getpwuid (uid_t uid) +{ + PW_PVTINIT (); + + return (uess_pw_be->byuid) (uess_pw_be, uid); +} + +static struct passwd * +_nss_ldap_getpwnam (const char *name) +{ + PW_PVTINIT (); + + return (uess_pw_be->byname) (uess_pw_be, name); +} + +static struct group * +_nss_ldap_getgracct (void *id, int type) +{ + GR_PVTINIT (); + + if (type == SEC_INT) + return (uess_gr_be->bygid) (uess_gr_be, *(gid_t *) id); + else + return (uess_gr_be->byname) (uess_gr_be, (char *) id); +} + +static int +_nss_ldap_authenticate (char *user, char *response, int *reenter, + char **message) +{ + NSS_STATUS stat; + int rc; + + debug ("==> _nss_ldap_authenticate"); + + *reenter = FALSE; + *message = NULL; + + stat = _nss_ldap_proxy_bind (user, response); + + switch (stat) + { + case NSS_TRYAGAIN: + rc = AUTH_FAILURE; + break; + case NSS_NOTFOUND: + rc = AUTH_NOTFOUND; + break; + case NSS_SUCCESS: + rc = AUTH_SUCCESS; + break; + default: + case NSS_UNAVAIL: + rc = AUTH_UNAVAIL; + break; + } + + debug ("<== _nss_ldap_authenticate"); + + return rc; +} + +/* + * Support this for when proxy authentication is disabled. + * There may be some re-entrancy issues here; not sure + * if we are supposed to return allocated memory or not, + * this is not documented. I am assuming not in line with + * the other APIs. + */ +static char * +_nss_ldap_getpasswd (char *user) +{ + struct passwd *pw; + static char pwdbuf[32]; + char *p = NULL; + + debug ("==> _nss_ldap_getpasswd"); + + pw = _nss_ldap_getpwnam (user); + if (pw != NULL) + { + if (strlen (pw->pw_passwd) > sizeof (pwdbuf) - 1) + { + errno = ERANGE; + } + else + { + strcpy (pwdbuf, pw->pw_passwd); + p = pwdbuf; + } + } + else + { + errno = ENOENT; /* user does not exist */ + } + + debug ("<== _nss_ldap_getpasswd"); + + return p; +} + +/* + * Convert a UESS table string to an nss_ldap map type + */ +static ldap_map_selector_t +table2map (const char *table) +{ + if (strcmp (table, TABLE_USER) == 0) + return LM_PASSWD; + else if (strcmp (table, TABLE_GROUP) == 0) + return LM_GROUP; + + return LM_NONE; +} + +/* + * Convert a UESS key to an nss_ldap internal search query + */ +static ldap_args_t * +key2filter (char *key, ldap_map_selector_t map, + ldap_args_t * a, const char **filter) +{ + if (strcmp (key, TABLE_KEY_ALL) == 0) + { + if (map == LM_PASSWD) + *filter = _nss_ldap_filt_getpwent; + else + *filter = _nss_ldap_filt_getgrent; + + return NULL; /* indicates enumeration */ + } + + LA_INIT (*a); + LA_TYPE (*a) = LA_TYPE_STRING; + LA_STRING (*a) = key; + + if (map == LM_PASSWD) + *filter = _nss_ldap_filt_getpwnam; + else + *filter = _nss_ldap_filt_getgrnam; + + return a; +} + +/* + * Map a UESS attribute to an LDAP attribute + */ +static const char * +uess2ldapattr (ldap_map_selector_t map, const char *attribute) +{ + if (strcmp (attribute, "username") == 0) + return ATM (LM_PASSWD, uid); + else if (strcmp (attribute, "groupname") == 0) + return ATM (LM_GROUP, cn); + else if (strcmp (attribute, S_ID) == 0) + { + if (map == LM_PASSWD) + return ATM (LM_PASSWD, uidNumber); + else + return ATM (LM_GROUP, gidNumber); + } + else if (strcmp (attribute, S_PWD) == 0) + return ATM (LM_PASSWD, userPassword); + else if (strcmp (attribute, S_HOME) == 0) + return ATM (LM_PASSWD, homeDirectory); + else if (strcmp (attribute, S_SHELL) == 0) + return ATM (LM_PASSWD, loginShell); + else if (strcmp (attribute, S_GECOS) == 0) + return ATM (LM_PASSWD, gecos); + else if (strcmp (attribute, SEC_PASSWD) == 0) + return ATM (LM_SHADOW, userPassword); + else if (strcmp (attribute, SEC_LASTUP) == 0) + return ATM (LM_SHADOW, shadowLastChange); + else if (strcmp (attribute, S_MAXAGE) == 0) + return ATM (LM_SHADOW, shadowMax); + else if (strcmp (attribute, S_MINAGE) == 0) + return ATM (LM_SHADOW, shadowMin); + else if (strcmp (attribute, S_MAXEXPIRED) == 0) + return ATM (LM_SHADOW, shadowExpire); + else if (strcmp (attribute, S_PWDWARNTIME) == 0) + return ATM (LM_SHADOW, shadowWarning); + else if (strcmp (attribute, S_PGRP) == 0) + return ATM (LM_GROUP, cn); + else if (strcmp (attribute, S_USERS) == 0) + return ATM (LM_GROUP, memberUid); + + return NULL; +} + +/* + * Get primary group name for a user + */ +static NSS_STATUS +uess_get_pgrp (LDAPMessage * e, ldap_uess_args_t * lua, int i) +{ + char **vals; + LDAPMessage *res; + const char *attrs[2]; + NSS_STATUS stat; + ldap_args_t a; + + vals = _nss_ldap_get_values (e, ATM (LM_PASSWD, gidNumber)); + if (vals == NULL) + return NSS_NOTFOUND; + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_NUMBER; + LA_NUMBER (a) = atol(vals[0]); + + attrs[0] = ATM (LM_GROUP, cn); + attrs[1] = NULL; + + stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getgrgid, LM_GROUP, + attrs, 1, &res); + if (stat != NSS_SUCCESS) + { + ldap_value_free (vals); + return NSS_NOTFOUND; + } + + ldap_value_free (vals); + + e = _nss_ldap_first_entry (res); + if (e == NULL) + { + ldap_msgfree (res); + return NSS_NOTFOUND; + } + + stat = uess_get_char_ex (e, lua, i, attrs[0]); + + ldap_msgfree (res); + + return stat; +} + +/* + * Get groups to which a user belongs + */ +static NSS_STATUS +uess_get_groupsids (LDAPMessage * e, ldap_uess_args_t * lua, int i) +{ + char *p, *q; + size_t len; + + p = _nss_ldap_getgrset ((char *) lua->lua_key); + if (p == NULL) + return NSS_NOTFOUND; + + len = strlen (p); + q = malloc (len + 2); + if (q == NULL) + { + errno = ENOMEM; + return NSS_NOTFOUND; + } + + memcpy (q, p, len + 1); + q[len + 1] = '\0'; + + free (p); + p = NULL; + + for (p = q; *p != '\0'; p++) + { + if (*p == ',') + *p++ = '\0'; + } + + lua->lua_results[i].attr_un.au_char = q; + + return NSS_SUCCESS; +} + +/* + * Get a mapped UESS string attribute + */ +static NSS_STATUS +uess_get_char (LDAPMessage * e, ldap_uess_args_t * lua, int i) +{ + const char *attribute; + + attribute = uess2ldapattr (lua->lua_map, lua->lua_attributes[i]); + if (attribute == NULL) + return NSS_NOTFOUND; + + return uess_get_char_ex (e, lua, i, attribute); +} + +/* + * Get a specific LDAP attribute + */ +static NSS_STATUS +uess_get_char_ex (LDAPMessage * e, + ldap_uess_args_t * lua, int i, const char *attribute) +{ + char **vals; + attrval_t *av = &lua->lua_results[i]; + + vals = _nss_ldap_get_values (e, attribute); + if (vals == NULL) + return NSS_NOTFOUND; + + if (vals[0] == NULL) + { + ldap_value_free (vals); + return NSS_NOTFOUND; + } + + av->attr_un.au_char = strdup (vals[0]); + if (av->attr_un.au_char == NULL) + { + ldap_value_free (vals); + return NSS_TRYAGAIN; + } + + ldap_value_free (vals); + return NSS_SUCCESS; +} + +/* + * Get an encoded crypt password + */ +static NSS_STATUS +uess_get_pwd (LDAPMessage * e, ldap_uess_args_t * lua, int i) +{ + char **vals; + attrval_t *av = &lua->lua_results[i]; + const char *pwd; + const char *attribute; + + attribute = uess2ldapattr (lua->lua_map, lua->lua_attributes[i]); + if (attribute == NULL) + return NSS_NOTFOUND; + + vals = _nss_ldap_get_values (e, attribute); + pwd = _nss_ldap_locate_userpassword (vals); + + av->attr_un.au_char = strdup (pwd); + if (vals != NULL) + ldap_value_free (vals); + + return (av->attr_un.au_char == NULL) ? NSS_TRYAGAIN : NSS_SUCCESS; +} + +/* + * Get a UESS integer attribute + */ +static NSS_STATUS +uess_get_int (LDAPMessage * e, ldap_uess_args_t * lua, int i) +{ + const char *attribute; + char **vals; + attrval_t *av = &lua->lua_results[i]; + + attribute = uess2ldapattr (lua->lua_map, lua->lua_attributes[i]); + if (attribute == NULL) + return NSS_NOTFOUND; + + vals = _nss_ldap_get_values (e, attribute); + if (vals == NULL) + return NSS_NOTFOUND; + + if (vals[0] == NULL) + { + ldap_value_free (vals); + return NSS_NOTFOUND; + } + + av->attr_un.au_int = atoi (vals[0]); + ldap_value_free (vals); + return NSS_SUCCESS; +} + +/* + * Get the GECOS/cn attribute + */ +static NSS_STATUS +uess_get_gecos (LDAPMessage * e, ldap_uess_args_t * lua, int i) +{ + NSS_STATUS stat; + + stat = uess_get_char (e, lua, i); + if (stat == NSS_NOTFOUND) + { + stat = uess_get_char_ex (e, lua, i, ATM (LM_PASSWD, cn)); + } + + return stat; +} + +/* + * Get the DN + */ +static NSS_STATUS +uess_get_dn (LDAPMessage * e, ldap_uess_args_t * lua, int i) +{ + lua->lua_results[i].attr_un.au_char = _nss_ldap_get_dn (e); + if (lua->lua_results[i].attr_un.au_char == NULL) + return NSS_NOTFOUND; + + return NSS_SUCCESS; +} + +static NSS_STATUS +do_parse_uess_getentry (LDAPMessage * e, + ldap_state_t * pvt, void *result, + char *buffer, size_t buflen) +{ + ldap_uess_args_t *lua = (ldap_uess_args_t *) result; + int i; + char **vals; + size_t len; + NSS_STATUS stat; + + /* If a buffer is supplied, then we are enumerating. */ + if (lua->lua__buffer != NULL) + { + attrval_t *av = lua->lua_results; + + vals = _nss_ldap_get_values (e, lua->lua_naming_attribute); + if (vals == NULL) + return NSS_NOTFOUND; + + if (vals[0] == NULL) + { + ldap_value_free (vals); + return NSS_NOTFOUND; + } + + len = strlen (vals[0]) + 1; /* for string terminator */ + + if (lua->lua__buflen < len + 1) /* for list terminator */ + { + size_t grow = len + 1; + size_t offset = (lua->lua__buffer - av->attr_un.au_char); + + grow += NSS_BUFSIZ - 1; + grow -= (grow % NSS_BUFSIZ); + + av->attr_un.au_char = + realloc (lua->lua__buffer, lua->lua__bufsiz + grow); + if (av->attr_un.au_char == NULL) + { + ldap_value_free (vals); + return NSS_TRYAGAIN; + } + /* reset buffer pointer in case realloc() returned a new region */ + lua->lua__buffer = &av->attr_un.au_char[offset]; + lua->lua__buflen += grow; + lua->lua__bufsiz += grow; + } + + memcpy (lua->lua__buffer, vals[0], len); + lua->lua__buflen -= len; + lua->lua__buffer += len; + ldap_value_free (vals); + + lua->lua__buffer[0] = '\0'; /* ensure _list_ is always terminated */ + + if (av->attr_flag != 0) + av->attr_flag = 0; + + return NSS_NOTFOUND; /* trick caller into calling us again */ + } + else + { + for (i = 0; i < lua->lua_size; i++) + { + int j; + attrval_t *av = &lua->lua_results[i]; + + av->attr_flag = -1; + av->attr_un.au_char = NULL; + + for (j = 0; __uess_fns[j].luf_attribute != NULL; j++) + { + if (strcmp (__uess_fns[j].luf_attribute, lua->lua_attributes[i]) + == 0) + { + stat = (__uess_fns[j].luf_translator) (e, lua, i); + switch (stat) + { + case NSS_SUCCESS: + av->attr_flag = 0; + break; + case NSS_TRYAGAIN: + return NSS_TRYAGAIN; + break; + default: + break; + } + } + } + } + } + + return NSS_SUCCESS; +} + +static int +_nss_ldap_getentry (char *key, char *table, char *attributes[], + attrval_t results[], int size) +{ + NSS_STATUS stat; + ent_context_t *ctx = NULL; + ldap_args_t a, *ap; + const char *filter; + int erange = 0; + ldap_uess_args_t lua; + const char *namingAttributes[2]; + + debug ("==> _nss_ldap_getentry (key=%s table=%s attributes[0]=%s size=%d)", + (key != NULL) ? key : "(null)", + (table != NULL) ? table : "(null)", + (size >= 1) ? attributes[0] : "(null)", + size); + + lua.lua_key = key; + lua.lua_table = table; + lua.lua_attributes = attributes; + lua.lua_results = results; + lua.lua_size = size; + lua.lua_naming_attribute = NULL; + + lua.lua_map = table2map (table); + if (lua.lua_map == LM_NONE) + { + errno = ENOSYS; + debug ("<== _nss_ldap_getentry (no such map)"); + return -1; + } + + lua.lua__buffer = NULL; + lua.lua__bufsiz = 0; + lua.lua__buflen = 0; + + ap = key2filter (key, lua.lua_map, &a, &filter); + if (ap == NULL) /* enumeration */ + { + const char **attrs; + + if (size != 1) + { + errno = EINVAL; + debug ("<== _nss_ldap_getentry (size != 1)"); + return -1; + } + + debug (":== _nss_ldap_getentry filter=%s attribute=%s", + filter, lua.lua_attributes[0]); + + lua.lua__bufsiz = NSS_BUFSIZ; + lua.lua__buflen = lua.lua__bufsiz; + lua.lua__buffer = results[0].attr_un.au_char = malloc (lua.lua__bufsiz); + if (lua.lua__buffer == NULL) + { + errno = ENOMEM; + debug ("<== _nss_ldap_getentry (no memory)"); + return -1; + } + results[0].attr_flag = -1; + + /* just request the naming attributes */ + attrs = _nss_ldap_get_attributes (lua.lua_map); + if (attrs == NULL || attrs[0] == NULL) + { + errno = ENOENT; + debug ("<== _nss_ldap_getentry (could not read schema)"); + return -1; + } + + lua.lua_naming_attribute = attrs[0]; + namingAttributes[0] = lua.lua_naming_attribute; + namingAttributes[1] = NULL; + } + else + { + /* Check at least one attribute is mapped before searching */ + int i, found = 0; + + for (i = 0; i < size; i++) + { + if (uess2ldapattr (lua.lua_map, lua.lua_attributes[i]) != NULL) + { + found++; + break; + } + } + + if (!found) + { + errno = ENOENT; + debug ("<== _nss_ldap_getentry (no mappable attribute requested)"); + return -1; + } + } + + _nss_ldap_enter (); + if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) + { + _nss_ldap_leave (); + if (results[0].attr_un.au_char != NULL) + free (results[0].attr_un.au_char); + errno = ENOMEM; + debug ("<== _nss_ldap_getentry (ent_context_init failed)"); + return -1; + } + + stat = _nss_ldap_getent_ex (ap, &ctx, (void *) &lua, NULL, 0, + &erange, filter, lua.lua_map, + (ap == NULL) ? namingAttributes : NULL, + do_parse_uess_getentry); + + _nss_ldap_ent_context_release (ctx); + free (ctx); + _nss_ldap_leave (); + + /* + * Whilst enumerating, we have the parser always return + * NSS_NOTFOUND so that it will be called for each entry. + * + * Although this is probably bogus overloading of the + * _nss_ldap_getent_ex() API, it does allow us to share + * the same code for matches and enumerations. However, + * for the enumeration case we need to treat NSS_NOTFOUND + * as a success code; hence, we use the attr_flag to + * indicate failure. + */ + if (ap == NULL) + { + if (stat == NSS_NOTFOUND && results[0].attr_flag == 0) + stat = NSS_SUCCESS; + } + + if (stat != NSS_SUCCESS) + { + if (stat == NSS_TRYAGAIN) + errno = ERANGE; + else + errno = ENOENT; + + debug ("<== _nss_ldap_getentry (failed with stat=%d)", stat); + return -1; + } + + debug ("<== _nss_ldap_getentry (success)"); + return AUTH_SUCCESS; +} + +/* + * + */ +static NSS_STATUS +uess_get_pwuid(const char *user, uid_t *uid) +{ + char **vals; + LDAPMessage *res, *e; + const char *attrs[2]; + NSS_STATUS stat; + ldap_args_t a; + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + LA_STRING (a) = user; + + attrs[0] = ATM (LM_PASSWD, uidNumber); + attrs[1] = NULL; + + stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getpwuid, LM_PASSWD, + attrs, 1, &res); + if (stat != NSS_SUCCESS) + return stat; + + e = _nss_ldap_first_entry (res); + if (e == NULL) + { + ldap_msgfree (res); + return NSS_NOTFOUND; + } + + vals = _nss_ldap_get_values (e, attrs[0]); + if (vals == NULL) + { + ldap_msgfree (res); + return NSS_NOTFOUND; + } + + if (vals[0] == NULL || (vals[0])[0] == '\0') + { + ldap_value_free (vals); + ldap_msgfree (res); + return NSS_NOTFOUND; + } + + *uid = atoi(vals[0]); + + ldap_value_free (vals); + ldap_msgfree (res); + + return NSS_SUCCESS; +} + +/* + * Get membership for a group + */ +static int +_nss_ldap_getgrusers (char *group, void *result, int type, int *size) +{ + struct group *gr; + struct irs_gr *be; + char **memp; + size_t i; + + be = (struct irs_gr *) gr_pvtinit (); + if (be == NULL) + { + errno = ENOSYS; + return -1; + } + + gr = (be->byname) (be, group); + if (gr == NULL) + { + (be->close) (be); + errno = ENOENT; + return -1; + } + + if (gr->gr_mem == NULL) + { + (be->close) (be); + *size = 0; + return 0; + } + + for (i = 0; gr->gr_mem[i] != NULL; i++) + ; + + if (i > *size) + { + (be->close) (be); + *size = i; + errno = ERANGE; + return -1; + } + + _nss_ldap_enter (); + + for (i = 0, memp = gr->gr_mem; *memp != NULL; memp++) + { + if (type == SEC_INT) + { + if (uess_get_pwuid(*memp, &(((uid_t *)result)[i])) != NSS_SUCCESS) + continue; + } + else + { + ((char **)result)[i] = strdup(*memp); + if (((char **)result)[i] == NULL) + { + _nss_ldap_leave (); + (be->close) (be); + errno = ENOMEM; + return -1; + } + } + i++; + } + + _nss_ldap_leave (); + + *size = i; + + (be->close) (be); + + return AUTH_SUCCESS; +} + +#if 0 +/* + * Additional attributes supported + */ +static attrlist_t ** +_nss_ldap_attrlist(void) +{ + attrlist_t **a; + + a = malloc(2 * sizeof(attrlist_t *) + sizeof(attrlist_t)); + if (a == NULL) + { + errno = ENOMEM; + return NULL; + } + + a[0] = (attrlist_t *)(a + 2); + + a[0]->al_name = strdup(S_LDAPDN); + a[0]->al_flags = AL_USERATTR; + a[0]->al_type = SEC_CHAR; + + a[1] = NULL; + + return a; +} +#endif /* notdef */ + +#if 0 +/* not implemented yet */ +static int +_nss_ldap_normalize (char *longname, char *shortname) +{ +} +#endif + +int +nss_ldap_initialize (struct secmethod_table *meths) +{ + memset (meths, 0, sizeof (*meths)); + + /* Initialize schema */ + (void) _nss_ldap_init(); + + /* Identification methods */ + meths->method_getpwnam = _nss_ldap_getpwnam; + meths->method_getpwuid = _nss_ldap_getpwuid; + meths->method_getgrnam = _nss_ldap_getgrnam; + meths->method_getgrgid = _nss_ldap_getgrgid; + meths->method_getgrset = _nss_ldap_getgrset; + meths->method_getentry = _nss_ldap_getentry; +/* meths->method_attrlist = _nss_ldap_attrlist; */ + meths->method_getgrusers = _nss_ldap_getgrusers; +/* meths->method_normalize = _nss_ldap_normalize; */ + meths->method_getgracct = _nss_ldap_getgracct; + meths->method_getpasswd = _nss_ldap_getpasswd; + + /* Support methods */ + meths->method_open = _nss_ldap_uess_open; + meths->method_close = _nss_ldap_uess_close; + + /* Authentication methods */ + meths->method_authenticate = _nss_ldap_authenticate; + + return AUTH_SUCCESS; +} + +#endif /* HAVE_USERSEC_H */ diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..33eeb75 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,5 @@ +#!/bin/sh +aclocal14 +automake14 +autoheader213 +autoconf213 diff --git a/certutil b/certutil new file mode 100755 index 0000000..bac2727 --- /dev/null +++ b/certutil @@ -0,0 +1,263 @@ +#!/bin/sh +#ident $Id: certutil,v 2.2 2001/05/27 12:16:31 lukeh Exp $ +# +# certutil -- manage trusted X.509 certificates +# inspired by Netscape PKCS #11 toolkit +# contributed by Jarkko Turkulainen <jt@wapit.com> +# +# +# INTRODUCTION +# +# certutil can be used with various OpenSSL routines and tools +# that utilize OpenSSL. Example: +# +# $ openssl s_client -CApath certdir +# +# where certdir is a directory created by certutil. Other well known +# programs that use the same format are stunnel, sendmail and pam_ldap +# +# +# +# HOWTO +# +# 1. Initialize certificate database +# +# Simply by adding a new certificate. If the certificate directory +# doesn't exist, the script asks for creating a one. Example: +# +# $ certutil -a -n "First Cert" -i cert.pem -d /home/jt/mycerts +# ./certutil: cannot access /home/jt/mycerts, create? [y/N] y +# +# +# 2. Add new certificate +# +# $ certutil -a -n "My Cert" -i cert.pem [-d certdir] +# +# Note that nickname (-n) must exist. certdir is optional - if it's +# not given, $PWD is used. The directory must have a file named certs.dat. +# If that file doesn't exist, the script refuses to do anything. If your +# certs.dat file is corrupted, "rm -rf" the whole dir and start from +# the scratch. cert.pem is the actual sertificate. +# +# 3. Delete certificate +# +# $ certutil -r -n "My Cert" [-d certdir] +# +# This command removes the certificate named "My Cert". certdir is +# optional, see 2. +# +# 4. List sertificates +# +# $ certutil -l [-d certdir] +# +# And again, certdir is optional. +# +# 5. View certificate properties +# +# $ certutil -v -n "My Cert" [-d certdir] +# +# + + +# Print usage +usage() { + cat << EOF + +Usage: $0 -l [-d dir] + -a -n name -i file [-d dir] + -r -n name [-d dir] + -v -n name [-d dir] + + Commands: + -l -- List sertificates (requires a valid dir) + -a -- Add sertificate and create dir if necessary + -r -- Remove sertificate (requires a valid dir) + -v -- View sertificate (requires a valid dir) + + Parameters: + dir -- Certificate directory, or \$PWD if not given + name -- Nickname of the certificate + file -- Certificate file in PEM format + +EOF + exit 1 +} + +# Check path +check_path() { + + # check the directory + if [ ! -d $CDIR -a $ADD -eq 1 ]; then + echo -n "$0: cannot access $CDIR, create? [y/N] " + read LINE + case $LINE in + y|Y) + mkdir $CDIR + chmod 700 $CDIR + touch $CDIR/certs.dat + chmod 600 $CDIR/certs.dat + ;; + *) + exit 1 + ;; + esac + fi + + # check certs.dat + if [ ! -e $CDIR/certs.dat ]; then + echo "$0: please specify a valid cert directory" + exit 1 + fi +} + +# Add certificates +add_cert() { + check_path + if [ ! -e $FILE ]; then + echo "$0: cannot find $FILE" + exit 1 + fi + HASH=`openssl x509 -in $FILE -hash -noout 2>/dev/null`.0 + if [ $? -ne 0 ]; then + echo "$0: unable to load certificate $FILE" + exit 1 + fi + + if grep "^$CNAME|" $CDIR/certs.dat 1>/dev/null 2>&1; then + echo "$0: nickname already in use" + exit 1 + fi + + if [ -e $CDIR/$HASH ]; then + echo "$0: certificate already in directory" + echo `openssl x509 -in $CDIR/$HASH -subject -noout` + exit 1 + else + cp $FILE $CDIR/$HASH + chmod 600 $CDIR/$HASH + echo "$CNAME|$HASH" >> $CDIR/certs.dat + chmod 600 $CDIR/certs.dat + fi + +} + +# List certificates +# +# (this is too slow...) +# +list_cert() { + check_path + echo + echo "Certificates in directory $CDIR" + echo + printf "%-30s%s\n" nickname subject/issuer + echo "----------------------------------------------------------------------------" + cat $CDIR/certs.dat | while read LINE; do + NICK=`echo $LINE | cut -d "|" -f 1` + HASH=`echo $LINE | cut -d "|" -f 2` + SUBJECT=`openssl x509 -in $CDIR/$HASH -subject -noout` + ISSUER=`openssl x509 -in $CDIR/$HASH -issuer -noout` + printf "%-30s%s\n" "$NICK" "$SUBJECT" + printf "%-30s%s\n\n" "" "$ISSUER" + + done +} + +# Remove certificates +remove_cert() { + check_path + ( + cat $CDIR/certs.dat | while read LINE; do + NICK=`echo $LINE | cut -d "|" -f 1` + HASH=`echo $LINE | cut -d "|" -f 2` + if [ "$CNAME" = "$NICK" ]; then + rm $CDIR/$HASH + else + echo $LINE + fi + done + ) > /tmp/$$ + mv /tmp/$$ $CDIR/certs.dat + chmod 600 $CDIR/certs.dat +} + +# View certificate +view_cert() { + check_path + cat $CDIR/certs.dat | while read LINE; do + NICK=`echo $LINE | cut -d "|" -f 1` + HASH=`echo $LINE | cut -d "|" -f 2` + if [ "$CNAME" = "$NICK" ]; then + openssl x509 -in $CDIR/$HASH -text + return 1 + fi + done +} + +# Parse option string +ADD=0 +REMOVE=0 +LIST=0 +VIEW=0 +while getopts "arlvd:n:i:" OPT; do + case $OPT in + a) + ADD=1 + ;; + r) + REMOVE=1 + ;; + l) + LIST=1 + ;; + v) + VIEW=1 + ;; + d) + CDIR=$OPTARG + ;; + n) + CNAME=$OPTARG + ;; + i) + FILE=$OPTARG + ;; + *) + usage + ;; + esac +done + +# Default options +CDIR=${CDIR:=.} + +# Check command line options +if [ $ADD -eq 1 -a $REMOVE -eq 0 -a $LIST -eq 0 -a $VIEW -eq 0 ]; then + if [ -n "$CNAME" -a -n "$FILE" ]; then + add_cert + else + echo "$0: missing certificate name or file" + usage + fi +elif [ $REMOVE -eq 1 -a $ADD -eq 0 -a $LIST -eq 0 -a $VIEW -eq 0 ]; then + if [ -n "$CNAME" ]; then + remove_cert + else + echo "$0: missing certificate name" + usage + fi +elif [ $LIST -eq 1 -a $ADD -eq 0 -a $REMOVE -eq 0 -a $VIEW -eq 0 ]; then + list_cert +elif [ $VIEW -eq 1 -a $ADD -eq 0 -a $REMOVE -eq 0 -a $LIST -eq 0 ]; then + if [ -n "$CNAME" ]; then + if view_cert; then + echo "$0: cert named \"$CNAME\" not found" + exit 1 + fi + else + echo "$0: missing certificate name" + usage + fi +else + usage +fi diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..8c7e3df --- /dev/null +++ b/config.guess @@ -0,0 +1,1334 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. +# Portions Copyright 1998-2002 OpenLDAP Foundation. + +timestamp='2002-01-30' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is distributed with OpenLDAP Software, which contains a +# configuration script generated by Autoconf, and is distributable +# under the same distributions terms as OpenLDAP inself. +# See the OpenLDAP COPYRIGHT and LICENSE file for details. +# $OpenLDAP: pkg/ldap/build/config.guess,v 1.11 2002/02/11 05:45:59 kurt Exp $ + +# Originally written by Per Bothner <per@bothner.com>. +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted 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. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +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 <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + 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' + +# 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". + UNAME_MACHINE_ARCH=`(uname -p) 2>/dev/null` || \ + UNAME_MACHINE_ARCH=unknown + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-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 __ELF__ >/dev/null + 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 + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # 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 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <<EOF >$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* 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 $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $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 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + 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 0 ;; + *: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 <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | 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 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + 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 <stdlib.h> + #include <unistd.h> + + 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 $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + 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 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + 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 ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + 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 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Export LANG=C to prevent ld from outputting information in other + # languages. + ld_supported_targets=`LANG=C; export LANG; cd /; ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + 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 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + 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 0 ;; + i*86:*:5:[78]*) + 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 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + 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 i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + echo i386-${UNAME_MACHINE}-nto-qnx + else + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + fi + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + 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 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#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 <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# 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 $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + ftp://ftp.gnu.org/pub/gnu/config/ + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> 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.h.in b/config.h.in new file mode 100755 index 0000000..4705535 --- /dev/null +++ b/config.h.in @@ -0,0 +1,316 @@ +/* config.h.in. Generated from configure.in by autoheader. */ +/* Define to the number of arguments to ldap_set_rebindproc */ +#undef LDAP_SET_REBIND_PROC_ARGS + +/* define to the number of args to gethostbyname_r */ +#undef GETHOSTBYNAME_R_ARGS + +/* define to set RFC2307BIS support */ +#undef RFC2307BIS + +/* define to enable debug code */ +#undef DEBUG + +/* define to enable attribute/objectclass mapping */ +#undef AT_OC_MAP + +/* define to enable proxy authentication for AIX */ +#undef PROXY_AUTH + +/* define to enable paged results control */ +#undef PAGE_RESULTS + +/* define to enable configurable Kerberos credentials cache */ +#undef CONFIGURE_KRB5_CCNAME + +/* define to enable configurable Kerberos credentials cache (putenv method) */ +#undef CONFIGURE_KRB5_CCNAME_ENV + +/* define to enable configurable Kerberos credentials cache (gssapi method) */ +#undef CONFIGURE_KRB5_CCNAME_GSSAPI + +/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_KRB5_H + +/* define to enable struct ether_addr definition */ +#undef HAVE_STRUCT_ETHER_ADDR + +/* define to enable socklen_t definition */ +#undef HAVE_SOCKLEN_T + +/* define if struct passwd has a pw_change member */ +#undef HAVE_PASSWD_PW_CHANGE + +/* define if struct passwd has a pw_expire member */ +#undef HAVE_PASSWD_PW_EXPIRE + +/* path to LDAP configuration file */ +#define NSS_LDAP_PATH_CONF "/etc/ldap.conf" + +/* path to LDAP root secret file */ +#define NSS_LDAP_PATH_ROOTPASSWD "/etc/ldap.secret" + +/* maximum number of group members in static buffer */ +#define LDAP_NSS_NGROUPS 64 + + +/* Define to 1 if you have the <aliases.h> header file. */ +#undef HAVE_ALIASES_H + +/* Define to 1 if you have the <alignof.h> header file. */ +#undef HAVE_ALIGNOF_H + +/* Define to 1 if you have the <bits/libc-lock.h> header file. */ +#undef HAVE_BITS_LIBC_LOCK_H + +/* Define to 1 if you have the <ctype.h> header file. */ +#undef HAVE_CTYPE_H + +/* Define to 1 if you have the `dn_expand' function. */ +#undef HAVE_DN_EXPAND + +/* Define to 1 if you have the `ether_aton' function. */ +#undef HAVE_ETHER_ATON + +/* Define to 1 if you have the `ether_ntoa' function. */ +#undef HAVE_ETHER_NTOA + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the `gethostbyname_r' function. */ +#undef HAVE_GETHOSTBYNAME_R + +/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_KRB5_H + +/* Define to 1 if you have the <gssapi.h> header file. */ +#undef HAVE_GSSAPI_H + +/* Define to 1 if you have the <gssldap.h> header file. */ +#undef HAVE_GSSLDAP_H + +/* Define to 1 if you have the <gsssasl.h> header file. */ +#undef HAVE_GSSSASL_H + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <irs.h> header file. */ +#undef HAVE_IRS_H + +/* Define to 1 if you have the <lber.h> header file. */ +#undef HAVE_LBER_H + +/* Define to 1 if you have the `ldapssl_client_init' function. */ +#undef HAVE_LDAPSSL_CLIENT_INIT + +/* Define to 1 if you have the `ldap_controls_free' function. */ +#undef HAVE_LDAP_CONTROLS_FREE + +/* Define to 1 if you have the `ldap_create_control' function. */ +#undef HAVE_LDAP_CREATE_CONTROL + +/* Define to 1 if you have the `ldap_create_page_control' function. */ +#undef HAVE_LDAP_CREATE_PAGE_CONTROL + +/* Define to 1 if you have the `ldap_explode_rdn' function. */ +#undef HAVE_LDAP_EXPLODE_RDN + +/* Define to 1 if you have the `ldap_get_lderrno' function. */ +#undef HAVE_LDAP_GET_LDERRNO + +/* Define to 1 if you have the `ldap_get_option' function. */ +#undef HAVE_LDAP_GET_OPTION + +/* Define to 1 if you have the <ldap.h> header file. */ +#undef HAVE_LDAP_H + +/* Define to 1 if you have the `ldap_init' function. */ +#undef HAVE_LDAP_INIT + +/* Define to 1 if you have the `ldap_initialize' function. */ +#undef HAVE_LDAP_INITIALIZE + +/* Define to 1 if you have the `ldap_ld_free' function. */ +#undef HAVE_LDAP_LD_FREE + +/* Define to 1 if you have the `ldap_memfree' function. */ +#undef HAVE_LDAP_MEMFREE + +/* Define to 1 if you have the `ldap_parse_page_control' function. */ +#undef HAVE_LDAP_PARSE_PAGE_CONTROL + +/* Define to 1 if you have the `ldap_parse_result' function. */ +#undef HAVE_LDAP_PARSE_RESULT + +/* Define to 1 if you have the `ldap_pvt_tls_set_option' function. */ +#undef HAVE_LDAP_PVT_TLS_SET_OPTION + +/* Define to 1 if you have the `ldap_sasl_interactive_bind_s' function. */ +#undef HAVE_LDAP_SASL_INTERACTIVE_BIND_S + +/* Define to 1 if you have the `ldap_search_ext' function. */ +#undef HAVE_LDAP_SEARCH_EXT + +/* Define to 1 if you have the `ldap_set_option' function. */ +#undef HAVE_LDAP_SET_OPTION + +/* Define to 1 if you have the `ldap_set_rebind_proc' function. */ +#undef HAVE_LDAP_SET_REBIND_PROC + +/* Define to 1 if you have the <ldap_ssl.h> header file. */ +#undef HAVE_LDAP_SSL_H + +/* Define to 1 if you have the `ldap_start_tls' function. */ +#undef HAVE_LDAP_START_TLS + +/* Define to 1 if you have the `ldap_start_tls_s' function. */ +#undef HAVE_LDAP_START_TLS_S + +/* Define to 1 if you have the <libc-lock.h> header file. */ +#undef HAVE_LIBC_LOCK_H + +/* Define to 1 if you have the `lber' library (-llber). */ +#undef HAVE_LIBLBER + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <netinet/ether.h> header file. */ +#undef HAVE_NETINET_ETHER_H + +/* Define to 1 if you have the <netinet/if_ether.h> header file. */ +#undef HAVE_NETINET_IF_ETHER_H + +/* Define to 1 if you have the <net/route.h> header file. */ +#undef HAVE_NET_ROUTE_H + +/* Define to 1 if you have the `nsdispatch' function. */ +#undef HAVE_NSDISPATCH + +/* Define to 1 if you have the <nsswitch.h> header file. */ +#undef HAVE_NSSWITCH_H + +/* Define to 1 if you have the <nss.h> header file. */ +#undef HAVE_NSS_H + +/* Define to 1 if you have the <port_after.h> header file. */ +#undef HAVE_PORT_AFTER_H + +/* Define to 1 if you have the <port_before.h> header file. */ +#undef HAVE_PORT_BEFORE_H + +/* Define to 1 if you have the <prot.h> header file. */ +#undef HAVE_PROT_H + +/* Define to 1 if you have the `pthread_atfork' function. */ +#undef HAVE_PTHREAD_ATFORK + +/* Define to 1 if you have the <pthread.h> header file. */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if you have the `res_search' function. */ +#undef HAVE_RES_SEARCH + +/* Define to 1 if you have the <rpc/rpcent.h> header file. */ +#undef HAVE_RPC_RPCENT_H + +/* Define to 1 if you have the `sasl_auxprop_request' function. */ +#undef HAVE_SASL_AUXPROP_REQUEST + +/* Define to 1 if you have the <sasl.h> header file. */ +#undef HAVE_SASL_H + +/* Define to 1 if you have the <sasl/sasl.h> header file. */ +#undef HAVE_SASL_SASL_H + +/* Define to 1 if you have the <shadow.h> header file. */ +#undef HAVE_SHADOW_H + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sigset' function. */ +#undef HAVE_SIGSET + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtok_r' function. */ +#undef HAVE_STRTOK_R + +/* Define to 1 if you have the <synch.h> header file. */ +#undef HAVE_SYNCH_H + +/* Define to 1 if you have the <sys/byteorder.h> header file. */ +#undef HAVE_SYS_BYTEORDER_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/un.h> header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the <thread.h> header file. */ +#undef HAVE_THREAD_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the <usersec.h> header file. */ +#undef HAVE_USERSEC_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..957578b --- /dev/null +++ b/config.sub @@ -0,0 +1,1457 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. +# Portions Copyright 1998-2002 OpenLDAP Foundation. + +timestamp='2002-02-01' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is distributed with OpenLDAP Software, which contains a +# configuration script generated by Autoconf, and is distributable +# under the same distributions terms as OpenLDAP inself. +# See the OpenLDAP COPYRIGHT and LICENSE file for details. +# $OpenLDAP: pkg/ldap/build/config.sub,v 1.11 2002/02/11 05:45:59 kurt Exp $ + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted 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. + +# 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 <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 0;; + + * ) + 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* | storm-chaos* | os2-emx* | windows32-*) + 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) + os= + basic_machine=$1 + ;; + -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 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -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] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # 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-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cray2-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \ + | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-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 + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [cjt]90) + basic_machine=${basic_machine}-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + 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 + ;; + 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 + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + 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 + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-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-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + 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 + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + 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 + ;; + 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=t3e-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + 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 + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-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. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* | -morphos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # 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 + ;; + 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 + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + 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 + ;; + -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 + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + 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 0 + +# 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 b/configure new file mode 100755 index 0000000..ad1e23a --- /dev/null +++ b/configure @@ -0,0 +1,5058 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_default_prefix= +ac_help="$ac_help + --enable-rfc2307bis use RFC2307bis schema by default " +ac_help="$ac_help + --enable-debugging enable debug code " +ac_help="$ac_help + --enable-paged-results use paged results control by default " +ac_help="$ac_help + --enable-configurable-krb5-ccname-env enable configurable Kerberos V credentials cache name (putenv method)" +ac_help="$ac_help + --enable-configurable-krb5-ccname-gssapi enable configurable Kerberos V credentials cache name (gssapi method)" +ac_help="$ac_help + --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]" +ac_help="$ac_help + --with-ldap-dir=DIR base directory of LDAP SDK" +ac_help="$ac_help + --with-ldap-conf-file path to LDAP configuration file" +ac_help="$ac_help + --with-ldap-secret-file path to LDAP root secret file" +ac_help="$ac_help + --with-gssapi-dir=DIR base directory of gssapi SDK" +ac_help="$ac_help + --with-ngroups=num average group size hint, experts only" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +sitefile= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --site-file=FILE use FILE as the site file + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -site-file | --site-file | --site-fil | --site-fi | --site-f) + ac_prev=sitefile ;; + -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) + sitefile="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ldap-nss.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$sitefile"; then + if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi + fi +else + CONFIG_SITE="$sitefile" +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:606: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:627: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:645: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:681: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:734: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:791: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=nss_ldap + +VERSION=251 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <<EOF +#define PACKAGE "$PACKAGE" +EOF + +cat >> confdefs.h <<EOF +#define VERSION "$VERSION" +EOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:837: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:850: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:863: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:876: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:889: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:909: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:939: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:990: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1022: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1033 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1064: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1069: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1078: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1097: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1129: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 1144 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1150: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 1161 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1167: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 1178 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1184: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1220: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +# Check whether --enable-rfc2307bis or --disable-rfc2307bis was given. +if test "${enable_rfc2307bis+set}" = set; then + enableval="$enable_rfc2307bis" + cat >> confdefs.h <<\EOF +#define RFC2307BIS 1 +EOF + +fi + + + +# Check whether --enable-debugging or --disable-debugging was given. +if test "${enable_debugging+set}" = set; then + enableval="$enable_debugging" + cat >> confdefs.h <<\EOF +#define DEBUG 1 +EOF + +fi + + +# Check whether --enable-paged-results or --disable-paged-results was given. +if test "${enable_paged_results+set}" = set; then + enableval="$enable_paged_results" + cat >> confdefs.h <<\EOF +#define PAGE_RESULTS 1 +EOF + +fi + + +# Check whether --enable-configurable-krb5-ccname-env or --disable-configurable-krb5-ccname-env was given. +if test "${enable_configurable_krb5_ccname_env+set}" = set; then + enableval="$enable_configurable_krb5_ccname_env" + cat >> confdefs.h <<\EOF +#define CONFIGURE_KRB5_CCNAME 1 +EOF + cat >> confdefs.h <<\EOF +#define CONFIGURE_KRB5_CCNAME_ENV 1 +EOF + +fi + +# Check whether --enable-configurable-krb5-ccname-gssapi or --disable-configurable-krb5-ccname-gssapi was given. +if test "${enable_configurable_krb5_ccname_gssapi+set}" = set; then + enableval="$enable_configurable_krb5_ccname_gssapi" + cat >> confdefs.h <<\EOF +#define CONFIGURE_KRB5_CCNAME 1 +EOF + cat >> confdefs.h <<\EOF +#define CONFIGURE_KRB5_CCNAME_GSSAPI 1 +EOF + +fi + + +# Check whether --with-ldap-lib or --without-ldap-lib was given. +if test "${with_ldap_lib+set}" = set; then + withval="$with_ldap_lib" + : +fi + +# Check whether --with-ldap-dir or --without-ldap-dir was given. +if test "${with_ldap_dir+set}" = set; then + withval="$with_ldap_dir" + : +fi + +# Check whether --with-ldap-conf-file or --without-ldap-conf-file was given. +if test "${with_ldap_conf_file+set}" = set; then + withval="$with_ldap_conf_file" + NSS_LDAP_PATH_CONF="$with_ldap_conf_file" +else + NSS_LDAP_PATH_CONF="/etc/ldap.conf" +fi + +# Check whether --with-ldap-secret-file or --without-ldap-secret-file was given. +if test "${with_ldap_secret_file+set}" = set; then + withval="$with_ldap_secret_file" + NSS_LDAP_PATH_ROOTPASSWD="$with_ldap_secret_file" +else + NSS_LDAP_PATH_ROOTPASSWD="/etc/ldap.secret" +fi + +# Check whether --with-gssapi-dir or --without-gssapi-dir was given. +if test "${with_gssapi_dir+set}" = set; then + withval="$with_gssapi_dir" + : +fi + +# Check whether --with-ngroups or --without-ngroups was given. +if test "${with_ngroups+set}" = set; then + withval="$with_ngroups" + cat >> confdefs.h <<EOF +#define LDAP_NSS_NGROUPS $with_ngroups +EOF + +fi + + +cat >> confdefs.h <<EOF +#define NSS_LDAP_PATH_CONF "$NSS_LDAP_PATH_CONF" +EOF + +cat >> confdefs.h <<EOF +#define NSS_LDAP_PATH_ROOTPASSWD "$NSS_LDAP_PATH_ROOTPASSWD" +EOF + + + + +if test "$ac_cv_prog_gcc" = "yes"; then CFLAGS="$CFLAGS -Wall -fPIC"; fi + +CPPFLAGS="$CPPFLAGS -DLDAP_REFERRALS -DLDAP_DEPRECATED" + +case "$target_os" in +freebsd*) CPPFLAGS="$CPPFLAGS -DPIC -D_REENTRANT" ;; +aix*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; +*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; +esac + +# Always use native linker on Solaris and AIX +# but only invoke directly if compiling with gcc (?) + +case "$target_os" in +aix*) if test "$ac_cv_prog_gcc" = "yes"; then + nss_ldap_so_LD="/usr/bin/ld" + fi + LDFLAGS="$LDFLAGS -Wl,-brtl" + nss_ldap_so_LDFLAGS="-bM:SRE -bnoentry -bE:\$(srcdir)/exports.aix -brtl -lc" + NSS_LDAP_LDFLAGS="-bM:SRE -enss_ldap_initialize -brtl -lc" + CPPFLAGS="$CPPFLAGS -I." + need_pthread=yes + TARGET_OS=AIX ;; +solaris*) if test "$ac_cv_prog_gcc" = yes; then + nss_ldap_so_LD="/usr/ccs/bin/ld" + fi + nss_ldap_so_LDFLAGS="-Bdynamic -M \$(srcdir)/exports.solaris -G" ;; +hpux*) if test "$ac_cv_prog_gcc" = yes; then + nss_ldap_so_LD="/bin/ld" + fi + nss_ldap_so_LDFLAGS="-b -dynamic -G `cat exports.hpux`" + CPPFLAGS="$CPPFLAGS -I. -DHPUX" + TARGET_OS=HPUX ;; +linux*) nss_ldap_so_LDFLAGS="-shared -Wl,-Bdynamic -Wl,--version-script,\$(srcdir)/exports.linux" ;; +*) nss_ldap_so_LDFLAGS="-shared -Wl,-Bdynamic" ;; +esac + + + +if test "$target_os" = "linux" -o "$target_os" = "linux-gnu"; then + GLIBC_TRUE= + GLIBC_FALSE='#' +else + GLIBC_TRUE='#' + GLIBC_FALSE= +fi + + +if test "$TARGET_OS" = AIX; then + AIX_TRUE= + AIX_FALSE='#' +else + AIX_TRUE='#' + AIX_FALSE= +fi + + +if test "$TARGET_OS" = HPUX; then + HPUX_TRUE= + HPUX_FALSE='#' +else + HPUX_TRUE='#' + HPUX_FALSE= +fi + + + +if test -n "$nss_ldap_so_LD"; then + USE_NATIVE_LINKER_TRUE= + USE_NATIVE_LINKER_FALSE='#' +else + USE_NATIVE_LINKER_TRUE='#' + USE_NATIVE_LINKER_FALSE= +fi + +# unfortunately the linker flags have to be defined twice for +# AIX as we can't force using the native linker for configure +# tests, and the gcc front-end does not understand native +# linker flags. +if test -n "$with_ldap_dir"; then + CPPFLAGS="$CPPFLAGS -I$with_ldap_dir/include" + LDFLAGS="$LDFLAGS -L$with_ldap_dir/lib" + case "$target_os" in + aix*) LDFLAGS="$LDFLAGS -Wl,-blibpath:$with_ldap_dir/lib" + nss_ldap_so_LDFLAGS="$nss_ldap_so_LDFLAGS -L$with_ldap_dir/lib -blibpath:$with_ldap_dir/lib" + NSS_LDAP_LDFLAGS="$NSS_LDAP_LDFLAGS -L$with_ldap_dir/lib -blibpath:$with_ldap_dir/lib" ;; + hpux*) LDFLAGS="$LDFLAGS -Wl,+b$with_ldap_dir/lib" + nss_ldap_so_LDFLAGS="$nss_ldap_so_LDFLAGS -L$with_ldap_dir/lib +b$with_ldap_dir/lib" ;; + solaris*) LDFLAGS="$LDFLAGS -R$with_ldap_dir/lib" + nss_ldap_so_LDFLAGS="$nss_ldap_so_LDFLAGS -L$with_ldap_dir/lib -R$with_ldap_dir/lib" ;; + *) LDFLAGS="$LDFLAGS -Wl,-rpath,$with_ldap_dir/lib" ;; + esac +fi +if test -n "$with_gssapi_dir"; then + CPPFLAGS="$CPPFLAGS -I$with_gssapi_dir/include" + LDFLAGS="$LDFLAGS -L$with_gssapi_dir/lib" +fi + + + + + +for ac_hdr in lber.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1490: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1495 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1500: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in ldap.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1530: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1535 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1540: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +{ echo "configure: error: could not locate <ldap.h>" 1>&2; exit 1; } +fi +done + +for ac_hdr in ldap_ssl.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1571: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1576 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1581: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + + +# For HP-UX and AIX we use private API, the headers for which +# are included locally. We need to do something to stop both +# API being detected. +case "$target_os" in + aix*) for ac_hdr in irs.h usersec.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1617: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1622 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1627: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + ;; + hpux*) for ac_hdr in nsswitch.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1657: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1662 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1667: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + ;; + *) for ac_hdr in nss.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1697: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1702 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1707: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_hdr in nsswitch.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1737: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1742 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1747: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_hdr in irs.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1777: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1782 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1787: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + ;; +esac +for ac_hdr in thread.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1818: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1823 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1828: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in pthread.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1858: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1863 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1868: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in synch.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1898: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1903 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in malloc.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1938: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1943 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1948: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in shadow.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1978: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1983 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1988: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in prot.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2018: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2023 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2028: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in port_before.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2058: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2063 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2068: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in port_after.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2098: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2103 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2108: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in aliases.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2138: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2143 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2148: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in net/route.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2178: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2183 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2188: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in netinet/if_ether.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2218: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2223 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2228: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in netinet/ether.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2258: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2263 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2268: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in ctype.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2298: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2303 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2308: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in alignof.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2338: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2343 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2348: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in rpc/rpcent.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2378: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2383 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2388: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in sys/byteorder.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2418: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2423 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2428: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in sys/un.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2458: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2463 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2468: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in libc-lock.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2498: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2503 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2508: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in bits/libc-lock.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2538: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2543 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2548: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in sasl.h sasl/sasl.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2578: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2583 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2588: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in strings.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2618: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2623 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2628: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in gssldap.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2658: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2663 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2668: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in gsssasl.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2698: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2703 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2708: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in gssapi/gssapi_krb5.h gssapi.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2738: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2743 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2748: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +echo $ac_n "checking for main in -lresolv""... $ac_c" 1>&6 +echo "configure:2776: checking for main in -lresolv" >&5 +ac_lib_var=`echo resolv'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2784 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:2791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lresolv $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6 +echo "configure:2819: checking for main in -lnsl" >&5 +ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2827 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:2834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lnsl $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 +echo "configure:2862: checking for main in -lsocket" >&5 +ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2870 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:2877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lsocket $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + +for ac_func in strtok_r +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2908: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2913 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in sigaction +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2963: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2968 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in sigset +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3018: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3023 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3046: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in res_search +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3073: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3078 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in dn_expand +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3128: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3133 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3156: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in snprintf +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3183: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3188 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in gethostbyname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3238: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3243 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in nsdispatch +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3293: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3298 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in pthread_atfork +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3348: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3353 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3376: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in ether_aton +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3403: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3408 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in ether_ntoa +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3458: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3463 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +echo $ac_n "checking for struct ether_addr""... $ac_c" 1>&6 +echo "configure:3512: checking for struct ether_addr" >&5 +cat > conftest.$ac_ext <<EOF +#line 3514 "configure" +#include "confdefs.h" +#include <sys/types.h> + #include <sys/socket.h> + #include <net/if.h> + #include <netinet/in.h> + #include <netinet/if_ether.h> +int main() { +struct ether_addr x; +; return 0; } +EOF +if { (eval echo configure:3525: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_ETHER_ADDR 1 +EOF + + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* + +echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 +echo "configure:3543: checking for socklen_t" >&5 +cat > conftest.$ac_ext <<EOF +#line 3545 "configure" +#include "confdefs.h" +#include <sys/types.h> + #include <sys/socket.h> +int main() { +socklen_t len; +; return 0; } +EOF +if { (eval echo configure:3553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_SOCKLEN_T 1 +EOF + + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* + +echo $ac_n "checking for pw_change in struct passwd""... $ac_c" 1>&6 +echo "configure:3571: checking for pw_change in struct passwd" >&5 +cat > conftest.$ac_ext <<EOF +#line 3573 "configure" +#include "confdefs.h" +#include <pwd.h> +int main() { +struct passwd pwd; time_t t = pwd.pw_change +; return 0; } +EOF +if { (eval echo configure:3580: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_PASSWD_PW_CHANGE 1 +EOF + + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* +echo $ac_n "checking for pw_expire in struct passwd""... $ac_c" 1>&6 +echo "configure:3597: checking for pw_expire in struct passwd" >&5 +cat > conftest.$ac_ext <<EOF +#line 3599 "configure" +#include "confdefs.h" +#include <pwd.h> +int main() { +struct passwd pwd; time_t t = pwd.pw_expire +; return 0; } +EOF +if { (eval echo configure:3606: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_PASSWD_PW_EXPIRE 1 +EOF + + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* + +if test -z "$with_ldap_lib"; then + with_ldap_lib=auto +fi + +echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "configure:3628: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3636 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen(); + +int main() { +dlopen() +; return 0; } +EOF +if { (eval echo configure:3647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-ldl $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking for gss_krb5_ccache_name in -lgssapi""... $ac_c" 1>&6 +echo "configure:3669: checking for gss_krb5_ccache_name in -lgssapi" >&5 +ac_lib_var=`echo gssapi'_'gss_krb5_ccache_name | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi $LIBS $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3677 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gss_krb5_ccache_name(); + +int main() { +gss_krb5_ccache_name() +; return 0; } +EOF +if { (eval echo configure:3688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lgssapi $LIBS" found_gssapi_lib=yes +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$found_gssapi_lib"; then + echo $ac_n "checking for gss_krb5_ccache_name in -lgssapi_krb5""... $ac_c" 1>&6 +echo "configure:3710: checking for gss_krb5_ccache_name in -lgssapi_krb5" >&5 +ac_lib_var=`echo gssapi_krb5'_'gss_krb5_ccache_name | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi_krb5 $LIBS $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3718 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gss_krb5_ccache_name(); + +int main() { +gss_krb5_ccache_name() +; return 0; } +EOF +if { (eval echo configure:3729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lgssapi_krb5 $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + +if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then + echo $ac_n "checking for main in -llber""... $ac_c" 1>&6 +echo "configure:3754: checking for main in -llber" >&5 +ac_lib_var=`echo lber'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-llber $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3762 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:3769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo lber | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-llber $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for main in -lldap""... $ac_c" 1>&6 +echo "configure:3797: checking for main in -lldap" >&5 +ac_lib_var=`echo ldap'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lldap $LIBS $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3805 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:3812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lldap $LIBS" found_ldap_lib=yes +else + echo "$ac_t""no" 1>&6 +fi + +fi +if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then +echo $ac_n "checking for main in -lldap50""... $ac_c" 1>&6 +echo "configure:3835: checking for main in -lldap50" >&5 +ac_lib_var=`echo ldap50'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lldap50 -lpthread $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3843 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:3850: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes need_pthread=yes +else + echo "$ac_t""no" 1>&6 +fi + +fi +if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then + echo $ac_n "checking for main in -lldapssl41""... $ac_c" 1>&6 +echo "configure:3873: checking for main in -lldapssl41" >&5 +ac_lib_var=`echo ldapssl41'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lldapssl41 -lpthread $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3881 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:3888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes need_pthread=yes +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$found_ldap_lib"; then + echo $ac_n "checking for main in -lldapssl40""... $ac_c" 1>&6 +echo "configure:3910: checking for main in -lldapssl40" >&5 +ac_lib_var=`echo ldapssl40'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lldapssl40 -lpthread $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3918 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:3925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes need_pthread=yes +else + echo "$ac_t""no" 1>&6 +fi + + fi + if test -z "$found_ldap_lib"; then + echo $ac_n "checking for main in -lldap41""... $ac_c" 1>&6 +echo "configure:3948: checking for main in -lldap41" >&5 +ac_lib_var=`echo ldap41'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lldap41 $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3956 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:3963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lldap41 $LIBS" found_ldap_lib=yes need_pthread=no +else + echo "$ac_t""no" 1>&6 +fi + + fi + if test -z "$found_ldap_lib"; then + echo $ac_n "checking for main in -lldap40""... $ac_c" 1>&6 +echo "configure:3986: checking for main in -lldap40" >&5 +ac_lib_var=`echo ldap40'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lldap40 $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3994 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:4001: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lldap40 $LIBS" found_ldap_lib=yes need_pthread=no +else + echo "$ac_t""no" 1>&6 +fi + + fi +fi +if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then + echo $ac_n "checking for main in -lldapssl30""... $ac_c" 1>&6 +echo "configure:4025: checking for main in -lldapssl30" >&5 +ac_lib_var=`echo ldapssl30'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lldapssl30 -lpthread $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4033 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:4040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes need_pthread=yes +else + echo "$ac_t""no" 1>&6 +fi + +fi + +if test -z "$found_ldap_lib"; then + { echo "configure: error: could not locate a valid LDAP library" 1>&2; exit 1; } +fi + +if test "$need_pthread" = "yes"; then + echo $ac_n "checking for main in -lpthread""... $ac_c" 1>&6 +echo "configure:4068: checking for main in -lpthread" >&5 +ac_lib_var=`echo pthread'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpthread $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4076 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:4083: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo pthread | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lpthread $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking for ldap_gss_bind in -lgssldap""... $ac_c" 1>&6 +echo "configure:4113: checking for ldap_gss_bind in -lgssldap" >&5 +ac_lib_var=`echo gssldap'_'ldap_gss_bind | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssldap $LIBS $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4121 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char ldap_gss_bind(); + +int main() { +ldap_gss_bind() +; return 0; } +EOF +if { (eval echo configure:4132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lgssldap $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + + +for ac_func in sasl_auxprop_request +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4156: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4161 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in ldap_init ldap_get_lderrno ldap_parse_result ldap_memfree ldap_controls_free +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4211: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4216 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in ldap_ld_free ldap_explode_rdn ldap_set_option ldap_get_option +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4266: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4271 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in ldap_sasl_interactive_bind_s ldap_initialize ldap_search_ext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4321: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4326 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in ldap_create_control ldap_create_page_control ldap_parse_page_control +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4376: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4381 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +if test "$enable_ssl" \!= "no"; then + for ac_func in ldapssl_client_init ldap_start_tls_s ldap_pvt_tls_set_option ldap_start_tls +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4432: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4437 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4460: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +fi +for ac_func in gethostbyname_r +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4488: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4493 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +if test "$ac_cv_func_gethostbyname_r" = "yes"; then +echo $ac_n "checking whether gethostbyname_r takes 6 arguments""... $ac_c" 1>&6 +echo "configure:4543: checking whether gethostbyname_r takes 6 arguments" >&5 +if eval "test \"`echo '$''{'nss_ldap_cv_gethostbyname_r_args'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext <<EOF +#line 4549 "configure" +#include "confdefs.h" + +#include <netdb.h> +int main() { +gethostbyname_r(0, 0, 0, 0, 0, 0); +; return 0; } +EOF +if { (eval echo configure:4557: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + nss_ldap_cv_gethostbyname_r_args=6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + nss_ldap_cv_gethostbyname_r_args=5 +fi +rm -f conftest* +fi + +echo "$ac_t""$nss_ldap_cv_gethostbyname_r_args" 1>&6 +cat >> confdefs.h <<EOF +#define GETHOSTBYNAME_R_ARGS $nss_ldap_cv_gethostbyname_r_args +EOF + +fi + +for ac_func in ldap_set_rebind_proc +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4579: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4584 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4607: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +echo $ac_n "checking whether ldap_set_rebind_proc takes 3 arguments""... $ac_c" 1>&6 +echo "configure:4632: checking whether ldap_set_rebind_proc takes 3 arguments" >&5 +if eval "test \"`echo '$''{'nss_ldap_cv_ldap_set_rebind_proc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext <<EOF +#line 4638 "configure" +#include "confdefs.h" + +#include <lber.h> +#include <ldap.h> +int main() { +ldap_set_rebind_proc(0, 0, 0); +; return 0; } +EOF +if { (eval echo configure:4647: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + nss_ldap_cv_ldap_set_rebind_proc=3 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + nss_ldap_cv_ldap_set_rebind_proc=2 +fi +rm -f conftest* +fi + +echo "$ac_t""$nss_ldap_cv_ldap_set_rebind_proc" 1>&6 +cat >> confdefs.h <<EOF +#define LDAP_SET_REBIND_PROC_ARGS $nss_ldap_cv_ldap_set_rebind_proc +EOF + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@NSS_LDAP_PATH_CONF@%$NSS_LDAP_PATH_CONF%g +s%@NSS_LDAP_PATH_ROOTPASSWD@%$NSS_LDAP_PATH_ROOTPASSWD%g +s%@GLIBC_TRUE@%$GLIBC_TRUE%g +s%@GLIBC_FALSE@%$GLIBC_FALSE%g +s%@AIX_TRUE@%$AIX_TRUE%g +s%@AIX_FALSE@%$AIX_FALSE%g +s%@HPUX_TRUE@%$HPUX_TRUE%g +s%@HPUX_FALSE@%$HPUX_FALSE%g +s%@USE_NATIVE_LINKER_TRUE@%$USE_NATIVE_LINKER_TRUE%g +s%@USE_NATIVE_LINKER_FALSE@%$USE_NATIVE_LINKER_FALSE%g +s%@nss_ldap_so_LD@%$nss_ldap_so_LD%g +s%@nss_ldap_so_LDFLAGS@%$nss_ldap_so_LDFLAGS%g +s%@NSS_LDAP_LDFLAGS@%$NSS_LDAP_LDFLAGS%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="config.h" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF + + +EOF +cat >> $CONFIG_STATUS <<\EOF +test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..2a09e2e --- /dev/null +++ b/configure.in @@ -0,0 +1,321 @@ +AC_INIT(ldap-nss.c) +AC_CANONICAL_SYSTEM +AC_PREFIX_DEFAULT() + +AM_INIT_AUTOMAKE(nss_ldap, 251) +AM_CONFIG_HEADER(config.h) + +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL + +dnl +dnl --enable-rfc2307bis is now deprecated; if this option is set, +dnl then RFC2307bis support will be enabled by default. However +dnl it can now always be enabled at runtime with the nss_schema +dnl keyword. See nss_ldap(5) for more information. +dnl +AC_ARG_ENABLE(rfc2307bis, [ --enable-rfc2307bis use RFC2307bis schema by default ], [AC_DEFINE(RFC2307BIS)]) + +dnl +dnl --enable-schema-mapping is no longer necessary as schema +dnl mapping is enabled by default +dnl +dnl AC_ARG_ENABLE(schema-mapping, [ --enable-schema-mapping enable attribute/objectclass mapping ], [AC_DEFINE(AT_OC_MAP)]) +dnl + +AC_ARG_ENABLE(debugging, [ --enable-debugging enable debug code ], [AC_DEFINE(DEBUG)]) + +dnl +dnl --enable-paged-results is now deprecated; if this option is set, +dnl then paged results will be enabled by default. However, it can +dnl now always be enabled at runtime (as long as the underlying LDAP +dnl library supports ldap_search_ext()) with the nss_paged_results +dnl keyword. See nss_ldap(5) for more information +dnl +AC_ARG_ENABLE(paged-results, [ --enable-paged-results use paged results control by default ], [AC_DEFINE(PAGE_RESULTS)]) + +dnl +dnl XXX TODO make configurable-krb5-ccname-* configurable at runtime +dnl +AC_ARG_ENABLE(configurable-krb5-ccname-env, [ --enable-configurable-krb5-ccname-env enable configurable Kerberos V credentials cache name (putenv method)], [AC_DEFINE(CONFIGURE_KRB5_CCNAME) AC_DEFINE(CONFIGURE_KRB5_CCNAME_ENV)]) +AC_ARG_ENABLE(configurable-krb5-ccname-gssapi, [ --enable-configurable-krb5-ccname-gssapi enable configurable Kerberos V credentials cache name (gssapi method)], [AC_DEFINE(CONFIGURE_KRB5_CCNAME) AC_DEFINE(CONFIGURE_KRB5_CCNAME_GSSAPI)]) + +AC_ARG_WITH(ldap-lib, [ --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]]) +AC_ARG_WITH(ldap-dir, [ --with-ldap-dir=DIR base directory of LDAP SDK]) +AC_ARG_WITH(ldap-conf-file, [ --with-ldap-conf-file path to LDAP configuration file], + [ NSS_LDAP_PATH_CONF="$with_ldap_conf_file" ], + [ NSS_LDAP_PATH_CONF="/etc/ldap.conf" ]) +AC_ARG_WITH(ldap-secret-file, [ --with-ldap-secret-file path to LDAP root secret file], + [ NSS_LDAP_PATH_ROOTPASSWD="$with_ldap_secret_file" ], + [ NSS_LDAP_PATH_ROOTPASSWD="/etc/ldap.secret" ]) +AC_ARG_WITH(gssapi-dir, [ --with-gssapi-dir=DIR base directory of gssapi SDK]) +AC_ARG_WITH(ngroups, [ --with-ngroups=num average group size hint, experts only], [AC_DEFINE_UNQUOTED(LDAP_NSS_NGROUPS, $with_ngroups)]) + +AC_DEFINE_UNQUOTED(NSS_LDAP_PATH_CONF, "$NSS_LDAP_PATH_CONF") +AC_DEFINE_UNQUOTED(NSS_LDAP_PATH_ROOTPASSWD, "$NSS_LDAP_PATH_ROOTPASSWD") +AC_SUBST(NSS_LDAP_PATH_CONF) +AC_SUBST(NSS_LDAP_PATH_ROOTPASSWD) + +if test "$ac_cv_prog_gcc" = "yes"; then CFLAGS="$CFLAGS -Wall -fPIC"; fi + +dnl This is needed for the native Solaris LDAP SDK and +dnl OpenLDAP 2.2, respectively +CPPFLAGS="$CPPFLAGS -DLDAP_REFERRALS -DLDAP_DEPRECATED" + +case "$target_os" in +freebsd*) CPPFLAGS="$CPPFLAGS -DPIC -D_REENTRANT" ;; +aix*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; +*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; +esac + +# Always use native linker on Solaris and AIX +# but only invoke directly if compiling with gcc (?) + +case "$target_os" in +aix*) if test "$ac_cv_prog_gcc" = "yes"; then + nss_ldap_so_LD="/usr/bin/ld" + fi + LDFLAGS="$LDFLAGS -Wl,-brtl" + nss_ldap_so_LDFLAGS="-bM:SRE -bnoentry -bE:\$(srcdir)/exports.aix -brtl -lc" + NSS_LDAP_LDFLAGS="-bM:SRE -enss_ldap_initialize -brtl -lc" + CPPFLAGS="$CPPFLAGS -I." + need_pthread=yes + TARGET_OS=AIX ;; +solaris*) if test "$ac_cv_prog_gcc" = yes; then + nss_ldap_so_LD="/usr/ccs/bin/ld" + fi + nss_ldap_so_LDFLAGS="-Bdynamic -M \$(srcdir)/exports.solaris -G" ;; +hpux*) if test "$ac_cv_prog_gcc" = yes; then + nss_ldap_so_LD="/bin/ld" + fi + nss_ldap_so_LDFLAGS="-b -dynamic -G `cat exports.hpux`" + CPPFLAGS="$CPPFLAGS -I. -DHPUX" + TARGET_OS=HPUX ;; +linux*) nss_ldap_so_LDFLAGS="-shared -Wl,-Bdynamic -Wl,--version-script,\$(srcdir)/exports.linux" ;; +*) nss_ldap_so_LDFLAGS="-shared -Wl,-Bdynamic" ;; +esac + +AM_CONDITIONAL(GLIBC, test "$target_os" = "linux" -o "$target_os" = "linux-gnu") +AM_CONDITIONAL(AIX, test "$TARGET_OS" = AIX) +AM_CONDITIONAL(HPUX, test "$TARGET_OS" = HPUX) + +AM_CONDITIONAL(USE_NATIVE_LINKER, test -n "$nss_ldap_so_LD") + +# unfortunately the linker flags have to be defined twice for +# AIX as we can't force using the native linker for configure +# tests, and the gcc front-end does not understand native +# linker flags. +if test -n "$with_ldap_dir"; then + CPPFLAGS="$CPPFLAGS -I$with_ldap_dir/include" + LDFLAGS="$LDFLAGS -L$with_ldap_dir/lib" + case "$target_os" in + aix*) LDFLAGS="$LDFLAGS -Wl,-blibpath:$with_ldap_dir/lib" + nss_ldap_so_LDFLAGS="$nss_ldap_so_LDFLAGS -L$with_ldap_dir/lib -blibpath:$with_ldap_dir/lib" + NSS_LDAP_LDFLAGS="$NSS_LDAP_LDFLAGS -L$with_ldap_dir/lib -blibpath:$with_ldap_dir/lib" ;; + hpux*) LDFLAGS="$LDFLAGS -Wl,+b$with_ldap_dir/lib" + nss_ldap_so_LDFLAGS="$nss_ldap_so_LDFLAGS -L$with_ldap_dir/lib +b$with_ldap_dir/lib" ;; + solaris*) LDFLAGS="$LDFLAGS -R$with_ldap_dir/lib" + nss_ldap_so_LDFLAGS="$nss_ldap_so_LDFLAGS -L$with_ldap_dir/lib -R$with_ldap_dir/lib" ;; + *) LDFLAGS="$LDFLAGS -Wl,-rpath,$with_ldap_dir/lib" ;; + esac +fi +if test -n "$with_gssapi_dir"; then + CPPFLAGS="$CPPFLAGS -I$with_gssapi_dir/include" + LDFLAGS="$LDFLAGS -L$with_gssapi_dir/lib" +fi + +AC_SUBST(nss_ldap_so_LD) +AC_SUBST(nss_ldap_so_LDFLAGS) +AC_SUBST(NSS_LDAP_LDFLAGS) + +AC_CHECK_HEADERS(lber.h) +AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate <ldap.h>)) +AC_CHECK_HEADERS(ldap_ssl.h) + +dnl AC_MSG_CHECKING(for ldap_ssl.h) +dnl AC_TRY_COMPILE([#include <sys/types.h> +dnl #include <ldap.h> +dnl #include <ldap_ssl.h>], , +dnl [ +dnl AC_MSG_RESULT(yes), +dnl AC_DEFINE(HAVE_LDAP_SSL_H, 1) +dnl ], +dnl AC_MSG_RESULT(no)) + +# For HP-UX and AIX we use private API, the headers for which +# are included locally. We need to do something to stop both +# API being detected. +case "$target_os" in + aix*) AC_CHECK_HEADERS(irs.h usersec.h) ;; + hpux*) AC_CHECK_HEADERS(nsswitch.h) ;; + *) AC_CHECK_HEADERS(nss.h) + AC_CHECK_HEADERS(nsswitch.h) + AC_CHECK_HEADERS(irs.h) ;; +esac +AC_CHECK_HEADERS(thread.h) +AC_CHECK_HEADERS(pthread.h) +AC_CHECK_HEADERS(synch.h) +AC_CHECK_HEADERS(malloc.h) +AC_CHECK_HEADERS(shadow.h) +AC_CHECK_HEADERS(prot.h) +AC_CHECK_HEADERS(port_before.h) +AC_CHECK_HEADERS(port_after.h) +AC_CHECK_HEADERS(aliases.h) +AC_CHECK_HEADERS(net/route.h) +AC_CHECK_HEADERS(netinet/if_ether.h) +AC_CHECK_HEADERS(netinet/ether.h) +AC_CHECK_HEADERS(ctype.h) +dnl AC_CHECK_HEADERS(db.h) +dnl AC_CHECK_HEADERS(db1/db.h) +dnl AC_CHECK_HEADERS(db_185.h) +dnl AC_CHECK_HEADERS(db3/db_185.h) +AC_CHECK_HEADERS(alignof.h) +AC_CHECK_HEADERS(rpc/rpcent.h) +AC_CHECK_HEADERS(sys/byteorder.h) +AC_CHECK_HEADERS(sys/un.h) +AC_CHECK_HEADERS(libc-lock.h) +AC_CHECK_HEADERS(bits/libc-lock.h) +AC_CHECK_HEADERS(sasl.h sasl/sasl.h) +AC_CHECK_HEADERS(strings.h) +AC_CHECK_HEADERS(gssldap.h) +AC_CHECK_HEADERS(gsssasl.h) +AC_CHECK_HEADERS(gssapi/gssapi_krb5.h gssapi.h) + +AC_CHECK_LIB(resolv, main) +AC_CHECK_LIB(nsl, main) +AC_CHECK_LIB(socket, main) + +AC_CHECK_FUNCS(strtok_r) +AC_CHECK_FUNCS(sigaction) +AC_CHECK_FUNCS(sigset) +AC_CHECK_FUNCS(res_search) +AC_CHECK_FUNCS(dn_expand) +AC_CHECK_FUNCS(snprintf) +AC_CHECK_FUNCS(gethostbyname) +AC_CHECK_FUNCS(nsdispatch) +AC_CHECK_FUNCS(pthread_atfork) +AC_CHECK_FUNCS(ether_aton) +AC_CHECK_FUNCS(ether_ntoa) + +AC_MSG_CHECKING(for struct ether_addr) +AC_TRY_COMPILE([#include <sys/types.h> + #include <sys/socket.h> + #include <net/if.h> + #include <netinet/in.h> + #include <netinet/if_ether.h>], + [struct ether_addr x;], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STRUCT_ETHER_ADDR, 1) + ], + AC_MSG_RESULT(no)) + +AC_MSG_CHECKING(for socklen_t) +AC_TRY_COMPILE([#include <sys/types.h> + #include <sys/socket.h>], + [socklen_t len;], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SOCKLEN_T, 1) + ], + AC_MSG_RESULT(no)) + +AC_MSG_CHECKING(for pw_change in struct passwd) +AC_TRY_COMPILE([#include <pwd.h>], + [struct passwd pwd; time_t t = pwd.pw_change], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PASSWD_PW_CHANGE, 1) + ], + AC_MSG_RESULT(no)) +AC_MSG_CHECKING(for pw_expire in struct passwd) +AC_TRY_COMPILE([#include <pwd.h>], + [struct passwd pwd; time_t t = pwd.pw_expire], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PASSWD_PW_EXPIRE, 1) + ], + AC_MSG_RESULT(no)) + +dnl check which ldap library we have +dnl check which ldap library we have +if test -z "$with_ldap_lib"; then + with_ldap_lib=auto +fi + +AC_CHECK_LIB(dl, dlopen,[LIBS="-ldl $LIBS"],,$LIBS) +dnl AC_CHECK_LIB(db, main,[LIBS="-ldb $LIBS"],,$LIBS) + +AC_CHECK_LIB(gssapi, gss_krb5_ccache_name,[LIBS="-lgssapi $LIBS" found_gssapi_lib=yes],,$LIBS) +if test -z "$found_gssapi_lib"; then + AC_CHECK_LIB(gssapi_krb5, gss_krb5_ccache_name,[LIBS="-lgssapi_krb5 $LIBS"],,$LIBS) +fi + +dnl Following checks probably not strictly necessary. +dnl AC_CHECK_LIB(crypto, main,[LIBS="-lcrypto $LIBS"],,$LIBS) +dnl AC_CHECK_LIB(ssl, main,[LIBS="-lssl $LIBS"],,$LIBS) +dnl AC_CHECK_LIB(com_err, main,[LIBS="-lcom_err $LIBS"],,$LIBS) +dnl AC_CHECK_LIB(k5crypto, main,[LIBS="-lk5crypto $LIBS"],,$LIBS) +dnl AC_CHECK_LIB(krb5, main,[LIBS="-lkrb5 $LIBS"],,$LIBS) +dnl AC_CHECK_LIB(krb4, main,[LIBS="-lkrb4 $LIBS"],,$LIBS) +dnl AC_CHECK_LIB(sasl, sasl_client_init,[LIBS="-lsasl $LIBS"],,$LIBS) + +if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then + AC_CHECK_LIB(lber, main) + AC_CHECK_LIB(ldap, main, [LIBS="-lldap $LIBS" found_ldap_lib=yes],,$LIBS) +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 need_pthread=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 need_pthread=yes,, -lpthread) + if test -z "$found_ldap_lib"; then + AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes need_pthread=yes,, -lpthread) + fi + if test -z "$found_ldap_lib"; then + AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes need_pthread=no,,) + fi + if test -z "$found_ldap_lib"; then + AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes need_pthread=no,,) + 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 need_pthread=yes,, -lpthread) +fi + +if test -z "$found_ldap_lib"; then + AC_MSG_ERROR(could not locate a valid LDAP library) +fi + +if test "$need_pthread" = "yes"; then + AC_CHECK_LIB(pthread, main) +fi + +AC_CHECK_LIB(gssldap, ldap_gss_bind,[LIBS="-lgssldap $LIBS"],,$LIBS) + +AC_CHECK_FUNCS(sasl_auxprop_request) +AC_CHECK_FUNCS(ldap_init ldap_get_lderrno ldap_parse_result ldap_memfree ldap_controls_free) +AC_CHECK_FUNCS(ldap_ld_free ldap_explode_rdn ldap_set_option ldap_get_option) +AC_CHECK_FUNCS(ldap_sasl_interactive_bind_s ldap_initialize ldap_search_ext) +AC_CHECK_FUNCS(ldap_create_control ldap_create_page_control ldap_parse_page_control) +if test "$enable_ssl" \!= "no"; then + AC_CHECK_FUNCS(ldapssl_client_init ldap_start_tls_s ldap_pvt_tls_set_option ldap_start_tls) +fi +AC_CHECK_FUNCS(gethostbyname_r) + +if test "$ac_cv_func_gethostbyname_r" = "yes"; then +AC_CACHE_CHECK(whether gethostbyname_r takes 6 arguments, nss_ldap_cv_gethostbyname_r_args, [ +AC_TRY_COMPILE([ +#include <netdb.h>], [gethostbyname_r(0, 0, 0, 0, 0, 0);], [nss_ldap_cv_gethostbyname_r_args=6], [nss_ldap_cv_gethostbyname_r_args=5]) ]) +AC_DEFINE_UNQUOTED(GETHOSTBYNAME_R_ARGS, $nss_ldap_cv_gethostbyname_r_args) +fi + +AC_CHECK_FUNCS(ldap_set_rebind_proc) +AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, nss_ldap_cv_ldap_set_rebind_proc, [ +AC_TRY_COMPILE([ +#include <lber.h> +#include <ldap.h>], [ldap_set_rebind_proc(0, 0, 0);], [nss_ldap_cv_ldap_set_rebind_proc=3], [nss_ldap_cv_ldap_set_rebind_proc=2]) ]) +AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $nss_ldap_cv_ldap_set_rebind_proc) + +AC_OUTPUT(Makefile) @@ -0,0 +1,411 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# 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 <oliva@dcc.unicamp.br>. + +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 +# `libtool' can also be set to `yes' or `no'. + +depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} +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 + +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. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + 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. 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. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + 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,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$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" + ;; + +tru64) + # The Tru64 AIX 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. + + tmpdepfile1="$object.d" + tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` + if test "$libtool" = yes; then + "$@" -Wc,-MD + else + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab 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 proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + test -z "$dashmflag" && dashmflag=-M + ( IFS=" " + case " $* " in + *" --mode=compile "*) # this is libtool, let us make it quiet + for arg + do # cycle over the arguments + case "$arg" in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + 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) + # X makedepend + ( + shift + cleared=no + for arg in "$@"; do + case $cleared in no) + set ""; shift + cleared=yes + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift;; + -*) + ;; + *) + set fnord "$@" "$arg"; shift;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tail +3 "$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 proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + 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 proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/dnsconfig.c b/dnsconfig.c new file mode 100644 index 0000000..e836c76 --- /dev/null +++ b/dnsconfig.c @@ -0,0 +1,192 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + (The author maintains a non-exclusive licence to distribute this file + under their own conditions.) + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/* + * Support DNS SRV records. I look up the SRV record for + * _ldap._tcp.gnu.org. + * and build the DN DC=gnu,DC=org. + * Thanks to Assar & co for resolve.[ch]. + */ + +static char rcsId[] = + "$Id: dnsconfig.c,v 2.43 2006/01/13 10:24:58 lukeh Exp $"; + +#include "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/param.h> +#include <netdb.h> +#include <syslog.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <string.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif + +#include "ldap-nss.h" +#include "util.h" +#include "resolve.h" +#include "dnsconfig.h" + + +/* map gnu.org into DC=gnu,DC=org */ +NSS_STATUS +_nss_ldap_getdnsdn (char *src_domain, + char **rval, char **buffer, size_t * buflen) +{ + char *p; + int len = 0; +#ifdef HAVE_STRTOK_R + char *st = NULL; +#endif + char *bptr; + char *domain, *domain_copy; + + /* we need to take a copy of domain, because strtok() modifies + * it in place. Bad. + */ + domain_copy = strdup (src_domain); + if (domain_copy == NULL) + { + return NSS_TRYAGAIN; + } + + domain = domain_copy; + + bptr = *rval = *buffer; + **rval = '\0'; + +#ifndef HAVE_STRTOK_R + while ((p = strtok (domain, "."))) +#else + while ((p = strtok_r (domain, ".", &st))) +#endif + { + len = strlen (p); + + if (*buflen < (size_t) (len + DC_ATTR_AVA_LEN + 1 /* D C = [,|\0] */ )) + { + free (domain_copy); + return NSS_TRYAGAIN; + } + + if (domain == NULL) + { + strcpy (bptr, ","); + bptr++; + } + else + { + domain = NULL; + } + + strcpy (bptr, DC_ATTR_AVA); + bptr += DC_ATTR_AVA_LEN; + + strcpy (bptr, p); + bptr += len; /* don't include comma */ + *buffer += len + DC_ATTR_AVA_LEN + 1; + *buflen -= len + DC_ATTR_AVA_LEN + 1; + } + + if (bptr != NULL) + { + (*rval)[bptr - *rval] = '\0'; + } + + free (domain_copy); + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_mergeconfigfromdns (ldap_config_t * result, + char **buffer, size_t *buflen) +{ + NSS_STATUS stat = NSS_SUCCESS; + struct dns_reply *r; + struct resource_record *rr; + char domain[MAXHOSTNAMELEN + 1]; + char *pDomain; + char uribuf[NSS_BUFSIZ]; + + if ((_res.options & RES_INIT) == 0 && res_init () == -1) + { + return NSS_UNAVAIL; + } + + if (result->ldc_srv_domain != NULL) + pDomain = result->ldc_srv_domain; + else + { + snprintf (domain, sizeof (domain), "_ldap._tcp.%s.", _res.defdname); + pDomain = domain; + } + + r = dns_lookup (pDomain, "srv"); + if (r == NULL) + { + return NSS_NOTFOUND; + } + + /* XXX sort by priority */ + for (rr = r->head; rr != NULL; rr = rr->next) + { + if (rr->type == T_SRV) + { + snprintf (uribuf, sizeof(uribuf), "ldap%s:%s:%d", + (rr->u.srv->port == LDAPS_PORT) ? "s" : "", + rr->u.srv->target, + rr->u.srv->port); + + stat = _nss_ldap_add_uri (result, uribuf, buffer, buflen); + if (stat != NSS_SUCCESS) + { + break; + } + } + } + + dns_free_data (r); + stat = NSS_SUCCESS; + + if (result->ldc_base == NULL) + { + stat = _nss_ldap_getdnsdn (_res.defdname, &result->ldc_base, + buffer, buflen); + } + + return stat; +} + diff --git a/dnsconfig.h b/dnsconfig.h new file mode 100644 index 0000000..e2a5404 --- /dev/null +++ b/dnsconfig.h @@ -0,0 +1,33 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + (The author maintains a non-exclusive licence to distribute this file + under their own conditions.) + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef _LDAP_NSS_LDAP_DNSCONFIG_H +#define _LDAP_NSS_LDAP_DNSCONFIG_H + +/* utility routines. */ + +NSS_STATUS _nss_ldap_getdnsdn (char *domain, + char **rval, char **buffer, size_t * buflen); + +NSS_STATUS _nss_ldap_mergeconfigfromdns (ldap_config_t * result, char **buffer, size_t *buflen); + +#endif /* _LDAP_NSS_LDAP_DNSCONFIG_H */ diff --git a/doc/README.AIX b/doc/README.AIX new file mode 100644 index 0000000..2e79fd4 --- /dev/null +++ b/doc/README.AIX @@ -0,0 +1,141 @@ +Quick notes for using nss_ldap on AIX +===================================== + +1. Introduction +--------------- + +The C library on AIX includes the IRS library which can also found in the +BIND 8.x distribution. Of course, IBM did some things The Other Way(tm)... +You can alo find related documentation at: + <URI:http://www.padl.com/Articles/nss_ldaponAIX.html> + +2. Compilation +-------------- + +I'm assuming you have successfully installed OpenLDAP 2.x or one of the +Netscape LDAP client libraries. I haven't tested it with IBM's LDAP +libraries. + +I'm using AIX 4.3.3. It may work with 4.[12]. It won't work with 3.x. +It is going to work on 5.x. + +You need to ensure that bos.adt.syscalls has been installed for -lsys +and -lcsys to work as the /lib/syscalls.exp file (this is found +on the Kernel Extensions developer kit). [Kyle_Chapman@G1.com] + +Run "configure" and "make" as usual. As of nss_ldap-196, it is no +longer necessary to specify --enable-proxy-auth if you want to use +the AIX authentication functionality; it is enabled by default. + +The /etc/ldap.conf is already used by the LDAP client from +IBM SecureWay, so use + + --with-ldap-conf-file=/etc/nss_ldap.conf + +to avoid confusion. If everything went OK, you will get two +objects: nss_ldap.so and NSS_LDAP. + +Some notes on dynamic linking that apply to dependent libraries +(such as Cyrus SASL and OpenLDAP; the nss_ldap Makefile will +take care of these for you within nss_ldap itself): + + o You may find it useful to build a current libtool and + use that rather than the version distributed with many + third party packages. + + o The GNU linker cannot reliably build shared libraries + on AIX and, even if newer versions can, libtool doesn't + think it can. + + o You should ensure libtool is using the runtime linker + (-brtl) -- this builds shared libraries that resolve + their symbols at runtime rather than link time. + +eg. for configuring libtool: + + $ LD=/usr/ccs/bin/ld LDFLAGS=-Wl,-brtl ./configure + +3. Installation +--------------- + +Copy nss_ldap.so to /usr/lib/netsvc/dynload (create the directory if it does +not exist), and copy NSS_LDAP to /usr/lib/security. ("make install" will +do this for you.) + +4. Configuration +---------------- + +Edit /etc/irs.conf as you like (create it if it does not exist). "man +irs.conf" tells everything you need. As you would guess, you have to use the +"nss_ldap" mechanism name to use nss_ldap. This lets you access host, +network, service, and protocol information using LDAP (well, you can also +configure netgroups here, but when I'm writing this, nss_ldap does not have +netgroup support). + +Due to the missing netgroup support, you will get lots of "dlsym of symbol: +ng_pvtinit failed: Function not implemented (ng_pvtinit)" in the system +logs. That's ugly, but harmless. + +Now, the interesting part: users and groups. Have I said that IBM did it The +Other Way(tm)? Ok, add the following stanza to /lib/security/methods.cfg: + +LDAP: + program = /usr/lib/security/NSS_LDAP + +If you are running AIX version which is less than 4.3.3 you will have +to add the stanza to /etc/security/login.cfg. In case of version +4.3.3 you will have to add the same stanza to both files. Make sure +you comment out existing references to LDAP, which are for IBM's +SecureWay implementation. + +Use chuser(8) to edit /etc/security/user. Change the "SYSTEM" +attribute of the "default" entry to "compat OR LDAP", i.e.: + +# chuser SYSTEM="compat or LDAP" default + +if you want to use the LDAP authentication system wide. +Alternatively, you can enable it on a per-user basis: + +# chuser SYSTEM="compat or LDAP" username + +After that you should be able to use getpwnam() and friends to get the +information from the LDAP server. If you want to allow users to +change their passwords using the standard passwd(1) command, you will +have to change the registry attribute as well: + +# chuser registry=LDAP username + +(This is pointless right now as there is no support for password +changing in nss_ldap.) + +NB: The registry attribute is used to fetch/modify all the other user +attributes which are not supported by the LDAP. In particular the +chuser(8) will fail to operate properly. However, it is possible to +use the "-R" option to specify the registry on which the command +should operate. For example, to change back to the normal files based +authentication and identification: + +# chuser -R files SYSTEM=compat registry=files default + +NB: Users should exist in the /etc/passwd file. That doesn't seem to +be necessary, but many strange things can happen depending on the AIX +version running. YMMV. + +5. What's missing +----------------- + +The provided NSS_LDAP authentication module supports the identification +and authentication interfaces. There is, however, no support for +modifying user/group attributes (which means you won't be able to use +the "chuser" command etc. to alter user/group attributes; you have to +make all modifications directly via LDAP). + +Also, lsgroup does not support querying group membership, although +group membership will be evaluted correctly when a user logs on. + +Enjoy. + +Gabor Gombas <gombasg@inf.elte.hu> +Luke Howard <dev@padl.com> +Dejan Muhamedagic <dejan.muhamedagic@at.ibm.com> + diff --git a/doc/README.HPUX b/doc/README.HPUX new file mode 100644 index 0000000..718d1fc --- /dev/null +++ b/doc/README.HPUX @@ -0,0 +1,6 @@ + +nss_ldap will not work on HP-UX using an LDAP library that requires +thread local storage. Specifically, the Netscape SSL-enabled libraries +(and perhaps all the Netscape libraries) will not work. Use OpenLDAP +instead. + diff --git a/doc/README.IRS b/doc/README.IRS new file mode 100644 index 0000000..ed2ff55 --- /dev/null +++ b/doc/README.IRS @@ -0,0 +1,314 @@ + +Using nss-ldap with BIND/IRS under FreeBSD / Quick'n'Dirty guide +================================================================ + +[ Notes by Luke Howard <lukeh@padl.com> Sep 2001 ] + +Emile's patch was a little unclean, and I'm not able to generate +a clean diff, so here is a list of the modifications you need to +make to the IRS to get things to compile "right". You will +need to apply these diffs by hand, sorry. + +- Add a prototype to irs/gen.c: + + struct irs_acc *irs_ldap_acc(const char *); + +- Edit gen.c and add "ldap" to the two stanzas, I suggest between + irs_nis and irs_irp. + +diff -u --recursive --new-file bind/src/lib/irs/gen.c bind-nss/src/lib/irs/gen.c +--- bind/src/lib/irs/gen.c Wed Oct 13 18:39:29 1999 ++++ bind-nss/src/lib/irs/gen.c Fri Sep 1 15:31:09 2000 +@@ -66,6 +66,7 @@ + { "local", irs_lcl }, + { "dns", irs_dns }, + { "nis", irs_nis }, ++ { "ldap", irs_ldap }, + { "irp", irs_irp }, + { NULL, irs_nacc } + }; + +and also: + +@@ -80,6 +81,7 @@ + #else + NULL, + #endif ++ irs_ldap_acc, + irs_irp_acc, + NULL + }; + +- Edit gen_p.h and add irs_ldap between irs_nis and irs_irp: + +diff -u --recursive --new-file bind/src/lib/irs/gen_p.h bind-nss/src/lib/irs/gen_p.h +--- bind/src/lib/irs/gen_p.h Mon Jan 18 08:46:50 1999 ++++ bind-nss/src/lib/irs/gen_p.h Fri Sep 1 15:31:23 2000 +@@ -43,6 +43,7 @@ + irs_lcl, /* Local. */ + irs_dns, /* DNS or Hesiod. */ + irs_nis, /* Sun NIS ("YP"). */ ++ irs_ldap, /* LDAP */ + +- Edit the Makefile and add the full path to each object file + in nss_ldap, eg: + +diff -u --recursive --new-file bind/src/lib/irs/Makefile bind-nss/src/lib/irs/Makefile +--- bind/src/lib/irs/Makefile Mon Feb 22 03:47:58 1999 ++++ bind-nss/src/lib/irs/Makefile Thu Aug 31 18:18:52 2000 +@@ -42,6 +42,8 @@ + INSTALL_LIB=-o bin -g bin + THREADED= threaded + ++LDAP=/usr/local/src/nss_ldap ++ + SRCS= dns.c dns_gr.c dns_ho.c dns_nw.c dns_pr.c dns_pw.c \ + dns_sv.c gai_strerror.c gen.c gen_gr.c gen_ho.c \ + gen_ng.c gen_nw.c gen_pr.c gen_pw.c gen_sv.c \ +@@ -70,7 +72,12 @@ + lcl.${O} lcl_gr.${O} \ + lcl_ho.${O} lcl_ng.${O} lcl_nw.${O} lcl_pr.${O} lcl_pw.${O} \ + lcl_sv.${O} nis.${O} nis_gr.${O} nis_ho.${O} nis_ng.${O} nis_nw.${O} \ +- nis_pr.${O} nis_pw.${O} nis_sv.${O} nul_ng.${O} util.${O} ++ nis_pr.${O} nis_pw.${O} nis_sv.${O} nul_ng.${O} util.${O} \ ++ ${LDAP}/ldap-nss.o ${LDAP}/ldap-pwd.o ${LDAP}/ldap-grp.o \ ++ ${LDAP}/ldap-hosts.o ${LDAP}/ldap-network.o ${LDAP}/ldap-proto.o \ ++ ${LDAP}/ldap-service.o ${LDAP}/util.o ${LDAP}/globals.o \ ++ ${LDAP}/ltf.o ${LDAP}/resolve.o ${LDAP}/dnsconfig.o ${LDAP}/irs-nss.o \ ++ ${LDAP}/snprintf.o + +[ Instructions from Emile Heitor <eheitor@isdnet.net> ] + +Tested under FreeBSD 4.1, but should work under 3.x & 4.x. + +o Get nss_ldap (http://www.padl.com/nss_ldap.html) +o Get bind-8.2.2p5 (http://www.isc.org) + +nss_ldap includes a patch to IRS in irs-nss.diff. + +then: + +tar zxvf nss_ldap-115.tar.gz +mkdir bind-nss +cd bind-nss +tar zxvf ../bind-src.tar.gz +patch -p1 < ../irs-nss.diff +cd src +make depend +cd ../../nss_ldap + +At this point, you may modify Makefile's TOP variable to suit to your +needs. Quit/Save. + +make clean && make +cd ../bind-nss/src +make all + +Ok, I know about nslookup's warnings and errors here, this is because of +newly linked nss-ldap stuff, just ignore it if you plan to use only +libbind for its IRS feature ( hey, I said "Quick'n'Dirty ;) ). +This will be cleaner very soon, i.e. when I'll make it a dynamic library +& will work around bind Makefiles. + +See if it works ! +================= + +Launch an LDAP server with your favourite data inside, then compile the +following : + +[cut here] +/* NSS-LDAP use exemple code */ + +#include <sys/types.h> +#include <pwd.h> + +int main(int argc, char **argv) { + + struct passwd *pw; + + if (argc < 2 ) { + printf("bad arg number\n"); + return(1); + } + + pw=getpwnam(argv[1]); + + if (!pw) + printf("Failure\n", argv[1]); + else + printf("getpwnam return value:\n%s\ns%s\n", + pw->pw_name, pw->pw_passwd); + + return(0); +} +[cut here] + +With the following Makefile : +( change LIBBIND and LIBDIR to suit to your needs ) + +[cut here] +LIBBIND=/home/imil/pub/net/bind-nss/src/lib/libbind.a +LIBDIR=-L/usr/local/openldap2/lib +LIBS=-lldap_r -llber -lc_r + +all: tpass + +tpass: tpass.o $(LIBBIND) + cc -g -o tpass tpass.o $(LIBBIND) $(LIBDIR) $(LIBS) + +clean: + rm -f *.o tpass +[cut here] + +launch it: + +./tpass user + +Watch your LDAP server logs, they should be nice ;) + +--- + +All the best, + +-------------------------- +Emile Heitor +Ingenieur Systeme Unix +Cable & Wireless isdnet +http://www.isdnet.net +Email : eheitor@isdnet.net +Tel : 06.03.29.65.70 +-------------------------- + + +Subject: Re: Documentation for IRS in BIND 8.x +From: Paul Vixie <paul@vix.com> +Date: 1997/06/26 +Message-ID: <g3radp5avm.fsf@wisdom.home.vix.com> +Newsgroups: comp.protocols.dns.bind +_[More Headers]_ + + +Ooops. I forgot to check in the man page for irs.conf(5). Here's one: + +IRS.CONF(5) BSD Programmer's Manual IRS.CONF(5) + +NAME + irs.conf - Information Retrieval System configuration file + +SYNOPSIS + irs.conf + +DESCRIPTION + The irs(3) functions are a set of routines in the C library which provide + access to various system maps. The maps that irs currently controls are + the following: passwd, group, services, protocols, hosts, networks and + netgroup. When a program first calls a function that accesses one of + these maps, the irs configuration file is read, and the source of each + map is determined for the life of the process. + + If this file does not exist, the irs routines default to using local + sources for all information, with the exception of the host and networks + maps, which use the Domain Name System (DNS). + + Each record in the file consists of one line. A record consists of a + map-name, an access-method and possibly a (comma delimited) set of op- + tions, separated by tabs or spaces. Blank lines, and text between a # + and a newline are ignored. + + Available maps: + + Map name Information in map + ========= ================================== + passwd User authentication information + group User group membership information + services Network services directory + protocols Network protocols directory + hosts Network hosts directory + networks Network "network names" directory + netgroup Network "host groups" directory + + Available access methods: + + Access method Description + ============= ================================================= + local Use a local file, usually in /etc + dns Use the domain name service (includes hesiod) + nis Use the Sun-compatible Network Information Service +>> ldap Use the Lightweight Directory Access Protocol + + Available options: + + Option Description + ======== ================================================ + continue don't stop searching if you can't find something + merge don't stop searching if you CAN find something + + The continue option creates ``union namespaces'' whereby subsequent ac- + cess methods of the same map type can be tried if a name cannot be found + using earlier access methods. This can be quite confusing in the case of + host names, since the name to address and address to name mappings can be + visibly asymmetric even though the data used by any given access method + is entirely consistent. This behavior is, therefore, not the default. + + The merge option only affects lookups in the groups map. If set, subse- + quent access methods will be tried in order to cause local users to ap- + pear in NIS (or other remote) groups in addition to the local groups. + +EXAMPLE + # Get password entries from local file, or failing that, NIS + passwd local continue + passwd nis + + # Build group membership from both local file, and NIS. + group local continue,merge + group nis + + # Services comes from just the local file. + services local + + protocols local + + # Hosts comes first from DNS, failing that, the local file + hosts dns continue + hosts local + + networks local + + netgroup local + +NOTES + If a local user needs to be in the local host's ``wheel'' group but not + in every host's ``wheel'' group, put them in the local host's /etc/group + ``wheel'' entry and set up the ``groups'' portion of your /etc/irs.conf + file as: + + group local continue,merge + group nis + + The dns access method is only supported for the ``hosts'' and + ``networks'' maps. The other maps fall under the control of Hesiod, and + have not been well tested. + + NIS takes a long time to time out. Especially for hosts if you use the + -d option to your server's ``ypserv'' daemon. + + It is important that the irs.conf file contain an entry for each map. If + a map is not mentioned in the irs.conf file, all queries to that map will + fail. + +FILES + /etc/irs.conf The file irs.conf resides in /etc. + +SEE ALSO + groups(5), hosts(5), netgroup(5), networks(5), passwd(5), + protocols(5), services(5) + + BSDI August 8, 1996 2 + +-- +Paul Vixie +La Honda, CA +<_paul@vix.com_> "Many NANOG members have been around +pacbell!vixie!paul longer than most." --Jim Fleming + + diff --git a/doc/README.SFU b/doc/README.SFU new file mode 100644 index 0000000..d8de70f --- /dev/null +++ b/doc/README.SFU @@ -0,0 +1,164 @@ +******************************************************************* + +nss_ldap-AD-pwdgrp + + This file describes the modifications that were made to, and the + build process of, the nss_ldap-150 source to allow passwd and + group info to be retrieved from a Windows 2000 Active Directory. + + Modified by: djflux (Andrew Rechenberg) - dj_flux@yahoo.com + Date: 3 May 2001 + URL: http://w3.one.net/~djflux/nss_ldap-AD.shtml + +******************************************************************* + +*** *** +*** IMPORTANT!!! *** +*** *** +-- One MUST have Microsoft Server for NIS from Microsoft Services + for UNIX 2.0 installed on a Windows 2000 Server Domain Controller + in order for this modified module to operate correctly. See the + URL below for more info about SFU 2.0: + + http://www.microsoft.com/windows2000/sfu + +-- One must also have the LDAP devel libraries installed on the machine + in order to properly build this module. The proper headers and + libraries can be found in the openldap-devel package. + +From: "Rechenberg, Andrew" <arechenberg@shermfin.com> +Subject: RE: [nssldap] Can not get nss_ldap to work, can anyone please hel p me? +To: "'Allister Maguire'" <amaguire@actonz.com>, nssldap@padl.com +Date: Thu, 24 Jan 2002 09:28:36 -0500 + + +The README.SFU is slightly little out of date and off topic now. I +originally wrote README.SFU when I modified nss_ldap and Luke Howard +integrated the patch into nss_ldap-150 I believe as a configure option. + +There is now the ability to do schema mapping in nss_ldap and change which +attributes are used for LDAP lookups. You have to use the following +configure option: + +./configure --enable-schema-mapping [REST_OF_YOUR_OPTIONS_HERE] + +Once nss_ldap is compiled then you edit your ldap.conf file and uncomment +the attribute mapping under the MSSFU section (use your favorite text editor +and search for MSSFU and you should find it). Once you do that, and you +modify your nsswitch.conf, you should be off and running. + +Let me know if you need anymore help. + +Regards, +Andy. + + + +* +*** Test systems specifications *** +* +This module has been tested and works with the following operating +system versions: + +RedHat Linux 7.1, kernel 2.4.2-2, against Win2000 Server SP1 mixed-mode +RedHat Linux 6.2, kernel 2.2.17 (smp, custom), Win2000 Server SP1 mixed mode +RedHat Linux 6.1, kernel 2.2.17 (smp, custom), Win2000 Server SP1 mixed mode + +The module should compile work with other *NIX/*BSD OS's, but your mileage +may vary. + +I believe there is a coding difference in certain applications between Red +Hat 6.1, and versions 6.2 and greater. When testing the modified module I +used 'id [USERNAME]' to make sure that the correct information was being +retrieved from the AD. In Red Hat versions 6.2 or greater (7.0 not tested, +but it should be the same), 'id [USERNAME]' would only return UID, and primary +GID. If [USERNAME] was logged in interactively and ran 'id' the command showed +UID, primary GID, and all other group memberships. + +However, when running 'id [USERNAME]' in Red Hat 6.1, the command returned a +"Segmentation Fault." If the user is logged in interactively on 6.1, all of +the correct information is still retrieved. + +I am going to check into this issue, but the module should still behave correctly +under 6.1. Let me know if you find out anything different. + + +* +*** What was modified *** +* +There is very little to modify in order to retrieve passwd and group +information from a Windows 2000 Active Directory. + +[Ed note: the patches are incorporated, so all you need to do is + run ./configure --enable-mssfu-schema] + +Supplied in the ./admods directory is the context diff of ldap-schema.h. +This file shows the attributes that needed to be modified in order to +use nss_ldap for user and group information on a Linux machine. Besides +a slight modification of the Makefile, this is the only file that needs +to be changed. + +Below are the lines that need to be modified in the Makefile. Just make +the lines in your Makefile similar to the ones below. + +nss_ldap_so_LDFLAGS = -shared -L/lib/libdb.so +LDFLAGS = -L/lib/libdb.so +NSS_LDAP_LDFLAGS = -enss_ldap_initialize -lsys -lcsys -lc -ldb +LIBS = -lldap -llber -lnsl -lresolv -ldb + +The "-ldb" in NSS_LDAP_LDFLAGS and LIBS may not be necessary, but I +wasn't about the change anything in the module after I had it working :) +Also, the -L switch should have the path to your libdb.so (e.g if libdb.so.3 +is in /usr/local/lib then your LDFLAGS should have -L/usr/local/lib/libdb.so.3). + + +* +*** Building it *** +* +This is the procedure that was used to build this module. The ldap-schema.h +file include in this source tree has already been modified to work with +SFUed Active Directory, so you do not need to modify that file. The +ldap-schema.diff file has been provided for illustration purposes so one +knows what attributes have been modified. + +1) make distclean +2) ./configure --with-ldap=openldap --libdir=/lib --enable-mssfu-schema +3) Modify Makefile so that the lines in Makefile are similar to those listed + above. +4) make install + +That's it! + + +* +*** /etc/ldap.conf *** +* +Modify your /etc/ldap.conf file to match your Active Directory/LDAP +configuration. Unless you have changed your AD from the stock install, +you should have the following RFC2307bis naming contexts in your +ldap.conf file: + +nss_base_passwd cn=Users,dc=yourdomain,dc=com?one +nss_base_group cn=Users,dc=yourdomain,dc=com?one + +With the stock Active Directory, all users and groups are located in the +cn=users container underneath your domain. If your AD has been modified, +then modify the naming contexts to suit your directory. + +You should also set the PAM login attribute. Mine is as follows: + +pam_login_attribute msSFUName + + +* +*** Basic info *** +* +For basic setup of LDAP authentication and information storage and retrieval +see the following URLs (specific to OpenLDAP and Linux, but they give one a +good base understanding of how the process works): + +http://www.linux.com/howto/LDAP-Implementation-HOWTO/pamnss.html +http://www.openldap.org/lists/openldap-software//200010/msg00097.html + + + diff --git a/doc/README.paged b/doc/README.paged new file mode 100644 index 0000000..5a5a7c1 --- /dev/null +++ b/doc/README.paged @@ -0,0 +1,53 @@ +Purpose +------- + +These amendments cause all "getXXent" calls implemented by +NSS_LDAP to request paging of results in accordance with RFC +2696. + +If you are using LDAP searches against a Microsoft Active +Directory database, you will find that search results are +divided into "chunks". A standard "ldap_search" against an +untweaked AD returns a maximum of 1000 entries. To get more than +that, you have to either use an extended search with paging, or +increase the query policy limits on your AD. If you have a +large number of users (we have over 30K) raising the policy +limits that high is worrying. + +The page size requested is 1000 entries, and is not a config +file item. However, it should be OK with any Active Directory. + +Because of the way the page control is used, any LDAPv3 server +that does not implement paging should simply ignore it and +return entries as normal; however, I haven't been able to test +this. + +Installing +---------- + +The TAR file contains 3 context diff files and one extra C file +(pagectrl. c) that implements the standard API calls for paged +results controls. If your LDAP library supports these anyway, +you shouldn't need it, but I don't know of one that does. The +Sun library has the entry points, but I couldn't get them to +work. + +1. Unpack the TAR file in your NSS LDAP directory. + +2. Run "patch" to apply the 3 diff files. On my system that is: + + patch ldap-nss.c < ldap-nss.c.diff + patch ldap-nss.h < ldap-nss.h.diff + patch Makefile.in < Makefile.in.diff + +3. Run "configure" as specified in the NSS LDAP installation +instructions, to recreate the Makefile. + +4. Run "make clean" + +5. Run "make" + +You should now have a new nss_ldap.so ready to copy to /lib. + +Max Caines (max.caines@wlv.ac.uk) +16 April 2002 diff --git a/doc/SolarisInstallNotes.txt b/doc/SolarisInstallNotes.txt new file mode 100644 index 0000000..a6228d1 --- /dev/null +++ b/doc/SolarisInstallNotes.txt @@ -0,0 +1,198 @@ +Date: Sat, Jun 16 2001 03:33:50 +Request created by sstone@foo3.com + +OK, this might just be a result of the specific combination I was using: + +OpenLDAP 2.0.11 with OpenSSL 0.9.6a, OpenLDAP compiled for SSL/TLS, +OpenSSL compiled to use RSAREF. slapd running on a freeBSD 4.3-STABLE +machine, client in question that these docs refer to is a Sun +SPARCStation4 (sun4m) running Solaris 7. A lot of my frustration here is +due to the fact that it compiles things really SLOW (only a 70mhz cpu...) + +This information is primarily for you to review and integrate into your +docs, to hopefully make your product more usable. I should preface this +by saying that after I did all this stuff, it eventually DOES work +correctly, so it has a happy ending. I'm authenticating users on the +solaris machine using SSL now, or so says my packet sniffer, snort. :) + +1) your docs should say, "Your openldap libs *and* your SSL/RSAREF libs +must be DYNAMIC LIBRARIES or neither nss_ldap nor pam_ldap will work". +You also should say that you need to have all these shared libraries in +/usr/lib, since LD_LIBRARY_PATH doesn't get sourced when these modules are +called, and if it's in /usr/local/ssl/lib or /usr/local/lib it's not going +to find them and the dynamic link calls will fail, and so will your LDAP +auth. [NB: compiling with -Wl,-R or -Wl,-rpath *will* include the +qualified library path in the resulting library or executable. LH] + +1a) compiling rsaref dynamically is a pain. You have to do it yourself +cuz its makefile will NOT. commandline: + +cd rsaref/install +make +rm -f rdemo.o +gcc -o librsaref.so.2 -shared -Wl,-soname,librsaref.so.2 *.o + +this will create you both the .a and the .so.2 file. you must have gnu +binutils for that to work. Then, install with: + +cp librsaref.so.2 /usr/lib +ln -sf /usr/lib/librsaref.so.2 /usr/lib/librsaref.so + +2) On Solaris, you need GNU Make and GNU binutils to compile openssl +dynamically. Using these tools on Solaris makes your configure/makefile +scripts act funny. I had to take out the "-Wl,./mapfile" from the LDFLAGS +in both nss_ldap and pam_ldap to make it link properly (but it works once +you do that). I was getting an error: "./mapfile: invalid file format" + +2a) to compile OpenSSL with RSAREF and dynamic lib support, you must: + +cd openssl-0.9.6a +./config rsaref dynamic +make +make install + +3) In your makefiles, you check for main in -lldap. BUT you don't check +for the SSL libraries, so this check will ALWAYS FAIL if libldap.so.2 was +compiled with TLS support. Go into the configure script and change: + +-lldap $LIBS + +to + +-lldap -lcrypto -lssl -lRSAglue -lrsaref -lsocket $LIBS + +and it works. yeah, you need -lsocket too. I dont have autoconf on my +solaris box or I'd have fixed the configure.in directly, but I'll leave +that up to you :) You need to make that change both in the place where it +specifies the libs to compile conftest.c and in in the place where it adds +the values to the $LIBS variable for eventual linking. + +4) you need a random number generator. Solaris doesn't come with one, and +Sun's SUNWski package seems to irritate OpenSSL to the point of coredump. +I used ANDI-rand, available as a solaris pkg for 2.5.1, 2.6, 2.7, and 2.8. +it works. + + +Anyway I hope this helps. I figured all of this out on my own, since the +end-to-end process isn't really well-documented ANYWHERE. If you use my +information here in your docs, I'd appreciate a small byline, ie, +"portions contributed by Scott Stone <sstone@foo3.com>" or something like +that :) thanks! + +-------------------------- +Scott M. Stone <sstone@foo3.com> +Cisco Certified Network Associate, Sun Solaris Certified Systems Administrator +Senior Technical Consultant - UNIX and Networking +Taos - The SysAdmin Company + +[http://www.css-solutions.ca/ad4unix/solaris8.html] + +To enable support of nss_ldap and pam_ldap modules from PADL for 64bit application on SUN SPARC platform using Sun C/C++ compiler version 5.0+ is required!!! (Note: with latest gcc 3.0.2 there is some support for 64bit platforms, but we didn't find what options are required for that kind of compilation... GNU as produced some errors, but GNU ld explicitly supported 64bit linking.) Our succesfull implementation was based on "Sun WorkShop 6 update 1 C 5.2 Patch 109513-07 2001/08/27" compiler and nss_ldap v.173 and pam_ldap v.133 modules from PADL Software. There was some issues with compailing and compatibility: + +1. For nss_ldap with --enable-schema-mapping configure option Berkeley db library is required. There is no precompiled 64bit Berkeley db library available. You can download db library sources from www.sleepycat.com and compile it with the follow batch file: + + #!/bin/sh + + CC64=" -xtarget=native64 -KPIC " + #CC64="" + export CC64 + + + CC=cc + export CC + CFLAGS=" $CC64 " + export CFLAGS + LDFLAGS=" $CC64 -R/usr/local/lib/sparcv9" + export LDFLAGS + + cd db-3.3.11/dist + ./configure \ + --prefix=/usr/local \ + --bindir=/usr/local/bin/sparcv9 \ + --libdir=/usr/local/lib/sparcv9 \ + --enable-compat185 + make + make install +I guess if you compile it for 64bit you also would like to compile for 32bit, for that just comment CC64 option and uncomment follow CC64 empty option, remove /sparcv9 suffix from LDFLAGS and remove --bindir and --libdir prefixes from configure command line. + + +2. The nss_ldap v.173 requires some patching for compatibility with Sun C (not only with Sun, but AIX C has same symptoms): +* Sun C compiler (latest from Sun and same issues as AIX C compiler) does not support construction like: +in ldap-nss.h near line 600: +#define debug(fmt, args...) fprintf(stderr, fmt, ## args) +workaround was - coping AIX workaround for SUN C:-) + +* Also Sun C compiler does not support initialization of arrays by not constant values (by functions for example - macro AT with class mapping will replaced by function call)... +in util.c (line 204) from: +const char *attrs[] = { AT (uid), attrs[1] = NULL }; +LDAPMessage *res; +to: +LDAPMessage *res; +const char *attrs[2]; +attrs[0] = AT (uid) ; +attrs[1] = NULL ; + + + + +Luke Howard from PADL Software said that in the next releases these problems will be patched. + +3. There is our batch file for compiling nss_ldap.so 64 bit with Sun C/C++ compiler (for compiling 32bit module comment CC64 statment and uncomment follow CC64 empty statment also remove /sparcv9 suffix from LDFLAGS): + + + #!/bin/sh + + + CC64=" -xtarget=native64 -KPIC " + #CC64="" + export CC64 + + CC=cc + export CC + CFLAGS=" $CC64 " + export CFLAGS + CPPFLAGS=" -I/usr/local/include " + export CPPFLAGS + LDFLAGS=" $CC64 -L/usr/local/lib/sparcv9 -R/usr/local/lib/sparcv9 " + export LDFLAGS + + cd nss_ldap-173 + ./configure --enable-schema-mapping \ + --enable-rfc2307bis + # --enable-debugging + +4. Batch file for compiling pam_ldap module is same, just change directory to pam_ldap-xxx and run ./configure without any parametrs. + + +32bit version +We found some incompatibility BUG in the gcc produced code (3.0.1 and 3.0.2) and dynamic linking with dlopen function calls. That BUG we found in 32bit compiled libraries with Sun C/C++ and applications that was compiled by GNU gcc 3.0.1 and 3.0.2 (we could not test it with GNU gcc 64 bit and we did not test it with other versions of GNU gcc). If Application was compiled with Sun C/C++ there is no problem. Workaround for that was erasing linked modules and relinking modules by explicitly call ld: + +1. Erase modules: +for PAM +rm pam_ldap.so +or for NSS +rm nss_ldap.so +2. run ld linker explicitly: +for PAM: +* for native Sun linker +/usr/ccs/bin/ld -M mapfile -R/usr/local/lib -o pam_ldap.so -G pam_ldap.o md5.o -lldap -lnsl -lcrypt -lresolv -lpam -ldl +* for GNU lg +/usr/local/bin/ld -R/usr/local/lib -o pam_ldap.so -G pam_ldap.o md5.o -lldap -lnsl -lcrypt -lresolv -lpam -ldl + +or for for NSS: +* for native Sun linker +/usr/ccs/bin/ld -R/usr/local/lib -o nss_ldap.so -M ./mapfile -G \ +ldap-nss.o ldap-pwd.o ldap-grp.o ldap-rpc.o ldap-hosts.o ldap-network.o \ +ldap-proto.o ldap-spwd.o ldap-alias.o ldap-service.o ldap-schema.o ldap-ethers.o \ +ldap-bp.o util.o globals.o ltf.o snprintf.o resolve.o dnsconfig.o irs-nss.o \ +-lldap -Bdynamic -ldb -ldl -lnsl -lresolv +* for GNU lg +/usr/local/bin/ld -R/usr/local/lib -o nss_ldap.so -G \ +ldap-nss.o ldap-pwd.o ldap-grp.o ldap-rpc.o ldap-hosts.o ldap-network.o \ +ldap-proto.o ldap-spwd.o ldap-alias.o ldap-service.o ldap-schema.o ldap-ethers.o \ +ldap-bp.o util.o globals.o ltf.o snprintf.o resolve.o dnsconfig.o irs-nss.o \ +-lldap -Bdynamic -ldb -ldl -lnsl -lresolv + + +3. make install :-) + diff --git a/doc/autofs-4.1.3-lookup-nssldap.patch b/doc/autofs-4.1.3-lookup-nssldap.patch new file mode 100644 index 0000000..d6b72c4 --- /dev/null +++ b/doc/autofs-4.1.3-lookup-nssldap.patch @@ -0,0 +1,401 @@ +--- autofs-4.1.3/modules/lookup_nssldap.c 1970-01-01 01:00:00.000000000 +0100 ++++ autofs-4.1.3/modules/lookup_nssldap.c 2005-06-28 15:13:49.000000000 +0200 +@@ -0,0 +1,326 @@ ++#ident "$Id: autofs-4.1.3-lookup-nssldap.patch,v 1.1 2005/08/08 23:28:37 lukeh Exp $" ++/* ----------------------------------------------------------------------- * ++ * ++ * lookup_nss.c - module for Linux automountd to access a NSS ++ * automount map ++ * ++ * Copyright 1997 Transmeta Corporation - All Rights Reserved ++ * Copyright 2001-2003 Ian Kent <raven@themaw.net> ++ * Copyright 2005 PADL Software Pty Ltd - All Rights Reserved ++ * ++ * 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, Inc., 675 Mass Ave, Cambridge MA 02139, ++ * USA; either version 2 of the License, or (at your option) any later ++ * version; incorporated herein by reference. ++ * ++ * ----------------------------------------------------------------------- */ ++ ++#include <sys/types.h> ++#include <ctype.h> ++#include <string.h> ++#include <syslog.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <time.h> ++#include <netinet/in.h> ++#include <arpa/nameser.h> ++#include <resolv.h> ++#include <dlfcn.h> ++#include <nss.h> ++ ++#define MODULE_LOOKUP ++#include "automount.h" ++ ++#define MAPFMT_DEFAULT "sun" ++ ++#define NAMESERVICE "ldap" ++ ++#define MODPREFIX "lookup(nss" NAMESERVICE "): " ++ ++struct lookup_context { ++ char *nsname; ++ char *mapname; ++ struct parse_mod *parse; ++ void *dlhandle; ++ enum nss_status (*setautomntent)(const char *, void **); ++ enum nss_status (*getautomntent_r)(void *, const char **, const char **, ++ char *, size_t, int *); ++ enum nss_status (*endautomntent)(void **); ++ enum nss_status (*getautomntbyname_r)(void *, const char *, ++ const char **, const char **, ++ char *, size_t, int *); ++}; ++ ++int lookup_version = AUTOFS_LOOKUP_VERSION; ++ ++int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context_p) ++{ ++ struct lookup_context *context; ++ char buf[1024]; ++ ++ context = (struct lookup_context *)malloc(sizeof(*context)); ++ if (context == NULL) { ++ crit(MODPREFIX "malloc: %m"); ++ return 1; ++ } ++ memset(context, 0, sizeof(*context)); ++ ++ context->nsname = NULL; ++ context->parse = NULL; ++ context->dlhandle = NULL; ++ context->setautomntent = NULL; ++ context->getautomntent_r = NULL; ++ context->endautomntent = NULL; ++ ++ if (mapfmt == NULL) { ++ mapfmt = MAPFMT_DEFAULT; ++ } ++ ++ if (argc < 1) { ++ crit(MODPREFIX "invalid number of arguments"); ++ return 1; ++ } ++ ++ asprintf(&context->nsname, "nss%s", NAMESERVICE); ++ if (context->nsname == NULL) { ++ crit(MODPREFIX "strdup: %m"); ++ return 1; ++ } ++ ++ snprintf(buf, sizeof(buf), "/lib/libnss_%s.so.2", NAMESERVICE); ++ ++ context->dlhandle = dlopen(buf, RTLD_NOW | RTLD_LOCAL); ++ if (context->dlhandle == NULL) { ++ crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); ++ return 1; ++ } ++ ++ snprintf(buf, sizeof(buf), "_nss_%s_setautomntent", NAMESERVICE); ++ context->setautomntent = dlsym(context->dlhandle, buf); ++ if (context->setautomntent == NULL) { ++ crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); ++ return 1; ++ } ++ ++ snprintf(buf, sizeof(buf), "_nss_%s_getautomntent_r", NAMESERVICE); ++ context->getautomntent_r = dlsym(context->dlhandle, buf); ++ if (context->getautomntent_r == NULL) { ++ crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); ++ return 1; ++ } ++ ++ snprintf(buf, sizeof(buf), "_nss_%s_endautomntent", NAMESERVICE); ++ context->endautomntent = dlsym(context->dlhandle, buf); ++ if (context->endautomntent == NULL) { ++ crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); ++ return 1; ++ } ++ ++ snprintf(buf, sizeof(buf), "_nss_%s_getautomntbyname_r", NAMESERVICE); ++ context->getautomntbyname_r = dlsym(context->dlhandle, buf); ++ if (context->getautomntbyname_r == NULL) { ++ crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); ++ return 1; ++ } ++ ++ context->mapname = strdup(argv[0]); ++ if (context->mapname == NULL) { ++ crit(MODPREFIX "strdup: %m"); ++ return 1; ++ } ++ ++ context->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (context->parse == NULL) { ++ free(context); ++ return 1; ++ } ++ ++ *context_p = context; ++ return 0; ++} ++ ++static const char *nsserr_string(enum nss_status status) ++{ ++ switch (status) { ++ case NSS_STATUS_TRYAGAIN: ++ return "Insufficient buffer space"; ++ break; ++ case NSS_STATUS_UNAVAIL: ++ return "Name service unavailable"; ++ break; ++ case NSS_STATUS_NOTFOUND: ++ return "Not found"; ++ break; ++ case NSS_STATUS_SUCCESS: ++ return "Success"; ++ break; ++ default: ++ break; ++ } ++ ++ return "Unknown error"; ++} ++ ++static int read_map(const char *root, struct lookup_context *context) ++{ ++ enum nss_status status; ++ void *private = NULL; ++ time_t age = time(NULL); ++ const char *key, *mapent; ++ int nss_errno; ++ char buffer[KEY_MAX_LEN + 1 + MAPENT_MAX_LEN + 1]; ++ ++ status = (*context->setautomntent)(context->mapname, &private); ++ if (status != NSS_STATUS_SUCCESS) { ++ warn(MODPREFIX "failed to read map %s: %s", ++ context->mapname, nsserr_string(status)); ++ return 0; ++ } ++ ++ for (;;) { ++ status = (*context->getautomntent_r)(private, &key, &mapent, ++ buffer, sizeof(buffer), ++ &nss_errno); ++ if (status != NSS_STATUS_SUCCESS) ++ break; ++ ++ cache_update(key, mapent, age); ++ } ++ ++ (*context->endautomntent)(&private); ++ ++ cache_clean(root, age); ++ return 1; ++} ++ ++int lookup_ghost(const char *root, int ghost, void *context) ++{ ++ struct lookup_context *ctxt = (struct lookup_context *)context; ++ struct mapent_cache *me; ++ int status = 1; ++ ++ if (!read_map(root, ctxt)) ++ return LKP_FAIL; ++ ++ status = cache_ghost(root, ghost, ctxt->mapname, ctxt->nsname, ctxt->parse); ++ ++ me = cache_lookup_first(); ++ if (me == NULL) ++ return LKP_FAIL; ++ ++ if (*me->key == '/' && *(root + 1) != '-') { ++ me = cache_partial_match(root); ++ /* me NULL => no entries for this direct mount root or indirect map */ ++ if (me == NULL) ++ return LKP_FAIL | LKP_INDIRECT; ++ } ++ ++ return status; ++} ++ ++int lookup_mount(const char *root, const char *name, int name_len, void *context) ++{ ++ struct lookup_context *ctxt = (struct lookup_context *)context; ++ char key[KEY_MAX_LEN + 1]; ++ char buffer[KEY_MAX_LEN + 1 + MAPENT_MAX_LEN + 1]; ++ const char *canon_key, *mapent; ++ struct mapent_cache *me = NULL; ++ time_t age = time(NULL); ++ enum nss_status status; ++ ++ debug(MODPREFIX "looking up %s", name); ++ ++ snprintf(key, sizeof(key), "%s/%s", root, name); ++ ++ me = cache_lookup(name); ++ if (me == NULL) { ++ me = cache_lookup(key); ++ } ++ ++ if (me == NULL) { ++ /* path component, do submount */ ++ me = cache_partial_match(key); ++ ++ if (me) { ++ snprintf(buffer, sizeof(buffer), "-fstype=autofs %s:%s", ++ ctxt->nsname, ctxt->mapname); ++ mapent = buffer; ++ } ++ } else { ++ snprintf(buffer, sizeof(buffer), "%s", me->mapent); ++ mapent = buffer; ++ } ++ ++ if (me == NULL) { ++ const char *keys[3]; ++ int i; ++ int nss_errno; ++ void *private = NULL; ++ ++ status = (*ctxt->setautomntent)(ctxt->mapname, &private); ++ if (status != NSS_STATUS_SUCCESS) { ++ warn(MODPREFIX "failed to read map %s: %s", ctxt->mapname, nsserr_string(status)); ++ goto out_err; ++ } ++ ++ keys[0] = name, ++ keys[1] = key; ++ keys[2] = "*"; ++ ++ for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) { ++ status = (*ctxt->getautomntbyname_r)(private, name, ++ &canon_key, &mapent, ++ buffer, sizeof(buffer), ++ &nss_errno); ++ if (status != NSS_STATUS_NOTFOUND) ++ break; ++ } ++ ++ (*ctxt->endautomntent)(&private); ++ ++ if (status != NSS_STATUS_SUCCESS) { ++ warn(MODPREFIX "failed to read map %s: %s", ctxt->mapname, nsserr_string(status)); ++ goto out_err; ++ } ++ ++ cache_update(keys[i], mapent, age); ++ } ++ ++ debug(MODPREFIX "%s -> %s", name, mapent); ++ ++ return ctxt->parse->parse_mount(root, name, name_len, mapent, ctxt->parse->context); ++ ++out_err: ++ warn(MODPREFIX "lookup for %s failed: %d", name, status); ++ return 1; ++} ++ ++int lookup_done(void *context) ++{ ++ struct lookup_context *ctxt = (struct lookup_context *)context; ++ int ret; ++ ++ if (ctxt->nsname != NULL) { ++ free(ctxt->nsname); ++ ctxt->nsname = NULL; ++ } ++ ++ if (ctxt->mapname != NULL) { ++ free(ctxt->mapname); ++ ctxt->mapname = NULL; ++ } ++ ++ ret = close_parse(ctxt->parse); ++ ++ if (ctxt->dlhandle != NULL) { ++ dlclose(ctxt->dlhandle); ++ ctxt->dlhandle = NULL; ++ } ++ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ free(ctxt); ++ ++ return ret; ++} ++ +--- autofs-4.1.3/modules/lookup_nssldap.c 2005-06-28 15:13:49.000000000 +0200 ++++ autofs-4.1.3/modules/lookup_nssldap.c 2005-07-21 11:32:58.000000000 +0200 +@@ -16,6 +16,8 @@ + * + * ----------------------------------------------------------------------- */ + ++#define _GNU_SOURCE ++#include <stdio.h> + #include <sys/types.h> + #include <ctype.h> + #include <string.h> +@@ -88,7 +90,7 @@ + return 1; + } + +- snprintf(buf, sizeof(buf), "/lib/libnss_%s.so.2", NAMESERVICE); ++ snprintf(buf, sizeof(buf), "libnss_%s.so.2", NAMESERVICE); + + context->dlhandle = dlopen(buf, RTLD_NOW | RTLD_LOCAL); + if (context->dlhandle == NULL) { +@@ -184,8 +186,11 @@ + &nss_errno); + if (status != NSS_STATUS_SUCCESS) + break; +- ++#ifdef CHE_FAIL ++ cache_update(root, key, mapent, age); ++#else + cache_update(key, mapent, age); ++#endif + } + + (*context->endautomntent)(&private); +@@ -194,7 +199,7 @@ + return 1; + } + +-int lookup_ghost(const char *root, int ghost, void *context) ++int lookup_ghost(const char *root, int ghost, time_t now, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *)context; + struct mapent_cache *me; +@@ -284,7 +289,11 @@ + goto out_err; + } + ++#ifdef CHE_FAIL ++ cache_update(root, keys[i], mapent, age); ++#else + cache_update(keys[i], mapent, age); ++#endif + } + + debug(MODPREFIX "%s -> %s", name, mapent); +--- autofs-4.1.3/modules/Makefile 2004-04-03 09:14:33.000000000 +0200 ++++ autofs-4.1.3/modules/Makefile 2005-07-21 11:39:35.000000000 +0200 +@@ -7,13 +7,13 @@ + include ../Makefile.rules + + SRCS := lookup_yp.c lookup_file.c lookup_program.c lookup_userhome.c \ +- lookup_multi.c \ ++ lookup_multi.c lookup_nssldap.c \ + parse_sun.c \ + mount_generic.c mount_nfs.c mount_afs.c mount_autofs.c \ + mount_changer.c mount_bind.c + + MODS := lookup_yp.so lookup_file.so lookup_program.so lookup_userhome.so \ +- lookup_multi.so \ ++ lookup_multi.so lookup_nssldap.so \ + parse_sun.so \ + mount_generic.so mount_nfs.so mount_afs.so mount_autofs.so \ + mount_changer.so mount_bind.so diff --git a/doc/lookup_nssldap.c b/doc/lookup_nssldap.c new file mode 100644 index 0000000..7ec7b6d --- /dev/null +++ b/doc/lookup_nssldap.c @@ -0,0 +1,335 @@ +#ident "$Id: lookup_nssldap.c,v 1.3 2005/08/08 23:28:37 lukeh Exp $" +/* ----------------------------------------------------------------------- * + * + * lookup_nss.c - module for Linux automountd to access a NSS + * automount map + * + * Copyright 1997 Transmeta Corporation - All Rights Reserved + * Copyright 2001-2003 Ian Kent <raven@themaw.net> + * Copyright 2005 PADL Software Pty Ltd - All Rights Reserved + * + * 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, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <sys/types.h> +#include <ctype.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <stdlib.h> +#include <time.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <dlfcn.h> +#include <nss.h> + +#define MODULE_LOOKUP +#include "automount.h" + +#define MAPFMT_DEFAULT "sun" + +#define NAMESERVICE "ldap" + +#define MODPREFIX "lookup(nss" NAMESERVICE "): " + +struct lookup_context { + char *nsname; + char *mapname; + struct parse_mod *parse; + void *dlhandle; + enum nss_status (*setautomntent)(const char *, void **); + enum nss_status (*getautomntent_r)(void *, const char **, const char **, + char *, size_t, int *); + enum nss_status (*endautomntent)(void **); + enum nss_status (*getautomntbyname_r)(void *, const char *, + const char **, const char **, + char *, size_t, int *); +}; + +int lookup_version = AUTOFS_LOOKUP_VERSION; + +int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context_p) +{ + struct lookup_context *context; + char buf[1024]; + + context = (struct lookup_context *)malloc(sizeof(*context)); + if (context == NULL) { + crit(MODPREFIX "malloc: %m"); + return 1; + } + memset(context, 0, sizeof(*context)); + + context->nsname = NULL; + context->parse = NULL; + context->dlhandle = NULL; + context->setautomntent = NULL; + context->getautomntent_r = NULL; + context->endautomntent = NULL; + + if (mapfmt == NULL) { + mapfmt = MAPFMT_DEFAULT; + } + + if (argc < 1) { + crit(MODPREFIX "invalid number of arguments"); + return 1; + } + + asprintf(&context->nsname, "nss%s", NAMESERVICE); + if (context->nsname == NULL) { + crit(MODPREFIX "strdup: %m"); + return 1; + } + + snprintf(buf, sizeof(buf), "libnss_%s.so.2", NAMESERVICE); + + context->dlhandle = dlopen(buf, RTLD_NOW | RTLD_LOCAL); + if (context->dlhandle == NULL) { + crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); + return 1; + } + + snprintf(buf, sizeof(buf), "_nss_%s_setautomntent", NAMESERVICE); + context->setautomntent = dlsym(context->dlhandle, buf); + if (context->setautomntent == NULL) { + crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); + return 1; + } + + snprintf(buf, sizeof(buf), "_nss_%s_getautomntent_r", NAMESERVICE); + context->getautomntent_r = dlsym(context->dlhandle, buf); + if (context->getautomntent_r == NULL) { + crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); + return 1; + } + + snprintf(buf, sizeof(buf), "_nss_%s_endautomntent", NAMESERVICE); + context->endautomntent = dlsym(context->dlhandle, buf); + if (context->endautomntent == NULL) { + crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); + return 1; + } + + snprintf(buf, sizeof(buf), "_nss_%s_getautomntbyname_r", NAMESERVICE); + context->getautomntbyname_r = dlsym(context->dlhandle, buf); + if (context->getautomntbyname_r == NULL) { + crit(MODPREFIX "failed to load %s nameservice provider: %s", NAMESERVICE, dlerror()); + return 1; + } + + context->mapname = strdup(argv[0]); + if (context->mapname == NULL) { + crit(MODPREFIX "strdup: %m"); + return 1; + } + + context->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); + if (context->parse == NULL) { + free(context); + return 1; + } + + *context_p = context; + return 0; +} + +static const char *nsserr_string(enum nss_status status) +{ + switch (status) { + case NSS_STATUS_TRYAGAIN: + return "Insufficient buffer space"; + break; + case NSS_STATUS_UNAVAIL: + return "Name service unavailable"; + break; + case NSS_STATUS_NOTFOUND: + return "Not found"; + break; + case NSS_STATUS_SUCCESS: + return "Success"; + break; + default: + break; + } + + return "Unknown error"; +} + +static int read_map(const char *root, struct lookup_context *context) +{ + enum nss_status status; + void *private = NULL; + time_t age = time(NULL); + const char *key, *mapent; + int nss_errno; + char buffer[KEY_MAX_LEN + 1 + MAPENT_MAX_LEN + 1]; + + status = (*context->setautomntent)(context->mapname, &private); + if (status != NSS_STATUS_SUCCESS) { + warn(MODPREFIX "failed to read map %s: %s", + context->mapname, nsserr_string(status)); + return 0; + } + + for (;;) { + status = (*context->getautomntent_r)(private, &key, &mapent, + buffer, sizeof(buffer), + &nss_errno); + if (status != NSS_STATUS_SUCCESS) + break; +#ifdef CHE_FAIL + cache_update(root, key, mapent, age); +#else + cache_update(key, mapent, age); +#endif + } + + (*context->endautomntent)(&private); + + cache_clean(root, age); + return 1; +} + +int lookup_ghost(const char *root, int ghost, time_t now, void *context) +{ + struct lookup_context *ctxt = (struct lookup_context *)context; + struct mapent_cache *me; + int status = 1; + + if (!read_map(root, ctxt)) + return LKP_FAIL; + + status = cache_ghost(root, ghost, ctxt->mapname, ctxt->nsname, ctxt->parse); + + me = cache_lookup_first(); + if (me == NULL) + return LKP_FAIL; + + if (*me->key == '/' && *(root + 1) != '-') { + me = cache_partial_match(root); + /* me NULL => no entries for this direct mount root or indirect map */ + if (me == NULL) + return LKP_FAIL | LKP_INDIRECT; + } + + return status; +} + +int lookup_mount(const char *root, const char *name, int name_len, void *context) +{ + struct lookup_context *ctxt = (struct lookup_context *)context; + char key[KEY_MAX_LEN + 1]; + char buffer[KEY_MAX_LEN + 1 + MAPENT_MAX_LEN + 1]; + const char *canon_key, *mapent; + struct mapent_cache *me = NULL; + time_t age = time(NULL); + enum nss_status status; + + debug(MODPREFIX "looking up %s", name); + + snprintf(key, sizeof(key), "%s/%s", root, name); + + me = cache_lookup(name); + if (me == NULL) { + me = cache_lookup(key); + } + + if (me == NULL) { + /* path component, do submount */ + me = cache_partial_match(key); + + if (me) { + snprintf(buffer, sizeof(buffer), "-fstype=autofs %s:%s", + ctxt->nsname, ctxt->mapname); + mapent = buffer; + } + } else { + snprintf(buffer, sizeof(buffer), "%s", me->mapent); + mapent = buffer; + } + + if (me == NULL) { + const char *keys[3]; + int i; + int nss_errno; + void *private = NULL; + + status = (*ctxt->setautomntent)(ctxt->mapname, &private); + if (status != NSS_STATUS_SUCCESS) { + warn(MODPREFIX "failed to read map %s: %s", ctxt->mapname, nsserr_string(status)); + goto out_err; + } + + keys[0] = name, + keys[1] = key; + keys[2] = "*"; + + for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) { + status = (*ctxt->getautomntbyname_r)(private, name, + &canon_key, &mapent, + buffer, sizeof(buffer), + &nss_errno); + if (status != NSS_STATUS_NOTFOUND) + break; + } + + (*ctxt->endautomntent)(&private); + + if (status != NSS_STATUS_SUCCESS) { + warn(MODPREFIX "failed to read map %s: %s", ctxt->mapname, nsserr_string(status)); + goto out_err; + } + +#ifdef CHE_FAIL + cache_update(root, keys[i], mapent, age); +#else + cache_update(keys[i], mapent, age); +#endif + } + + debug(MODPREFIX "%s -> %s", name, mapent); + + return ctxt->parse->parse_mount(root, name, name_len, mapent, ctxt->parse->context); + +out_err: + warn(MODPREFIX "lookup for %s failed: %d", name, status); + return 1; +} + +int lookup_done(void *context) +{ + struct lookup_context *ctxt = (struct lookup_context *)context; + int ret; + + if (ctxt->nsname != NULL) { + free(ctxt->nsname); + ctxt->nsname = NULL; + } + + if (ctxt->mapname != NULL) { + free(ctxt->mapname); + ctxt->mapname = NULL; + } + + ret = close_parse(ctxt->parse); + + if (ctxt->dlhandle != NULL) { + dlclose(ctxt->dlhandle); + ctxt->dlhandle = NULL; + } + + memset(ctxt, 0, sizeof(*ctxt)); + free(ctxt); + + return ret; +} + diff --git a/exports.aix b/exports.aix new file mode 100644 index 0000000..d51fa7e --- /dev/null +++ b/exports.aix @@ -0,0 +1,64 @@ +#! + +* Group-related routines (not used on AIX directly) +gr_pvtinit +gr_close +gr_rewind +gr_minimize +gr_next +gr_byname +gr_bygid + +* Host-related routines +ho_pvtinit +ho_close +ho_rewind +ho_minimize +ho_next +ho_byname +* No ho_byname2 +ho_byaddr + +* Netgroup-related routines +ng_pvtinit +ng_close +ng_rewind +ng_minimize +ng_next +ng_test + +* Networks-related routines +nw_pvtinit +nw_close +nw_rewind +nw_minimize +nw_next +nw_byname +nw_byaddr + +* Protocols-related routines +pr_pvtinit +pr_close +pr_rewind +pr_minimize +pr_next +pr_byname +pr_bynumber + +* Password-related routines (not used on AIX directly) +pw_pvtinit +pw_close +pw_rewind +pw_minimize +pw_next +pw_byname +pw_byuid + +* Services-related routines +sv_pvtinit +sv_close +sv_rewind +sv_minimize +sv_next +sv_byname +sv_byport diff --git a/exports.hpux b/exports.hpux new file mode 100644 index 0000000..4f0f2f6 --- /dev/null +++ b/exports.hpux @@ -0,0 +1 @@ ++e _nss_ldap_bootparams_constr +e _nss_ldap_ethers_constr +e _nss_ldap_group_constr +e _nss_ldap_hosts_constr +e _nss_ldap_networks_constr +e _nss_ldap_protocols_constr +e _nss_ldap_passwd_constr +e _nss_ldap_rpc_constr +e _nss_ldap_services_constr +e _nss_ldap_shadow_constr diff --git a/exports.linux b/exports.linux new file mode 100644 index 0000000..2df32e5 --- /dev/null +++ b/exports.linux @@ -0,0 +1,65 @@ +#ident $Id: exports.linux,v 2.8 2005/05/25 00:05:08 lukeh Exp $ +EXPORTED { + global: + # Published NSS service module interfaces + _nss_ldap_endaliasent; + _nss_ldap_endautomntent; + _nss_ldap_endetherent; + _nss_ldap_endgrent; + _nss_ldap_endhostent; + _nss_ldap_endnetent; + _nss_ldap_endnetgrent; + _nss_ldap_endprotoent; + _nss_ldap_endpwent; + _nss_ldap_endrpcent; + _nss_ldap_endservent; + _nss_ldap_endspent; + _nss_ldap_getaliasbyname_r; + _nss_ldap_getaliasent_r; + _nss_ldap_getautomntbyname_r; + _nss_ldap_getautomntent_r; + _nss_ldap_getetherent_r; + _nss_ldap_getgrent_r; + _nss_ldap_getgrgid_r; + _nss_ldap_getgrnam_r; + _nss_ldap_gethostbyaddr_r; + _nss_ldap_gethostbyname_r; + _nss_ldap_gethostbyname2_r; + _nss_ldap_gethostent_r; + _nss_ldap_gethostton_r; + _nss_ldap_getnetbyaddr_r; + _nss_ldap_getnetbyname_r; + _nss_ldap_getnetent_r; + _nss_ldap_getnetgrent_r; + _nss_ldap_getntohost_r; + _nss_ldap_getprotobyname_r; + _nss_ldap_getprotobynumber_r; + _nss_ldap_getprotoent_r; + _nss_ldap_getpwent_r; + _nss_ldap_getpwnam_r; + _nss_ldap_getpwuid_r; + _nss_ldap_getrpcbyname_r; + _nss_ldap_getrpcbynumber_r; + _nss_ldap_getrpcent_r; + _nss_ldap_getservbyname_r; + _nss_ldap_getservbyport_r; + _nss_ldap_getservent_r; + _nss_ldap_getspent_r; + _nss_ldap_getspnam_r; + _nss_ldap_initgroups; + _nss_ldap_initgroups_dyn; + _nss_ldap_setaliasent; + _nss_ldap_setautomntent; + _nss_ldap_setetherent; + _nss_ldap_setgrent; + _nss_ldap_sethostent; + _nss_ldap_setnetent; + _nss_ldap_setnetgrent; + _nss_ldap_setprotoent; + _nss_ldap_setpwent; + _nss_ldap_setrpcent; + _nss_ldap_setservent; + _nss_ldap_setspent; + local: + *; +}; diff --git a/exports.solaris b/exports.solaris new file mode 100644 index 0000000..3ad3bd4 --- /dev/null +++ b/exports.solaris @@ -0,0 +1,30 @@ +#ident $Id: exports.solaris,v 2.6 2006/01/12 10:19:20 lukeh Exp $ +nss_ldap.so.1 { + global: + # Published NSS service module interfaces + _nss_ldap_bootparams_constr; + _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; + # libsldap library interfaces + __ns_ldap_getMappedAttributes; + __ns_ldap_getMappedObjectClass; + __ns_ldap_getParam; + __ns_ldap_freeError; + __ns_ldap_freeEntry; + __ns_ldap_freeResult; + __ns_ldap_list; + __ns_ldap_err2str; + __ns_ldap_firstEntry; + __ns_ldap_nextEntry; + __ns_ldap_endEntry; + local: + *; +}; diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/irs-grp.c b/irs-grp.c new file mode 100644 index 0000000..1a56742 --- /dev/null +++ b/irs-grp.c @@ -0,0 +1,125 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_IRS_H + +#include <errno.h> +#include "irs-nss.h" + +/* $Id: irs-grp.c,v 2.26 2005/05/20 05:30:39 lukeh Exp $ */ + +#ifdef HAVE_USERSEC_H +void *gr_pvtinit (void); +#endif +IRS_EXPORT void gr_close (struct irs_gr *); +IRS_EXPORT struct group *gr_next (struct irs_gr *); +IRS_EXPORT struct group *gr_byname (struct irs_gr *, const char *); +IRS_EXPORT struct group *gr_bygid (struct irs_gr *, gid_t); +IRS_EXPORT void gr_rewind (struct irs_gr *); +IRS_EXPORT void gr_minimize (struct irs_gr *); + +struct pvt +{ + struct group result; + char buffer[NSS_BUFLEN_GROUP]; + ent_context_t *state; +}; + +IRS_EXPORT struct group * +gr_byname (struct irs_gr *this, const char *name) +{ + LOOKUP_NAME (name, this, _nss_ldap_filt_getgrnam, LM_GROUP, + _nss_ldap_parse_gr, NSS_BUFLEN_GROUP); +} + +IRS_EXPORT struct group * +gr_bygid (struct irs_gr *this, gid_t gid) +{ + LOOKUP_NUMBER (gid, this, _nss_ldap_filt_getgrgid, LM_GROUP, + _nss_ldap_parse_gr, NSS_BUFLEN_GROUP); +} + +IRS_EXPORT void +gr_close (struct irs_gr *this) +{ + LOOKUP_ENDENT (this); +#ifdef HAVE_USERSEC_H + free (this->private); + free (this); +#endif +} + +IRS_EXPORT struct group * +gr_next (struct irs_gr *this) +{ + LOOKUP_GETENT (this, _nss_ldap_filt_getgrent, LM_GROUP, _nss_ldap_parse_gr, + NSS_BUFLEN_GROUP); +} + +IRS_EXPORT void +gr_rewind (struct irs_gr *this) +{ + LOOKUP_SETENT (this); +} + +IRS_EXPORT void +gr_minimize (struct irs_gr *this) +{ +} + +#ifdef HAVE_USERSEC_H +void * +gr_pvtinit (void) +#else +struct irs_gr * +irs_ldap_gr (struct irs_acc *this) +#endif +{ + struct irs_gr *gr; + struct pvt *pvt; + + gr = calloc (1, sizeof (*gr)); + if (gr == NULL) + return NULL; + + pvt = calloc (1, sizeof (*pvt)); + if (pvt == NULL) + { + free (gr); + return NULL; + } + + pvt->state = NULL; + gr->private = pvt; + gr->close = gr_close; + gr->next = gr_next; + gr->byname = gr_byname; + gr->bygid = gr_bygid; +#ifndef HAVE_USERSEC_H + gr->list = make_group_list; +#else + gr->list = NULL; +#endif + gr->rewind = gr_rewind; + gr->minimize = gr_minimize; + return gr; +} + +#endif /* HAVE_IRS_H */ diff --git a/irs-hosts.c b/irs-hosts.c new file mode 100644 index 0000000..216d944 --- /dev/null +++ b/irs-hosts.c @@ -0,0 +1,201 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_IRS_H + +#include <errno.h> +#include "irs-nss.h" + +/* $Id: irs-hosts.c,v 2.26 2005/05/20 05:30:39 lukeh Exp $ */ + +#ifdef HAVE_USERSEC_H +void *ho_pvtinit (void); +#endif +IRS_EXPORT void ho_close (struct irs_ho *this); +IRS_EXPORT struct hostent *ho_byname (struct irs_ho *this, const char *name); +IRS_EXPORT struct hostent *ho_byname2 (struct irs_ho *this, const char *name, + int af); +IRS_EXPORT struct hostent *ho_byaddr (struct irs_ho *this, const void *addr, + int len, int af); +IRS_EXPORT struct hostent *ho_next (struct irs_ho *this); +IRS_EXPORT void ho_rewind (struct irs_ho *this); +IRS_EXPORT void ho_minimize (struct irs_ho *this); + + +static const u_char mapped[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; +static const u_char tunnelled[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +struct pvt +{ + struct hostent result; + char buffer[NSS_BUFLEN_HOSTS]; + ent_context_t *state; +}; + +IRS_EXPORT struct hostent * +ho_byname (struct irs_ho *this, const char *name) +{ + NSS_STATUS s; + struct pvt *pvt = (struct pvt *) this->private; + ldap_args_t a; + + LA_INIT (a); + LA_STRING (a) = name; + LA_TYPE (a) = LA_TYPE_STRING; + + s = _nss_ldap_getbyname (&a, + &pvt->result, + pvt->buffer, + sizeof (pvt->buffer), + &errno, + _nss_ldap_filt_gethostbyname, + LM_HOSTS, _nss_ldap_parse_hostv4); + + if (s != NSS_SUCCESS) + { + MAP_H_ERRNO (s, h_errno); + return NULL; + } + return &pvt->result; +} + +IRS_EXPORT struct hostent * +ho_byaddr (struct irs_ho *this, const void *addr, int len, int af) +{ + struct pvt *pvt = (struct pvt *) this->private; + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + const u_char *uaddr = addr; + NSS_STATUS s; + ldap_args_t a; + + if (af == AF_INET6 && len == IN6ADDRSZ + && (!memcmp (uaddr, mapped, sizeof mapped) || + !memcmp (uaddr, tunnelled, sizeof tunnelled))) + { + /* Unmap. */ + addr = (u_char *) addr + sizeof mapped; + uaddr += sizeof mapped; + af = AF_INET; + len = INADDRSZ; + } + if (inet_ntop (af, uaddr, tmp, sizeof tmp) == NULL) + { + h_errno = NETDB_INTERNAL; + return (NULL); + } + + LA_INIT (a); + LA_STRING (a) = tmp; + LA_TYPE (a) = LA_TYPE_STRING; + + s = _nss_ldap_getbyname (&a, + &pvt->result, + pvt->buffer, + sizeof (pvt->buffer), + &errno, + _nss_ldap_filt_gethostbyaddr, + LM_HOSTS, _nss_ldap_parse_hostv4); + + if (s != NSS_SUCCESS) + { + MAP_H_ERRNO (s, h_errno); + return NULL; + } + return &pvt->result; +} + +IRS_EXPORT void +ho_close (struct irs_ho *this) +{ + LOOKUP_ENDENT (this); +#ifdef HAVE_USERSEC_H + free (this->private); + free (this); +#endif +} + +IRS_EXPORT struct hostent * +ho_next (struct irs_ho *this) +{ + struct pvt *pvt = (struct pvt *) this->private; + NSS_STATUS s; + + s = _nss_ldap_getent (&pvt->state, + &pvt->result, + pvt->buffer, + sizeof (pvt->buffer), + &errno, + _nss_ldap_filt_gethostent, + LM_HOSTS, _nss_ldap_parse_hostv4); + + if (s != NSS_SUCCESS) + { + MAP_H_ERRNO (s, h_errno); + return NULL; + } + return &pvt->result; +} + +IRS_EXPORT void +ho_rewind (struct irs_ho *this) +{ + LOOKUP_SETENT (this); +} + +IRS_EXPORT void +ho_minimize (struct irs_ho *this) +{ +} + +#ifdef HAVE_USERSEC_H +void * +ho_pvtinit (void) +#else +struct irs_ho * +irs_ldap_ho (struct irs_acc *this) +#endif +{ + struct irs_ho *ho; + struct pvt *pvt; + + ho = calloc (1, sizeof (*ho)); + if (ho == NULL) + return NULL; + + pvt = calloc (1, sizeof (*pvt)); + if (pvt == NULL) + { + free (ho); + return NULL; + } + + pvt->state = NULL; + ho->private = pvt; + ho->close = ho_close; + ho->next = ho_next; + ho->byname = ho_byname; +/* ho->byname2 = ho_byname2; */ + ho->byaddr = ho_byaddr; + ho->rewind = ho_rewind; + ho->minimize = ho_minimize; + return ho; +} + +#endif /*HAVE_IRS_H */ diff --git a/irs-netgrp.c b/irs-netgrp.c new file mode 100644 index 0000000..cb15015 --- /dev/null +++ b/irs-netgrp.c @@ -0,0 +1,191 @@ +/* Copyright (C) 2004 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 2004. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_IRS_H + +#include <errno.h> +#include "irs-nss.h" + +/* $Id: irs-netgrp.c,v 2.6 2004/09/16 10:14:46 lukeh Exp $ */ + +#ifdef HAVE_USERSEC_H +void *ng_pvtinit (void); +#endif +IRS_EXPORT void ng_close (struct irs_ng *); +IRS_EXPORT int ng_next (struct irs_ng *, char **, char **, char **); +IRS_EXPORT int ng_test (struct irs_ng *, const char *, const char *, + const char *, const char *); +IRS_EXPORT void ng_rewind (struct irs_ng *, const char *); +IRS_EXPORT void ng_minimize (struct irs_ng *); + +IRS_EXPORT int +ng_test (struct irs_ng *this, + const char *name, const char *host, + const char *user, const char *domain) +{ + NSS_STATUS parseStat; + ldap_innetgr_args_t li_args; + + li_args.lia_netgroup = name; + li_args.lia_netgr_status = NSS_NETGR_NO; + li_args.lia_depth = 0; + li_args.lia_erange = 0; + + _nss_ldap_enter (); + + /* fall through to NSS implementation */ + parseStat = do_innetgr (&li_args, host, user, domain); + if (parseStat != NSS_SUCCESS && parseStat != NSS_NOTFOUND) + { + if (li_args.lia_erange) + errno = ERANGE; + _nss_ldap_leave (); + + return 0; + } + + _nss_ldap_leave (); + + return (li_args.lia_netgr_status == NSS_NETGR_FOUND); +} + +IRS_EXPORT void +ng_rewind (struct irs_ng *this, const char *group) +{ + nss_ldap_netgr_backend_t *ngbe; + ldap_args_t a; + NSS_STATUS stat; + + ngbe = (nss_ldap_netgr_backend_t *) this->private; + + /* clear out old state */ + _nss_ldap_namelist_destroy (&ngbe->known_groups); + _nss_ldap_namelist_destroy (&ngbe->needed_groups); + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + LA_STRING (a) = group; + + if (_nss_ldap_ent_context_init (&ngbe->state) == NULL) + return; + + _nss_ldap_enter (); + stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getgrent, + LM_NETGROUP, NULL, 1, &ngbe->state->ec_res); + + if (stat == NSS_SUCCESS) + _nss_ldap_namelist_push (&ngbe->known_groups, group); + + if (stat != NSS_SUCCESS) + _nss_ldap_ent_context_release (ngbe->state); + + _nss_ldap_leave (); +} + +IRS_EXPORT int +ng_next (struct irs_ng *this, char **machine, char **user, char **domain) +{ + nss_ldap_netgr_backend_t *ngbe = (nss_ldap_netgr_backend_t *) this->private; + enum nss_netgr_status netgr_stat; + NSS_STATUS stat; + + if (ngbe->state == NULL) + return 0; + + _nss_ldap_enter (); + + stat = do_getnetgrent (ngbe, + ngbe->buffer, + NSS_BUFLEN_NETGROUP, + &netgr_stat, + machine, + user, + domain); + + _nss_ldap_leave (); + + return (stat == NSS_SUCCESS); +} + +IRS_EXPORT void +ng_minimize (struct irs_ng *this) +{ +} + +IRS_EXPORT void +ng_close (struct irs_ng *this) +{ +#ifdef HAVE_USERSEC_H + nss_ldap_netgr_backend_t *ngbe; + + ngbe = (nss_ldap_netgr_backend_t *) this->private; + if (ngbe != NULL) + { + if (ngbe->state != NULL) + { + _nss_ldap_enter (); + _nss_ldap_ent_context_release (ngbe->state); + free (ngbe->state); + _nss_ldap_leave (); + } + + _nss_ldap_namelist_destroy (&ngbe->known_groups); + _nss_ldap_namelist_destroy (&ngbe->needed_groups); + + free (ngbe); + } + + free (this); +#endif /* HAVE_USERSEC_H */ +} + +#ifdef HAVE_USERSEC_H +void * +ng_pvtinit (void) +#else +struct irs_ng * +irs_ldap_ng (struct irs_acc *this) +#endif +{ + struct irs_ng *ng; + nss_ldap_netgr_backend_t *pvt; + + ng = calloc (1, sizeof (*ng)); + if (ng == NULL) + return NULL; + + pvt = calloc (1, sizeof (*pvt)); + if (pvt == NULL) + { + free (ng); + return NULL; + } + + pvt->state = NULL; + ng->private = pvt; + ng->close = ng_close; + ng->next = ng_next; + ng->test = ng_test; + ng->rewind = ng_rewind; + ng->minimize = ng_minimize; + return ng; +} + +#endif /*HAVE_IRS_H */ diff --git a/irs-network.c b/irs-network.c new file mode 100644 index 0000000..0bef0a6 --- /dev/null +++ b/irs-network.c @@ -0,0 +1,213 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_IRS_H + +#include <errno.h> +#include "irs-nss.h" + +/* $Id: irs-network.c,v 2.25 2005/05/20 05:30:39 lukeh Exp $ */ + +#ifdef HAVE_USERSEC_H +void *nw_pvtinit (void); +#endif +IRS_EXPORT void nw_close (struct irs_nw *); +IRS_EXPORT struct nwent *nw_byname (struct irs_nw *, const char *, int); +IRS_EXPORT struct nwent *nw_byaddr (struct irs_nw *, void *, int, int); +IRS_EXPORT struct nwent *nw_next (struct irs_nw *); +IRS_EXPORT void nw_rewind (struct irs_nw *); +IRS_EXPORT void nw_minimize (struct irs_nw *); + +struct pvt +{ + struct nwent result; + char buffer[NSS_BUFLEN_NETWORKS]; + ent_context_t *state; +}; + +IRS_EXPORT struct nwent * +nw_byname (struct irs_nw *this, const char *name, int af) +{ + NSS_STATUS s; + struct pvt *pvt = (struct pvt *) this->private; + ldap_args_t a; + + LA_INIT (a); + LA_STRING (a) = name; + LA_TYPE (a) = LA_TYPE_STRING; + + if (af != AF_INET) + { + h_errno = NETDB_INTERNAL; + errno = EAFNOSUPPORT; + return (NULL); + } + + s = _nss_ldap_getbyname (&a, + &pvt->result, + pvt->buffer, + sizeof (pvt->buffer), + &errno, + _nss_ldap_filt_getnetbyname, + LM_NETWORKS, _nss_ldap_parse_net); + + if (s != NSS_SUCCESS) + { + MAP_H_ERRNO (s, h_errno); + return NULL; + } + return &pvt->result; +} + +IRS_EXPORT struct nwent * +nw_byaddr (struct irs_nw *this, void *net, int length, int af) +{ + ldap_args_t a; + NSS_STATUS s; + struct pvt *pvt = (struct pvt *) this->private; + char tmp[sizeof "255.255.255.255/32"], *t; + + if (af != AF_INET) + { + h_errno = NETDB_INTERNAL; + errno = EAFNOSUPPORT; + return (NULL); + } + + /* Try it with /CIDR first. */ + if (inet_net_ntop (AF_INET, net, length, tmp, sizeof tmp) == NULL) + { + h_errno = NETDB_INTERNAL; + return (NULL); + } + + LA_INIT (a); + LA_STRING (a) = tmp; + LA_TYPE (a) = LA_TYPE_STRING; + + s = _nss_ldap_getbyname (&a, + &pvt->result, + pvt->buffer, + sizeof (pvt->buffer), + &errno, + _nss_ldap_filt_getnetbyaddr, + LM_NETWORKS, _nss_ldap_parse_net); + + if (s != NSS_SUCCESS) + { + if ((t = strchr (tmp, '/')) != NULL) + { + *t = '\0'; + s = _nss_ldap_getbyname (&a, + &pvt->result, + pvt->buffer, + sizeof (pvt->buffer), + &errno, + _nss_ldap_filt_getnetbyaddr, + LM_NETWORKS, _nss_ldap_parse_net); + if (s != NSS_SUCCESS) + { + MAP_H_ERRNO (s, h_errno); + return (NULL); + } + } + } + + return &pvt->result; +} + +IRS_EXPORT void +nw_close (struct irs_nw *this) +{ + LOOKUP_ENDENT (this); +#ifdef HAVE_USERSEC_H + free (this->private); + free (this); +#endif +} + +IRS_EXPORT struct nwent * +nw_next (struct irs_nw *this) +{ + struct pvt *pvt = (struct pvt *) this->private; + NSS_STATUS s; + + s = _nss_ldap_getent (&pvt->state, + &pvt->result, + pvt->buffer, + sizeof (pvt->buffer), + &errno, + _nss_ldap_filt_getnetent, + LM_NETWORKS, _nss_ldap_parse_net); + + if (s != NSS_SUCCESS) + { + MAP_H_ERRNO (s, h_errno); + return NULL; + } + return &pvt->result; +} + +IRS_EXPORT void +nw_rewind (struct irs_nw *this) +{ + LOOKUP_SETENT (this); +} + +IRS_EXPORT void +nw_minimize (struct irs_nw *this) +{ +} + +#ifdef HAVE_USERSEC_H +void * +nw_pvtinit (void) +#else +struct irs_nw * +irs_ldap_nw (struct irs_acc *this) +#endif +{ + struct irs_nw *nw; + struct pvt *pvt; + + nw = calloc (1, sizeof (*nw)); + if (nw == NULL) + return NULL; + + pvt = calloc (1, sizeof (*pvt)); + if (pvt == NULL) + { + free (nw); + return NULL; + } + + pvt->state = NULL; + nw->private = pvt; + nw->close = nw_close; + nw->next = nw_next; + nw->byname = nw_byname; +/* nw->byname2 = nw_byname2; */ + nw->byaddr = nw_byaddr; + nw->rewind = nw_rewind; + nw->minimize = nw_minimize; + return nw; +} + +#endif /*HAVE_IRS_H */ diff --git a/irs-nss.c b/irs-nss.c new file mode 100644 index 0000000..6aebe64 --- /dev/null +++ b/irs-nss.c @@ -0,0 +1,90 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +static char rcsId[] = "$Id: irs-nss.c,v 2.16 2005/05/20 05:30:39 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_IRS_H + +#ifndef HAVE_USERSEC_H + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif + +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "irs-nss.h" +#include "ldap-nss.h" +#include "ltf.h" +#include "util.h" + +static void irs_ldap_close (struct irs_acc *this); + +/* Dispatch table for IRS LDAP module */ + +struct irs_acc * +irs_ldap_acc (const char *options) +{ + struct irs_acc *acc; + + if (!(acc = malloc (sizeof (*acc)))) + { + errno = ENOMEM; + return NULL; + } + + memset (acc, 0x5e, sizeof *acc); + + /* private stuff gets kept as static in ldap-nss.c. */ + acc->private = NULL; + + acc->gr_map = irs_ldap_gr; +#ifdef WANT_IRS_PW + acc->pw_map = irs_ldap_pw; +#endif + acc->sv_map = irs_ldap_sv; + acc->pr_map = irs_ldap_pr; + acc->ho_map = irs_ldap_ho; + acc->nw_map = irs_ldap_nw; + acc->ng_map = irs_ldap_ng; + + acc->close = irs_ldap_close; + + return (acc); +} + +/* Methods */ + +static void +irs_ldap_close (struct irs_acc *this) +{ + free (this); +} +#endif /* HAVE_USERSEC_H */ +#endif /* HAVE_IRS_H */ diff --git a/irs-nss.h b/irs-nss.h new file mode 100644 index 0000000..b59c1da --- /dev/null +++ b/irs-nss.h @@ -0,0 +1,60 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: irs-nss.h,v 2.20 2005/05/20 05:30:40 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_IRS_H +#define _LDAP_NSS_LDAP_IRS_H + +#ifdef HAVE_IRS_H +/* + * This header is only needed when using the BSD Information + * Retrieval Service. It is not necessary for the Solaris or + * GNU nameservice switch modules. + */ +#include <irs.h> +#endif + +struct irs_gr *irs_ldap_gr __P ((struct irs_acc *)); +struct irs_pw *irs_ldap_pw __P ((struct irs_acc *)); +struct irs_sv *irs_ldap_sv __P ((struct irs_acc *)); +struct irs_pr *irs_ldap_pr __P ((struct irs_acc *)); +struct irs_ho *irs_ldap_ho __P ((struct irs_acc *)); +struct irs_nw *irs_ldap_nw __P ((struct irs_acc *)); +/* not done yet */ +struct irs_ng *irs_ldap_ng __P ((struct irs_acc *)); + +/* Keep namespace clean. */ +#define irs_ldap_acc __irs_ldap_acc + +struct irs_acc *irs_ldap_acc __P ((const char *)); + +#define make_group_list __make_group_list + +extern int make_group_list (struct irs_gr *, const char *, + gid_t, gid_t *, int *); + +#ifdef HAVE_USERSEC_H /* aka AIX */ +#define IRS_EXPORT +#else +#define IRS_EXPORT static +#endif + +#endif /* _LDAP_NSS_LDAP_IRS_H */ diff --git a/irs-proto.c b/irs-proto.c new file mode 100644 index 0000000..2e36497 --- /dev/null +++ b/irs-proto.c @@ -0,0 +1,120 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_IRS_H + +#include <errno.h> +#include "irs-nss.h" + +/* $Id: irs-proto.c,v 2.23 2005/05/20 05:30:40 lukeh Exp $ */ + +#ifdef HAVE_USERSEC_H +void *pr_pvtinit (void); +#endif +IRS_EXPORT void pr_close (struct irs_pr *); +IRS_EXPORT struct protoent *pr_byname (struct irs_pr *, const char *); +IRS_EXPORT struct protoent *pr_bynumber (struct irs_pr *, int); +IRS_EXPORT struct protoent *pr_next (struct irs_pr *); +IRS_EXPORT void pr_rewind (struct irs_pr *); +IRS_EXPORT void pr_minimize (struct irs_pr *); + +struct pvt +{ + struct protoent result; + char buffer[NSS_BUFLEN_PROTOCOLS]; + ent_context_t *state; +}; + +IRS_EXPORT struct protoent * +pr_byname (struct irs_pr *this, const char *name) +{ + LOOKUP_NAME (name, this, _nss_ldap_filt_getprotobyname, LM_PROTOCOLS, + _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} + +IRS_EXPORT struct protoent * +pr_bynumber (struct irs_pr *this, int num) +{ + LOOKUP_NUMBER (num, this, _nss_ldap_filt_getprotobynumber, LM_PROTOCOLS, + _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} + +IRS_EXPORT void +pr_close (struct irs_pr *this) +{ + LOOKUP_ENDENT (this); +#ifdef HAVE_USERSEC_H + free (this->private); + free (this); +#endif +} + +IRS_EXPORT struct protoent * +pr_next (struct irs_pr *this) +{ + LOOKUP_GETENT (this, _nss_ldap_filt_getprotoent, LM_PROTOCOLS, + _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} + +IRS_EXPORT void +pr_rewind (struct irs_pr *this) +{ + LOOKUP_SETENT (this); +} + +IRS_EXPORT void +pr_minimize (struct irs_pr *this) +{ +} + +#ifdef HAVE_USERSEC_H +void * +pr_pvtinit (void) +#else +struct irs_pr * +irs_ldap_pr (struct irs_acc *this) +#endif +{ + struct irs_pr *pr; + struct pvt *pvt; + + pr = calloc (1, sizeof (*pr)); + if (pr == NULL) + return NULL; + + pvt = calloc (1, sizeof (*pvt)); + if (pvt == NULL) + { + free (pr); + return NULL; + } + + pvt->state = NULL; + pr->private = pvt; + pr->close = pr_close; + pr->next = pr_next; + pr->byname = pr_byname; + pr->bynumber = pr_bynumber; + pr->rewind = pr_rewind; + pr->minimize = pr_minimize; + return pr; +} + +#endif /*HAVE_IRS_H */ diff --git a/irs-pwd.c b/irs-pwd.c new file mode 100644 index 0000000..8783f76 --- /dev/null +++ b/irs-pwd.c @@ -0,0 +1,120 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_IRS_H + +#include <errno.h> +#include "irs-nss.h" + +/* $Id: irs-pwd.c,v 2.24 2005/05/20 05:30:40 lukeh Exp $ */ + +#ifdef HAVE_USERSEC_H +void *pw_pvtinit (void); +#endif +IRS_EXPORT void pw_close (struct irs_pw *); +IRS_EXPORT struct passwd *pw_next (struct irs_pw *); +IRS_EXPORT struct passwd *pw_byname (struct irs_pw *, const char *); +IRS_EXPORT struct passwd *pw_byuid (struct irs_pw *, uid_t); +IRS_EXPORT void pw_rewind (struct irs_pw *); +IRS_EXPORT void pw_minimize (struct irs_pw *); + +struct pvt +{ + struct passwd result; + char buffer[NSS_BUFLEN_PASSWD]; + ent_context_t *state; +}; + +IRS_EXPORT struct passwd * +pw_byname (struct irs_pw *this, const char *name) +{ + LOOKUP_NAME (name, this, _nss_ldap_filt_getpwnam, LM_PASSWD, + _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT); +} + +IRS_EXPORT struct passwd * +pw_byuid (struct irs_pw *this, uid_t uid) +{ + LOOKUP_NUMBER (uid, this, _nss_ldap_filt_getpwuid, LM_PASSWD, + _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT); +} + +IRS_EXPORT void +pw_close (struct irs_pw *this) +{ + LOOKUP_ENDENT (this); +#ifdef HAVE_USERSEC_H + free (this->private); + free (this); +#endif +} + +IRS_EXPORT struct passwd * +pw_next (struct irs_pw *this) +{ + LOOKUP_GETENT (this, _nss_ldap_filt_getpwent, LM_PASSWD, + _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT); +} + +IRS_EXPORT void +pw_rewind (struct irs_pw *this) +{ + LOOKUP_SETENT (this); +} + +IRS_EXPORT void +pw_minimize (struct irs_pw *this) +{ +} + +#ifdef HAVE_USERSEC_H +void * +pw_pvtinit (void) +#else +struct irs_pw * +irs_ldap_pw (struct irs_acc *this) +#endif +{ + struct irs_pw *pw; + struct pvt *pvt; + + pw = calloc (1, sizeof (*pw)); + if (pw == NULL) + return NULL; + + pvt = calloc (1, sizeof (*pvt)); + if (pvt == NULL) + { + free (pw); + return NULL; + } + + pvt->state = NULL; + pw->private = pvt; + pw->close = pw_close; + pw->next = pw_next; + pw->byname = pw_byname; + pw->byuid = pw_byuid; + pw->rewind = pw_rewind; + pw->minimize = pw_minimize; + return pw; +} + +#endif /*HAVE_IRS_H */ diff --git a/irs-service.c b/irs-service.c new file mode 100644 index 0000000..0a53dbb --- /dev/null +++ b/irs-service.c @@ -0,0 +1,161 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_IRS_H + +#include <errno.h> +#include "irs-nss.h" + +/* $Id: irs-service.c,v 2.26 2005/05/20 05:30:40 lukeh Exp $ */ + +#ifdef HAVE_USERSEC_H +void *sv_pvtinit (void); +#endif +IRS_EXPORT void sv_close (struct irs_sv *); +IRS_EXPORT struct servent *sv_next (struct irs_sv *); +IRS_EXPORT struct servent *sv_byname (struct irs_sv *, const char *, + const char *); +IRS_EXPORT struct servent *sv_byport (struct irs_sv *, int, const char *); +IRS_EXPORT void sv_rewind (struct irs_sv *); +IRS_EXPORT void sv_minimize (struct irs_sv *); + +struct pvt +{ + struct servent result; + char buffer[NSS_BUFLEN_SERVICES]; + ent_context_t *state; +}; + +IRS_EXPORT struct servent * +sv_byname (struct irs_sv *this, const char *name, const char *proto) +{ + ldap_args_t a; + struct pvt *pvt = (struct pvt *) this->private; + NSS_STATUS s; + + LA_INIT (a); + LA_STRING (a) = name; + LA_TYPE (a) = (proto == NULL) ? LA_TYPE_STRING : LA_TYPE_STRING_AND_STRING; + LA_STRING2 (a) = proto; + s = + _nss_ldap_getbyname (&a, &pvt->result, pvt->buffer, sizeof (pvt->buffer), + &errno, + (proto == + NULL) ? _nss_ldap_filt_getservbyname : + _nss_ldap_filt_getservbynameproto, + LM_SERVICES, _nss_ldap_parse_serv); + + if (s != NSS_SUCCESS) + { + MAP_ERRNO (s, errno); + return NULL; + } + return &pvt->result; +} + +IRS_EXPORT struct servent * +sv_byport (struct irs_sv *this, int port, const char *proto) +{ + ldap_args_t a; + struct pvt *pvt = (struct pvt *) this->private; + NSS_STATUS s; + + LA_INIT (a); + LA_NUMBER (a) = port; + LA_TYPE (a) = (proto == NULL) ? LA_TYPE_NUMBER : LA_TYPE_NUMBER_AND_STRING; + LA_STRING2 (a) = proto; + s = + _nss_ldap_getbyname (&a, &pvt->result, pvt->buffer, sizeof (pvt->buffer), + &errno, + (proto == + NULL) ? _nss_ldap_filt_getservbyport : + _nss_ldap_filt_getservbyportproto, + LM_SERVICES, _nss_ldap_parse_serv); + + if (s != NSS_SUCCESS) + { + MAP_ERRNO (s, errno); + return NULL; + } + return &pvt->result; +} + +IRS_EXPORT void +sv_close (struct irs_sv *this) +{ + LOOKUP_ENDENT (this); +#ifdef HAVE_USERSEC_H + free (this->private); + free (this); +#endif +} + +IRS_EXPORT struct servent * +sv_next (struct irs_sv *this) +{ + LOOKUP_GETENT (this, _nss_ldap_filt_getservent, LM_SERVICES, + _nss_ldap_parse_serv, LDAP_NSS_BUFLEN_DEFAULT); +} + +IRS_EXPORT void +sv_rewind (struct irs_sv *this) +{ + LOOKUP_SETENT (this); +} + +IRS_EXPORT void +sv_minimize (struct irs_sv *this) +{ +} + +#ifdef HAVE_USERSEC_H +void * +sv_pvtinit (void) +#else +struct irs_sv * +irs_ldap_sv (struct irs_acc *this) +#endif +{ + struct irs_sv *sv; + struct pvt *pvt; + + sv = calloc (1, sizeof (*sv)); + if (sv == NULL) + return NULL; + + pvt = calloc (1, sizeof (*pvt)); + if (pvt == NULL) + { + free (sv); + return NULL; + } + + pvt->state = NULL; + sv->private = pvt; + sv->close = sv_close; + sv->next = sv_next; + sv->byname = sv_byname; + sv->byport = sv_byport; + sv->rewind = sv_rewind; + sv->minimize = sv_minimize; + return sv; +} + +#endif /*HAVE_IRS_H */ @@ -0,0 +1,330 @@ +/* + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * $Id: irs.h,v 2.3 2004/09/10 11:49:09 lukeh Exp $ + */ + +#ifndef _IRS_H_INCLUDED +#define _IRS_H_INCLUDED + +#include <sys/types.h> + +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> + +#include <grp.h> +#include <netdb.h> + +#include <resolv.h> +#include <pwd.h> + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +/* + * This is the group map class. + */ +struct irs_gr { + void * private; + void (*close) __P((struct irs_gr *)); + struct group * (*next) __P((struct irs_gr *)); + struct group * (*byname) __P((struct irs_gr *, const char *)); + struct group * (*bygid) __P((struct irs_gr *, gid_t)); + int (*list) __P((struct irs_gr *, const char *, + gid_t, gid_t *, int *)); + void (*rewind) __P((struct irs_gr *)); + void (*minimize) __P((struct irs_gr *)); + struct __res_state * (*res_get) __P((struct irs_gr *)); + void (*res_set) __P((struct irs_gr *, struct __res_state *, + void (*)(void *))); +}; + +/* + * This is the password map class. + */ +struct irs_pw { + void * private; + void (*close) __P((struct irs_pw *)); + struct passwd * (*next) __P((struct irs_pw *)); + struct passwd * (*byname) __P((struct irs_pw *, const char *)); + struct passwd * (*byuid) __P((struct irs_pw *, uid_t)); + void (*rewind) __P((struct irs_pw *)); + void (*minimize) __P((struct irs_pw *)); + struct __res_state * (*res_get) __P((struct irs_pw *)); + void (*res_set) __P((struct irs_pw *, struct __res_state *, + void (*)(void *))); +}; + +/* + * This is the service map class. + */ +struct irs_sv { + void * private; + void (*close) __P((struct irs_sv *)); + struct servent *(*byname) __P((struct irs_sv *, + const char *, const char *)); + struct servent *(*byport) __P((struct irs_sv *, int, const char *)); + struct servent *(*next) __P((struct irs_sv *)); + void (*rewind) __P((struct irs_sv *)); + void (*minimize) __P((struct irs_sv *)); + struct __res_state * (*res_get) __P((struct irs_sv *)); + void (*res_set) __P((struct irs_sv *, struct __res_state *, + void (*)(void *))); +}; + +/* + * This is the protocols map class. + */ +struct irs_pr { + void * private; + void (*close) __P((struct irs_pr *)); + struct protoent *(*byname) __P((struct irs_pr *, const char *)); + struct protoent *(*bynumber) __P((struct irs_pr *, int)); + struct protoent *(*next) __P((struct irs_pr *)); + void (*rewind) __P((struct irs_pr *)); + void (*minimize) __P((struct irs_pr *)); + struct __res_state * (*res_get) __P((struct irs_pr *)); + void (*res_set) __P((struct irs_pr *, struct __res_state *, + void (*)(void *))); +}; + +/* + * This is the hosts map class. + */ +struct irs_ho { + void * private; + void (*close) __P((struct irs_ho *)); + struct hostent *(*byname) __P((struct irs_ho *, const char *)); + struct hostent *(*byname2) __P((struct irs_ho *, const char *, int)); + struct hostent *(*byaddr) __P((struct irs_ho *, + const void *, int, int)); + struct hostent *(*next) __P((struct irs_ho *)); + void (*rewind) __P((struct irs_ho *)); + void (*minimize) __P((struct irs_ho *)); + struct __res_state * (*res_get) __P((struct irs_ho *)); + void (*res_set) __P((struct irs_ho *, struct __res_state *, + void (*)(void *))); +}; + +/* + * This is the networks map class. + */ +struct irs_nw { + void * private; + void (*close) __P((struct irs_nw *)); + struct nwent * (*byname) __P((struct irs_nw *, const char *, int)); + struct nwent * (*byaddr) __P((struct irs_nw *, void *, int, int)); + struct nwent * (*next) __P((struct irs_nw *)); + void (*rewind) __P((struct irs_nw *)); + void (*minimize) __P((struct irs_nw *)); + struct __res_state * (*res_get) __P((struct irs_nw *)); + void (*res_set) __P((struct irs_nw *, struct __res_state *, + void (*)(void *))); +}; + +/* + * This is the netgroups map class. + */ +struct irs_ng { + void * private; + void (*close) __P((struct irs_ng *)); + int (*next) __P((struct irs_ng *, char **, char **, + char **)); + int (*test) __P((struct irs_ng *, const char *, + const char *, const char *, + const char *)); + void (*rewind) __P((struct irs_ng *, const char *)); + void (*minimize) __P((struct irs_ng *)); +}; + +/* + * This is the generic map class, which copies the front of all others. + */ +struct irs_map { + void * private; + void (*close) __P((void *)); +}; + +/* + * This is the accessor class. It contains pointers to all of the + * initializers for the map classes for a particular accessor. + */ +struct irs_acc { + void * private; + void (*close) __P((struct irs_acc *)); + struct irs_gr * (*gr_map) __P((struct irs_acc *)); + struct irs_pw * (*pw_map) __P((struct irs_acc *)); + struct irs_sv * (*sv_map) __P((struct irs_acc *)); + struct irs_pr * (*pr_map) __P((struct irs_acc *)); + struct irs_ho * (*ho_map) __P((struct irs_acc *)); + struct irs_nw * (*nw_map) __P((struct irs_acc *)); + struct irs_ng * (*ng_map) __P((struct irs_acc *)); + struct __res_state * (*res_get) __P((struct irs_acc *)); + void (*res_set) __P((struct irs_acc *, struct __res_state *, + void (*)(void *))); +}; + +/* + * This is because the official definition of "struct netent" has no + * concept of CIDR even though it allows variant address families (on + * output but not input). The compatibility stubs convert the structs + * below into "struct netent"'s. + */ +struct nwent { + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + int n_addrtype; /* net address type */ + void *n_addr; /* network address */ + int n_length; /* address length, in bits */ +}; + +/* + * Hide external function names from POSIX. + */ +#define irs_gen_acc __irs_gen_acc +#define irs_lcl_acc __irs_lcl_acc +#define irs_dns_acc __irs_dns_acc +#define irs_nis_acc __irs_nis_acc +#define irs_irp_acc __irs_irp_acc + +/* + * Externs. + */ +extern struct irs_acc * irs_gen_acc __P((const char *options, + const char *conf_file)); +extern struct irs_acc * irs_lcl_acc __P((const char *options)); +extern struct irs_acc * irs_dns_acc __P((const char *options)); +extern struct irs_acc * irs_nis_acc __P((const char *options)); +extern struct irs_acc * irs_irp_acc __P((const char *options)); + +/* + * These forward declarations are for the semi-private functions in + * the get*.c files. Each of these funcs implements the real get* + * functionality and the standard versions are just wrappers that + * call these. Apart from the wrappers, only irpd is expected to + * call these directly, hence these decls are put here and not in + * the /usr/include replacements. + */ + +struct net_data; /* forward */ + +/* + * net_data_create gets a singleton net_data object. net_data_init + * creates as many net_data objects as times it is called. Clients using + * the default interface will use net_data_create by default. Servers will + * probably want net_data_init (one call per client) + */ +struct net_data *net_data_create(const char *conf_file); +struct net_data *net_data_init(const char *conf_file); +void net_data_destroy(void *p); + +extern struct group *getgrent_p __P((struct net_data *net_data)); +extern struct group *getgrnam_p __P((const char *name, + struct net_data *net_data)); +extern struct group *getgrgid_p __P((gid_t gid, + struct net_data *net_data)); +extern int setgroupent_p __P((int stayopen, + struct net_data *net_data)); +extern void endgrent_p __P((struct net_data *net_data)); +extern int getgrouplist_p __P((const char *name, + gid_t basegid, + gid_t *groups, + int *ngroups, + struct net_data *net_data)); + +#ifdef SETGRENT_VOID +extern void setgrent_p __P((struct net_data *net_data)); +#else +extern int setgrent_p __P((struct net_data *net_data)); +#endif + +extern struct hostent *gethostbyname_p __P((const char *name, + struct net_data *net_data)); +extern struct hostent *gethostbyname2_p __P((const char *name, int af, + struct net_data *net_data)); +extern struct hostent *gethostbyaddr_p __P((const char *addr, int len, + int af, + struct net_data *net_data)); +extern struct hostent *gethostent_p __P((struct net_data *net_data)); +extern void sethostent_p __P((int stayopen, + struct net_data *net_data)); +extern void endhostent_p __P((struct net_data *net_data)); + +extern struct netent *getnetent_p __P((struct net_data *net_data)); +extern struct netent *getnetbyname_p __P((const char *name, + struct net_data *net_data)); +extern struct netent *getnetbyaddr_p __P((unsigned long net, int type, + struct net_data *net_data)); +extern void setnetent_p __P((int stayopen, + struct net_data *net_data)); +extern void endnetent_p __P((struct net_data *net_data)); + +extern void setnetgrent_p __P((const char *netgroup, + struct net_data *net_data)); +extern void endnetgrent_p __P((struct net_data *net_data)); +extern int innetgr_p __P((const char *netgroup, + const char *host, + const char *user, + const char *domain, + struct net_data *net_data)); +extern int getnetgrent_p __P((char **host, char **user, + char **domain, + struct net_data *net_data)); + +extern struct protoent *getprotoent_p __P((struct net_data *net_data)); +extern struct protoent *getprotobyname_p __P((const char *name, + struct net_data *net_data)); +extern struct protoent *getprotobynumber_p __P((int proto, + struct net_data *net_data)); +extern void setprotoent_p __P((int stayopen, + struct net_data *net_data)); +extern void endprotoent_p __P((struct net_data *net_data)); + + +extern struct passwd *getpwent_p __P((struct net_data *net_data)); +extern struct passwd *getpwnam_p __P((const char *name, + struct net_data *net_data)); +extern struct passwd *getpwuid_p __P((uid_t uid, + struct net_data *net_data)); +extern int setpassent_p __P((int stayopen, + struct net_data *net_data)); +extern void endpwent_p __P((struct net_data *net_data)); + +#ifdef SETPWENT_VOID +extern void setpwent_p __P((struct net_data *net_data)); +#else +extern int setpwent_p __P((struct net_data *net_data)); +#endif + +extern struct servent *getservent_p __P((struct net_data *net_data)); +extern struct servent *getservbyname_p __P((const char *name, + const char *proto, + struct net_data *net_data)); +extern struct servent *getservbyport_p __P((int port, const char *proto, + struct net_data *net_data)); +extern void setservent_p __P((int stayopen, + struct net_data *net_data)); +extern void endservent_p __P((struct net_data *net_data)); + +#endif /*_IRS_H_INCLUDED*/ diff --git a/ldap-alias.c b/ldap-alias.c new file mode 100644 index 0000000..f6004e4 --- /dev/null +++ b/ldap-alias.c @@ -0,0 +1,113 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-alias.c,v 2.31 2006/01/11 18:03:48 lukeh Exp $ + */ + + +static char rcsId[] = + "$Id: ldap-alias.c,v 2.31 2006/01/11 18:03:48 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <lber.h> +#include <ldap.h> + +#ifdef HAVE_ALIASES_H +#include <aliases.h> + +#include "ldap-nss.h" +#include "ldap-alias.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *alias_context = NULL; + +static NSS_STATUS +_nss_ldap_parse_alias (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + + struct aliasent *alias = (struct aliasent *) result; + NSS_STATUS stat; + + stat = + _nss_ldap_getrdnvalue (e, ATM (LM_ALIASES, cn), &alias->alias_name, + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrvals (e, AT (rfc822MailMember), NULL, + &alias->alias_members, &buffer, &buflen, + &alias->alias_members_len); + + alias->alias_local = 0; + + return stat; +} + +NSS_STATUS +_nss_ldap_getaliasbyname_r (const char *name, struct aliasent * result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, + _nss_ldap_filt_getaliasbyname, LM_ALIASES, + _nss_ldap_parse_alias, LDAP_NSS_BUFLEN_DEFAULT); +} + +NSS_STATUS _nss_ldap_setaliasent (void) +{ + LOOKUP_SETENT (alias_context); +} + +NSS_STATUS _nss_ldap_endaliasent (void) +{ + LOOKUP_ENDENT (alias_context); +} + +NSS_STATUS +_nss_ldap_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen, + int *errnop) +{ + LOOKUP_GETENT (alias_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getaliasent, LM_ALIASES, + _nss_ldap_parse_alias, LDAP_NSS_BUFLEN_DEFAULT); +} + +#endif /* HAVE_NSS_H */ +#endif /* HAVE_ALIASES_H */ diff --git a/ldap-alias.h b/ldap-alias.h new file mode 100644 index 0000000..2ee8b95 --- /dev/null +++ b/ldap-alias.h @@ -0,0 +1,48 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-alias.h,v 2.18 2005/05/20 05:30:40 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_ALIAS_H +#define _LDAP_NSS_LDAP_LDAP_ALIAS_H + +static NSS_STATUS _nss_ldap_parse_alias (LDAPMessage * e, + ldap_state_t *, + void *result, + char *buffer, size_t buflen); + +#if 0 +/* no support in Sun NSS for aliases */ + +static NSS_STATUS _nss_ldap_getaliasbyname_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_getaliasent_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_setaliasent (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_endaliasent (nss_backend_t * be, + void *fakeargs); + +nss_backend_t *_nss_ldap_alias_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif + +#endif /* _LDAP_NSS_LDAP_LDAP_ALIAS_H */ diff --git a/ldap-automount.c b/ldap-automount.c new file mode 100644 index 0000000..19f58fa --- /dev/null +++ b/ldap-automount.c @@ -0,0 +1,400 @@ +/* Copyright (C) 2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 2005. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-automount.c,v 2.9 2006/01/13 16:15:33 lukeh Exp $ + */ + + +static char rcsId[] = "$Id: ldap-automount.c,v 2.9 2006/01/13 16:15:33 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-automount.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +static NSS_STATUS +_nss_ldap_parse_automount (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + NSS_STATUS stat; + char ***keyval = result; + + stat = + _nss_ldap_assign_attrval (e, AT (automountKey), keyval[0], + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrval (e, AT (automountInformation), keyval[1], + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_am_context_alloc(ldap_automount_context_t **pContext) +{ + ldap_automount_context_t *context; + + context = (ldap_automount_context_t *)malloc (sizeof(*context)); + if (context == NULL) + { + return NSS_TRYAGAIN; + } + + context->lac_state = NULL; + + context->lac_dn_size = 1; /* number of slots allocated */ + context->lac_dn_count = 0; /* number of slots used */ + context->lac_dn_index = 0; /* enumeration index */ + + /* List of DNs, grown on demand */ + context->lac_dn_list = (char **)malloc (context->lac_dn_size * + sizeof(char *)); + if (context->lac_dn_list == NULL) + { + free (context); + return NSS_TRYAGAIN; + } + + if (_nss_ldap_ent_context_init_locked (&context->lac_state) == NULL) + { + free (context->lac_dn_list); + free (context); + return NSS_UNAVAIL; + } + + *pContext = context; + + return NSS_SUCCESS; +} + +void +_nss_ldap_am_context_free(ldap_automount_context_t **pContext) +{ + ldap_automount_context_t *context; + size_t i; + + context = *pContext; + + if (context == NULL) + return; + + if (context->lac_dn_list != NULL) + { + for (i = 0; i < context->lac_dn_count; i++) + { +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (context->lac_dn_list[i]); +#else + free (context->lac_dn_list[i]); +#endif /* HAVE_LDAP_MEMFREE */ + } + free (context->lac_dn_list); + } + + if (context->lac_state != NULL) + { + _nss_ldap_ent_context_release (context->lac_state); + free (context->lac_state); + } + + memset (context, 0, sizeof (*context)); + free (context); + + *pContext = NULL; + + return; +} + +static NSS_STATUS +am_context_add_dn (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + ldap_automount_context_t *context = (ldap_automount_context_t *) result; + char *dn; + + dn = _nss_ldap_get_dn (e); + if (dn == NULL) + { + return NSS_NOTFOUND; + } + + if (context->lac_dn_count >= context->lac_dn_size) + { + char **new_dns; + + new_dns = (char **)realloc(context->lac_dn_list, + 2 * context->lac_dn_size * sizeof(char *)); + if (new_dns == NULL) + { +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (dn); +#else + free (dn); +#endif /* HAVE_LDAP_MEMFREE */ + return NSS_TRYAGAIN; + } + + context->lac_dn_list = new_dns; + context->lac_dn_size *= 2; + } + + context->lac_dn_list[context->lac_dn_count++] = dn; + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_am_context_init(const char *mapname, ldap_automount_context_t **pContext) +{ + NSS_STATUS stat; + ldap_automount_context_t *context = NULL; + const char *no_attrs[] = { NULL }; + ldap_args_t a; + ent_context_t *key = NULL; + int errnop; + + *pContext = NULL; + + stat = _nss_ldap_am_context_alloc (&context); + if (stat != NSS_SUCCESS) + return stat; + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + LA_STRING (a) = mapname; + + do + { + stat = _nss_ldap_getent_ex (&a, &key, + (void *)context, + NULL, 0, &errnop, + _nss_ldap_filt_setautomntent, + LM_AUTOMOUNT, + no_attrs, + am_context_add_dn); + } + while (stat == NSS_SUCCESS); + + if (key != NULL) + { + _nss_ldap_ent_context_release (key); + free (key); + } + + if (context->lac_dn_count == 0) + { + _nss_ldap_am_context_free (&context); + return NSS_NOTFOUND; + } + else if (stat == NSS_NOTFOUND) + { + stat = NSS_SUCCESS; + } + + context->lac_dn_index = 0; + + *pContext = context; + return NSS_SUCCESS; +} + +#ifdef HAVE_NSS_H +NSS_STATUS _nss_ldap_setautomntent(const char *mapname, void **private) +{ + ldap_automount_context_t *context = NULL; + NSS_STATUS stat; + + debug ("==> _nss_ldap_setautomntent"); + + _nss_ldap_enter (); + + stat = _nss_ldap_init (); + if (stat != NSS_SUCCESS) + { + _nss_ldap_leave (); + debug ("<== _nss_ldap_setautomntent"); + return stat; + } + + stat = _nss_ldap_am_context_init (mapname, &context); + if (stat != NSS_SUCCESS) + { + _nss_ldap_leave (); + debug ("<== _nss_ldap_setautomntent"); + return stat; + } + + *private = (void *)context; + _nss_ldap_leave (); + + debug ("<== _nss_ldap_setautomntent"); + + return stat; +} + +NSS_STATUS _nss_ldap_getautomntent_r(void *private, const char **key, const char **value, + char *buffer, size_t buflen, int *errnop) +{ + NSS_STATUS stat; + ldap_automount_context_t *context = (ldap_automount_context_t *)private; + ldap_args_t a; + char **keyval[2]; + + if (context == NULL) + return NSS_NOTFOUND; + + debug ("==> _nss_ldap_getautomntent_r"); + + keyval[0] = (char **)key; + keyval[1] = (char **)value; + + _nss_ldap_enter (); + + do + { + assert (context->lac_dn_index < context->lac_dn_count); + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_NONE; + LA_BASE (a) = context->lac_dn_list[context->lac_dn_index]; + + stat = _nss_ldap_getent_ex (&a, &context->lac_state, + (void *)keyval, + buffer, buflen, errnop, + _nss_ldap_filt_getautomntent, + LM_AUTOMOUNT, + NULL, + _nss_ldap_parse_automount); + if (stat == NSS_NOTFOUND) + { + if (context->lac_dn_index < context->lac_dn_count - 1) + context->lac_dn_index++; + else + break; /* move along, nothing more to see here */ + } + } + while (stat == NSS_NOTFOUND); + + _nss_ldap_leave (); + + debug ("<== _nss_ldap_getautomntent_r"); + + return stat; +} + +NSS_STATUS _nss_ldap_endautomntent(void **private) +{ + ldap_automount_context_t **pContext = (ldap_automount_context_t **)private; + + debug ("==> _nss_ldap_endautomntent"); + + _nss_ldap_enter (); + _nss_ldap_am_context_free (pContext); + /* workaround because Linux automounter spawns a lot of processes */ + _nss_ldap_close (); + _nss_ldap_leave (); + + debug ("<== _nss_ldap_endautomntent"); + + return NSS_SUCCESS; +} + +NSS_STATUS _nss_ldap_getautomntbyname_r(void *private, const char *key, + const char **canon_key, const char **value, + char *buffer, size_t buflen, int *errnop) +{ + NSS_STATUS stat = NSS_NOTFOUND; + ldap_automount_context_t *context = (ldap_automount_context_t *)private; + ldap_args_t a; + char **keyval[2]; + size_t i; + + if (context == NULL) + return NSS_NOTFOUND; + + debug ("==> _nss_ldap_getautomntbyname_r"); + + keyval[0] = (char **)canon_key; + keyval[1] = (char **)value; + + for (i = 0; i < context->lac_dn_count; i++) + { + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + LA_STRING (a) = key; + LA_BASE (a) = context->lac_dn_list[i]; + + /* we do not acquire lock in this case */ + stat = _nss_ldap_getbyname (&a, + (void *)keyval, + buffer, buflen, errnop, + _nss_ldap_filt_getautomntbyname, + LM_AUTOMOUNT, + _nss_ldap_parse_automount); + + if (stat != NSS_NOTFOUND) + { + break; /* on success or error other than not found */ + } + } + + debug ("<== _nss_ldap_getautomntbyname_r"); + + return stat; +} + +#endif /* HAVE_NSS_H */ + diff --git a/ldap-automount.h b/ldap-automount.h new file mode 100644 index 0000000..de5dc68 --- /dev/null +++ b/ldap-automount.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 2005. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-automount.h,v 1.5 2006/01/12 10:19:20 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_AUTOMOUNT_H +#define _LDAP_NSS_LDAP_LDAP_AUTOMOUNT_H + +/* Linux only for now */ +struct ldap_automount_context { + /* Enumeration state */ + ent_context_t *lac_state; + + /* DNs of containers representing automount map */ + char **lac_dn_list; + size_t lac_dn_size; + size_t lac_dn_count; + size_t lac_dn_index; +}; + +typedef struct ldap_automount_context ldap_automount_context_t; + +NSS_STATUS _nss_ldap_am_context_alloc(ldap_automount_context_t **pContext); +void _nss_ldap_am_context_free(ldap_automount_context_t **pContext); +NSS_STATUS _nss_ldap_am_context_init(const char *mapname, ldap_automount_context_t **pContext); + +#ifdef HAVE_NSS_H +NSS_STATUS _nss_ldap_setautomntent(const char *mapname, void **context); +NSS_STATUS _nss_ldap_getautomntent(void *context, const char **key, const char **value, + char *buffer, size_t buflen, int *errnop); +NSS_STATUS _nss_ldap_endautomntent(void **context); +NSS_STATUS _nss_ldap_getautomntbyname_r(void *private, const char *key, + const char **canon_key, const char **value, + char *buffer, size_t buflen, int *errnop); +#endif /* HAVE_NSS_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_AUTOMOUNT_H */ diff --git a/ldap-bp.c b/ldap-bp.c new file mode 100644 index 0000000..fa881f5 --- /dev/null +++ b/ldap-bp.c @@ -0,0 +1,136 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-bp.c,v 2.27 2006/01/11 18:03:48 lukeh Exp $ + */ + + +static char rcsId[] = "$Id: ldap-bp.c,v 2.27 2006/01/11 18:03:48 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-bp.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) + +#ifdef HAVE_NSS_H +static ent_context_t *bp_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_bp (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + struct bootparams *bp = (struct bootparams *) result; + NSS_STATUS stat; + + stat = + _nss_ldap_assign_attrval (e, ATM (LM_BOOTPARAMS, cn), &bp->bp_name, + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrvals (e, AT (bootParameter), NULL, + &bp->bp_params, &buffer, &buflen, NULL); + if (stat != NSS_SUCCESS) + return stat; + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getbootparamsbyname_r (nss_backend_t * be, void *args) +{ + LOOKUP_NAME (args, _nss_ldap_filt_getbootparamsbyname, LM_BOOTPARAMS, + _nss_ldap_parse_bp, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_bootparams_destr (nss_backend_t * bp_context, void *args) +{ + return _nss_ldap_default_destr (bp_context, args); +} + +static nss_backend_op_t bp_ops[] = { + _nss_ldap_bootparams_destr, + _nss_ldap_getbootparamsbyname_r +}; + +nss_backend_t * +_nss_ldap_bootparams_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + +/* + if (!(be = (nss_ldap_backend_t *)malloc(sizeof(*be)))) + return NULL; + + be->ops = bp_ops; + be->n_ops = sizeof(bp_ops) / sizeof(nss_backend_op_t); + + if (_nss_ldap_default_constr(be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *)be; + */ + + /* this is a noop until we figure it out properly */ + return NULL; +} + +#endif /* HAVE_NSSWITCH_H */ + +#endif /* !HAVE_IRS_H */ diff --git a/ldap-bp.h b/ldap-bp.h new file mode 100644 index 0000000..5989ae3 --- /dev/null +++ b/ldap-bp.h @@ -0,0 +1,57 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-bp.h,v 2.18 2005/05/20 05:30:40 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_BP_H +#define _LDAP_NSS_LDAP_LDAP_BP_H + +/* I'm guessing here. This is certainly wrong. */ +struct bootparams +{ + char *bp_name; + char **bp_params; +}; + + +static NSS_STATUS _nss_ldap_parse_bp (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); + +#ifdef HAVE_NSSWITCH_H + +/* + int parse_bootparams_entry(const char *bp_entry, + char **bp_uniquehostname, char **bp_sharedhostname, + char **bp_rootpath, char **bp_swappath, char **bp_dumppath, + char **bp_execpath, char **bp_kvmpath); + */ + +static NSS_STATUS _nss_ldap_getbootparamsbyname_r (nss_backend_t * be, + void *fakeargs); + +nss_backend_t *_nss_ldap_bootparams_constr (const char *db_name, + const char *src_name, + const char *cfg_args); + +#endif + +#endif /* _LDAP_NSS_LDAP_LDAP_BP_H */ diff --git a/ldap-ethers.c b/ldap-ethers.c new file mode 100644 index 0000000..5cd7b54 --- /dev/null +++ b/ldap-ethers.c @@ -0,0 +1,352 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-ethers.c,v 2.36 2006/01/11 18:03:48 lukeh Exp $ + */ + + +static char rcsId[] = + "$Id: ldap-ethers.c,v 2.36 2006/01/11 18:03:48 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#ifdef HAVE_NET_ROUTE_H +#include <net/route.h> +#endif +#include <net/if.h> +#include <netinet/in.h> + +#ifdef HAVE_NETINET_IF_ETHER_H +#include <netinet/if_ether.h> +#endif + +#ifdef HAVE_NETINET_ETHER_H +#include <netinet/ether.h> +#endif + +#include "ldap-nss.h" +#include "ldap-ethers.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifndef NSS_BUFLEN_ETHERS +/* for HP-UX */ +#define NSS_BUFLEN_ETHERS 1024 +#endif /* NSS_BUFLEN_ETHERS */ + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) + +#ifdef HAVE_NSSWITCH_H +#ifdef HAVE_ETHER_ATON +extern struct ether_addr *ether_aton (const char *s); +#else +static struct ether_addr *ether_aton (const char *s); +#endif /* HAVE_ETHER_ATON */ +#ifdef HAVE_ETHER_NTOA +extern char *ether_ntoa (const struct ether_addr *e); +#else +static char *ether_ntoa (const struct ether_addr *e); +#endif /* HAVE_ETHER_NTOA */ +#endif /* HAVE_NSSWITCH_H */ + +#ifdef HAVE_NSS_H +static ent_context_t *ether_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_ether (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + struct ether *ether = (struct ether *) result; + char *saddr; + NSS_STATUS stat; + struct ether_addr *addr; + + stat = _nss_ldap_assign_attrval (e, ATM (LM_ETHERS, cn), + ðer->e_name, &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = _nss_ldap_assign_attrval (e, AT (macAddress), &saddr, + &buffer, &buflen); + + if (stat != NSS_SUCCESS || ((addr = ether_aton (saddr)) == NULL)) + return NSS_NOTFOUND; + + memcpy (ðer->e_addr, addr, sizeof (*addr)); + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_gethostton_r (nss_backend_t * be, void *args) +{ + struct ether result; + ldap_args_t a; + char buffer[NSS_BUFLEN_ETHERS]; + NSS_STATUS status; + + LA_INIT (a); + LA_STRING (a) = NSS_ARGS (args)->key.name; + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + &result, + buffer, + sizeof (buffer), + &NSS_ARGS (args)->erange, + _nss_ldap_filt_gethostton, + LM_ETHERS, _nss_ldap_parse_ether); + + if (status == NSS_SUCCESS) + { + memcpy (NSS_ARGS (args)->buf.result, &result.e_addr, + sizeof (result.e_addr)); + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + } + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_gethostton_r (const char *name, struct ether * result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, + _nss_ldap_filt_gethostton, LM_ETHERS, _nss_ldap_parse_ether, + LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getntohost_r (nss_backend_t * be, void *args) +{ + struct ether result; + char *addr; + ldap_args_t a; + char buffer[NSS_BUFLEN_ETHERS]; + NSS_STATUS status; + + addr = ether_ntoa ((struct ether_addr *) (NSS_ARGS (args)->key.ether)); + + LA_INIT (a); + LA_STRING (a) = addr; + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + &result, + buffer, + sizeof (buffer), + &NSS_ARGS (args)->erange, + _nss_ldap_filt_getntohost, + LM_ETHERS, _nss_ldap_parse_ether); + + if (status == NSS_SUCCESS) + { + memcpy (NSS_ARGS (args)->buf.buffer, result.e_name, + strlen (result.e_name) + 1); + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result = + NSS_ARGS (args)->buf.buffer; + NSS_ARGS (args)->buf.buflen = strlen (result.e_name); + } + else + { + NSS_ARGS (args)->returnval = NULL; + } + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getntohost_r (struct ether_addr * addr, struct ether * result, + char *buffer, size_t buflen, int *errnop) +{ +/* The correct ether_ntoa call would have a struct ether instead of whatever + result->e_addr is */ + + LOOKUP_NAME (ether_ntoa ((struct ether_addr *) (&result->e_addr)), result, + buffer, buflen, errnop, _nss_ldap_filt_getntohost, LM_ETHERS, + _nss_ldap_parse_ether, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_setetherent_r (nss_backend_t * ether_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_setetherent (void) +#endif +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) +{ + LOOKUP_SETENT (ether_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_endetherent_r (nss_backend_t * ether_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_endetherent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_ENDENT (ether_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getetherent_r (nss_backend_t * ether_context, void *args) +{ + struct ether result; + NSS_STATUS status; + + status = _nss_ldap_getent (&((nss_ldap_backend_t *) ether_context)->state, + &result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + _nss_ldap_filt_getetherent, + LM_ETHERS, _nss_ldap_parse_ether); + + if (status == NSS_SUCCESS) + { + memcpy (NSS_ARGS (args)->buf.result, &result.e_addr, + sizeof (result.e_addr)); + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + } + else + { + NSS_ARGS (args)->returnval = NULL; + } + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getetherent_r (struct ether * result, char *buffer, size_t buflen, + int *errnop) +{ + LOOKUP_GETENT (ether_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getetherent, LM_ETHERS, + _nss_ldap_parse_ether, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_ethers_destr (nss_backend_t * ether_context, void *args) +{ + return _nss_ldap_default_destr (ether_context, args); +} + +static nss_backend_op_t ethers_ops[] = { + _nss_ldap_ethers_destr, + _nss_ldap_gethostton_r, + _nss_ldap_getntohost_r +}; + +nss_backend_t * +_nss_ldap_ethers_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = ethers_ops; + be->n_ops = sizeof (ethers_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; + +} + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_NSSWITCH_H + +#ifndef HAVE_ETHER_ATON +static struct ether_addr *ether_aton (const char *s) +{ + static struct ether_addr ep; + register int i; + unsigned int t[6]; + + i = sscanf(s, " %x:%x:%x:%x:%x:%x", + &t[0], &t[1], &t[2], &t[3], &t[4], &t[5]); + if (i != 6) + return NULL; + for (i = 0; i < 6; i++) + ep.ether_addr_octet[i] = t[i]; + + return &ep; +} +#endif /* !HAVE_ETHER_ATON */ + +#ifndef HAVE_ETHER_NTOA +#define EI(i) (unsigned int)(e->ether_addr_octet[(i)]) +static char *ether_ntoa (const struct ether_addr *e) +{ + static char s[18]; + + s[0] = 0; + sprintf(s, "%x:%x:%x:%x:%x:%x", + EI(0), EI(1), EI(2), EI(3), EI(4), EI(5)); + + return s; +} +#endif /* !HAVE_ETHER_NTOA */ + +#endif /* HAVE_NSSWITCH_H */ + +#endif /* !HAVE_IRS_H */ diff --git a/ldap-ethers.h b/ldap-ethers.h new file mode 100644 index 0000000..76e5c7a --- /dev/null +++ b/ldap-ethers.h @@ -0,0 +1,73 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-ethers.h,v 2.26 2005/05/20 05:30:40 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_ETHERS_H +#define _LDAP_NSS_LDAP_LDAP_ETHERS_H + +#ifdef HAVE_NETINET_IF_ETHER_H +#include <netinet/if_ether.h> +#endif +#ifdef HAVE_NETINET_ETHER_H +#include <netinet/ether.h> +#endif + +#ifndef HAVE_STRUCT_ETHER_ADDR +struct ether_addr { + u_char ether_addr_octet[6]; +}; +#endif + +struct ether +{ + char *e_name; + struct ether_addr e_addr; +}; + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) +static NSS_STATUS _nss_ldap_parse_ether (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_gethostton_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getntohost_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_ethers_constr (const char *db_name, + const char *src_name, + const char *cfg_args); + +#elif defined(HAVE_NSS_H) +/* for the record */ +NSS_STATUS _nss_ldap_gethostton_r (const char *name, struct ether *eth, + char *buffer, size_t buflen, int *errnop); +NSS_STATUS _nss_ldap_getntohost_r (struct ether_addr *addr, struct ether *eth, + char *buffer, size_t buflen, int *errnop); +NSS_STATUS _nss_ldap_endetherent (void); +NSS_STATUS _nss_ldap_setetherent (void); +NSS_STATUS _nss_ldap_getetherent_r (struct ether *result, char *buffer, + size_t buflen, int *errnop); +#endif + + +#endif /* _LDAP_NSS_LDAP_LDAP_ETHERS_H */ diff --git a/ldap-grp.c b/ldap-grp.c new file mode 100644 index 0000000..dfeb568 --- /dev/null +++ b/ldap-grp.c @@ -0,0 +1,1297 @@ +/* Copyright (C) 1997-2006 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +static char rcsId[] = + "$Id: ldap-grp.c,v 2.105 2006/03/22 13:18:56 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/param.h> +#include <grp.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif + +#include "ldap-nss.h" +#include "ldap-grp.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *gr_context = NULL; +#endif + +#ifdef HAVE_USERSEC_H +typedef struct ldap_initgroups_args +{ + char *grplist; + size_t listlen; + int depth; + struct name_list *known_groups; + int backlink; +} +ldap_initgroups_args_t; +#else +# ifdef HAVE_NSSWITCH_H +typedef struct ldap_initgroups_args +{ + struct nss_groupsbymem *gbm; + int depth; + struct name_list *known_groups; + int backlink; +} +ldap_initgroups_args_t; +# else +typedef struct ldap_initgroups_args +{ + gid_t group; + long int *start; + long int *size; + gid_t **groups; + long int limit; + int depth; + struct name_list *known_groups; + int backlink; +} +ldap_initgroups_args_t; +# endif +#endif /* HAVE_USERSEC_H */ + +static NSS_STATUS +ng_chase (const char *dn, ldap_initgroups_args_t * lia); + +static NSS_STATUS +ng_chase_backlink (const char ** membersOf, ldap_initgroups_args_t * lia); + +/* + * Range retrieval logic was reimplemented from example in + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/searching_using_range_retrieval.asp + */ + +static NSS_STATUS +do_parse_range (const char *attributeType, + const char *attributeDescription, int *start, int *end) +{ + NSS_STATUS stat = NSS_NOTFOUND; + char *attribute; + size_t attributeTypeLength; + size_t attributeDescriptionLength; + char *p; +#ifdef HAVE_STRTOK_R + char *st = NULL; +#endif + + *start = 0; + *end = -1; + + if (strcasecmp (attributeType, attributeDescription) == 0) + { + return NSS_SUCCESS; + } + + attributeDescriptionLength = strlen (attributeDescription); + attributeTypeLength = strlen (attributeType); + + if (attributeDescriptionLength < attributeTypeLength) + { + /* could not be a subtype */ + return NSS_NOTFOUND; + } + + /* XXX need to copy as strtok() is destructive */ + attribute = strdup (attributeDescription); + if (attribute == NULL) + { + return NSS_TRYAGAIN; + } + +#ifndef HAVE_STRTOK_R + for (p = strtok (attribute, ";"); p != NULL; p = strtok (NULL, ";")) +#else + for (p = strtok_r (attribute, ";", &st); + p != NULL; p = strtok_r (NULL, ";", &st)) +#endif /* !HAVE_STRTOK_R */ + { + char *q; + + if (p == attribute) + { + if (strcasecmp (p, attributeType) != 0) + { + free (attribute); + return NSS_NOTFOUND; + } + } + else if (strncasecmp (p, "range=", sizeof ("range=") - 1) == 0) + { + p += sizeof ("range=") - 1; + + q = strchr (p, '-'); + if (q == NULL) + { + free (attribute); + return NSS_NOTFOUND; + } + + *q++ = '\0'; + + *start = strtoul (p, (char **) NULL, 10); + if (strcmp (q, "*") == 0) + *end = -1; + else + *end = strtoul (q, (char **) NULL, 10); + + stat = NSS_SUCCESS; + break; + } + } + + free (attribute); + return stat; +} + +static NSS_STATUS +do_get_range_values (LDAPMessage * e, + const char *attributeType, + int *start, int *end, char ***pGroupMembers) +{ + NSS_STATUS stat = NSS_NOTFOUND; + BerElement *ber = NULL; + char *attribute; + + *pGroupMembers = NULL; + + for (attribute = _nss_ldap_first_attribute (e, &ber); + attribute != NULL; attribute = _nss_ldap_next_attribute (e, ber)) + { + stat = do_parse_range (attributeType, attribute, start, end); + if (stat == NSS_SUCCESS) + { + *pGroupMembers = _nss_ldap_get_values (e, attribute); + if (*pGroupMembers == NULL) + { + stat = NSS_NOTFOUND; + } + else if ((*pGroupMembers)[0] == NULL) + { + ldap_value_free (*pGroupMembers); + *pGroupMembers = NULL; + stat = NSS_NOTFOUND; + } + } + +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (attribute); +#endif + + if (stat == NSS_SUCCESS) + break; + } + + if (ber != NULL) + ber_free (ber, 0); + + return stat; +} + +/* + * Format an attribute with description as: + * attribute;range=START-END + */ +static NSS_STATUS +do_construct_range_attribute (const char *attribute, + int start, + int end, + char **buffer, + size_t * buflen, + const char **pAttributeWithRange) +{ + size_t len; + char startbuf[32], endbuf[32]; + + snprintf (startbuf, sizeof (startbuf), "%u", start); + + if (end != -1) + snprintf (endbuf, sizeof (endbuf), "%u", end); + else + snprintf (endbuf, sizeof (endbuf), "*"); + + len = strlen (attribute) + sizeof (";range=") - 1; + len += strlen (startbuf) + 1 /* - */ + strlen (endbuf); + len++; /* \0 */ + + if (*buflen < len) + return NSS_TRYAGAIN; + + *pAttributeWithRange = *buffer; + + snprintf (*buffer, len, "%s;range=%s-%s", attribute, startbuf, endbuf); + + *buffer += len; + *buflen -= len; + + return NSS_SUCCESS; +} + +/* + * Expand group members, including nested groups + */ +static NSS_STATUS +do_parse_group_members (LDAPMessage * e, + char ***pGroupMembers, + size_t * pGroupMembersCount, + size_t * pGroupMembersBufferSize, + int *pGroupMembersBufferIsMalloced, + char **buffer, size_t * buflen, + int *depth, + struct name_list **pKnownGroups) /* traversed groups */ +{ + NSS_STATUS stat = NSS_SUCCESS; + char **dnValues = NULL; + char **uidValues = NULL; + char **groupMembers; + size_t groupMembersCount, i; + char **valiter; + /* support for range retrieval */ + const char *uniquemember_attr; + const char *uniquemember_attrs[2]; + LDAPMessage *res = NULL; + int start, end = 0; + char *groupdn = NULL; + + uniquemember_attr = ATM (LM_GROUP, uniqueMember); + + uniquemember_attrs[0] = uniquemember_attr; + uniquemember_attrs[1] = NULL; + + if (*depth > LDAP_NSS_MAXGR_DEPTH) + { + return NSS_NOTFOUND; + } + + i = *pGroupMembersCount; /* index of next member */ + groupMembers = *pGroupMembers; + + groupdn = _nss_ldap_get_dn (e); + if (groupdn == NULL) + { + stat = NSS_NOTFOUND; + goto out; + } + + if (_nss_ldap_namelist_find (*pKnownGroups, groupdn)) + { + stat = NSS_NOTFOUND; + goto out; + } + + /* store group DN for nested group loop detection */ + stat = _nss_ldap_namelist_push (pKnownGroups, groupdn); + if (stat != NSS_SUCCESS) + { + goto out; + } + + do + { + if (e == NULL) + { + stat = NSS_NOTFOUND; + goto out; + } + + groupMembersCount = 0; /* number of members in this group */ + + (void) do_get_range_values (e, uniquemember_attrs[0], &start, &end, &dnValues); + if (dnValues != NULL) + { + groupMembersCount += ldap_count_values (dnValues); + } + + uidValues = _nss_ldap_get_values (e, ATM (LM_GROUP, memberUid)); + if (uidValues != NULL) + { + groupMembersCount += ldap_count_values (uidValues); + } + + /* + * Check whether we need to increase the group membership buffer. + * As an optimization the buffer is preferentially allocated off + * the stack + */ + if ((i + groupMembersCount) * sizeof (char *) >= + *pGroupMembersBufferSize) + { + *pGroupMembersBufferSize = + (i + groupMembersCount + 1) * sizeof (char *); + *pGroupMembersBufferSize += + (LDAP_NSS_NGROUPS * sizeof (char *)) - 1; + *pGroupMembersBufferSize -= + (*pGroupMembersBufferSize % + (LDAP_NSS_NGROUPS * sizeof (char *))); + + if (*pGroupMembersBufferIsMalloced == 0) + { + groupMembers = *pGroupMembers; + *pGroupMembers = NULL; /* force malloc() */ + } + + *pGroupMembers = + (char **) realloc (*pGroupMembers, *pGroupMembersBufferSize); + if (*pGroupMembers == NULL) + { + *pGroupMembersBufferIsMalloced = 0; /* don't try to free */ + stat = NSS_TRYAGAIN; + goto out; + } + + if (*pGroupMembersBufferIsMalloced == 0) + { + memcpy (*pGroupMembers, groupMembers, i * sizeof (char *)); + groupMembers = NULL; /* defensive programming */ + *pGroupMembersBufferIsMalloced = 1; + } + } + + groupMembers = *pGroupMembers; + + /* Parse distinguished name members */ + if (dnValues != NULL) + { + for (valiter = dnValues; *valiter != NULL; valiter++) + { + LDAPMessage *res; + NSS_STATUS parseStat; + int isNestedGroup = 0; + char *uid; + + uid = strrchr (*valiter, '#'); + if (uid != NULL) + { + *uid = '\0'; + } + + parseStat = _nss_ldap_dn2uid (*valiter, &groupMembers[i], + buffer, buflen, &isNestedGroup, + &res); + if (parseStat == NSS_SUCCESS) + { + if (isNestedGroup == 0) + { + /* just a normal user which we have flattened */ + i++; + continue; + } + + (*depth)++; + parseStat = + do_parse_group_members (_nss_ldap_first_entry (res), + &groupMembers, &i, + pGroupMembersBufferSize, + pGroupMembersBufferIsMalloced, + buffer, buflen, depth, + pKnownGroups); + (*depth)--; + + if (parseStat == NSS_TRYAGAIN) + { + stat = NSS_TRYAGAIN; + goto out; + } + + ldap_msgfree (res); + } + else if (parseStat == NSS_TRYAGAIN) + { + stat = NSS_TRYAGAIN; + goto out; + } + } + } + + /* Parse RFC 2307 (flat) members */ + if (uidValues != NULL) + { + for (valiter = uidValues; *valiter != NULL; valiter++) + { + size_t len = strlen (*valiter) + 1; + if (*buflen < len) + { + stat = NSS_TRYAGAIN; + goto out; + } + groupMembers[i] = *buffer; + *buffer += len; + *buflen -= len; + + memcpy (groupMembers[i++], *valiter, len); + } + } + + /* Get next range for Active Directory compat */ + if (end != -1) + { + stat = do_construct_range_attribute (uniquemember_attr, + end + 1, + -1, + buffer, + buflen, + &uniquemember_attrs[0]); + if (stat == NSS_SUCCESS) + { + if (dnValues != NULL) + { + ldap_value_free (dnValues); + dnValues = NULL; + } + if (uidValues != NULL) + { + ldap_value_free (uidValues); + uidValues = NULL; + } + if (res != NULL) + { + ldap_msgfree (res); + res = NULL; + } + + stat = _nss_ldap_read (groupdn, uniquemember_attrs, &res); + if (stat != NSS_SUCCESS) + goto out; + + e = _nss_ldap_first_entry (res); + } + } + } + while (end != -1); + +out: + if (dnValues != NULL) + ldap_value_free (dnValues); + if (uidValues != NULL) + ldap_value_free (uidValues); + if (res != NULL) + ldap_msgfree (res); + if (groupdn != NULL) +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (groupdn); +#else + free (groupdn); +#endif + + *pGroupMembers = groupMembers; + *pGroupMembersCount = i; + + return stat; +} + +/* + * "Fix" group membership list into caller provided buffer, + * and NULL terminate. +*/ +static NSS_STATUS +do_fix_group_members_buffer (char **mallocedGroupMembers, + size_t groupMembersCount, + char ***pGroupMembers, + char **buffer, size_t * buflen) +{ + size_t len; + + len = (groupMembersCount + 1) * sizeof (char *); + + if (bytesleft (*buffer, *buflen, char *) < len) + { + return NSS_TRYAGAIN; + } + + align (*buffer, *buflen, char *); + *pGroupMembers = (char **) *buffer; + *buffer += len; + *buflen -= len; + + memcpy (*pGroupMembers, mallocedGroupMembers, + groupMembersCount * sizeof (char *)); + (*pGroupMembers)[groupMembersCount] = NULL; + + return NSS_SUCCESS; +} + +static NSS_STATUS +_nss_ldap_parse_gr (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + struct group *gr = (struct group *) result; + char *gid; + NSS_STATUS stat; + char **groupMembers; + size_t groupMembersCount; + size_t groupMembersBufferSize; + char *groupMembersBuffer[LDAP_NSS_NGROUPS]; + int groupMembersBufferIsMalloced; + int depth; + struct name_list *knownGroups = NULL; + + stat = + _nss_ldap_assign_attrval (e, ATM (LM_GROUP, gidNumber), &gid, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + + gr->gr_gid = + (*gid == '\0') ? (unsigned) GID_NOBODY : (gid_t) strtoul (gid, + (char **) NULL, + 10); + + stat = + _nss_ldap_getrdnvalue (e, ATM (LM_GROUP, cn), &gr->gr_name, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_userpassword (e, ATM (LM_GROUP, userPassword), + &gr->gr_passwd, &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) + { + groupMembers = groupMembersBuffer; + groupMembersCount = 0; + groupMembersBufferSize = sizeof (groupMembers); + groupMembersBufferIsMalloced = 0; + depth = 0; + + stat = do_parse_group_members (e, &groupMembers, &groupMembersCount, + &groupMembersBufferSize, + &groupMembersBufferIsMalloced, &buffer, + &buflen, &depth, &knownGroups); + if (stat != NSS_SUCCESS) + { + if (groupMembersBufferIsMalloced) + free (groupMembers); + _nss_ldap_namelist_destroy (&knownGroups); + return stat; + } + + stat = do_fix_group_members_buffer (groupMembers, groupMembersCount, + &gr->gr_mem, &buffer, &buflen); + + if (groupMembersBufferIsMalloced) + free (groupMembers); + _nss_ldap_namelist_destroy (&knownGroups); + } + else + { + stat = + _nss_ldap_assign_attrvals (e, ATM (LM_GROUP, memberUid), NULL, + &gr->gr_mem, &buffer, &buflen, NULL); + } + + return stat; +} + +/* + * Add a group ID to a group list, and optionally the group IDs + * of any groups to which this group belongs (RFC2307bis nested + * group expansion is done by do_parse_initgroups_nested()). + */ +static NSS_STATUS +do_parse_initgroups (LDAPMessage * e, + ldap_state_t * pvt, void *result, + char *buffer, size_t buflen) +{ + char **values; + ssize_t i; + gid_t gid; + ldap_initgroups_args_t *lia = (ldap_initgroups_args_t *) result; + + values = _nss_ldap_get_values (e, ATM (LM_GROUP, gidNumber)); + if (values == NULL) + { + /* invalid group; skip it */ + return NSS_NOTFOUND; + } + + if (values[0] == NULL) + { + /* invalid group; skip it */ + ldap_value_free (values); + return NSS_NOTFOUND; + } + +#ifdef HAVE_USERSEC_H + i = strlen (values[0]); + lia->grplist = realloc (lia->grplist, lia->listlen + i + 2); + if (lia->grplist == NULL) + { + ldap_value_free (values); + return NSS_TRYAGAIN; + } + memcpy (lia->grplist + lia->listlen, values[0], i); + lia->grplist[lia->listlen + i] = ','; + lia->listlen += i + 1; + ldap_value_free (values); +#else + gid = strtoul (values[0], (char **) NULL, 10); + ldap_value_free (values); + + if (gid == LONG_MAX && errno == ERANGE) + { + /* invalid group, skip it */ + return NSS_NOTFOUND; + } + +# ifdef HAVE_NSSWITCH_H + /* weed out duplicates; is this really our resposibility? */ + for (i = 0; i < lia->gbm->numgids; i++) + { + if (lia->gbm->gid_array[i] == (gid_t) gid) + return NSS_NOTFOUND; + } + + if (lia->gbm->numgids == lia->gbm->maxgids) + { + /* can't fit any more */ + /* + * should probably return NSS_TRYAGAIN but IIRC + * will send Solaris into an infinite loop XXX + */ + return NSS_SUCCESS; + } + + lia->gbm->gid_array[lia->gbm->numgids++] = (gid_t) gid; +# else + if (gid == lia->group) + { + /* primary group, so skip it */ + return NSS_NOTFOUND; + } + + if (lia->limit > 0) + { + if (*(lia->start) >= lia->limit) + { + /* can't fit any more */ + return NSS_TRYAGAIN; + } + } + if (*(lia->start) == *(lia->size)) + { + /* Need a bigger buffer */ + *(lia->groups) = (gid_t *) realloc (*(lia->groups), + 2 * *(lia->size) * sizeof (gid_t)); + if (*(lia->groups) == NULL) + { + return NSS_TRYAGAIN; + } + *(lia->size) *= 2; + } + + /* weed out duplicates; is this really our responsibility? */ + for (i = 0; i < *(lia->start); i++) + { + if ((*(lia->groups))[i] == gid) + { + return NSS_NOTFOUND; + } + } + + /* add to group list */ + (*(lia->groups))[*(lia->start)] = gid; + (*(lia->start)) += 1; +# endif /* HAVE_NSSWITCH_H */ +#endif /* HAVE_USERSEC_H */ + + return NSS_NOTFOUND; +} + +static NSS_STATUS +do_parse_initgroups_nested (LDAPMessage * e, + ldap_state_t * pvt, void *result, + char *buffer, size_t buflen) +{ + NSS_STATUS stat; + ldap_initgroups_args_t *lia = (ldap_initgroups_args_t *) result; + char **values; + char *groupdn; + + stat = do_parse_initgroups (e, pvt, result, buffer, buflen); + if (stat != NSS_NOTFOUND) + { + return stat; + } + + if (!_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) + { + return NSS_NOTFOUND; + } + + if (lia->backlink != 0) + { + /* + * Now add the GIDs of any groups of which this group is + * a member. + */ + values = _nss_ldap_get_values (e, ATM (LM_GROUP, memberOf)); + if (values != NULL) + { + NSS_STATUS stat; + + lia->depth++; + stat = ng_chase_backlink ((const char **)values, lia); + lia->depth--; + + ldap_value_free (values); + + return stat; + } + } + else + { + /* + * Now add the GIDs of any groups which refer to this group + */ + groupdn = _nss_ldap_get_dn (e); + if (groupdn != NULL) + { + NSS_STATUS stat; + + lia->depth++; + stat = ng_chase (groupdn, lia); + lia->depth--; +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (groupdn); +#else + free (groupdn); +#endif + } + } + + return stat; +} + +static NSS_STATUS +ng_chase (const char *dn, ldap_initgroups_args_t * lia) +{ + ldap_args_t a; + NSS_STATUS stat; + ent_context_t *ctx = NULL; + const char *gidnumber_attrs[2]; + int erange; + + if (lia->depth > LDAP_NSS_MAXGR_DEPTH) + return NSS_NOTFOUND; + + if (_nss_ldap_namelist_find (lia->known_groups, dn)) + return NSS_NOTFOUND; + + gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); + gidnumber_attrs[1] = NULL; + + LA_INIT (a); + LA_STRING (a) = dn; + LA_TYPE (a) = LA_TYPE_STRING; + + if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) + { + return NSS_UNAVAIL; + } + + stat = _nss_ldap_getent_ex (&a, &ctx, lia, NULL, 0, + &erange, _nss_ldap_filt_getgroupsbydn, + LM_GROUP, gidnumber_attrs, + do_parse_initgroups_nested); + + if (stat == NSS_SUCCESS) + { + stat = _nss_ldap_namelist_push (&lia->known_groups, dn); + } + + _nss_ldap_ent_context_release (ctx); + free (ctx); + + return stat; +} + +static NSS_STATUS +ng_chase_backlink (const char ** membersOf, ldap_initgroups_args_t * lia) +{ + ldap_args_t a; + NSS_STATUS stat; + ent_context_t *ctx = NULL; + const char *gidnumber_attrs[3]; + const char **memberP; + const char **filteredMembersOf; /* remove already traversed groups */ + size_t memberCount, i; + int erange; + + if (lia->depth > LDAP_NSS_MAXGR_DEPTH) + return NSS_NOTFOUND; + + for (memberCount = 0; membersOf[memberCount] != NULL; memberCount++) + ; + + /* Build a list of membersOf values without any already traversed groups */ + filteredMembersOf = (const char **) malloc(sizeof(char *) * (memberCount + 1)); + if (filteredMembersOf == NULL) + { + return NSS_TRYAGAIN; + } + + memberP = filteredMembersOf; + + for (i = 0; i < memberCount; i++) + { + if (_nss_ldap_namelist_find (lia->known_groups, membersOf[i])) + continue; + + *memberP = membersOf[i]; + memberP++; + } + + *memberP = NULL; + + if (filteredMembersOf[0] == NULL) + { + free (filteredMembersOf); + return NSS_NOTFOUND; + } + + gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); + gidnumber_attrs[1] = ATM (LM_GROUP, memberOf); + gidnumber_attrs[2] = NULL; + + LA_INIT (a); + LA_STRING_LIST (a) = filteredMembersOf; + LA_TYPE (a) = LA_TYPE_STRING_LIST_OR; + + if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) + { + free (filteredMembersOf); + return NSS_UNAVAIL; + } + + stat = _nss_ldap_getent_ex (&a, &ctx, lia, NULL, 0, + &erange, "(distinguishedName=%s)", + LM_GROUP, gidnumber_attrs, + do_parse_initgroups_nested); + + if (stat == NSS_SUCCESS) + { + NSS_STATUS stat2; + + for (memberP = filteredMembersOf; *memberP != NULL; memberP++) + { + stat2 = _nss_ldap_namelist_push (&lia->known_groups, *memberP); + if (stat2 != NSS_SUCCESS) + { + stat = stat2; + break; + } + } + } + + free (filteredMembersOf); + + _nss_ldap_ent_context_release (ctx); + free (ctx); + + return stat; +} + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) || defined(HAVE_USERSEC_H) +#ifdef HAVE_NSS_H +NSS_STATUS _nss_ldap_initgroups_dyn (const char *user, gid_t group, + long int *start, long int *size, + gid_t ** groupsp, long int limit, + int *errnop); + +NSS_STATUS +_nss_ldap_initgroups (const char *user, gid_t group, long int *start, + long int *size, gid_t * groups, long int limit, + int *errnop) +{ + return (_nss_ldap_initgroups_dyn (user, group, start, size, &groups, limit, + errnop)); +} +#endif + +#ifdef HAVE_NSSWITCH_H +#define NSS_LDAP_INITGROUPS_FUNCTION "_nss_ldap_getgroupsbymember_r" +#elif defined(HAVE_NSS_H) +#define NSS_LDAP_INITGROUPS_FUNCTION "_nss_ldap_initgroups_dyn" +#elif defined(HAVE_USERSEC_H) +#define NSS_LDAP_INITGROUPS_FUNCTION "_nss_ldap_getgrset" +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getgroupsbymember_r (nss_backend_t * be, void *args) +#elif defined(HAVE_NSS_H) + NSS_STATUS +_nss_ldap_initgroups_dyn (const char *user, gid_t group, long int *start, + long int *size, gid_t ** groupsp, long int limit, + int *errnop) +#elif defined(HAVE_USERSEC_H) +char *_nss_ldap_getgrset (char *user) +#endif +{ + ldap_initgroups_args_t lia; +#ifndef HAVE_NSS_H + int erange = 0; +#endif /* HAVE_NSS_H */ + char *userdn = NULL; + LDAPMessage *res, *e; + static const char *no_attrs[] = { NULL }; + const char *filter; + ldap_args_t a; + NSS_STATUS stat; + ent_context_t *ctx = NULL; + const char *gidnumber_attrs[3]; + ldap_map_selector_t map = LM_GROUP; + + LA_INIT (a); +#if defined(HAVE_NSS_H) || defined(HAVE_USERSEC_H) + LA_STRING (a) = user; +#else + LA_STRING (a) = ((struct nss_groupsbymem *) args)->username; +#endif /* HAVE_NSS_H || HAVE_USERSEC_H */ + LA_TYPE (a) = LA_TYPE_STRING; + + debug ("==> " NSS_LDAP_INITGROUPS_FUNCTION " (user=%s)", LA_STRING (a) ); + +#ifdef INITGROUPS_ROOT_ONLY + /* XXX performance hack for old versions of KDE only */ + if ((getuid() != 0) && (geteuid() != 0)) + return NSS_NOTFOUND; +#endif + +#ifdef HAVE_USERSEC_H + lia.grplist = NULL; + lia.listlen = 0; +#elif defined(HAVE_NSSWITCH_H) + lia.gbm = (struct nss_groupsbymem *) args; +#else + lia.group = group; + lia.start = start; + lia.size = size; + lia.groups = groupsp; + lia.limit = limit; +#endif /* HAVE_USERSEC_H */ + lia.depth = 0; + lia.known_groups = NULL; + + _nss_ldap_enter (); + + /* initialize schema */ + stat = _nss_ldap_init (); + if (stat != NSS_SUCCESS) + { + debug ("<== " NSS_LDAP_INITGROUPS_FUNCTION " (init failed)"); + _nss_ldap_leave (); +# ifdef HAVE_USERSEC_H + return NULL; +# else + return stat; +# endif /* !HAVE_USERSEC_H */ + } + + if (_nss_ldap_test_initgroups_ignoreuser (LA_STRING (a))) + { + debug ("<== " NSS_LDAP_INITGROUPS_FUNCTION " (user ignored)"); + _nss_ldap_leave (); + return NSS_NOTFOUND; + } + + lia.backlink = _nss_ldap_test_config_flag (NSS_LDAP_FLAGS_INITGROUPS_BACKLINK); + + if (lia.backlink != 0) + { + filter = _nss_ldap_filt_getpwnam_groupsbymember; + LA_STRING2 (a) = LA_STRING (a); + LA_TYPE (a) = LA_TYPE_STRING_AND_STRING; + + gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); + gidnumber_attrs[1] = ATM (LM_GROUP, memberOf); + gidnumber_attrs[2] = NULL; + + map = LM_PASSWD; + } + else + { + if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) + { + /* lookup the user's DN. */ + stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getpwnam, LM_PASSWD, + no_attrs, 1, &res); + if (stat == NSS_SUCCESS) + { + e = _nss_ldap_first_entry (res); + if (e != NULL) + { + userdn = _nss_ldap_get_dn (e); + } + ldap_msgfree (res); + } + } + else + { + userdn = NULL; + } + + if (userdn != NULL) + { + LA_STRING2 (a) = userdn; + LA_TYPE (a) = LA_TYPE_STRING_AND_STRING; + filter = _nss_ldap_filt_getgroupsbymemberanddn; + } + else + { + filter = _nss_ldap_filt_getgroupsbymember; + } + + gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); + gidnumber_attrs[1] = NULL; + } + + if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) + { + debug ("<== " NSS_LDAP_INITGROUPS_FUNCTION " (ent_context_init failed)"); + _nss_ldap_leave (); +# ifdef HAVE_USERSEC_H + return NULL; +# else + return NSS_UNAVAIL; +# endif /* HAVE_USERSEC_H */ + } + + stat = _nss_ldap_getent_ex (&a, &ctx, (void *) &lia, NULL, 0, +#ifdef HAVE_NSS_H + errnop, +#else + &erange, +#endif /* HAVE_NSS_H */ + filter, + map, + gidnumber_attrs, + do_parse_initgroups_nested); + + if (userdn != NULL) + { +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (userdn); +#else + free (userdn); +#endif /* HAVE_LDAP_MEMFREE */ + } + + _nss_ldap_namelist_destroy (&lia.known_groups); + _nss_ldap_ent_context_release (ctx); + free (ctx); + _nss_ldap_leave (); + + /* + * We return NSS_NOTFOUND to force the parser to be called + * for as many entries (i.e. groups) as exist, for all + * search descriptors. So confusingly this means "success". + */ + if (stat != NSS_SUCCESS && stat != NSS_NOTFOUND) + { + debug ("<== " NSS_LDAP_INITGROUPS_FUNCTION " (not found)"); +#ifndef HAVE_NSS_H + if (erange) + errno = ERANGE; +#endif /* HAVE_NSS_H */ +#ifndef HAVE_USERSEC_H + return stat; +#else + return NULL; +#endif /* HAVE_USERSEC_H */ + } + + debug ("<== " NSS_LDAP_INITGROUPS_FUNCTION " (success)"); + +#ifdef HAVE_NSS_H + return NSS_SUCCESS; +#elif defined(HAVE_USERSEC_H) + /* Strip last comma and terminate the string */ + if (lia.grplist == NULL) + lia.grplist = strdup(""); + else if (lia.listlen != 0) + lia.grplist[lia.listlen - 1] = '\0'; + + return lia.grplist; +#else + /* yes, NSS_NOTFOUND is the successful errno code. see nss_dbdefs.h */ + return NSS_NOTFOUND; +#endif /* HAVE_NSS_H */ +} + +#endif /* HAVE_NSSWITCH_H || HAVE_NSS_H || HAVE_USERSEC_H */ + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getgrnam_r (const char *name, + struct group * result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, _nss_ldap_filt_getgrnam, + LM_GROUP, _nss_ldap_parse_gr, LDAP_NSS_BUFLEN_GROUP); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getgrnam_r (nss_backend_t * be, void *args) +{ + LOOKUP_NAME (args, _nss_ldap_filt_getgrnam, LM_GROUP, _nss_ldap_parse_gr, + LDAP_NSS_BUFLEN_GROUP); +} +#endif + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getgrgid_r (gid_t gid, + struct group *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NUMBER (gid, result, buffer, buflen, errnop, _nss_ldap_filt_getgrgid, + LM_GROUP, _nss_ldap_parse_gr, LDAP_NSS_BUFLEN_GROUP); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getgrgid_r (nss_backend_t * be, void *args) +{ + LOOKUP_NUMBER (args, key.gid, _nss_ldap_filt_getgrgid, LM_GROUP, + _nss_ldap_parse_gr, LDAP_NSS_BUFLEN_GROUP); +} +#endif + +#if defined(HAVE_NSS_H) +NSS_STATUS _nss_ldap_setgrent (void) +{ + LOOKUP_SETENT (gr_context); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_setgrent_r (nss_backend_t * gr_context, void *args) +{ + LOOKUP_SETENT (gr_context); +} +#endif + +#if defined(HAVE_NSS_H) +NSS_STATUS _nss_ldap_endgrent (void) +{ + LOOKUP_ENDENT (gr_context); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_endgrent_r (nss_backend_t * gr_context, void *args) +{ + LOOKUP_ENDENT (gr_context); +} +#endif + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getgrent_r (struct group *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_GETENT (gr_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getgrent, LM_GROUP, _nss_ldap_parse_gr, + LDAP_NSS_BUFLEN_GROUP); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getgrent_r (nss_backend_t * gr_context, void *args) +{ + LOOKUP_GETENT (args, gr_context, _nss_ldap_filt_getgrent, LM_GROUP, + _nss_ldap_parse_gr, LDAP_NSS_BUFLEN_GROUP); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_group_destr (nss_backend_t * gr_context, void *args) +{ + return _nss_ldap_default_destr (gr_context, args); +} + +static nss_backend_op_t group_ops[] = { + _nss_ldap_group_destr, + _nss_ldap_endgrent_r, + _nss_ldap_setgrent_r, + _nss_ldap_getgrent_r, + _nss_ldap_getgrnam_r, + _nss_ldap_getgrgid_r, + _nss_ldap_getgroupsbymember_r +}; + +nss_backend_t * +_nss_ldap_group_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = group_ops; + be->n_ops = sizeof (group_ops) / sizeof (nss_backend_op_t); + + /* a NOOP at the moment */ + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} + + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_IRS_H +#include "irs-grp.c" +#endif diff --git a/ldap-grp.h b/ldap-grp.h new file mode 100644 index 0000000..a5ec7c1 --- /dev/null +++ b/ldap-grp.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-grp.h,v 2.22 2005/05/20 05:30:40 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_GRP_H +#define _LDAP_NSS_LDAP_LDAP_GRP_H + +static NSS_STATUS _nss_ldap_parse_gr (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_endgrent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_setgrent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getgrent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getgrnam_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getgrgid_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_group_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif + +#endif /* _LDAP_NSS_LDAP_LDAP_GRP_H */ diff --git a/ldap-hosts.c b/ldap-hosts.c new file mode 100644 index 0000000..3fe6dca --- /dev/null +++ b/ldap-hosts.c @@ -0,0 +1,484 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-hosts.c,v 2.35 2006/01/11 18:03:48 lukeh Exp $ + */ + +static char rcsId[] = + "$Id: ldap-hosts.c,v 2.35 2006/01/11 18:03:48 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <sys/socket.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> +#include <resolv.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#ifdef INET6 +#include <resolv/mapv4v6addr.h> +#endif + +#ifndef MAXALIASES +#define MAXALIASES 35 +#endif + +#include "ldap-nss.h" +#include "ldap-hosts.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *hosts_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_hostv4 (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + return _nss_ldap_parse_host (e, pvt, result, buffer, buflen, + AF_INET); +} + +#ifdef INET6 +static NSS_STATUS +_nss_ldap_parse_hostv6 (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + return _nss_ldap_parse_host (e, pvt, result, buffer, buflen, + AF_INET6); +} +#endif + +static NSS_STATUS +_nss_ldap_parse_host (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen, + int af) +{ + /* this code needs reviewing. XXX */ + struct hostent *host = (struct hostent *) result; + NSS_STATUS stat; +#ifdef INET6 + char addressbuf[sizeof ("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") * + MAXALIASES]; +#else + char addressbuf[sizeof ("255.255.255.255") * MAXALIASES]; +#endif + char *p_addressbuf = addressbuf; + char **addresses = NULL; + size_t addresslen = sizeof (addressbuf); + size_t addresscount = 0; + char **host_addresses = NULL; + int i; + + *addressbuf = *buffer = '\0'; + + stat = _nss_ldap_assign_attrval (e, ATM (LM_HOSTS, cn), &host->h_name, + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrvals (e, ATM (LM_HOSTS, cn), host->h_name, + &host->h_aliases, &buffer, &buflen, NULL); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrvals (e, AT (ipHostNumber), NULL, &addresses, + &p_addressbuf, &addresslen, &addresscount); + if (stat != NSS_SUCCESS) + return stat; + if (addresscount == 0) + return NSS_NOTFOUND; + +#ifdef INET6 + if (af == AF_INET6) + { + if (bytesleft (buffer, buflen, char *) < + (size_t) ((addresscount + 1) * IN6ADDRSZ)) + return NSS_TRYAGAIN; + } + else + { + if (bytesleft (buffer, buflen, char *) < + (size_t) ((addresscount + 1) * INADDRSZ)) + return NSS_TRYAGAIN; + } +#else + if (bytesleft (buffer, buflen, char *) < + (size_t) ((addresscount + 1) * INADDRSZ)) + return NSS_TRYAGAIN; +#endif + + align (buffer, buflen, char *); + host_addresses = (char **) buffer; + host->h_addr_list = host_addresses; + host_addresses[addresscount] = NULL; + + buffer += (addresscount + 1) * sizeof (char *); + buflen -= (addresscount + 1) * sizeof (char *); +#ifdef INET6 + host->h_addrtype = 0; + host->h_length = 0; +#else + host->h_addrtype = AF_INET; + host->h_length = INADDRSZ; +#endif + + for (i = 0; i < (int) addresscount; i++) + { +#ifdef INET6 + char *addr = addresses[i]; + char entdata[16]; + /* from glibc NIS parser. Thanks, Uli. */ + + if (af == AF_INET && inet_pton (AF_INET, addr, entdata) > 0) + { + if (_res.options & RES_USE_INET6) + { + map_v4v6_address ((char *) entdata, + (char *) entdata); + host->h_addrtype = AF_INET6; + host->h_length = IN6ADDRSZ; + } + else + { + host->h_addrtype = AF_INET; + host->h_length = INADDRSZ; + } + } + else if (af == AF_INET6 + && inet_pton (AF_INET6, addr, entdata) > 0) + { + host->h_addrtype = AF_INET6; + host->h_length = IN6ADDRSZ; + } + else + /* Illegal address: ignore line. */ + continue; + +#else + unsigned long haddr; + haddr = inet_addr (addresses[i]); +#endif + + if (buflen < (size_t) host->h_length) + return NSS_TRYAGAIN; + +#ifdef INET6 + memcpy (buffer, entdata, host->h_length); + *host_addresses = buffer; + buffer += host->h_length; + buflen -= host->h_length; +#else + memcpy (buffer, &haddr, INADDRSZ); + *host_addresses = buffer; + buffer += INADDRSZ; + buflen -= INADDRSZ; +#endif + + host_addresses++; + *host_addresses = NULL; + } + +#ifdef INET6 + /* if host->h_addrtype is not changed, this entry does not + have the right IP address. */ + if (host->h_addrtype == 0) + return NSS_NOTFOUND; +#endif + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_gethostbyname_r (nss_backend_t * be, void *args) +{ + ldap_args_t a; + NSS_STATUS status; + + LA_INIT (a); + LA_STRING (a) = NSS_ARGS (args)->key.name; + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + _nss_ldap_filt_gethostbyname, + LM_HOSTS, _nss_ldap_parse_hostv4); + + if (status == NSS_SUCCESS) + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + + MAP_H_ERRNO (status, NSS_ARGS (args)->h_errno); + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_gethostbyname2_r (const char *name, int af, struct hostent * result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop) +{ + NSS_STATUS status; + ldap_args_t a; + + LA_INIT (a); + LA_STRING (a) = name; + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + result, + buffer, + buflen, + errnop, + _nss_ldap_filt_gethostbyname, + LM_HOSTS, +#ifdef INET6 + (af == AF_INET6) ? + _nss_ldap_parse_hostv6 : +#endif + _nss_ldap_parse_hostv4); + + MAP_H_ERRNO (status, *h_errnop); + + return status; +} + +NSS_STATUS +_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, +#ifdef INET6 + (_res.options & RES_USE_INET6) ? + AF_INET6 : +#endif + AF_INET, result, buffer, buflen, + errnop, h_errnop); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_gethostbyaddr_r (nss_backend_t * be, void *args) +{ + struct in_addr iaddr; + ldap_args_t a; + NSS_STATUS status; + + memcpy (&iaddr.s_addr, NSS_ARGS (args)->key.hostaddr.addr, + NSS_ARGS (args)->key.hostaddr.len); + LA_INIT (a); + LA_STRING (a) = inet_ntoa (iaddr); + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + _nss_ldap_filt_gethostbyaddr, + LM_HOSTS, _nss_ldap_parse_hostv4); + + if (status == NSS_SUCCESS) + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + + MAP_H_ERRNO (status, NSS_ARGS (args)->h_errno); + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_gethostbyaddr_r (struct in_addr * addr, int len, int type, + struct hostent * result, char *buffer, + size_t buflen, int *errnop, int *h_errnop) +{ + NSS_STATUS status; + ldap_args_t a; + + /* if querying by IPv6 address, make sure the address is "normalized" -- + * it should contain no leading zeros and all components of the address. + * still we can't fit an IPv6 address in an int, so who cares for now. + */ + + LA_INIT (a); + LA_STRING (a) = inet_ntoa (*addr); + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + result, + buffer, + buflen, + errnop, + _nss_ldap_filt_gethostbyaddr, + LM_HOSTS, +#ifdef INET6 + (type == AF_INET6) ? + _nss_ldap_parse_hostv6 : +#endif + _nss_ldap_parse_hostv4); + + MAP_H_ERRNO (status, *h_errnop); + + return status; +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_sethostent_r (nss_backend_t * hosts_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_sethostent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_SETENT (hosts_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_endhostent_r (nss_backend_t * hosts_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_endhostent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_ENDENT (hosts_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_gethostent_r (nss_backend_t * hosts_context, void *args) +{ + NSS_STATUS status = _nss_ldap_getent (&((nss_ldap_backend_t *) + hosts_context)->state, + NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + _nss_ldap_filt_gethostent, + LM_HOSTS, + _nss_ldap_parse_hostv4); + + if (status == NSS_SUCCESS) + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + + MAP_H_ERRNO (status, NSS_ARGS (args)->h_errno); + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_gethostent_r (struct hostent * result, char *buffer, size_t buflen, + int *errnop, int *h_errnop) +{ + NSS_STATUS status; + + status = _nss_ldap_getent (&hosts_context, + result, + buffer, + buflen, + errnop, + _nss_ldap_filt_gethostent, LM_HOSTS, +#ifdef INET6 + (_res.options & RES_USE_INET6) ? + _nss_ldap_parse_hostv6 : +#endif + _nss_ldap_parse_hostv4); + + MAP_H_ERRNO (status, *h_errnop); + + return status; +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_hosts_destr (nss_backend_t * hosts_context, void *args) +{ + return _nss_ldap_default_destr (hosts_context, args); +} + +static nss_backend_op_t host_ops[] = { + _nss_ldap_hosts_destr, + _nss_ldap_endhostent_r, + _nss_ldap_sethostent_r, + _nss_ldap_gethostent_r, + _nss_ldap_gethostbyname_r, + _nss_ldap_gethostbyaddr_r +}; + +nss_backend_t * +_nss_ldap_hosts_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = host_ops; + be->n_ops = sizeof (host_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_IRS_H +#include "irs-hosts.c" +#endif diff --git a/ldap-hosts.h b/ldap-hosts.h new file mode 100644 index 0000000..3e283f5 --- /dev/null +++ b/ldap-hosts.h @@ -0,0 +1,59 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_HOSTS_H +#define _LDAP_NSS_LDAP_LDAP_HOSTS_H + +/* + * It's critical that we support IPv6 both in the IRS and the NSS modules. + * For code, check out the BIND IRS and the glibc as it stands. Both support + * NIS lookups for IPv6 addresses. + * + */ + + +#if defined(HAVE_NSSWITCH_H) || defined(DL_NSS) +/* XXX Fixme */ +#ifndef INADDRSZ +#define INADDRSZ (sizeof(u_long)) +#endif +#endif + + +static NSS_STATUS _nss_ldap_parse_host (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen, int af); + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_gethostbyname_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_gethostbyaddr_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_gethostent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_sethostent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_endhostent_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_hosts_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif + +#endif /* _LDAP_NSS_LDAP_LDAP_HOSTS_H */ diff --git a/ldap-netgrp.c b/ldap-netgrp.c new file mode 100644 index 0000000..bb5c63c --- /dev/null +++ b/ldap-netgrp.c @@ -0,0 +1,993 @@ +/* Copyright (C) 2002-2005 Luke Howard. + This file is part of the nss_ldap library. + Linux support contributed by Larry Lile, <llile@dreamworks.com>, 2002. + Solaris support contributed by Luke Howard, <lukeh@padl.com>, 2004. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-netgrp.c,v 2.44 2006/01/11 18:03:48 lukeh Exp $ + */ + +static char rcsId[] = + "$Id: ldap-netgrp.c,v 2.44 2006/01/11 18:03:48 lukeh Exp $"; + +#include "config.h" + +#include <stdio.h> +#include <stdarg.h> +#include <ctype.h> + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/param.h> +#include <string.h> +#include <assert.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif + +#include "ldap-nss.h" +#include "ldap-netgrp.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *_ngbe = NULL; +#endif + +#ifdef HAVE_IRS_H +enum nss_netgr_status { + NSS_NETGR_FOUND, + NSS_NETGR_NO, + NSS_NETGR_NOMEM +}; + +struct pvt; /* forward declaration for IRS backend type */ +#endif /* HAVE_IRS_H */ + +#ifdef HAVE_NSSWITCH_H +static nss_backend_op_t netgroup_ops[]; +#endif + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) +struct ldap_innetgr_args +{ + const char *lia_netgroup; + enum nss_netgr_status lia_netgr_status; + int lia_depth; + int lia_erange; +}; + +typedef struct ldap_innetgr_args ldap_innetgr_args_t; + +static NSS_STATUS do_innetgr_nested (ldap_innetgr_args_t * li_args, + const char *nested); +#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ + +/* + * I pulled the following macro (EXPAND), functions (strip_whitespace and + * _nss_netgroup_parseline) and structures (name_list and __netgrent) from + * glibc-2.2.x. _nss_netgroup_parseline became _nss_ldap_parse_netgr after + * some modification. + * + * The rest of the code is modeled on various other _nss_ldap functions. + */ + +#define EXPAND(needed) \ + do \ + { \ + size_t old_cursor = result->cursor - result->data; \ + \ + result->data_size += 512 > 2 * needed ? 512 : 2 * needed; \ + result->data = realloc (result->data, result->data_size); \ + \ + if (result->data == NULL) \ + { \ + stat = NSS_UNAVAIL; \ + goto out; \ + } \ + \ + result->cursor = result->data + old_cursor; \ + } \ + while (0) + +/* A netgroup can consist of names of other netgroups. We have to + track which netgroups were read and which still have to be read. */ + + +/* Dataset for iterating netgroups. */ +struct __netgrent +{ + enum + { triple_val, group_val } + type; + + union + { + struct + { + const char *host; + const char *user; + const char *domain; + } + triple; + + const char *group; + } + val; + + /* Room for the data kept between the calls to the netgroup + functions. We must avoid global variables. */ + char *data; + size_t data_size; + char *cursor; + int first; + + struct name_list *known_groups; + struct name_list *needed_groups; +}; + +static char * +strip_whitespace (char *str) +{ + char *cp = str; + + /* Skip leading spaces. */ + while (isspace ((int) *cp)) + cp++; + + str = cp; + while (*cp != '\0' && !isspace ((int) *cp)) + cp++; + + /* Null-terminate, stripping off any trailing spaces. */ + *cp = '\0'; + + return *str == '\0' ? NULL : str; +} + +static NSS_STATUS +_nss_ldap_parse_netgr (void *vresultp, char *buffer, size_t buflen) +{ + struct __netgrent *result = (struct __netgrent *) vresultp; + char *cp = result->cursor; + char *user, *host, *domain; + + /* The netgroup either doesn't exist or is empty. */ + if (cp == NULL) + return NSS_RETURN; + + /* First skip leading spaces. */ + while (isspace ((int) *cp)) + ++cp; + + if (*cp != '(') + { + /* We have a list of other netgroups. */ + char *name = cp; + + while (*cp != '\0' && !isspace ((int) *cp)) + ++cp; + + if (name != cp) + { + /* It is another netgroup name. */ + int last = *cp == '\0'; + + result->type = group_val; + result->val.group = name; + *cp = '\0'; + if (!last) + ++cp; + result->cursor = cp; + result->first = 0; + + return NSS_SUCCESS; + } + return result->first ? NSS_NOTFOUND : NSS_RETURN; + } + + /* Match host name. */ + host = ++cp; + while (*cp != ',') + if (*cp++ == '\0') + return result->first ? NSS_NOTFOUND : NSS_RETURN; + + /* Match user name. */ + user = ++cp; + while (*cp != ',') + if (*cp++ == '\0') + return result->first ? NSS_NOTFOUND : NSS_RETURN; + + /* Match domain name. */ + domain = ++cp; + while (*cp != ')') + if (*cp++ == '\0') + return result->first ? NSS_NOTFOUND : NSS_RETURN; + ++cp; + + /* When we got here we have found an entry. Before we can copy it + to the private buffer we have to make sure it is big enough. */ + if (cp - host > buflen) + return NSS_TRYAGAIN; + + strncpy (buffer, host, cp - host); + result->type = triple_val; + + buffer[(user - host) - 1] = '\0'; + result->val.triple.host = strip_whitespace (buffer); + + buffer[(domain - host) - 1] = '\0'; + result->val.triple.user = strip_whitespace (buffer + (user - host)); + + buffer[(cp - host) - 1] = '\0'; + result->val.triple.domain = strip_whitespace (buffer + (domain - host)); + + /* Remember where we stopped reading. */ + result->cursor = cp; + result->first = 0; + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSS_H +static NSS_STATUS +_nss_ldap_load_netgr (LDAPMessage * e, + ldap_state_t * pvt, + void *vresultp, char *buffer, size_t buflen) +{ + int attr; + int nvals; + int valcount = 0; + char **vals; + char **valiter; + struct __netgrent *result = vresultp; + NSS_STATUS stat = NSS_SUCCESS; + + for (attr = 0; attr < 2; attr++) + { + switch (attr) + { + case 1: + vals = _nss_ldap_get_values (e, AT (nisNetgroupTriple)); + break; + default: + vals = _nss_ldap_get_values (e, AT (memberNisNetgroup)); + break; + } + + nvals = ldap_count_values (vals); + + if (vals == NULL) + continue; + + if (nvals == 0) + { + ldap_value_free (vals); + continue; + } + + if (result->data_size > 0 + && result->cursor - result->data + 1 > result->data_size) + EXPAND (1); + + if (result->data_size > 0) + *result->cursor++ = ' '; + + valcount += nvals; + valiter = vals; + + while (*valiter != NULL) + { + int curlen = strlen (*valiter); + if (result->cursor - result->data + curlen + 1 > result->data_size) + EXPAND (curlen + 1); + memcpy (result->cursor, *valiter, curlen + 1); + result->cursor += curlen; + valiter++; + if (*valiter != NULL) + *result->cursor++ = ' '; + } + ldap_value_free (vals); + } + + result->first = 1; + result->cursor = result->data; + +out: + + return stat; +} + +NSS_STATUS +_nss_ldap_endnetgrent (struct __netgrent * result) +{ + if (result->data != NULL) + { + free (result->data); + result->data = NULL; + result->data_size = 0; + result->cursor = NULL; + } + + LOOKUP_ENDENT (_ngbe); +} + +NSS_STATUS +_nss_ldap_setnetgrent (char *group, struct __netgrent *result) +{ + int errnop = 0, buflen = 0; + char *buffer = (char *) NULL; + ldap_args_t a; + NSS_STATUS stat = NSS_SUCCESS; + + if (group[0] == '\0') + return NSS_UNAVAIL; + + if (result->data != NULL) + free (result->data); + result->data = result->cursor = NULL; + result->data_size = 0; + + LA_INIT (a); + LA_STRING (a) = group; + LA_TYPE (a) = LA_TYPE_STRING; + + stat = + _nss_ldap_getbyname (&a, result, buffer, buflen, &errnop, + _nss_ldap_filt_getnetgrent, LM_NETGROUP, + _nss_ldap_load_netgr); + + LOOKUP_SETENT (_ngbe); +} + +NSS_STATUS +_nss_ldap_getnetgrent_r (struct __netgrent *result, + char *buffer, size_t buflen, int *errnop) +{ + return _nss_ldap_parse_netgr (result, buffer, buflen); +} +#endif /* HAVE_NSS_H */ + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) +/* + * Chase nested netgroups. If we can't find a nested netgroup, we try + * the next one - don't want to fail authoritatively because of bad + * user data. + */ +static NSS_STATUS +nn_chase (nss_ldap_netgr_backend_t * ngbe, LDAPMessage ** pEntry) +{ + ldap_args_t a; + NSS_STATUS stat = NSS_NOTFOUND; + + debug ("==> nn_chase"); + + if (ngbe->state->ec_res != NULL) + { + ldap_msgfree (ngbe->state->ec_res); + ngbe->state->ec_res = NULL; + } + + while (ngbe->needed_groups != NULL) + { + /* If this netgroup has already been seen, avoid it */ + if (_nss_ldap_namelist_find (ngbe->known_groups, ngbe->needed_groups->name)) + { + _nss_ldap_namelist_pop (&ngbe->needed_groups); + continue; + } + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + LA_STRING (a) = ngbe->needed_groups->name; + + debug (":== nn_chase: nested netgroup=%s", LA_STRING (a)); + + _nss_ldap_enter (); + stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getnetgrent, + LM_NETGROUP, NULL, 1, &ngbe->state->ec_res); + _nss_ldap_leave (); + + if (stat == NSS_SUCCESS) + { + /* we have "seen" this netgroup; track it for loop detection */ + stat = _nss_ldap_namelist_push (&ngbe->known_groups, ngbe->needed_groups->name); + if (stat != NSS_SUCCESS) + { + _nss_ldap_namelist_pop (&ngbe->needed_groups); + break; + } + } + + _nss_ldap_namelist_pop (&ngbe->needed_groups); + + if (stat == NSS_SUCCESS) + { + /* Check we got an entry, not just a result. */ + *pEntry = _nss_ldap_first_entry (ngbe->state->ec_res); + if (*pEntry == NULL) + { + ldap_msgfree (ngbe->state->ec_res); + ngbe->state->ec_res = NULL; + stat = NSS_NOTFOUND; + } + } + + if (stat == NSS_SUCCESS) + { + /* found one. */ + break; + } + } + + debug ("<== nn_chase result=%d", stat); + + return stat; +} +#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) +/* + * getnetgrent() inner implementation, used by both Solaris NSS + * and IRS/AIX + */ +static NSS_STATUS +do_getnetgrent (nss_ldap_netgr_backend_t *be, + char *buffer, size_t buflen, + enum nss_netgr_status *status, + char **machine, char **user, char **domain) +{ + ent_context_t *ctx; + NSS_STATUS parseStat = NSS_NOTFOUND; + + /* + * This function is called with the pseudo-backend that + * we created in _nss_ldap_setnetgrent() (see below) + */ + debug ("==> do_getnetgrent"); + + ctx = be->state; + assert (ctx != NULL); + + *status = NSS_NETGR_NO; + *machine = NULL; + *user = NULL; + *domain = NULL; + + do + { + NSS_STATUS resultStat = NSS_SUCCESS; + char **vals, **p; + ldap_state_t *state = &ctx->ec_state; + struct __netgrent __netgrent; + LDAPMessage *e; + + if (state->ls_retry == 0 && state->ls_info.ls_index == -1) + { + resultStat = NSS_NOTFOUND; + + if (ctx->ec_res != NULL) + { + e = _nss_ldap_first_entry (ctx->ec_res); + if (e != NULL) + resultStat = NSS_SUCCESS; + } + + if (resultStat != NSS_SUCCESS) + { + /* chase nested netgroups */ + resultStat = nn_chase (be, &e); + } + + if (resultStat != NSS_SUCCESS) + { + parseStat = resultStat; + break; + } + + assert (e != NULL); + + /* Push nested netgroups onto stack for deferred chasing */ + vals = _nss_ldap_get_values (e, AT (memberNisNetgroup)); + if (vals != NULL) + { + for (p = vals; *p != NULL; p++) + { + parseStat = _nss_ldap_namelist_push (&be->needed_groups, *p); + if (parseStat != NSS_SUCCESS) + break; + } + ldap_value_free (vals); + + if (parseStat != NSS_SUCCESS) + break; /* out of memory */ + } + } + else + { + assert (ctx->ec_res != NULL); + e = _nss_ldap_first_entry (ctx->ec_res); + if (e == NULL) + { + /* This should never happen, but we fail gracefully. */ + parseStat = NSS_UNAVAIL; + break; + } + } + + /* We have an entry; now, try to parse it. */ + vals = _nss_ldap_get_values (e, AT (nisNetgroupTriple)); + if (vals == NULL) + { + state->ls_info.ls_index = -1; + parseStat = NSS_NOTFOUND; + ldap_msgfree (ctx->ec_res); + ctx->ec_res = NULL; + continue; + } + + switch (state->ls_info.ls_index) + { + case 0: + /* last time. decrementing ls_index to -1 AND returning + * an error code will force this entry to be discared. + */ + parseStat = NSS_NOTFOUND; + break; + case -1: + /* first time */ + state->ls_info.ls_index = ldap_count_values (vals); + /* fall off to default... */ + default: + __netgrent.data = vals[state->ls_info.ls_index - 1]; + __netgrent.data_size = strlen (vals[state->ls_info.ls_index - 1]); + __netgrent.cursor = __netgrent.data; + __netgrent.first = 1; + + parseStat = _nss_ldap_parse_netgr (&__netgrent, buffer, buflen); + if (parseStat != NSS_SUCCESS) + { + break; + } + if (__netgrent.type != triple_val) + { + parseStat = NSS_NOTFOUND; + break; + } + *machine = (char *) __netgrent.val.triple.host; + *user = (char *) __netgrent.val.triple.user; + *domain = (char *) __netgrent.val.triple.domain; + break; + } + + ldap_value_free (vals); + state->ls_info.ls_index--; + + /* hold onto the state if we're out of memory XXX */ + state->ls_retry = (parseStat == NSS_TRYAGAIN ? 1 : 0); + *status = (parseStat == NSS_SUCCESS) ? NSS_NETGR_FOUND : NSS_NETGR_NOMEM; + + if (state->ls_retry == 0 && state->ls_info.ls_index == -1) + { + ldap_msgfree (ctx->ec_res); + ctx->ec_res = NULL; + } + } + while (parseStat == NSS_NOTFOUND); + + if (parseStat == NSS_TRYAGAIN) + { + errno = ERANGE; + } + + debug ("<== do_getnetgrent"); + + return parseStat; +} + +/* + * Test a 4-tuple + */ +static NSS_STATUS +do_parse_innetgr (LDAPMessage * e, ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + ldap_innetgr_args_t *li_args = (ldap_innetgr_args_t *) result; + int count; + char **values = NULL; + NSS_STATUS stat = NSS_NOTFOUND; + + debug ("==> do_parse_innetgr"); + + values = _nss_ldap_get_values (e, ATM (LM_NETGROUP, cn)); + if (values == NULL) + return NSS_NOTFOUND; + + count = ldap_count_values (values); + + while (--count >= 0) + { + assert (values[count] != NULL); + + if (strcasecmp (li_args->lia_netgroup, values[count]) == 0) + { + li_args->lia_netgr_status = NSS_NETGR_FOUND; + stat = NSS_SUCCESS; + } + else + { + stat = do_innetgr_nested (li_args, values[count]); + } + + if (stat == NSS_SUCCESS) + break; + } + + ldap_value_free (values); + + debug ("<== do_parse_innetgr"); + + return stat; +} + +/* + * NB: caller has acquired the global lock + */ +static NSS_STATUS +do_innetgr_nested (ldap_innetgr_args_t * li_args, const char *nested) +{ + NSS_STATUS stat; + ldap_args_t a; + ent_context_t *ctx = NULL; + + debug ("==> do_innetgr_nested netgroup=%s assertion=%s", + li_args->lia_netgroup, nested); + + if (li_args->lia_depth >= LDAP_NSS_MAXNETGR_DEPTH) + { + debug ("<== do_innetgr_nested: maximum depth exceeded"); + return NSS_NOTFOUND; + } + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + LA_STRING (a) = nested; /* memberNisNetgroup */ + + if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) + { + debug ("<== do_innetgr_nested: failed to initialize context"); + return NSS_UNAVAIL; + } + + li_args->lia_depth++; + + stat = _nss_ldap_getent_ex (&a, &ctx, (void *) li_args, NULL, 0, + &li_args->lia_erange, _nss_ldap_filt_innetgr, + LM_NETGROUP, NULL, do_parse_innetgr); + + li_args->lia_depth--; + + _nss_ldap_ent_context_release (ctx); + free (ctx); + + debug ("<== do_innetgr_nested status=%d netgr_status=%d", + stat, li_args->lia_netgr_status); + + return stat; +} + +/* + * NB: caller has acquired the global lock + */ +static NSS_STATUS +do_innetgr (ldap_innetgr_args_t * li_args, + const char *machine, const char *user, const char *domain) +{ + NSS_STATUS stat; + ldap_args_t a; + ent_context_t *ctx = NULL; + + debug ("==> do_innetgr netgroup=%s", li_args->lia_netgroup); + + /* + * First, find which netgroup the 3-tuple belongs to. + */ + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_TRIPLE; + LA_TRIPLE (a).user = user; + LA_TRIPLE (a).host = machine; + LA_TRIPLE (a).domain = domain; + + if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) + { + debug ("<== do_innetgr: failed to initialize context"); + return NSS_UNAVAIL; + } + + stat = _nss_ldap_getent_ex (&a, &ctx, (void *) li_args, NULL, 0, + &li_args->lia_erange, NULL, LM_NETGROUP, + NULL, do_parse_innetgr); + + _nss_ldap_ent_context_release (ctx); + free (ctx); + + debug ("<== do_innetgr status=%d netgr_status=%d", + stat, li_args->lia_netgr_status); + + return stat; +} +#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getnetgroup_endent (nss_backend_t * be, void *_args) +{ + LOOKUP_ENDENT (be); +} + +static NSS_STATUS +_nss_ldap_getnetgroup_setent (nss_backend_t * be, void *_args) +{ + return NSS_SUCCESS; +} + +static NSS_STATUS +_nss_ldap_getnetgroup_getent (nss_backend_t * _be, void *_args) +{ + nss_ldap_netgr_backend_t *be = (nss_ldap_netgr_backend_t *) _be; + struct nss_getnetgrent_args *args = (struct nss_getnetgrent_args *) _args; + NSS_STATUS stat; + + _nss_ldap_enter (); + + stat = do_getnetgrent (be, + args->buffer, + args->buflen, + &args->status, + &args->retp[NSS_NETGR_MACHINE], + &args->retp[NSS_NETGR_USER], + &args->retp[NSS_NETGR_DOMAIN]); + + _nss_ldap_leave (); + + return stat; +} + +static NSS_STATUS +_nss_ldap_innetgr (nss_backend_t * be, void *_args) +{ + NSS_STATUS stat = NSS_NOTFOUND; + struct nss_innetgr_args *args = (struct nss_innetgr_args *) _args; + int i; + + /* + * Enumerate the groups in args structure and see whether + * any 4-tuple was satisfied. This really needs LDAP + * component matching to be done efficiently. + */ + + debug + ("==> _nss_ldap_innetgr MACHINE.argc=%d USER.argc=%d DOMAIN.argc=%d groups.argc=%d", + args->arg[NSS_NETGR_MACHINE].argc, args->arg[NSS_NETGR_USER].argc, + args->arg[NSS_NETGR_DOMAIN].argc, args->groups.argc); + + /* Presume these are harmonized -- this is a strange interface */ + assert (args->arg[NSS_NETGR_MACHINE].argc == 0 || + args->arg[NSS_NETGR_MACHINE].argc == args->groups.argc); + assert (args->arg[NSS_NETGR_USER].argc == 0 || + args->arg[NSS_NETGR_USER].argc == args->groups.argc); + assert (args->arg[NSS_NETGR_DOMAIN].argc == 0 || + args->arg[NSS_NETGR_DOMAIN].argc == args->groups.argc); + + _nss_ldap_enter (); + + for (i = 0; i < args->groups.argc; i++) + { + NSS_STATUS parseStat; + ldap_innetgr_args_t li_args; + + const char *machine = (args->arg[NSS_NETGR_MACHINE].argc != 0) ? + args->arg[NSS_NETGR_MACHINE].argv[i] : NULL; + const char *user = (args->arg[NSS_NETGR_USER].argc != 0) ? + args->arg[NSS_NETGR_USER].argv[i] : NULL; + const char *domain = (args->arg[NSS_NETGR_DOMAIN].argc != 0) ? + args->arg[NSS_NETGR_DOMAIN].argv[i] : NULL; + + li_args.lia_netgroup = args->groups.argv[i]; + li_args.lia_netgr_status = NSS_NETGR_NO; + li_args.lia_depth = 0; + li_args.lia_erange = 0; + + parseStat = do_innetgr (&li_args, machine, user, domain); + if (parseStat != NSS_SUCCESS && parseStat != NSS_NOTFOUND) + { + /* fatal error */ + if (li_args.lia_erange != 0) + errno = ERANGE; + break; + } + + args->status = li_args.lia_netgr_status; + + if (args->status == NSS_NETGR_FOUND) + { + stat = NSS_SUCCESS; + } + } + + _nss_ldap_leave (); + + debug ("<== _nss_ldap_innetgr"); + + return stat; +} + +/* + * According to the "documentation", setnetgrent() is really + * a getXXXbyYYY() operation that returns a pseudo-backend + * through which one may enumerate the netgroup's members. + * + * ie. this is the constructor for the pseudo-backend. + */ +static NSS_STATUS +_nss_ldap_setnetgrent (nss_backend_t * be, void *_args) +{ + NSS_STATUS stat; + struct nss_setnetgrent_args *args; + nss_ldap_netgr_backend_t *ngbe; + ldap_args_t a; + + debug ("==> _nss_ldap_setnetgrent"); + + args = (struct nss_setnetgrent_args *) _args; + args->iterator = NULL; /* initialize */ + + /* + * This retrieves the top-level netgroup; nested netgroups + * are chased inside the pseudo-backend. + */ + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + LA_STRING (a) = args->netgroup; /* cn */ + + ngbe = (nss_ldap_netgr_backend_t *) malloc (sizeof (*ngbe)); + if (ngbe == NULL) + { + debug ("<== _nss_ldap_setnetgrent"); + return NSS_UNAVAIL; + } + + ngbe->ops = netgroup_ops; + ngbe->n_ops = 6; + ngbe->state = NULL; + ngbe->known_groups = NULL; + ngbe->needed_groups = NULL; + + stat = _nss_ldap_default_constr ((nss_ldap_backend_t *) ngbe); + if (stat != NSS_SUCCESS) + { + free (ngbe); + debug ("<== _nss_ldap_setnetgrent"); + return stat; + } + + if (_nss_ldap_ent_context_init (&ngbe->state) == NULL) + { + _nss_ldap_default_destr ((nss_backend_t *) ngbe, NULL); + debug ("<== _nss_ldap_setnetgrent"); + return NSS_UNAVAIL; + } + + assert (ngbe->state != NULL); + assert (ngbe->state->ec_res == NULL); + + _nss_ldap_enter (); + stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getnetgrent, + LM_NETGROUP, NULL, 1, &ngbe->state->ec_res); + _nss_ldap_leave (); + + if (stat == NSS_SUCCESS) + { + /* we have "seen" this netgroup; track it for loop detection */ + stat = _nss_ldap_namelist_push (&ngbe->known_groups, args->netgroup); + } + + if (stat == NSS_SUCCESS) + { + args->iterator = (nss_backend_t *) ngbe; + } + else + { + _nss_ldap_default_destr ((nss_backend_t *) ngbe, NULL); + } + + debug ("<== _nss_ldap_setnetgrent"); + + return stat; +} + +static NSS_STATUS +_nss_ldap_netgroup_destr (nss_backend_t * _ngbe, void *args) +{ + nss_ldap_netgr_backend_t *ngbe = (nss_ldap_netgr_backend_t *) _ngbe; + + /* free list of nested netgroups */ + _nss_ldap_namelist_destroy (&ngbe->known_groups); + _nss_ldap_namelist_destroy (&ngbe->needed_groups); + + return _nss_ldap_default_destr (_ngbe, args); +} + +static nss_backend_op_t netgroup_ops[] = { + _nss_ldap_netgroup_destr, /* NSS_DBOP_DESTRUCTOR */ + _nss_ldap_getnetgroup_endent, /* NSS_DBOP_ENDENT */ + _nss_ldap_getnetgroup_setent, /* NSS_DBOP_SETENT */ + _nss_ldap_getnetgroup_getent, /* NSS_DBOP_GETENT */ + _nss_ldap_innetgr, /* NSS_DBOP_NETGROUP_IN */ + _nss_ldap_setnetgrent /* NSS_DBOP_NETGROUP_SET */ +}; + +nss_backend_t * +_nss_ldap_netgroup_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_netgr_backend_t *be; + + if (!(be = (nss_ldap_netgr_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = netgroup_ops; + be->n_ops = sizeof (netgroup_ops) / sizeof (nss_backend_op_t); + be->known_groups = NULL; + be->needed_groups = NULL; + + if (_nss_ldap_default_constr ((nss_ldap_backend_t *) be) != NSS_SUCCESS) + { + free (be); + return NULL; + } + + return (nss_backend_t *) be; +} + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_IRS_H +#include "irs-netgrp.c" +#endif /* HAVE_IRS_H */ diff --git a/ldap-netgrp.h b/ldap-netgrp.h new file mode 100644 index 0000000..b4b4cd4 --- /dev/null +++ b/ldap-netgrp.h @@ -0,0 +1,45 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-netgrp.h,v 2.18 2005/05/20 05:30:41 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_NETGRP_H +#define _LDAP_NSS_LDAP_LDAP_NETGRP_H + + +static NSS_STATUS _nss_ldap_parse_netgr (void *result, + char *buffer, size_t buflen); + +#ifdef HAVE_NSSWITCH_H +#if 0 +static NSS_STATUS _nss_ldap_setnetgrent_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_endnetgrent_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_getnetgrent_r (nss_backend_t * be, + void *fakeargs); + +nss_backend_t *_nss_ldap_netgroup_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif +#endif /* !HAVE_NSS_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_NETGRP_H */ diff --git a/ldap-network.c b/ldap-network.c new file mode 100644 index 0000000..cafc872 --- /dev/null +++ b/ldap-network.c @@ -0,0 +1,372 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-network.c,v 2.33 2006/01/11 18:03:48 lukeh Exp $ + */ + +/* parts based on nss_nis */ + +static char rcsId[] = + "$Id: ldap-network.c,v 2.33 2006/01/11 18:03:48 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> +#include <sys/socket.h> +#include <errno.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-network.h" +#include "util.h" + +#if defined(HAVE_IRS_H) || defined(HAVE_USERSEC_H) +#define MAXALIASES 35 +#define MAXADDRSIZE 4 +#endif /* HAVE_IRS_H || HAVE_USERSEC_H */ + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *net_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_net (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + + char *tmp; +#ifdef HAVE_IRS_H + struct nwent *network = (struct nwent *) result; + unsigned char *addr; +#else + struct netent *network = (struct netent *) result; +#endif + NSS_STATUS stat; + + /* IPv6 support ? XXX */ + network->n_addrtype = AF_INET; + + stat = _nss_ldap_assign_attrval (e, ATM (LM_NETWORKS, cn), &network->n_name, + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrval (e, AT (ipNetworkNumber), &tmp, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + +#ifdef HAVE_IRS_H + if (buflen < MAXADDRSIZE) + return NSS_TRYAGAIN; + addr = buffer; + buffer += MAXADDRSIZE; + buffer -= MAXADDRSIZE; + network->n_length = inet_net_pton (AF_INET, tmp, &addr, MAXADDRSIZE); + network->n_addr = addr; +#else + network->n_net = inet_network (tmp); +#endif + + stat = + _nss_ldap_assign_attrvals (e, ATM (LM_NETWORKS, cn), network->n_name, + &network->n_aliases, &buffer, &buflen, NULL); + if (stat != NSS_SUCCESS) + return stat; + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getnetbyname_r (nss_backend_t * be, void *args) +{ + ldap_args_t a; + NSS_STATUS status; + + LA_INIT (a); + LA_STRING (a) = NSS_ARGS (args)->key.name; + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + _nss_ldap_filt_getnetbyname, + LM_NETWORKS, _nss_ldap_parse_net); + + if (status == NSS_SUCCESS) + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + + MAP_H_ERRNO (status, NSS_ARGS (args)->h_errno); + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getnetbyname_r (const char *name, struct netent * result, + char *buffer, size_t buflen, int *errnop, + int *herrnop) +{ + NSS_STATUS status; + ldap_args_t a; + + LA_INIT (a); + LA_STRING (a) = name; + LA_TYPE (a) = LA_TYPE_STRING; + + status = _nss_ldap_getbyname (&a, + result, + buffer, + buflen, + errnop, + _nss_ldap_filt_getnetbyname, + LM_NETWORKS, _nss_ldap_parse_net); + + MAP_H_ERRNO (status, *herrnop); + + return status; +} +#endif + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getnetbyaddr_r (nss_backend_t * be, void *args) +#else +NSS_STATUS +_nss_ldap_getnetbyaddr_r (unsigned long addr, int type, + struct netent * result, char *buffer, size_t buflen, + int *errnop, int *herrnop) +#endif +{ + struct in_addr in; + char buf[256]; + int blen; + ldap_args_t a; + NSS_STATUS retval = NSS_NOTFOUND; + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_STRING; + +#ifdef HAVE_NSSWITCH_H + in = inet_makeaddr (NSS_ARGS (args)->key.netaddr.net, 0); +#else + in = inet_makeaddr (addr, 0); +#endif + strcpy (buf, inet_ntoa (in)); + blen = strlen (buf); + LA_STRING (a) = buf; + + while (1) + { +#ifdef HAVE_NSSWITCH_H + retval = + _nss_ldap_getbyname (&a, NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, +#else + retval = _nss_ldap_getbyname (&a, result, buffer, buflen, errnop, +#endif + _nss_ldap_filt_getnetbyaddr, + LM_NETWORKS, _nss_ldap_parse_net); + + if (retval != NSS_SUCCESS) + { + if (retval == NSS_NOTFOUND) + { + if (buf[blen - 2] == '.' && buf[blen - 1] == '\0') + { + buf[blen - 2] = '\0'; + blen -= 2; + continue; + } + else + { +#ifdef HAVE_NSSWITCH_H + NSS_ARGS (args)->returnval = NULL; + MAP_H_ERRNO (retval, NSS_ARGS (args)->h_errno); +#else + MAP_H_ERRNO (retval, *herrnop); +#endif + return NSS_NOTFOUND; + } + } + else + { +#ifdef HAVE_NSSWITCH_H + NSS_ARGS (args)->returnval = NULL; + MAP_H_ERRNO (retval, NSS_ARGS (args)->h_errno); +#else + MAP_H_ERRNO (retval, *herrnop); +#endif + return retval; + } + } + else + { + /* retval == NSS_SUCCESS */ + break; + } + } + +#ifdef HAVE_NSSWITCH_H + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + MAP_H_ERRNO (retval, NSS_ARGS (args)->h_errno); +#else + MAP_H_ERRNO (NSS_SUCCESS, *herrnop); +#endif + + return retval; +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_setnetent_r (nss_backend_t * net_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_setnetent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_SETENT (net_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_endnetent_r (nss_backend_t * net_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_endnetent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_ENDENT (net_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getnetent_r (nss_backend_t * net_context, void *args) +{ + NSS_STATUS status = + _nss_ldap_getent (&((nss_ldap_backend_t *) net_context)->state, + NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + _nss_ldap_filt_getnetent, + LM_NETWORKS, + _nss_ldap_parse_net); + + if (status == NSS_SUCCESS) + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getnetent_r (struct netent * result, char *buffer, size_t buflen, + int *errnop, int *herrnop) +{ + NSS_STATUS status; + + status = _nss_ldap_getent (&net_context, + result, + buffer, + buflen, + errnop, + _nss_ldap_filt_getnetent, + LM_NETWORKS, _nss_ldap_parse_net); + + MAP_H_ERRNO (status, *herrnop); + + return status; +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_networks_destr (nss_backend_t * net_context, void *args) +{ + return _nss_ldap_default_destr (net_context, args); +} + +static nss_backend_op_t net_ops[] = { + _nss_ldap_networks_destr, + _nss_ldap_endnetent_r, + _nss_ldap_setnetent_r, + _nss_ldap_getnetent_r, + _nss_ldap_getnetbyname_r, + _nss_ldap_getnetbyaddr_r +}; + +nss_backend_t * +_nss_ldap_networks_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = net_ops; + be->n_ops = sizeof (net_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_IRS_H +#include "irs-network.c" +#endif diff --git a/ldap-network.h b/ldap-network.h new file mode 100644 index 0000000..d847115 --- /dev/null +++ b/ldap-network.h @@ -0,0 +1,47 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-network.h,v 2.17 2005/05/20 05:30:41 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_NETWORK_H +#define _LDAP_NSS_LDAP_LDAP_NETWORK_H + +static NSS_STATUS _nss_ldap_parse_net (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); + + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_getnetbyname_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_getnetbyaddr_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_setnetent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_endnetent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getnetent_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_networks_constr (const char *db_name, + const char *src_name, + const char *cfg_args); + +#endif /* !HAVE_NSS_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_NETWORK_H */ diff --git a/ldap-nss.c b/ldap-nss.c new file mode 100644 index 0000000..3019cf6 --- /dev/null +++ b/ldap-nss.c @@ -0,0 +1,4251 @@ +/* Copyright (C) 1997-2006 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +static char rcsId[] = + "$Id: ldap-nss.c,v 2.282 2006/05/15 08:13:44 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <assert.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#include <stdio.h> +#include <syslog.h> +#include <signal.h> +#include <fcntl.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/param.h> +#include <errno.h> +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif +#include <netinet/in.h> +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif +#ifdef HAVE_LDAP_SSL_H +#include <ldap_ssl.h> +#endif +#ifdef HAVE_GSSLDAP_H +#include <gssldap.h> +#endif +#ifdef HAVE_GSSSASL_H +#include <gsssasl.h> +#endif + +/* Try to handle systems with both SASL libraries installed */ +#if defined(HAVE_SASL_SASL_H) && defined(HAVE_SASL_AUXPROP_REQUEST) +#include <sasl/sasl.h> +#elif defined(HAVE_SASL_H) +#include <sasl.h> +#endif + +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif +#ifdef HAVE_GSSAPI_H +#include <gssapi.h> +#elif defined(HAVE_GSSAPI_GSSAPI_KRB5_H) +#include <gssapi/gssapi.h> +#include <gssapi/gssapi_krb5.h> +#endif + +#include "ldap-nss.h" +#include "ltf.h" +#include "util.h" +#include "dnsconfig.h" +#include "pagectrl.h" + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#ifdef HAVE_PTHREAD_ATFORK +#undef HAVE_PTHREAD_ATFORK +#endif +#endif + +/* how many messages to retrieve results for */ +#ifndef LDAP_MSG_ONE +#define LDAP_MSG_ONE 0x00 +#endif +#ifndef LDAP_MSG_ALL +#define LDAP_MSG_ALL 0x01 +#endif +#ifndef LDAP_MSG_RECEIVED +#define LDAP_MSG_RECEIVED 0x02 +#endif + +#ifdef HAVE_LDAP_LD_FREE +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +extern int ldap_ld_free (LDAP * ld, int close, LDAPControl **, + LDAPControl **); +#else +extern int ldap_ld_free (LDAP * ld, int close); +#endif /* OPENLDAP 2.x */ +#endif /* HAVE_LDAP_LD_FREE */ + +NSS_LDAP_DEFINE_LOCK (__lock); + +/* + * the configuration is read by the first call to do_open(). + * Pointers to elements of the list are passed around but should not + * be freed. + */ +static char __configbuf[NSS_LDAP_CONFIG_BUFSIZ]; +static ldap_config_t *__config = NULL; + +#ifdef HAVE_SIGACTION +static struct sigaction __stored_handler; +static int __sigaction_retval = -1; +#else +static void (*__sigpipe_handler) (int) = SIG_DFL; +#endif /* HAVE_SIGACTION */ + +/* + * Global LDAP session. + */ +static ldap_session_t __session = { NULL, NULL, 0, LS_UNINITIALIZED }; + +#if defined(HAVE_PTHREAD_ATFORK) || defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) +static pthread_once_t __once = PTHREAD_ONCE_INIT; +#endif + +#ifdef LBER_OPT_LOG_PRINT_FILE +static FILE *__debugfile; +#endif /* LBER_OPT_LOG_PRINT_FILE */ + +#ifndef HAVE_PTHREAD_ATFORK +/* + * Process ID that opened the session. + */ +static pid_t __pid = -1; +#endif +static uid_t __euid = -1; + +#ifdef HAVE_LDAPSSL_CLIENT_INIT +static int __ssl_initialized = 0; +#endif /* HAVE_LDAPSSL_CLIENT_INIT */ + +#if defined(HAVE_PTHREAD_ATFORK) || defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) +/* + * Prepare for fork(); lock mutex. + */ +static void do_atfork_prepare (void); + +/* + * Forked in parent, unlock mutex. + */ +static void do_atfork_parent (void); + +/* + * Forked in child; close LDAP socket, unlock mutex. + */ +static void do_atfork_child (void); + +/* + * Install handlers for atfork, called once. + */ +static void do_atfork_setup (void); +#endif + +/* + * Close the global session, sending an unbind. + */ +static void do_close (void); + +/* + * Close the global session without sending an unbind. + */ +static void do_close_no_unbind (void); + +/* + * Disable keepalive on a LDAP connection's socket. + */ +static void do_set_sockopts (void); + +/* + * TLS routines: set global SSL session options. + */ +#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS) || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) +static int do_ssl_options (ldap_config_t * cfg); +static int do_start_tls (ldap_session_t * session); +#endif + +/* + * Read configuration file and initialize schema + */ +static NSS_STATUS do_init (void); + +/* + * Open the global session + */ +static NSS_STATUS do_open (void); + +/* + * Perform an asynchronous search. + */ +static int do_search (const char *base, int scope, + const char *filter, const char **attrs, + int sizelimit, int *); + +/* + * Perform a synchronous search. + */ +static int do_search_s (const char *base, int scope, + const char *filter, const char **attrs, + int sizelimit, LDAPMessage **); + +/* + * Fetch an LDAP result. + */ +static NSS_STATUS do_result (ent_context_t * ctx, int all); + +/* + * Format a filter given a prototype. + */ +static NSS_STATUS do_filter (const ldap_args_t * args, const char *filterprot, + ldap_service_search_descriptor_t * sd, + char *filter, size_t filterlen, + char **dynamicFilter, const char **retFilter); + +/* + * Parse a result, fetching new results until a successful parse + * or exceptional condition. + */ +static NSS_STATUS do_parse (ent_context_t * ctx, void *result, char *buffer, + size_t buflen, int *errnop, parser_t parser); + +/* + * Parse a result, fetching results from the result chain + * rather than the server. + */ +static NSS_STATUS do_parse_s (ent_context_t * ctx, void *result, char *buffer, + size_t buflen, int *errnop, parser_t parser); + +/* + * Function to be braced by reconnect harness. Used so we + * can apply the reconnect code to both asynchronous and + * synchronous searches. + */ +typedef int (*search_func_t) (const char *, int, const char *, + const char **, int, void *); + +/* + * Do a search with a reconnect harness. + */ +static NSS_STATUS +do_with_reconnect (const char *base, int scope, + const char *filter, const char **attrs, int sizelimit, + void *private, search_func_t func); + +/* + * Map error from LDAP status code to NSS status code + */ +static NSS_STATUS do_map_error (int rc); + +/* + * Do a bind with a defined timeout + */ +static int do_bind (LDAP * ld, int timelimit, const char *dn, const char *pw, + int with_sasl); + +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) +static int do_sasl_interact (LDAP * ld, unsigned flags, void *defaults, + void *p); +#endif + +static int +do_get_our_socket(int *sd); + +static int +do_dupfd(int oldfd, int newfd); + +static void +do_drop_connection(int sd, int closeSd); + +static NSS_STATUS +do_map_error (int rc) +{ + NSS_STATUS stat; + + switch (rc) + { + case LDAP_SUCCESS: + case LDAP_SIZELIMIT_EXCEEDED: + case LDAP_TIMELIMIT_EXCEEDED: + stat = NSS_SUCCESS; + break; + case LDAP_NO_SUCH_ATTRIBUTE: + case LDAP_UNDEFINED_TYPE: + case LDAP_INAPPROPRIATE_MATCHING: + case LDAP_CONSTRAINT_VIOLATION: + case LDAP_TYPE_OR_VALUE_EXISTS: + case LDAP_INVALID_SYNTAX: + case LDAP_NO_SUCH_OBJECT: + case LDAP_ALIAS_PROBLEM: + case LDAP_INVALID_DN_SYNTAX: + case LDAP_IS_LEAF: + case LDAP_ALIAS_DEREF_PROBLEM: + case LDAP_FILTER_ERROR: + stat = NSS_NOTFOUND; + break; + case LDAP_SERVER_DOWN: + case LDAP_TIMEOUT: + case LDAP_UNAVAILABLE: + case LDAP_BUSY: +#ifdef LDAP_CONNECT_ERROR + case LDAP_CONNECT_ERROR: +#endif /* LDAP_CONNECT_ERROR */ + case LDAP_LOCAL_ERROR: + case LDAP_INVALID_CREDENTIALS: + default: + stat = NSS_UNAVAIL; + break; + } + return stat; +} + +/* + * Rebind functions. + */ + +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +#if LDAP_SET_REBIND_PROC_ARGS == 3 +static int +do_rebind (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, + ber_int_t msgid, void *arg) +#else +static int +do_rebind (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid) +#endif +{ + char *who, *cred; + int timelimit; + int with_sasl = 0; + + if (geteuid () == 0 && __session.ls_config->ldc_rootbinddn) + { + who = __session.ls_config->ldc_rootbinddn; +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) + with_sasl = __session.ls_config->ldc_rootusesasl; + if (with_sasl) + { + cred = __session.ls_config->ldc_rootsaslid; + } + else + { +#endif + cred = __session.ls_config->ldc_rootbindpw; +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) + } +#endif + } + else + { + who = __session.ls_config->ldc_binddn; +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) + with_sasl = __session.ls_config->ldc_usesasl; + if (with_sasl) + { + cred = __session.ls_config->ldc_saslid; + } + else + { +#endif + cred = __session.ls_config->ldc_bindpw; +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) + } +#endif + } + + timelimit = __session.ls_config->ldc_bind_timelimit; + +#ifdef HAVE_LDAP_START_TLS_S + if (__session.ls_config->ldc_ssl_on == SSL_START_TLS) + { + int version; + + if (ldap_get_option + (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, + &version) == LDAP_OPT_SUCCESS) + { + if (version < LDAP_VERSION3) + { + version = LDAP_VERSION3; + ldap_set_option (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, + &version); + } + } + + if (do_start_tls (&__session) == LDAP_SUCCESS) + { + debug ("TLS startup succeeded"); + } + else + { + debug ("TLS startup failed"); + return NSS_UNAVAIL; + } + } +#endif /* HAVE_LDAP_START_TLS_S */ + + return do_bind (ld, timelimit, who, cred, with_sasl); +} +#else +#if LDAP_SET_REBIND_PROC_ARGS == 3 +static int +do_rebind (LDAP * ld, char **whop, char **credp, int *methodp, + int freeit, void *arg) +#elif LDAP_SET_REBIND_PROC_ARGS == 2 +static int +do_rebind (LDAP * ld, char **whop, char **credp, int *methodp, int freeit) +#endif +{ + if (freeit) + { + if (*whop != NULL) + free (*whop); + if (*credp != NULL) + free (*credp); + } + + *whop = *credp = NULL; + if (geteuid () == 0 && __session.ls_config->ldc_rootbinddn) + { + *whop = strdup (__session.ls_config->ldc_rootbinddn); + if (__session.ls_config->ldc_rootbindpw != NULL) + *credp = strdup (__session.ls_config->ldc_rootbindpw); + } + else + { + if (__session.ls_config->ldc_binddn != NULL) + *whop = strdup (__session.ls_config->ldc_binddn); + if (__session.ls_config->ldc_bindpw != NULL) + *credp = strdup (__session.ls_config->ldc_bindpw); + } + + *methodp = LDAP_AUTH_SIMPLE; + + return LDAP_SUCCESS; +} +#endif + +#ifdef HAVE_NSSWITCH_H +/* + * Default destructor. + * The entry point for this function is the destructor in the dispatch + * table for the switch. Thus, it's safe to grab the mutex from this + * function. + */ +NSS_STATUS +_nss_ldap_default_destr (nss_backend_t * be, void *args) +{ + debug ("==> _nss_ldap_default_destr"); + + if ((((nss_ldap_backend_t *) be)->state) != NULL) + { + _nss_ldap_enter (); + _nss_ldap_ent_context_release ((((nss_ldap_backend_t *) be)->state)); + free ((((nss_ldap_backend_t *) be)->state)); + ((nss_ldap_backend_t *) be)->state = NULL; + _nss_ldap_leave (); + } + + /* Ditch the backend. */ + free (be); + + debug ("<== _nss_ldap_default_destr"); + + return NSS_SUCCESS; +} + +/* + * This is the default "constructor" which gets called from each + * constructor, in the NSS dispatch table. + */ +NSS_STATUS +_nss_ldap_default_constr (nss_ldap_backend_t * be) +{ + debug ("==> _nss_ldap_default_constr"); + + be->state = NULL; +#ifdef HPUX + __thread_mutex_init (&__lock, NULL); +#endif + + debug ("<== _nss_ldap_default_constr"); + + return NSS_SUCCESS; +} +#endif /* HAVE_NSSWITCH_H */ + +#if defined(HAVE_PTHREAD_ATFORK) || defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) +static void +do_atfork_prepare (void) +{ + debug ("==> do_atfork_prepare"); + NSS_LDAP_LOCK (__lock); + debug ("<== do_atfork_prepare"); +} + +static void +do_atfork_parent (void) +{ + debug ("==> do_atfork_parent"); + NSS_LDAP_UNLOCK (__lock); + debug ("<== do_atfork_parent"); +} + +static void +do_atfork_child (void) +{ + debug ("==> do_atfork_child"); + do_close_no_unbind (); + NSS_LDAP_UNLOCK (__lock); + debug ("<== do_atfork_child"); +} + +static void +do_atfork_setup (void) +{ + debug ("==> do_atfork_setup"); + +#ifdef HAVE_PTHREAD_ATFORK + (void) pthread_atfork (do_atfork_prepare, do_atfork_parent, + do_atfork_child); +#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + (void) __libc_atfork (do_atfork_prepare, do_atfork_parent, do_atfork_child); +#endif + + debug ("<== do_atfork_setup"); +} +#endif + +/* + * Acquires global lock, blocks SIGPIPE. + */ +void +_nss_ldap_enter (void) +{ + +#ifdef HAVE_SIGACTION + struct sigaction new_handler; + + memset (&new_handler, 0, sizeof (new_handler)); +#if 0 + /* XXX need to test for sa_sigaction, not on all platforms */ + new_handler.sa_sigaction = NULL; +#endif + new_handler.sa_handler = SIG_IGN; + sigemptyset (&new_handler.sa_mask); + new_handler.sa_flags = 0; +#endif /* HAVE_SIGACTION */ + + debug ("==> _nss_ldap_enter"); + + NSS_LDAP_LOCK (__lock); + + /* + * Patch for Debian Bug 130006: + * ignore SIGPIPE for all LDAP operations. + * + * The following bug was reintroduced in nss_ldap-213 and is fixed here: + * http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=84344 + * + * See: + * http://www.gnu.org/software/libc/manual/html_node/Signal-and-Sigaction.html + * for more details. + */ +#ifdef HAVE_SIGACTION + __sigaction_retval = sigaction (SIGPIPE, &new_handler, &__stored_handler); +#elif defined(HAVE_SIGSET) + __sigpipe_handler = sigset (SIGPIPE, SIG_IGN); +#else + __sigpipe_handler = signal (SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + debug ("<== _nss_ldap_enter"); +} + +/* + * Releases global mutex, releases SIGPIPE. + */ +void +_nss_ldap_leave (void) +{ + debug ("==> _nss_ldap_leave"); + +#ifdef HAVE_SIGACTION + if (__sigaction_retval == 0) + (void) sigaction (SIGPIPE, &__stored_handler, NULL); +#else + if (__sigpipe_handler != SIG_ERR && __sigpipe_handler != SIG_IGN) + { +# ifdef HAVE_SIGSET + (void) sigset (SIGPIPE, __sigpipe_handler); +# else + (void) signal (SIGPIPE, __sigpipe_handler); +# endif /* HAVE_SIGSET */ + } +#endif /* HAVE_SIGACTION */ + + NSS_LDAP_UNLOCK (__lock); + + debug ("<== _nss_ldap_leave"); +} + +static void +do_set_sockopts (void) +{ +/* + * Netscape SSL-enabled LDAP library does not + * return the real socket. + */ +#ifndef HAVE_LDAPSSL_CLIENT_INIT + int sd = -1; + + debug ("==> do_set_sockopts"); +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_DESC) + if (ldap_get_option (__session.ls_conn, LDAP_OPT_DESC, &sd) == 0) +#else + if ((sd = __session.ls_conn->ld_sb.sb_sd) > 0) +#endif /* LDAP_OPT_DESC */ + { + int off = 0; + NSS_LDAP_SOCKLEN_T socknamelen = sizeof (NSS_LDAP_SOCKADDR_STORAGE); + NSS_LDAP_SOCKLEN_T peernamelen = sizeof (NSS_LDAP_SOCKADDR_STORAGE); + + (void) setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, (void *) &off, + sizeof (off)); + (void) fcntl (sd, F_SETFD, FD_CLOEXEC); + /* + * NSS modules shouldn't open file descriptors that the program/utility + * linked against NSS doesn't know about. The LDAP library opens a + * connection to the LDAP server transparently. There's an edge case + * where a daemon might fork a child and, being written well, closes + * all its file descriptors. This will close the socket descriptor + * being used by the LDAP library! Worse, the daemon might open many + * files and sockets, eventually opening a descriptor with the same number + * as that originally used by the LDAP library. The only way to know that + * this isn't "our" socket descriptor is to save the local and remote + * sockaddr_in structures for later comparison. + */ + (void) getsockname (sd, (struct sockaddr *) &__session.ls_sockname, + &socknamelen); + (void) getpeername (sd, (struct sockaddr *) &__session.ls_peername, + &peernamelen); + } + debug ("<== do_set_sockopts"); +#endif /* HAVE_LDAPSSL_CLIENT_INIT */ + + return; +} + +/* + * Closes connection to the LDAP server. + * This assumes that we have exclusive access to __session.ls_conn, + * either by some other function having acquired a lock, or by + * using a thread safe libldap. + */ +static void +do_close (void) +{ +#if defined(DEBUG) || defined(DEBUG_SOCKETS) + int sd = -1; +#endif + + debug ("==> do_close"); + + if (__session.ls_conn != NULL) + { +#if defined(DEBUG) || defined(DEBUG_SOCKETS) +# if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_DESC) + ldap_get_option (__session.ls_conn, LDAP_OPT_DESC, &sd); +# else + sd = __session.ls_conn->ld_sb.sb_sd; +# endif /* LDAP_OPT_DESC */ + syslog (LOG_INFO, "nss_ldap: closing connection %p fd %d", + __session.ls_conn, sd); +#endif /* DEBUG */ + + ldap_unbind (__session.ls_conn); + __session.ls_conn = NULL; + __session.ls_state = LS_UNINITIALIZED; + } + + debug ("<== do_close"); +} + +static int +do_sockaddr_isequal (NSS_LDAP_SOCKADDR_STORAGE *_s1, + NSS_LDAP_SOCKLEN_T _slen1, + NSS_LDAP_SOCKADDR_STORAGE *_s2, + NSS_LDAP_SOCKLEN_T _slen2) +{ + int ret; + + if (_s1->ss_family != _s2->ss_family) + return 0; + + if (_slen1 != _slen2) + return 0; + + ret = 0; + + switch (_s1->ss_family) + { + case AF_INET: + { + struct sockaddr_in *s1 = (struct sockaddr_in *) _s1; + struct sockaddr_in *s2 = (struct sockaddr_in *) _s2; + + ret = (s1->sin_port == s2->sin_port && + memcmp (&s1->sin_addr, &s2->sin_addr, sizeof(struct in_addr)) == 0); + break; + } + case AF_UNIX: + { + struct sockaddr_un *s1 = (struct sockaddr_un *) _s1; + struct sockaddr_un *s2 = (struct sockaddr_un *) _s2; + + ret = (memcmp (s1->sun_path, s2->sun_path, + _slen1 - sizeof (_s1->ss_family)) == 0); + break; + } +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 *s1 = (struct sockaddr_in6 *) _s1; + struct sockaddr_in6 *s2 = (struct sockaddr_in6 *) _s2; + + ret = (s1->sin6_port == s2->sin6_port && + memcmp (&s1->sin6_addr, &s2->sin6_addr, sizeof(struct in6_addr)) == 0 && + s1->sin6_scope_id == s2->sin6_scope_id); + break; + } +#endif + default: + ret = (memcmp (_s1, _s2, _slen1) == 0); + break; + } + + return ret; +} + +static int +do_get_our_socket(int *sd) +{ + /* + * Before freeing the LDAP context or closing the socket descriptor, + * we must ensure that it is *our* socket descriptor. See the much + * lengthier description of this at the end of do_open () where the + * values __session.ls_sockname and __session.ls_peername are saved. + * With HAVE_LDAPSSL_CLIENT_INIT this returns 0 if the socket has + * been closed or reopened, and sets *sd to the ldap socket + * descriptor.. Returns 1 in all other cases. + */ + + int isOurSocket = 1; + +#ifndef HAVE_LDAPSSL_CLIENT_INIT +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_DESC) + if (ldap_get_option (__session.ls_conn, LDAP_OPT_DESC, sd) == 0) +#else + if ((*sd = __session.ls_conn->ld_sb.sb_sd) > 0) +#endif /* LDAP_OPT_DESC */ + { + NSS_LDAP_SOCKADDR_STORAGE sockname; + NSS_LDAP_SOCKADDR_STORAGE peername; + NSS_LDAP_SOCKLEN_T socknamelen = sizeof (sockname); + NSS_LDAP_SOCKLEN_T peernamelen = sizeof (peername); + + if (getsockname (*sd, (struct sockaddr *) &sockname, &socknamelen) != 0 || + getpeername (*sd, (struct sockaddr *) &peername, &peernamelen) != 0) + { + isOurSocket = 0; + } + else + { + isOurSocket = do_sockaddr_isequal (&__session.ls_sockname, + socknamelen, + &sockname, + socknamelen); + if (isOurSocket) + { + isOurSocket = do_sockaddr_isequal (&__session.ls_peername, + peernamelen, + &peername, + peernamelen); + } + } + } +#endif /* HAVE_LDAPSSL_CLIENT_INIT */ + return isOurSocket; +} + +static int +do_dupfd(int oldfd, int newfd) +{ + int d = -1; + int flags; + + flags = fcntl(oldfd, F_GETFD); + + while (1) + { + d = (newfd > -1) ? dup2 (oldfd, newfd) : dup (oldfd); + if (d > -1) + break; + + if (errno == EBADF) + return -1; /* not open */ + + if (errno != EINTR +#ifdef EBUSY + && errno != EBUSY +#endif + ) + return -1; + } + + /* duplicate close-on-exec flag */ + (void) fcntl (d, F_SETFD, flags); + + return d; +} + +static int +do_closefd(int fd) +{ + int rc; + + while ((rc = close(fd)) < 0 && errno == EINTR) + ; + + return rc; +} + +static void +do_drop_connection(int sd, int closeSd) +{ + /* Close the LDAP connection without writing anything to the + underlying socket. The socket will be left open afterwards if + closeSd is 0 */ +#ifndef HAVE_LDAPSSL_CLIENT_INIT + { + int dummyfd = -1, savedfd = -1; + /* Under OpenLDAP 2.x, ldap_set_option (..., LDAP_OPT_DESC, ...) is + a no-op, so to shut down the LDAP connection without writing + anything to the socket, we swap a dummy socket onto that file + descriptor, and then swap the real fd back once the shutdown is + done. */ + savedfd = do_dupfd (sd, -1); + dummyfd = socket (AF_INET, SOCK_STREAM, 0); + if (dummyfd > -1 && dummyfd != sd) + { + do_closefd (sd); + do_dupfd (dummyfd, sd); + do_closefd (dummyfd); + } + +#ifdef HAVE_LDAP_LD_FREE +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + (void) ldap_ld_free (__session.ls_conn, 0, NULL, NULL); +#else + (void) ldap_ld_free (__session.ls_conn, 0); +#endif /* OPENLDAP 2.x */ +#else + ldap_unbind (__session.ls_conn); +#endif /* HAVE_LDAP_LD_FREE */ + + /* Do we want our original sd back? */ + do_closefd (sd); + if (savedfd > -1) + { + if (closeSd == 0) + do_dupfd (savedfd, sd); + do_closefd (savedfd); + } + } +#else /* No sd available */ + { + int bogusSd = -1; + if (closeSd == 0) + { + sd = -1; /* don't want to really close the socket */ +#ifdef HAVE_LDAP_LD_FREE +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_DESC) + (void) ldap_set_option (__session.ls_conn, LDAP_OPT_DESC, &sd); +#else + __session.ls_conn->ld_sb.sb_sd = -1; +#endif /* LDAP_OPT_DESC */ +#endif /* HAVE_LDAP_LD_FREE */ + } + +#ifdef HAVE_LDAP_LD_FREE + +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + (void) ldap_ld_free (__session.ls_conn, 0, NULL, NULL); +#else + (void) ldap_ld_free (__session.ls_conn, 0); +#endif /* OPENLDAP 2.x */ + +#else + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DESC) + (void) ldap_set_option (__session.ls_conn, LDAP_OPT_DESC, &bogusSd); +#else + __session.ls_conn->ld_sb.sb_sd = bogusSd; +#endif /* LDAP_OPT_DESC */ + + /* hope we closed it OK! */ + ldap_unbind (__session.ls_conn); + +#endif /* HAVE_LDAP_LD_FREE */ + + } +#endif /* HAVE_LDAPSSL_CLIENT_INIT */ + __session.ls_conn = NULL; + __session.ls_state = LS_UNINITIALIZED; + + return; +} + +/* + * If we've forked, then we need to open a new session. + * Careful: we have the socket shared with our parent, + * so we don't want to send an unbind to the server. + * However, we want to close the descriptor to avoid + * leaking it, and we also want to release the memory + * used by __session.ls_conn. The only entry point + * we have is ldap_unbind() which does both of these + * things, so we use an internal API, at the expense + * of compatibility. + */ +static void +do_close_no_unbind (void) +{ + int sd = -1; + int closeSd = 1; + + debug ("==> do_close_no_unbind"); + + if (__session.ls_state == LS_UNINITIALIZED) + { + assert (__session.ls_conn == NULL); + debug ("<== do_close_no_unbind (connection was not open)"); + return; + } + + closeSd = do_get_our_socket (&sd); + +#if defined(DEBUG) || defined(DEBUG_SOCKETS) + syslog (LOG_INFO, "nss_ldap: %sclosing connection (no unbind) %p fd %d", + closeSd ? "" : "not ", __session.ls_conn, sd); +#endif /* DEBUG */ + + do_drop_connection(sd, closeSd); + + debug ("<== do_close_no_unbind"); + + return; +} + +/* + * A simple alias around do_init(). + */ +NSS_STATUS +_nss_ldap_init (void) +{ + return do_init (); +} + +/* + * A simple alias around do_close(). + */ +void +_nss_ldap_close (void) +{ + do_close (); +} + +static NSS_STATUS +do_init_session (LDAP ** ld, const char *uri, int defport) +{ + int rc; + int ldaps; + char uribuf[NSS_BUFSIZ]; + char *p; + NSS_STATUS stat; + + ldaps = (strncasecmp (uri, "ldaps://", sizeof ("ldaps://") - 1) == 0); + p = strchr (uri, ':'); + /* we should be looking for the second instance to find the port number */ + if (p != NULL) + { + p = strchr (p, ':'); + } + +#ifdef HAVE_LDAP_INITIALIZE + if (p == NULL && + ((ldaps && defport != LDAPS_PORT) || (!ldaps && defport != LDAP_PORT))) + { + /* No port specified in URI and non-default port specified */ + snprintf (uribuf, sizeof (uribuf), "%s:%d", uri, defport); + uri = uribuf; + } + + rc = ldap_initialize (ld, uri); +#else + if (strncasecmp (uri, "ldap://", sizeof ("ldap://") - 1) != 0) + { + return NSS_UNAVAIL; + } + + uri += sizeof ("ldap://") - 1; + p = strchr (uri, ':'); + + if (p != NULL) + { + size_t urilen = (p - uri); + + if (urilen >= sizeof (uribuf)) + { + return NSS_UNAVAIL; + } + + memcpy (uribuf, uri, urilen); + uribuf[urilen] = '\0'; + + defport = atoi (p + 1); + uri = uribuf; + } + +# ifdef HAVE_LDAP_INIT + *ld = ldap_init (uri, defport); +# else + *ld = ldap_open (uri, defport); +# endif + + rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS; + +#endif /* HAVE_LDAP_INITIALIZE */ + + stat = do_map_error (rc); + if (stat == NSS_SUCCESS && *ld == NULL) + { + stat = NSS_UNAVAIL; + } + return stat; +} + + +static NSS_STATUS +do_init (void) +{ + ldap_config_t *cfg; +#ifndef HAVE_PTHREAD_ATFORK + pid_t pid; +#endif + uid_t euid; + NSS_STATUS stat; + int sd=-1; + + debug ("==> do_init"); + + if (_nss_ldap_validateconfig (__config) != NSS_SUCCESS) + { + do_close (); + __config = NULL; + __session.ls_current_uri = 0; + } + +#ifndef HAVE_PTHREAD_ATFORK +#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + /* + * This bogosity is necessary because Linux uses different + * PIDs for different threads (like IRIX, which we don't + * support). We can tell whether we are linked against + * libpthreads by whether __pthread_once is NULL or + * not. If it is NULL, then we're not linked with the + * threading library, and we need to compare the current + * process ID against the saved one to figure out + * whether we've forked. + * + * Once we know whether we have forked or not, + * courtesy of pthread_atfork() or us checking + * ourselves, we can close the socket to the LDAP + * server to avoid leaking a socket, and reopen + * another connection. Under no circumstances do we + * wish to use the same connection, or to send an + * unbind PDU over the parents connection, as that + * will wreak all sorts of havoc or inefficiencies, + * respectively. + */ + if (__pthread_once == NULL) + pid = getpid (); + else + pid = -1; /* linked against libpthreads, don't care */ +#else + pid = getpid (); +#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ +#endif /* HAVE_PTHREAD_ATFORK */ + + euid = geteuid (); + +#ifdef DEBUG +#ifdef HAVE_PTHREAD_ATFORK + syslog (LOG_DEBUG, + "nss_ldap: __session.ls_state=%d, __session.ls_conn=%p, __euid=%i, euid=%i", + __session.ls_state, __session.ls_conn, __euid, euid); +#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + syslog (LOG_DEBUG, + "nss_ldap: libpthreads=%s, __session.ls_state=%d, __session.ls_conn=%p, __pid=%i, pid=%i, __euid=%i, euid=%i", + (__pthread_once == NULL ? "FALSE" : "TRUE"), + __session.ls_state, + __session.ls_conn, + (__pthread_once == NULL ? __pid : -1), + (__pthread_once == NULL ? pid : -1), __euid, euid); +#else + syslog (LOG_DEBUG, + "nss_ldap: __session.ls_state=%d, __session.ls_conn=%p, __pid=%i, pid=%i, __euid=%i, euid=%i", + __session.ls_state, __session.ls_conn, __pid, pid, __euid, euid); +#endif +#endif /* DEBUG */ + + if (__session.ls_state == LS_CONNECTED_TO_DSA && + do_get_our_socket (&sd) == 0) + { + /* The calling app has stolen our socket. */ + debug (":== do_init (stolen socket detected)"); + do_drop_connection (sd, 0); + } + else +#ifndef HAVE_PTHREAD_ATFORK +#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + if (__pthread_once == NULL && __pid != pid) +#else + if (__pid != pid) +#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ + { + do_close_no_unbind (); + } + else +#endif /* HAVE_PTHREAD_ATFORK */ + if (__euid != euid && (__euid == 0 || euid == 0)) + { + /* + * If we've changed user ids, close the session so we can + * rebind as the correct user. + */ + do_close (); + } + else if (__session.ls_state == LS_CONNECTED_TO_DSA) + { + time_t current_time; + + /* + * Otherwise we can hand back this process' global + * LDAP session. + * + * Patch from Steven Barrus <sbarrus@eng.utah.edu> to + * close the session after an idle timeout. + */ + + assert (__session.ls_conn != NULL); + assert (__session.ls_config != NULL); + + if (__session.ls_config->ldc_idle_timelimit) + { + time (¤t_time); + if ((__session.ls_timestamp + + __session.ls_config->ldc_idle_timelimit) < current_time) + { + debug ("idle_timelimit reached"); + do_close (); + } + } + + /* + * If the connection is still there (ie. do_close() wasn't + * called) then we can return the cached connection. + */ + if (__session.ls_state == LS_CONNECTED_TO_DSA) + { + debug ("<== do_init (cached session)"); + return NSS_SUCCESS; + } + } + + __session.ls_conn = NULL; + __session.ls_timestamp = 0; + __session.ls_state = LS_UNINITIALIZED; + +#ifdef HAVE_PTHREAD_ATFORK + if (pthread_once (&__once, do_atfork_setup) != 0) + { + debug ("<== do_init (pthread_once failed)"); + return NSS_UNAVAIL; + } +#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + /* + * Only install the pthread_atfork() handlers i + * we are linked against libpthreads. Otherwise, + * do close the session when the PID changes. + */ + if (__pthread_once == NULL) + __pid = pid; + else + __libc_once (__once, do_atfork_setup); +#else + __pid = pid; +#endif + + __euid = euid; + + /* Initialize schema and LDAP handle (but do not connect) */ + if (__config == NULL) + { + char *configbufp = __configbuf; + size_t configbuflen = sizeof (__configbuf); + + stat = _nss_ldap_readconfig (&__config, &configbufp, &configbuflen); + if (stat == NSS_NOTFOUND) + { + /* Config was read but no host information specified; try DNS */ + stat = _nss_ldap_mergeconfigfromdns (__config, &configbufp, &configbuflen); + } + + if (stat != NSS_SUCCESS) + { + debug ("<== do_init (failed to read config)"); + return NSS_UNAVAIL; + } + } + + cfg = __config; + + _nss_ldap_init_attributes (cfg->ldc_attrtab); + _nss_ldap_init_filters (); + +#ifdef HAVE_LDAP_SET_OPTION + if (cfg->ldc_debug) + { +# ifdef LBER_OPT_LOG_PRINT_FILE + if (cfg->ldc_logdir && !__debugfile) + { + char namebuf[PATH_MAX]; + + snprintf (namebuf, sizeof (namebuf), "%s/ldap.%d", cfg->ldc_logdir, + (int) getpid ()); + __debugfile = fopen (namebuf, "a"); + + if (__debugfile != NULL) + { + ber_set_option (NULL, LBER_OPT_LOG_PRINT_FILE, __debugfile); + } + } +# endif /* LBER_OPT_LOG_PRINT_FILE */ +# ifdef LBER_OPT_DEBUG_LEVEL + if (cfg->ldc_debug) + { + ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &cfg->ldc_debug); + ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &cfg->ldc_debug); + } +# endif /* LBER_OPT_DEBUG_LEVEL */ + } +#endif /* HAVE_LDAP_SET_OPTION */ + +#ifdef HAVE_LDAPSSL_CLIENT_INIT + /* + * Initialize the SSL library. + */ + if (cfg->ldc_ssl_on == SSL_LDAPS) + { + int rc = 0; + if (__ssl_initialized == 0 + && (rc = ldapssl_client_init (cfg->ldc_sslpath, NULL)) != LDAP_SUCCESS) + { + debug ("<== do_init (ldapssl_client_init failed with rc = %d)", rc); + return NSS_UNAVAIL; + } + __ssl_initialized = 1; + } +#endif /* SSL */ + + __session.ls_conn = NULL; + + assert (__session.ls_current_uri <= NSS_LDAP_CONFIG_URI_MAX); + assert (cfg->ldc_uris[__session.ls_current_uri] != NULL); + + stat = do_init_session (&__session.ls_conn, + cfg->ldc_uris[__session.ls_current_uri], + cfg->ldc_port); + if (stat != NSS_SUCCESS) + { + debug ("<== do_init (failed to initialize LDAP session)"); + return stat; + } + + __session.ls_config = cfg; + __session.ls_state = LS_INITIALIZED; + + debug ("<== do_init (initialized session)"); + + return NSS_SUCCESS; +} + +#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS) +static int +do_start_tls (ldap_session_t * session) +{ + int rc; +#ifdef HAVE_LDAP_START_TLS + int msgid; + struct timeval tv, *timeout; + LDAPMessage *res = NULL; + + debug ("==> do_start_tls"); + + rc = ldap_start_tls (session->ls_conn, NULL, NULL, &msgid); + if (rc != LDAP_SUCCESS) + { + debug ("<== do_start_tls (ldap_start_tls failed: %s)", ldap_err2string (rc)); + return rc; + } + + if (session->ls_config->ldc_bind_timelimit == LDAP_NO_LIMIT) + { + timeout = NULL; + } + else + { + tv.tv_sec = session->ls_config->ldc_bind_timelimit; + tv.tv_usec = 0; + timeout = &tv; + } + + rc = ldap_result (session->ls_conn, msgid, 1, timeout, &res); + if (rc == -1) + { +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) + if (ldap_get_option (session->ls_conn, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS) + { + rc = LDAP_UNAVAILABLE; + } +#else + rc = ld->ld_errno; +#endif /* LDAP_OPT_ERROR_NUMBER */ + + debug ("<== do_start_tls (ldap_start_tls failed: %s)", ldap_err2string (rc)); + return rc; + } + + rc = ldap_result2error (session->ls_conn, res, 1); + if (rc != LDAP_SUCCESS) + { + debug ("<== do_start_tls (ldap_result2error failed: %s)", ldap_err2string (rc)); + return rc; + } + + rc = ldap_install_tls (session->ls_conn); +#else + rc = ldap_start_tls_s (session->ls_conn, NULL, NULL); +#endif /* HAVE_LDAP_START_TLS */ + + if (rc != LDAP_SUCCESS) + { + debug ("<== do_start_tls (start TLS failed: %s)", ldap_err2string(rc)); + return rc; + } + + return LDAP_SUCCESS; +} +#endif + +/* + * Opens connection to an LDAP server - should only be called from search + * API. Other API that just needs access to configuration and schema should + * call do_init(). + * + * As with do_close(), this assumes ownership of sess. + * It also wants to own __config: is there a potential deadlock here? XXX + */ +static NSS_STATUS +do_open (void) +{ + ldap_config_t *cfg; + int usesasl; + char *bindarg; + NSS_STATUS stat; +#ifdef LDAP_OPT_NETWORK_TIMEOUT + struct timeval tv; +#endif +#ifdef LDAP_X_OPT_CONNECT_TIMEOUT + int timeout; +#endif + int rc; + + debug ("==> do_open"); + + /* Moved the head part of do_open() into do_init() */ + stat = do_init (); + if (stat != NSS_SUCCESS) + { + debug ("<== do_open (session initialization failed)"); + return stat; + } + + assert (__session.ls_conn != NULL); + assert (__session.ls_config != NULL); + assert (__session.ls_state != LS_UNINITIALIZED); + + if (__session.ls_state == LS_CONNECTED_TO_DSA) + { + debug ("<== do_open (cached session)"); + return NSS_SUCCESS; + } + + cfg = __session.ls_config; + +#ifdef LDAP_OPT_THREAD_FN_PTRS + if (_nss_ldap_ltf_thread_init (__session.ls_conn) != NSS_SUCCESS) + { + do_close (); + debug ("<== do_open (thread initialization failed)"); + return NSS_UNAVAIL; + } +#endif /* LDAP_OPT_THREAD_FN_PTRS */ + +#if LDAP_SET_REBIND_PROC_ARGS == 3 + ldap_set_rebind_proc (__session.ls_conn, do_rebind, NULL); +#elif LDAP_SET_REBIND_PROC_ARGS == 2 + ldap_set_rebind_proc (__session.ls_conn, do_rebind); +#endif + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION) + ldap_set_option (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, + &cfg->ldc_version); +#else + __session.ls_conn->ld_version = cfg->ldc_version; +#endif /* LDAP_OPT_PROTOCOL_VERSION */ + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DEREF) + ldap_set_option (__session.ls_conn, LDAP_OPT_DEREF, &cfg->ldc_deref); +#else + __session.ls_conn->ld_deref = cfg->ldc_deref; +#endif /* LDAP_OPT_DEREF */ + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_TIMELIMIT) + ldap_set_option (__session.ls_conn, LDAP_OPT_TIMELIMIT, + &cfg->ldc_timelimit); +#else + __session.ls_conn->ld_timelimit = cfg->ldc_timelimit; +#endif /* LDAP_OPT_TIMELIMIT */ + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_X_OPT_CONNECT_TIMEOUT) + /* + * This is a new option in the Netscape SDK which sets + * the TCP connect timeout. For want of a better value, + * we use the bind_timelimit to control this. + */ + timeout = cfg->ldc_bind_timelimit * 1000; + ldap_set_option (__session.ls_conn, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout); +#endif /* LDAP_X_OPT_CONNECT_TIMEOUT */ + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT) + tv.tv_sec = cfg->ldc_bind_timelimit; + tv.tv_usec = 0; + ldap_set_option (__session.ls_conn, LDAP_OPT_NETWORK_TIMEOUT, &tv); +#endif /* LDAP_OPT_NETWORK_TIMEOUT */ + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_REFERRALS) + ldap_set_option (__session.ls_conn, LDAP_OPT_REFERRALS, + cfg->ldc_referrals ? LDAP_OPT_ON : LDAP_OPT_OFF); +#endif + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_RESTART) + ldap_set_option (__session.ls_conn, LDAP_OPT_RESTART, + cfg->ldc_restart ? LDAP_OPT_ON : LDAP_OPT_OFF); +#endif + +#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS) + if (cfg->ldc_ssl_on == SSL_START_TLS) + { + int version; + + if (ldap_get_option + (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, + &version) == LDAP_OPT_SUCCESS) + { + if (version < LDAP_VERSION3) + { + version = LDAP_VERSION3; + ldap_set_option (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, + &version); + } + } + + /* set up SSL context */ + if (do_ssl_options (cfg) != LDAP_SUCCESS) + { + do_close (); + debug ("<== do_open (SSL setup failed)"); + return NSS_UNAVAIL; + } + + stat = do_map_error (do_start_tls (&__session)); + if (stat == NSS_SUCCESS) + { + debug (":== do_open (TLS startup succeeded)"); + } + else + { + do_close (); + debug ("<== do_open (TLS startup failed)"); + return stat; + } + } + else +#endif /* HAVE_LDAP_START_TLS_S || HAVE_LDAP_START_TLS */ + + /* + * If SSL is desired, then enable it. + */ + if (cfg->ldc_ssl_on == SSL_LDAPS) + { +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) + int tls = LDAP_OPT_X_TLS_HARD; + if (ldap_set_option (__session.ls_conn, LDAP_OPT_X_TLS, &tls) != + LDAP_SUCCESS) + { + do_close (); + debug ("<== do_open (TLS setup failed)"); + return NSS_UNAVAIL; + } + + /* set up SSL context */ + if (do_ssl_options (cfg) != LDAP_SUCCESS) + { + do_close (); + debug ("<== do_open (SSL setup failed)"); + return NSS_UNAVAIL; + } + +#elif defined(HAVE_LDAPSSL_CLIENT_INIT) + if (ldapssl_install_routines (__session.ls_conn) != LDAP_SUCCESS) + { + do_close (); + debug ("<== do_open (SSL setup failed)"); + return NSS_UNAVAIL; + } +/* not in Solaris 9? */ +#ifndef LDAP_OPT_SSL +#define LDAP_OPT_SSL 0x0A +#endif + if (ldap_set_option (__session.ls_conn, LDAP_OPT_SSL, LDAP_OPT_ON) != + LDAP_SUCCESS) + { + do_close (); + debug ("<== do_open (SSL setup failed)"); + return NSS_UNAVAIL; + } +#endif + } + + /* + * If we're running as root, let us bind as a special + * user, so we can fake shadow passwords. + * Thanks to Doug Nazar <nazard@dragoninc.on.ca> for this + * patch. + */ + if (__euid == 0 && cfg->ldc_rootbinddn != NULL) + { +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) + usesasl = cfg->ldc_rootusesasl; + bindarg = + cfg->ldc_rootusesasl ? cfg->ldc_rootsaslid : cfg->ldc_rootbindpw; +#else + usesasl = 0; + bindarg = cfg->ldc_rootbindpw; +#endif + + rc = do_bind (__session.ls_conn, + cfg->ldc_bind_timelimit, + cfg->ldc_rootbinddn, bindarg, usesasl); + } + else + { +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) + usesasl = cfg->ldc_usesasl; + bindarg = cfg->ldc_usesasl ? cfg->ldc_saslid : cfg->ldc_bindpw; +#else + usesasl = 0; + bindarg = cfg->ldc_bindpw; +#endif + + rc = do_bind (__session.ls_conn, + cfg->ldc_bind_timelimit, + cfg->ldc_binddn, + cfg->ldc_bindpw, usesasl); + } + + if (rc != LDAP_SUCCESS) + { + /* log actual LDAP error code */ + syslog (LOG_INFO, + "nss_ldap: failed to bind to LDAP server %s: %s", + cfg->ldc_uris[__session.ls_current_uri], + ldap_err2string (rc)); + stat = do_map_error (rc); + do_close (); + debug ("<== do_open (failed to bind to DSA"); + } + else + { + do_set_sockopts (); + time (&__session.ls_timestamp); + __session.ls_state = LS_CONNECTED_TO_DSA; + stat = NSS_SUCCESS; + debug ("<== do_open (session connected to DSA)"); + } + + return stat; +} + +#if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) +static int +do_ssl_options (ldap_config_t * cfg) +{ + int rc; + + debug ("==> do_ssl_options"); + +#ifdef LDAP_OPT_X_TLS_RANDOM_FILE + if (cfg->ldc_tls_randfile != NULL) + { + /* rand file */ + rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE, + cfg->ldc_tls_randfile); + if (rc != LDAP_SUCCESS) + { + debug + ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_RANDOM_FILE failed"); + return LDAP_OPERATIONS_ERROR; + } + } +#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */ + + if (cfg->ldc_tls_cacertfile != NULL) + { + /* ca cert file */ + rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, + cfg->ldc_tls_cacertfile); + if (rc != LDAP_SUCCESS) + { + debug + ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTFILE failed"); + return LDAP_OPERATIONS_ERROR; + } + } + + if (cfg->ldc_tls_cacertdir != NULL) + { + /* ca cert directory */ + rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, + cfg->ldc_tls_cacertdir); + if (rc != LDAP_SUCCESS) + { + debug + ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTDIR failed"); + return LDAP_OPERATIONS_ERROR; + } + } + + /* require cert? */ + if (cfg->ldc_tls_checkpeer > -1) + { + rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, + &cfg->ldc_tls_checkpeer); + if (rc != LDAP_SUCCESS) + { + debug + ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_REQUIRE_CERT failed"); + return LDAP_OPERATIONS_ERROR; + } + } + + if (cfg->ldc_tls_ciphers != NULL) + { + /* set cipher suite, certificate and private key: */ + rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, + cfg->ldc_tls_ciphers); + if (rc != LDAP_SUCCESS) + { + debug + ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CIPHER_SUITE failed"); + return LDAP_OPERATIONS_ERROR; + } + } + + if (cfg->ldc_tls_cert != NULL) + { + rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE, cfg->ldc_tls_cert); + if (rc != LDAP_SUCCESS) + { + debug + ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CERTFILE failed"); + return LDAP_OPERATIONS_ERROR; + } + } + + if (cfg->ldc_tls_key != NULL) + { + rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE, cfg->ldc_tls_key); + if (rc != LDAP_SUCCESS) + { + debug + ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_KEYFILE failed"); + return LDAP_OPERATIONS_ERROR; + } + } + + debug ("<== do_ssl_options"); + + return LDAP_SUCCESS; +} +#endif + +static int +do_bind (LDAP * ld, int timelimit, const char *dn, const char *pw, + int with_sasl) +{ + int rc; + int msgid; + struct timeval tv; + LDAPMessage *result; + + debug("==> do_bind"); + + /* + * set timelimit in ld for select() call in ldap_pvt_connect() + * function implemented in libldap2's os-ip.c + */ + tv.tv_sec = timelimit; + tv.tv_usec = 0; + +#if (defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H))) || defined(HAVE_LDAP_GSS_BIND) + if (!with_sasl) + { +#endif + msgid = ldap_simple_bind (ld, dn, pw); + + if (msgid < 0) + { +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) + if (ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &rc) != + LDAP_SUCCESS) + { + rc = LDAP_UNAVAILABLE; + } +#else + rc = ld->ld_errno; +#endif /* LDAP_OPT_ERROR_NUMBER */ + debug ("<== do_bind"); + + return rc; + } + + rc = ldap_result (ld, msgid, 0, &tv, &result); + if (rc > 0) + { + debug ("<== do_bind"); + return ldap_result2error (ld, result, 1); + } + + /* took too long */ + if (rc == 0) + { + ldap_abandon (ld, msgid); + } +#if (defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H))) || defined(HAVE_LDAP_GSS_BIND) + } + else + { +#ifdef HAVE_LDAP_GSS_BIND + return ldap_gss_bind (ld, dn, pw, GSSSASL_NO_SECURITY_LAYER, + LDAP_SASL_GSSAPI); +#else +# ifdef CONFIGURE_KRB5_CCNAME +# ifndef CONFIGURE_KRB5_CCNAME_GSSAPI + char tmpbuf[256]; + static char envbuf[256]; +# endif + char *ccname; + const char *oldccname = NULL; + int retval; +# endif /* CONFIGURE_KRB5_CCNAME */ + + if (__config->ldc_sasl_secprops != NULL) + { + rc = + ldap_set_option (ld, LDAP_OPT_X_SASL_SECPROPS, + (void *) __config->ldc_sasl_secprops); + if (rc != LDAP_SUCCESS) + { + debug ("do_bind: unable to set SASL security properties"); + return rc; + } + } + +# ifdef CONFIGURE_KRB5_CCNAME + /* Set default Kerberos ticket cache for SASL-GSSAPI */ + /* There are probably race conditions here XXX */ + if (__config->ldc_krb5_ccname != NULL) + { + ccname = __config->ldc_krb5_ccname; +# ifdef CONFIGURE_KRB5_CCNAME_ENV + oldccname = getenv ("KRB5CCNAME"); + if (oldccname != NULL) + { + strncpy (tmpbuf, oldccname, sizeof (tmpbuf)); + tmpbuf[sizeof (tmpbuf) - 1] = '\0'; + } + else + { + tmpbuf[0] = '\0'; + } + oldccname = tmpbuf; + snprintf (envbuf, sizeof (envbuf), "KRB5CCNAME=%s", ccname); + putenv (envbuf); +# elif defined(CONFIGURE_KRB5_CCNAME_GSSAPI) + if (gss_krb5_ccache_name (&retval, ccname, &oldccname) != + GSS_S_COMPLETE) + { + debug ("do_bind: unable to set default credential cache"); + return -1; + } +# endif + } +# endif /* CONFIGURE_KRB5_CCNAME */ + + rc = ldap_sasl_interactive_bind_s (ld, dn, "GSSAPI", NULL, NULL, + LDAP_SASL_QUIET, + do_sasl_interact, (void *) pw); + +# ifdef CONFIGURE_KRB5_CCNAME + /* Restore default Kerberos ticket cache. */ + if (oldccname != NULL) + { +# ifdef CONFIGURE_KRB5_CCNAME_ENV + snprintf (envbuf, sizeof (envbuf), "KRB5CCNAME=%s", oldccname); + putenv (envbuf); +# elif defined(CONFIGURE_KRB5_CCNAME_GSSAPI) + if (gss_krb5_ccache_name (&retval, oldccname, NULL) != + GSS_S_COMPLETE) + { + debug ("do_bind: unable to restore default credential cache"); + return -1; + } +# endif + } +# endif /* CONFIGURE_KRB5_CCNAME */ + + return rc; +#endif /* HAVE_LDAP_GSS_BIND */ + } +#endif + + debug ("<== do_bind"); + + return -1; +} + +/* + * This function initializes an enumeration context, acquiring + * the global mutex. + * + * It could be done from the default constructor, under Solaris, but we + * delay it until the setXXent() function is called. + */ +ent_context_t * +_nss_ldap_ent_context_init (ent_context_t ** pctx) +{ + ent_context_t *ctx; + + _nss_ldap_enter (); + + ctx = _nss_ldap_ent_context_init_locked (pctx); + + _nss_ldap_leave (); + + return ctx; +} + +/* + * This function initializes an enumeration context. + * + * It could be done from the default constructor, under Solaris, but we + * delay it until the setXXent() function is called. + */ +ent_context_t * +_nss_ldap_ent_context_init_locked (ent_context_t ** pctx) +{ + ent_context_t *ctx; + + debug ("==> _nss_ldap_ent_context_init_locked"); + + ctx = *pctx; + + if (ctx == NULL) + { + ctx = (ent_context_t *) malloc (sizeof (*ctx)); + if (ctx == NULL) + { + debug ("<== _nss_ldap_ent_context_init_locked"); + return NULL; + } + *pctx = ctx; + } + else + { + if (ctx->ec_res != NULL) + { + ldap_msgfree (ctx->ec_res); + } + if (ctx->ec_cookie != NULL) + { + ber_bvfree (ctx->ec_cookie); + } + if (ctx->ec_msgid > -1 && do_result (ctx, LDAP_MSG_ONE) == NSS_SUCCESS) + { + ldap_abandon (__session.ls_conn, ctx->ec_msgid); + } + } + + ctx->ec_cookie = NULL; + ctx->ec_res = NULL; + ctx->ec_msgid = -1; + ctx->ec_sd = NULL; + + LS_INIT (ctx->ec_state); + + debug ("<== _nss_ldap_ent_context_init_locked"); + + return ctx; +} + +/* + * Clears a given context; we require the caller + * to acquire the lock. + */ +void +_nss_ldap_ent_context_release (ent_context_t * ctx) +{ + debug ("==> _nss_ldap_ent_context_release"); + + if (ctx == NULL) + { + debug ("<== _nss_ldap_ent_context_release"); + return; + } + + if (ctx->ec_res != NULL) + { + ldap_msgfree (ctx->ec_res); + ctx->ec_res = NULL; + } + + /* + * Abandon the search if there were more results to fetch. + */ + if (ctx->ec_msgid > -1 && do_result (ctx, LDAP_MSG_ONE) == NSS_SUCCESS) + { + ldap_abandon (__session.ls_conn, ctx->ec_msgid); + ctx->ec_msgid = -1; + } + + if (ctx->ec_cookie != NULL) + { + ber_bvfree (ctx->ec_cookie); + ctx->ec_cookie = NULL; + } + + ctx->ec_sd = NULL; + + LS_INIT (ctx->ec_state); + + if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT)) + { + do_close (); + } + + debug ("<== _nss_ldap_ent_context_release"); + + return; +} + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) +/* + * Make all triple permutations + */ +static NSS_STATUS +do_triple_permutations (const char *machine, const char *user, + const char *domain, char *bufptr, size_t buflen) +{ + /* + * Map a triple + * + * (M,U,D) + * + * to the filter + * + * (|(nisNetgroupTriple=P1)...(nisNetgroupTriple=PN)) + * + * where P1..PN are all permutations of triples that may match + * ie. including wildcards. Certainly this would be preferable + * to do server-side with an appropriate matching rule. + */ + char escaped_machine[3 * (MAXHOSTNAMELEN + 1)]; + char escaped_user[3 * (LOGNAME_MAX + 1)]; + char escaped_domain[3 * (MAXHOSTNAMELEN + 1)]; + const char *AT_NISNETGROUPTRIPLE = AT (nisNetgroupTriple); + NSS_STATUS stat; + +#define ESCAPE_TRIPLE_COMPONENT(component) do { \ + if ((component) == NULL) \ + { \ + (escaped_##component)[0] = '*'; \ + (escaped_##component)[1] = '\0'; \ + } \ + else \ + { \ + stat = _nss_ldap_escape_string((component), (escaped_##component), \ + (sizeof((escaped_##component)))); \ + if (stat != NSS_SUCCESS) \ + return stat; \ + } \ + } while (0) + + ESCAPE_TRIPLE_COMPONENT (machine); + ESCAPE_TRIPLE_COMPONENT (user); + ESCAPE_TRIPLE_COMPONENT (domain); + +#define _APPEND_STRING(_buffer, _buflen, _s, _len) do { \ + if ((_buflen) < (size_t)((_len) + 1)) \ + { \ + return NSS_TRYAGAIN; \ + } \ + memcpy((_buffer), (_s), (_len)); \ + (_buffer)[(_len)] = '\0'; \ + (_buffer) += (_len); \ + (_buflen) -= (_len); \ + } while (0) + +#define APPEND_STRING(_buffer, _buflen, _s) _APPEND_STRING(_buffer, _buflen, _s, strlen((_s))) +#define APPEND_CONSTANT_STRING(_buffer, _buflen, _s) _APPEND_STRING(_buffer, _buflen, _s, (sizeof((_s)) - 1)) + +#define APPEND_TRIPLE(_buffer, _buflen, _machine, _user, _domain) do { \ + APPEND_CONSTANT_STRING((_buffer), (_buflen), "("); \ + APPEND_STRING((_buffer), (_buflen), AT_NISNETGROUPTRIPLE); \ + APPEND_CONSTANT_STRING((_buffer), (_buflen), "=\\("); \ + if ((_machine) != NULL) \ + { \ + APPEND_STRING((_buffer), (_buflen), (_machine)); \ + } \ + APPEND_CONSTANT_STRING((_buffer), (_buflen), ","); \ + if ((_user) != NULL) \ + { \ + APPEND_STRING((_buffer), (_buflen), (_user)); \ + } \ + APPEND_CONSTANT_STRING((_buffer), (_buflen), ","); \ + if ((_domain) != NULL) \ + { \ + APPEND_STRING((_buffer), (_buflen), (_domain)); \ + } \ + APPEND_CONSTANT_STRING((_buffer), (_buflen), "\\))"); \ + } while (0) + + APPEND_CONSTANT_STRING (bufptr, buflen, "(&("); + APPEND_STRING (bufptr, buflen, AT (objectClass)); + APPEND_CONSTANT_STRING (bufptr, buflen, "="); + APPEND_STRING (bufptr, buflen, OC (nisNetgroup)); + APPEND_CONSTANT_STRING (bufptr, buflen, ")(|"); + + APPEND_TRIPLE (bufptr, buflen, escaped_machine, escaped_user, + escaped_domain); + APPEND_TRIPLE (bufptr, buflen, escaped_machine, escaped_user, NULL); + APPEND_TRIPLE (bufptr, buflen, escaped_machine, NULL, NULL); + APPEND_TRIPLE (bufptr, buflen, NULL, escaped_user, escaped_domain); + APPEND_TRIPLE (bufptr, buflen, NULL, escaped_user, NULL); + APPEND_TRIPLE (bufptr, buflen, escaped_machine, NULL, escaped_domain); + APPEND_TRIPLE (bufptr, buflen, NULL, NULL, escaped_domain); + APPEND_TRIPLE (bufptr, buflen, NULL, NULL, NULL); + + APPEND_CONSTANT_STRING (bufptr, buflen, "))"); + + return NSS_SUCCESS; +} +#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ + +/* + * AND or OR a set of filters. + */ +static NSS_STATUS +do_aggregate_filter (const char **values, + ldap_args_types_t type, + const char *filterprot, char *bufptr, size_t buflen) +{ + NSS_STATUS stat; + const char **valueP; + + assert (buflen > sizeof ("(|)")); + + bufptr[0] = '('; + bufptr[1] = (type == LA_TYPE_STRING_LIST_AND) ? '&' : '|'; + + bufptr += 2; + buflen -= 2; + + for (valueP = values; *valueP != NULL; valueP++) + { + size_t len; + char filter[LDAP_FILT_MAXSIZ], escapedBuf[LDAP_FILT_MAXSIZ]; + + stat = + _nss_ldap_escape_string (*valueP, escapedBuf, sizeof (escapedBuf)); + if (stat != NSS_SUCCESS) + return stat; + + snprintf (filter, sizeof (filter), filterprot, escapedBuf); + len = strlen (filter); + + if (buflen < len + 1 /* ')' */ ) + return NSS_TRYAGAIN; + + memcpy (bufptr, filter, len); + bufptr[len] = '\0'; + bufptr += len; + buflen -= len; + } + + if (buflen < 2) + return NSS_TRYAGAIN; + + *bufptr++ = ')'; + *bufptr++ = '\0'; + + buflen -= 2; + + return NSS_SUCCESS; +} + +/* + * Do the necessary formatting to create a string filter. + */ +static NSS_STATUS +do_filter (const ldap_args_t * args, const char *filterprot, + ldap_service_search_descriptor_t * sd, char *userBuf, + size_t userBufSiz, char **dynamicUserBuf, const char **retFilter) +{ + char buf1[LDAP_FILT_MAXSIZ], buf2[LDAP_FILT_MAXSIZ]; + char *filterBufP, filterBuf[LDAP_FILT_MAXSIZ]; + size_t filterSiz; + NSS_STATUS stat = NSS_SUCCESS; + + debug ("==> do_filter"); + + *dynamicUserBuf = NULL; + + if (args != NULL && args->la_type != LA_TYPE_NONE) + { + /* choose what to use for temporary storage */ + + if (sd != NULL && sd->lsd_filter != NULL) + { + filterBufP = filterBuf; + filterSiz = sizeof (filterBuf); + } + else + { + filterBufP = userBuf; + filterSiz = userBufSiz; + } + + switch (args->la_type) + { + case LA_TYPE_STRING: + stat = _nss_ldap_escape_string (args->la_arg1.la_string, buf1, + sizeof (buf1)); + if (stat != NSS_SUCCESS) + break; + + snprintf (filterBufP, filterSiz, filterprot, buf1); + break; + case LA_TYPE_NUMBER: + snprintf (filterBufP, filterSiz, filterprot, + args->la_arg1.la_number); + break; + case LA_TYPE_STRING_AND_STRING: + stat = _nss_ldap_escape_string (args->la_arg1.la_string, buf1, + sizeof (buf1)); + if (stat != NSS_SUCCESS) + break; + + stat = _nss_ldap_escape_string (args->la_arg2.la_string, buf2, + sizeof (buf2)); + if (stat != NSS_SUCCESS) + break; + + snprintf (filterBufP, filterSiz, filterprot, buf1, buf2); + break; + case LA_TYPE_NUMBER_AND_STRING: + stat = _nss_ldap_escape_string (args->la_arg2.la_string, buf1, + sizeof (buf1)); + if (stat != NSS_SUCCESS) + break; + + snprintf (filterBufP, filterSiz, filterprot, + args->la_arg1.la_number, buf1); + break; +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) + case LA_TYPE_TRIPLE: + do + { + stat = do_triple_permutations (args->la_arg1.la_triple.host, + args->la_arg1.la_triple.user, + args->la_arg1.la_triple.domain, + filterBufP, filterSiz); + if (stat == NSS_TRYAGAIN) + { + filterBufP = *dynamicUserBuf = realloc (*dynamicUserBuf, + 2 * filterSiz); + if (filterBufP == NULL) + return NSS_UNAVAIL; + filterSiz *= 2; + } + } + while (stat == NSS_TRYAGAIN); + break; +#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ + case LA_TYPE_STRING_LIST_OR: + case LA_TYPE_STRING_LIST_AND: + do + { + stat = do_aggregate_filter (args->la_arg1.la_string_list, + args->la_type, + filterprot, filterBufP, filterSiz); + if (stat == NSS_TRYAGAIN) + { + filterBufP = *dynamicUserBuf = realloc (*dynamicUserBuf, + 2 * filterSiz); + if (filterBufP == NULL) + return NSS_UNAVAIL; + filterSiz *= 2; + } + } + while (stat == NSS_TRYAGAIN); + break; + default: + return NSS_UNAVAIL; + break; + } + + if (stat != NSS_SUCCESS) + return stat; + + /* + * This code really needs to be cleaned up. + */ + if (sd != NULL && sd->lsd_filter != NULL) + { + size_t filterBufPLen = strlen (filterBufP); + + /* remove trailing bracket */ + if (filterBufP[filterBufPLen - 1] == ')') + filterBufP[filterBufPLen - 1] = '\0'; + + if (*dynamicUserBuf != NULL) + { + char *oldDynamicUserBuf = *dynamicUserBuf; + size_t dynamicUserBufSiz; + + dynamicUserBufSiz = filterBufPLen + strlen (sd->lsd_filter) + + sizeof ("())"); + *dynamicUserBuf = malloc (dynamicUserBufSiz); + if (*dynamicUserBuf == NULL) + { + free (oldDynamicUserBuf); + return NSS_UNAVAIL; + } + + snprintf (*dynamicUserBuf, dynamicUserBufSiz, "%s(%s))", + filterBufP, sd->lsd_filter); + free (oldDynamicUserBuf); + } + else + { + snprintf (userBuf, userBufSiz, "%s(%s))", + filterBufP, sd->lsd_filter); + } + } + + if (*dynamicUserBuf != NULL) + *retFilter = *dynamicUserBuf; + else + *retFilter = userBuf; + } + else + { + /* no arguments, probably an enumeration filter */ + if (sd != NULL && sd->lsd_filter != NULL) + { + snprintf (userBuf, userBufSiz, "(&%s(%s))", + filterprot, sd->lsd_filter); + *retFilter = userBuf; + } + else + { + *retFilter = filterprot; + } + } + + debug (":== do_filter: %s", *retFilter); + + debug ("<== do_filter"); + + return NSS_SUCCESS; +} + +/* + * Wrapper around ldap_result() to skip over search references + * and deal transparently with the last entry. + */ +static NSS_STATUS +do_result (ent_context_t * ctx, int all) +{ + int rc = LDAP_UNAVAILABLE; + NSS_STATUS stat = NSS_TRYAGAIN; + struct timeval tv, *tvp; + + debug ("==> do_result"); + + if (__session.ls_config->ldc_timelimit == LDAP_NO_LIMIT) + { + tvp = NULL; + } + else + { + tv.tv_sec = __session.ls_config->ldc_timelimit; + tv.tv_usec = 0; + tvp = &tv; + } + + do + { + if (ctx->ec_res != NULL) + { + ldap_msgfree (ctx->ec_res); + ctx->ec_res = NULL; + } + + rc = + ldap_result (__session.ls_conn, ctx->ec_msgid, all, tvp, + &ctx->ec_res); + switch (rc) + { + case -1: + case 0: +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) + if (ldap_get_option + (__session.ls_conn, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS) + { + rc = LDAP_UNAVAILABLE; + } +#else + rc = __session.ls_conn->ld_errno; +#endif /* LDAP_OPT_ERROR_NUMBER */ + syslog (LOG_ERR, "nss_ldap: could not get LDAP result - %s", + ldap_err2string (rc)); + stat = NSS_UNAVAIL; + break; + case LDAP_RES_SEARCH_ENTRY: + stat = NSS_SUCCESS; + break; + case LDAP_RES_SEARCH_RESULT: + if (all == LDAP_MSG_ALL) + { + /* we asked for the result chain, we got it. */ + stat = NSS_SUCCESS; + } + else + { +#ifdef LDAP_MORE_RESULTS_TO_RETURN + int parserc; + /* NB: this frees ctx->ec_res */ + LDAPControl **resultControls = NULL; + + ctx->ec_cookie = NULL; + + parserc = + ldap_parse_result (__session.ls_conn, ctx->ec_res, &rc, NULL, + NULL, NULL, &resultControls, 1); + if (parserc != LDAP_SUCCESS + && parserc != LDAP_MORE_RESULTS_TO_RETURN) + { + stat = NSS_UNAVAIL; + ldap_abandon (__session.ls_conn, ctx->ec_msgid); + syslog (LOG_ERR, + "nss_ldap: could not get LDAP result - %s", + ldap_err2string (rc)); + } + else if (resultControls != NULL) + { + /* See if there are any more pages to come */ + parserc = ldap_parse_page_control (__session.ls_conn, + resultControls, NULL, + &(ctx->ec_cookie)); + ldap_controls_free (resultControls); + stat = NSS_NOTFOUND; + } + else + { + stat = NSS_NOTFOUND; + } +#else + stat = NSS_NOTFOUND; +#endif /* LDAP_MORE_RESULTS_TO_RETURN */ + ctx->ec_res = NULL; + ctx->ec_msgid = -1; + } + break; + default: + stat = NSS_UNAVAIL; + break; + } + } +#ifdef LDAP_RES_SEARCH_REFERENCE + while (rc == LDAP_RES_SEARCH_REFERENCE); +#else + while (0); +#endif /* LDAP_RES_SEARCH_REFERENCE */ + + if (stat == NSS_SUCCESS) + time (&__session.ls_timestamp); + + debug ("<== do_result"); + + return stat; +} + +/* + * Function to call either do_search() or do_search_s() with + * reconnection logic. + */ +static NSS_STATUS +do_with_reconnect (const char *base, int scope, + const char *filter, const char **attrs, int sizelimit, + void *private, search_func_t search_func) +{ + int rc = LDAP_UNAVAILABLE, tries = 0, backoff = 0; + int hard = 1, start_uri = 0, log = 0; + NSS_STATUS stat = NSS_UNAVAIL; + int maxtries; + + debug ("==> do_with_reconnect"); + + /* caller must successfully call do_init() first */ + assert (__session.ls_config != NULL); + + maxtries = __session.ls_config->ldc_reconnect_maxconntries + + __session.ls_config->ldc_reconnect_tries; + + while (stat == NSS_UNAVAIL && hard && tries < maxtries) + { + if (tries >= __session.ls_config->ldc_reconnect_maxconntries) + { + if (backoff == 0) + backoff = __session.ls_config->ldc_reconnect_sleeptime; + else if (backoff < __session.ls_config->ldc_reconnect_maxsleeptime) + backoff *= 2; + + syslog (LOG_INFO, + "nss_ldap: reconnecting to LDAP server (sleeping %d seconds)...", + backoff); + (void) sleep (backoff); + } + else if (tries > 1) + { + /* Don't sleep, reconnect immediately. */ + syslog (LOG_INFO, "nss_ldap: reconnecting to LDAP server..."); + } + + /* For each "try", attempt to connect to all specified URIs */ + start_uri = __session.ls_current_uri; + do + { + stat = do_open (); + if (stat == NSS_SUCCESS) + { + stat = do_map_error (search_func (base, scope, filter, + attrs, sizelimit, private)); + } + if (stat != NSS_UNAVAIL) + break; + + log++; + + /* test in case config file could not be read */ + if (__session.ls_config != NULL) + { + assert (__session.ls_config-> + ldc_uris[__session.ls_current_uri] != NULL); + + __session.ls_current_uri++; + + if (__session.ls_config->ldc_uris[__session.ls_current_uri] == + NULL) + __session.ls_current_uri = 0; + } + } + while (__session.ls_current_uri != start_uri); + + if (stat == NSS_UNAVAIL) + { + do_close (); + + /* + * If a soft reconnect policy is specified, then do not + * try to reconnect to the LDAP server if it is down. + */ + if (__session.ls_config->ldc_reconnect_pol == LP_RECONNECT_SOFT) + hard = 0; + + ++tries; + } + } + + switch (stat) + { + case NSS_UNAVAIL: + syslog (LOG_ERR, "nss_ldap: could not search LDAP server - %s", + ldap_err2string (rc)); + break; + case NSS_TRYAGAIN: + syslog (LOG_ERR, + "nss_ldap: could not %s %sconnect to LDAP server - %s", + hard ? "hard" : "soft", tries ? "re" : "", + ldap_err2string (rc)); + stat = NSS_UNAVAIL; + break; + case NSS_SUCCESS: + if (log) + { + char *uri = __session.ls_config->ldc_uris[__session.ls_current_uri]; + + if (uri == NULL) + uri = "(null)"; + + if (tries) + syslog (LOG_INFO, + "nss_ldap: reconnected to LDAP server %s after %d attempt%s", + uri, tries, (tries == 1) ? "" : "s"); + else + syslog (LOG_INFO, "nss_ldap: reconnected to LDAP server %s", uri); + } + time (&__session.ls_timestamp); + break; + default: + break; + } + + debug ("<== do_with_reconnect"); + return stat; +} + +/* + * Synchronous search function. Don't call this directly; + * always wrap calls to this with do_with_reconnect(), or, + * better still, use _nss_ldap_search_s(). + */ +static int +do_search_s (const char *base, int scope, + const char *filter, const char **attrs, int sizelimit, + LDAPMessage ** res) +{ + int rc; + struct timeval tv, *tvp; + + debug ("==> do_search_s"); + +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_SIZELIMIT) + ldap_set_option (__session.ls_conn, LDAP_OPT_SIZELIMIT, + (void *) &sizelimit); +#else + __session.ls_conn->ld_sizelimit = sizelimit; +#endif /* LDAP_OPT_SIZELIMIT */ + + if (__session.ls_config->ldc_timelimit == LDAP_NO_LIMIT) + { + tvp = NULL; + } + else + { + tv.tv_sec = __session.ls_config->ldc_timelimit; + tv.tv_usec = 0; + tvp = &tv; + } + + rc = ldap_search_st (__session.ls_conn, base, scope, filter, + (char **) attrs, 0, tvp, res); + + debug ("<== do_search_s"); + + return rc; +} + +/* + * Asynchronous search function. Don't call this directly; + * always wrap calls to this with do_with_reconnect(), or, + * better still, use _nss_ldap_search(). + */ +static int +do_search (const char *base, int scope, + const char *filter, const char **attrs, int sizelimit, int *msgid) +{ + int rc; + LDAPControl *serverCtrls[2]; + LDAPControl **pServerCtrls; + + debug ("==> do_search"); + +#ifdef HAVE_LDAP_SEARCH_EXT + if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_PAGED_RESULTS)) + { + rc = ldap_create_page_control (__session.ls_conn, + __session.ls_config->ldc_pagesize, + NULL, 0, &serverCtrls[0]); + if (rc != LDAP_SUCCESS) + return rc; + + serverCtrls[1] = NULL; + pServerCtrls = serverCtrls; + } + else + { + pServerCtrls = NULL; + } + + rc = ldap_search_ext (__session.ls_conn, base, scope, filter, + (char **) attrs, 0, pServerCtrls, NULL, + LDAP_NO_LIMIT, sizelimit, msgid); + + if (pServerCtrls != NULL) + { + ldap_control_free (serverCtrls[0]); + serverCtrls[0] = NULL; + } + +#else +#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_SIZELIMIT) + ldap_set_option (__session.ls_conn, LDAP_OPT_SIZELIMIT, + (void *) &sizelimit); +#else + __session.ls_conn->ld_sizelimit = sizelimit; +#endif /* LDAP_OPT_SIZELIMIT */ + + *msgid = ldap_search (__session.ls_conn, base, scope, filter, + (char **) attrs, 0); + if (*msgid < 0) + { +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) + if (ldap_get_option + (__session.ls_conn, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS) + { + rc = LDAP_UNAVAILABLE; + } +#else + rc = __session.ls_conn->ld_errno; +#endif /* LDAP_OPT_ERROR_NUMBER */ + } + else + { + rc = LDAP_SUCCESS; + } +#endif /* HAVE_LDAP_SEARCH_EXT */ + + debug ("<== do_search"); + + return rc; +} + +static void +do_map_errno (NSS_STATUS status, int *errnop) +{ + switch (status) + { + case NSS_TRYAGAIN: +#ifdef HAVE_NSSWITCH_H + errno = ERANGE; + *errnop = 1; /* this is really + erange */ +#else + *errnop = ERANGE; +#endif /* HAVE_NSSWITCH_H */ + break; + +#ifndef HAVE_NSSWITCH_H + case NSS_NOTFOUND: + *errnop = ENOENT; + break; +#endif /* !HAVE_NSSWITCH_H */ + + case NSS_SUCCESS: + default: + *errnop = 0; + } +} + +/* + * Tries parser function "parser" on entries, calling do_result() + * to retrieve them from the LDAP server until one parses + * correctly or there is an exceptional condition. + */ +static NSS_STATUS +do_parse (ent_context_t * ctx, void *result, char + *buffer, size_t buflen, int *errnop, parser_t parser) +{ + NSS_STATUS parseStat = NSS_NOTFOUND; + + debug ("==> do_parse"); + + /* + * if ec_state.ls_info.ls_index is non-zero, then we don't collect another + * entry off the LDAP chain, and instead refeed the existing result to + * the parser. Once the parser has finished with it, it will return + * NSS_NOTFOUND and reset the index to -1, at which point we'll retrieve + * another entry. + */ + do + { + NSS_STATUS resultStat = NSS_SUCCESS; + + if (ctx->ec_state.ls_retry == 0 && + (ctx->ec_state.ls_type == LS_TYPE_KEY + || ctx->ec_state.ls_info.ls_index == -1)) + { + resultStat = do_result (ctx, LDAP_MSG_ONE); + } + + if (resultStat != NSS_SUCCESS) + { + /* Could not get a result; bail */ + parseStat = resultStat; + break; + } + + /* + * We have an entry; now, try to parse it. + * + * If we do not parse the entry because of a schema + * violation, the parser should return NSS_NOTFOUND. + * We'll keep on trying subsequent entries until we + * find one which is parseable, or exhaust avialable + * entries, whichever is first. + */ + parseStat = parser (ctx->ec_res, &ctx->ec_state, result, + buffer, buflen); + + /* hold onto the state if we're out of memory XXX */ + ctx->ec_state.ls_retry = (parseStat == NSS_TRYAGAIN && buffer != NULL ? 1 : 0); + + /* free entry is we're moving on */ + if (ctx->ec_state.ls_retry == 0 && + (ctx->ec_state.ls_type == LS_TYPE_KEY + || ctx->ec_state.ls_info.ls_index == -1)) + { + /* we don't need the result anymore, ditch it. */ + ldap_msgfree (ctx->ec_res); + ctx->ec_res = NULL; + } + } + while (parseStat == NSS_NOTFOUND); + + do_map_errno (parseStat, errnop); + + debug ("<== do_parse"); + + return parseStat; +} + +/* + * Parse, fetching reuslts from chain instead of server. + */ +static NSS_STATUS +do_parse_s (ent_context_t * ctx, void *result, char + *buffer, size_t buflen, int *errnop, parser_t parser) +{ + NSS_STATUS parseStat = NSS_NOTFOUND; + LDAPMessage *e = NULL; + + debug ("==> do_parse_s"); + + /* + * if ec_state.ls_info.ls_index is non-zero, then we don't collect another + * entry off the LDAP chain, and instead refeed the existing result to + * the parser. Once the parser has finished with it, it will return + * NSS_NOTFOUND and reset the index to -1, at which point we'll retrieve + * another entry. + */ + do + { + if (ctx->ec_state.ls_retry == 0 && + (ctx->ec_state.ls_type == LS_TYPE_KEY + || ctx->ec_state.ls_info.ls_index == -1)) + { + if (e == NULL) + e = ldap_first_entry (__session.ls_conn, ctx->ec_res); + else + e = ldap_next_entry (__session.ls_conn, e); + } + + if (e == NULL) + { + /* Could not get a result; bail */ + parseStat = NSS_NOTFOUND; + break; + } + + /* + * We have an entry; now, try to parse it. + * + * If we do not parse the entry because of a schema + * violation, the parser should return NSS_NOTFOUND. + * We'll keep on trying subsequent entries until we + * find one which is parseable, or exhaust avialable + * entries, whichever is first. + */ + parseStat = parser (e, &ctx->ec_state, result, buffer, buflen); + + /* hold onto the state if we're out of memory XXX */ + ctx->ec_state.ls_retry = (parseStat == NSS_TRYAGAIN && buffer != NULL ? 1 : 0); + } + while (parseStat == NSS_NOTFOUND); + + do_map_errno (parseStat, errnop); + + debug ("<== do_parse_s"); + + return parseStat; +} + +/* + * Read an entry from the directory, a la X.500. This is used + * for functions that need to retrieve attributes from a DN, + * such as the RFC2307bis group expansion function. + */ +NSS_STATUS +_nss_ldap_read (const char *dn, const char **attributes, LDAPMessage ** res) +{ + return do_with_reconnect (dn, LDAP_SCOPE_BASE, "(objectclass=*)", + attributes, 1, /* sizelimit */ res, + (search_func_t) do_search_s); +} + +/* + * Simple wrapper around ldap_get_values(). Requires that + * session is already established. + */ +char ** +_nss_ldap_get_values (LDAPMessage * e, const char *attr) +{ + if (__session.ls_state != LS_CONNECTED_TO_DSA) + { + return NULL; + } + assert (__session.ls_conn != NULL); + + return ldap_get_values (__session.ls_conn, e, (char *) attr); +} + +/* + * Simple wrapper around ldap_get_dn(). Requires that + * session is already established. + */ +char * +_nss_ldap_get_dn (LDAPMessage * e) +{ + if (__session.ls_state != LS_CONNECTED_TO_DSA) + { + return NULL; + } + assert (__session.ls_conn != NULL); + + return ldap_get_dn (__session.ls_conn, e); +} + +/* + * Simple wrapper around ldap_first_entry(). Requires that + * session is already established. + */ +LDAPMessage * +_nss_ldap_first_entry (LDAPMessage * res) +{ + if (__session.ls_state != LS_CONNECTED_TO_DSA) + { + return NULL; + } + assert (__session.ls_conn != NULL); + + return ldap_first_entry (__session.ls_conn, res); +} + +/* + * Simple wrapper around ldap_next_entry(). Requires that + * session is already established. + */ +LDAPMessage * +_nss_ldap_next_entry (LDAPMessage * res) +{ + if (__session.ls_state != LS_CONNECTED_TO_DSA) + { + return NULL; + } + assert (__session.ls_conn != NULL); + + return ldap_next_entry (__session.ls_conn, res); +} + +char * +_nss_ldap_first_attribute (LDAPMessage * entry, BerElement ** berptr) +{ + if (__session.ls_state != LS_CONNECTED_TO_DSA) + { + return NULL; + } + assert (__session.ls_conn != NULL); + + return ldap_first_attribute (__session.ls_conn, entry, berptr); +} + +char * +_nss_ldap_next_attribute (LDAPMessage * entry, BerElement * ber) +{ + if (__session.ls_state != LS_CONNECTED_TO_DSA) + { + return NULL; + } + assert (__session.ls_conn != NULL); + + return ldap_next_attribute (__session.ls_conn, entry, ber); +} + +/* + * The generic synchronous lookup cover function. + * Assumes caller holds lock. + */ +NSS_STATUS +_nss_ldap_search_s (const ldap_args_t * args, + const char *filterprot, ldap_map_selector_t sel, const + char **user_attrs, int sizelimit, LDAPMessage ** res) +{ + char sdBase[LDAP_FILT_MAXSIZ]; + const char *base = NULL; + char filterBuf[LDAP_FILT_MAXSIZ], *dynamicFilterBuf = NULL; + const char **attrs, *filter; + int scope; + NSS_STATUS stat; + ldap_service_search_descriptor_t *sd = NULL; + + debug ("==> _nss_ldap_search_s"); + + stat = do_init (); + if (stat != NSS_SUCCESS) + { + debug ("<== _nss_ldap_search_s"); + return stat; + } + + /* Set some reasonable defaults. */ + base = __session.ls_config->ldc_base; + scope = __session.ls_config->ldc_scope; + attrs = NULL; + + if (args != NULL && args->la_base != NULL) + { + sel = LM_NONE; + base = args->la_base; + } + + if (sel < LM_NONE) + { + sd = __session.ls_config->ldc_sds[sel]; + next: + if (sd != NULL) + { + size_t len = strlen (sd->lsd_base); + if (sd->lsd_base[len - 1] == ',') + { + /* is relative */ + snprintf (sdBase, sizeof (sdBase), + "%s%s", sd->lsd_base, + __session.ls_config->ldc_base); + base = sdBase; + } + else + { + base = sd->lsd_base; + } + + if (sd->lsd_scope != -1) + { + scope = sd->lsd_scope; + } + } + attrs = __session.ls_config->ldc_attrtab[sel]; + } + + stat = + do_filter (args, filterprot, sd, filterBuf, sizeof (filterBuf), + &dynamicFilterBuf, &filter); + if (stat != NSS_SUCCESS) + return stat; + + stat = do_with_reconnect (base, scope, filter, + (user_attrs != NULL) ? user_attrs : attrs, + sizelimit, res, (search_func_t) do_search_s); + + if (dynamicFilterBuf != NULL) + { + free (dynamicFilterBuf); + dynamicFilterBuf = NULL; + } + + /* If no entry was returned, try the next search descriptor. */ + if (sd != NULL && sd->lsd_next != NULL) + { + if (stat == NSS_NOTFOUND || + (stat == NSS_SUCCESS && + ldap_first_entry (__session.ls_conn, *res) == NULL)) + { + sd = sd->lsd_next; + goto next; + } + } + + debug ("<== _nss_ldap_search_s"); + + return stat; +} + +/* + * The generic lookup cover function (asynchronous). + * Assumes caller holds lock. + */ +NSS_STATUS +_nss_ldap_search (const ldap_args_t * args, + const char *filterprot, ldap_map_selector_t sel, + const char **user_attrs, int sizelimit, int *msgid, + ldap_service_search_descriptor_t ** csd) +{ + char sdBase[LDAP_FILT_MAXSIZ]; + const char *base = NULL; + char filterBuf[LDAP_FILT_MAXSIZ], *dynamicFilterBuf = NULL; + const char **attrs, *filter; + int scope; + NSS_STATUS stat; + ldap_service_search_descriptor_t *sd = NULL; + + debug ("==> _nss_ldap_search"); + + *msgid = -1; + + stat = do_init (); + if (stat != NSS_SUCCESS) + { + debug ("<== _nss_ldap_search"); + return stat; + } + + /* Set some reasonable defaults. */ + base = __session.ls_config->ldc_base; + scope = __session.ls_config->ldc_scope; + attrs = NULL; + + if (args != NULL && args->la_base != NULL) + { + sel = LM_NONE; + base = args->la_base; + } + + if (sel < LM_NONE || *csd != NULL) + { + /* + * If we were chasing multiple descriptors and there are none left, + * just quit with NSS_NOTFOUND. + */ + if (*csd != NULL) + { + sd = (*csd)->lsd_next; + if (sd == NULL) + return NSS_NOTFOUND; + } + else + { + sd = __session.ls_config->ldc_sds[sel]; + } + + *csd = sd; + + if (sd != NULL) + { + size_t len = strlen (sd->lsd_base); + if (sd->lsd_base[len - 1] == ',') + { + /* is relative */ + snprintf (sdBase, sizeof (sdBase), "%s%s", sd->lsd_base, + __session.ls_config->ldc_base); + base = sdBase; + } + else + { + base = sd->lsd_base; + } + + if (sd->lsd_scope != -1) + { + scope = sd->lsd_scope; + } + } + attrs = __session.ls_config->ldc_attrtab[sel]; + } + + stat = + do_filter (args, filterprot, sd, filterBuf, sizeof (filterBuf), + &dynamicFilterBuf, &filter); + if (stat != NSS_SUCCESS) + return stat; + + stat = do_with_reconnect (base, scope, filter, + (user_attrs != NULL) ? user_attrs : attrs, + sizelimit, msgid, (search_func_t) do_search); + + if (dynamicFilterBuf != NULL) + free (dynamicFilterBuf); + + debug ("<== _nss_ldap_search"); + + return stat; +} + +#ifdef HAVE_LDAP_SEARCH_EXT +static NSS_STATUS +do_next_page (const ldap_args_t * args, + const char *filterprot, ldap_map_selector_t sel, int + sizelimit, int *msgid, struct berval *pCookie) +{ + char sdBase[LDAP_FILT_MAXSIZ]; + const char *base = NULL; + char filterBuf[LDAP_FILT_MAXSIZ], *dynamicFilterBuf = NULL; + const char **attrs, *filter; + int scope; + NSS_STATUS stat; + ldap_service_search_descriptor_t *sd = NULL; + LDAPControl *serverctrls[2] = { + NULL, NULL + }; + + /* Set some reasonable defaults. */ + base = __session.ls_config->ldc_base; + scope = __session.ls_config->ldc_scope; + attrs = NULL; + + if (args != NULL && args->la_base != NULL) + { + sel = LM_NONE; + base = args->la_base; + } + + if (sel < LM_NONE) + { + sd = __session.ls_config->ldc_sds[sel]; + if (sd != NULL) + { + size_t len = strlen (sd->lsd_base); + if (sd->lsd_base[len - 1] == ',') + { + snprintf (sdBase, sizeof (sdBase), "%s%s", sd->lsd_base, + __session.ls_config->ldc_base); + base = sdBase; + } + else + { + base = sd->lsd_base; + } + + if (sd->lsd_scope != -1) + { + scope = sd->lsd_scope; + } + } + attrs = __session.ls_config->ldc_attrtab[sel]; + } + + stat = + do_filter (args, filterprot, sd, filterBuf, sizeof (filterBuf), + &dynamicFilterBuf, &filter); + if (stat != NSS_SUCCESS) + { + return stat; + } + + stat = + ldap_create_page_control (__session.ls_conn, + __session.ls_config->ldc_pagesize, + pCookie, 0, &serverctrls[0]); + if (stat != LDAP_SUCCESS) + { + if (dynamicFilterBuf != NULL) + free (dynamicFilterBuf); + return NSS_UNAVAIL; + } + + stat = + ldap_search_ext (__session.ls_conn, base, + __session.ls_config->ldc_scope, + filter, + (char **) attrs, 0, serverctrls, NULL, LDAP_NO_LIMIT, + sizelimit, msgid); + + ldap_control_free (serverctrls[0]); + if (dynamicFilterBuf != NULL) + free (dynamicFilterBuf); + + return (*msgid < 0) ? NSS_UNAVAIL : NSS_SUCCESS; +} +#endif /* HAVE_LDAP_SEARCH_EXT */ + +/* + * General entry point for enumeration routines. + * This should really use the asynchronous LDAP search API to avoid + * pulling down all the entries at once, particularly if the + * enumeration is not completed. + * Locks mutex. + */ +NSS_STATUS +_nss_ldap_getent (ent_context_t ** ctx, + void *result, char *buffer, size_t buflen, + int *errnop, const char *filterprot, + ldap_map_selector_t sel, parser_t parser) +{ + NSS_STATUS status; + + /* + * we need to lock here as the context may not be thread-specific + * data (under glibc, for example). Maybe we should make the lock part + * of the context. + */ + + _nss_ldap_enter (); + status = _nss_ldap_getent_ex (NULL, ctx, result, + buffer, buflen, + errnop, filterprot, sel, NULL, parser); + _nss_ldap_leave (); + + return status; +} + +/* + * Internal entry point for enumeration routines. + * Caller holds global mutex + */ +NSS_STATUS +_nss_ldap_getent_ex (ldap_args_t * args, + ent_context_t ** ctx, void *result, + char *buffer, size_t buflen, int *errnop, + const char *filterprot, + ldap_map_selector_t sel, + const char **user_attrs, parser_t parser) +{ + NSS_STATUS stat = NSS_SUCCESS; + + debug ("==> _nss_ldap_getent_ex"); + + if (*ctx == NULL || (*ctx)->ec_msgid < 0) + { + /* + * implicitly call setent() if this is the first time + * or there is no active search + */ + if (_nss_ldap_ent_context_init_locked (ctx) == NULL) + { + debug ("<== _nss_ldap_getent_ex"); + return NSS_UNAVAIL; + } + } + +next: + /* + * If ctx->ec_msgid < 0, then we haven't searched yet. Let's do it! + */ + if ((*ctx)->ec_msgid < 0) + { + int msgid; + + stat = _nss_ldap_search (args, filterprot, sel, user_attrs, + LDAP_NO_LIMIT, &msgid, &(*ctx)->ec_sd); + if (stat != NSS_SUCCESS) + { + debug ("<== _nss_ldap_getent_ex"); + return stat; + } + + (*ctx)->ec_msgid = msgid; + } + + stat = do_parse (*ctx, result, buffer, buflen, errnop, parser); + +#ifdef HAVE_LDAP_SEARCH_EXT + if (stat == NSS_NOTFOUND) + { + /* Is there another page of results? */ + if ((*ctx)->ec_cookie != NULL && (*ctx)->ec_cookie->bv_len != 0) + { + int msgid; + + stat = + do_next_page (NULL, filterprot, sel, LDAP_NO_LIMIT, &msgid, + (*ctx)->ec_cookie); + if (stat != NSS_SUCCESS) + { + debug ("<== _nss_ldap_getent_ex"); + return stat; + } + (*ctx)->ec_msgid = msgid; + stat = do_parse (*ctx, result, buffer, buflen, errnop, parser); + } + } +#endif /* HAVE_LDAP_SEARCH_EXT */ + + if (stat == NSS_NOTFOUND && (*ctx)->ec_sd != NULL) + { + (*ctx)->ec_msgid = -1; + goto next; + } + + debug ("<== _nss_ldap_getent_ex"); + + return stat; +} + +/* + * General match function. + * Locks mutex. + */ +NSS_STATUS +_nss_ldap_getbyname (ldap_args_t * args, + void *result, char *buffer, size_t buflen, int + *errnop, const char *filterprot, + ldap_map_selector_t sel, parser_t parser) +{ + NSS_STATUS stat = NSS_NOTFOUND; + ent_context_t ctx; + + _nss_ldap_enter (); + + debug ("==> _nss_ldap_getbyname"); + + ctx.ec_msgid = -1; + ctx.ec_cookie = NULL; + + stat = _nss_ldap_search_s (args, filterprot, sel, NULL, 1, &ctx.ec_res); + if (stat != NSS_SUCCESS) + { + _nss_ldap_leave (); + debug ("<== _nss_ldap_getbyname"); + return stat; + } + + /* + * we pass this along for the benefit of the services parser, + * which uses it to figure out which protocol we really wanted. + * we only pass the second argument along, as that's what we need + * in services. + */ + LS_INIT (ctx.ec_state); + ctx.ec_state.ls_type = LS_TYPE_KEY; + ctx.ec_state.ls_info.ls_key = args->la_arg2.la_string; + + stat = do_parse_s (&ctx, result, buffer, buflen, errnop, parser); + + _nss_ldap_ent_context_release (&ctx); + + /* moved unlock here to avoid race condition bug #49 */ + _nss_ldap_leave (); + + debug ("<== _nss_ldap_getbyname"); + + return stat; +} + +/* + * These functions are called from within the parser, where it is assumed + * to be safe to use the connection and the respective message. + */ + +/* + * Assign all values, bar omitvalue (if not NULL), to *valptr. + */ +NSS_STATUS +_nss_ldap_assign_attrvals (LDAPMessage * e, + const char *attr, const char *omitvalue, + char ***valptr, char **pbuffer, size_t * + pbuflen, size_t * pvalcount) +{ + char **vals; + char **valiter; + int valcount; + char **p = NULL; + + register int buflen = *pbuflen; + register char *buffer = *pbuffer; + + if (pvalcount != NULL) + { + *pvalcount = 0; + } + + if (__session.ls_conn == NULL) + { + return NSS_UNAVAIL; + } + + vals = ldap_get_values (__session.ls_conn, e, (char *) attr); + + valcount = (vals == NULL) ? 0 : ldap_count_values (vals); + if (bytesleft (buffer, buflen, char *) < (valcount + 1) * sizeof (char *)) + { + ldap_value_free (vals); + return NSS_TRYAGAIN; + } + + align (buffer, buflen, char *); + p = *valptr = (char **) buffer; + + buffer += (valcount + 1) * sizeof (char *); + buflen -= (valcount + 1) * sizeof (char *); + + if (valcount == 0) + { + *p = NULL; + *pbuffer = buffer; + *pbuflen = buflen; + return NSS_SUCCESS; + } + + valiter = vals; + + while (*valiter != NULL) + { + int vallen; + char *elt = NULL; + + if (omitvalue != NULL && strcmp (*valiter, omitvalue) == 0) + { + valcount--; + } + else + { + vallen = strlen (*valiter); + if (buflen < (size_t) (vallen + 1)) + { + ldap_value_free (vals); + return NSS_TRYAGAIN; + } + + /* copy this value into the next block of buffer space */ + elt = buffer; + buffer += vallen + 1; + buflen -= vallen + 1; + + strncpy (elt, *valiter, vallen); + elt[vallen] = '\0'; + *p = elt; + p++; + } + valiter++; + } + + *p = NULL; + *pbuffer = buffer; + *pbuflen = buflen; + + if (pvalcount != NULL) + { + *pvalcount = valcount; + } + + ldap_value_free (vals); + return NSS_SUCCESS; +} + +/* Assign a single value to *valptr. */ +NSS_STATUS +_nss_ldap_assign_attrval (LDAPMessage * e, + const char *attr, char **valptr, char **buffer, + size_t * buflen) +{ + char **vals; + int vallen; + const char *ovr, *def; + + ovr = OV (attr); + if (ovr != NULL) + { + vallen = strlen (ovr); + if (*buflen < (size_t) (vallen + 1)) + { + return NSS_TRYAGAIN; + } + + *valptr = *buffer; + + strncpy (*valptr, ovr, vallen); + (*valptr)[vallen] = '\0'; + + *buffer += vallen + 1; + *buflen -= vallen + 1; + + return NSS_SUCCESS; + } + + if (__session.ls_conn == NULL) + { + return NSS_UNAVAIL; + } + + vals = ldap_get_values (__session.ls_conn, e, (char *) attr); + if (vals == NULL) + { + def = DF (attr); + if (def != NULL) + { + vallen = strlen (def); + if (*buflen < (size_t) (vallen + 1)) + { + return NSS_TRYAGAIN; + } + + *valptr = *buffer; + + strncpy (*valptr, def, vallen); + (*valptr)[vallen] = '\0'; + + *buffer += vallen + 1; + *buflen -= vallen + 1; + + return NSS_SUCCESS; + } + else + { + return NSS_NOTFOUND; + } + } + + vallen = strlen (*vals); + if (*buflen < (size_t) (vallen + 1)) + { + ldap_value_free (vals); + return NSS_TRYAGAIN; + } + + *valptr = *buffer; + + strncpy (*valptr, *vals, vallen); + (*valptr)[vallen] = '\0'; + + *buffer += vallen + 1; + *buflen -= vallen + 1; + + ldap_value_free (vals); + + return NSS_SUCCESS; +} + +const char * +_nss_ldap_locate_userpassword (char **vals) +{ + const char *token = NULL; + size_t token_length = 0; + char **valiter; + const char *pwd = NULL; + + if (__config != NULL) + { + switch (__config->ldc_password_type) + { + case LU_RFC2307_USERPASSWORD: + token = "{CRYPT}"; + token_length = sizeof ("{CRYPT}") - 1; + break; + case LU_RFC3112_AUTHPASSWORD: + token = "CRYPT$"; + token_length = sizeof ("CRYPT$") - 1; + break; + case LU_OTHER_PASSWORD: + break; + } + } + + if (vals != NULL) + { + for (valiter = vals; *valiter != NULL; valiter++) + { + if (token_length == 0 || + strncasecmp (*valiter, token, token_length) == 0) + { + pwd = *valiter; + break; + } + } + } + + if (pwd == NULL) + pwd = "*"; + else + pwd += token_length; + + return pwd; +} + +/* + * Assign a single value to *valptr, after examining userPassword for + * a syntactically suitable value. + */ +NSS_STATUS +_nss_ldap_assign_userpassword (LDAPMessage * e, + const char *attr, char **valptr, + char **buffer, size_t * buflen) +{ + char **vals; + const char *pwd; + int vallen; + + debug ("==> _nss_ldap_assign_userpassword"); + + if (__session.ls_conn == NULL) + { + return NSS_UNAVAIL; + } + + vals = ldap_get_values (__session.ls_conn, e, (char *) attr); + pwd = _nss_ldap_locate_userpassword (vals); + + vallen = strlen (pwd); + + if (*buflen < (size_t) (vallen + 1)) + { + if (vals != NULL) + { + ldap_value_free (vals); + } + debug ("<== _nss_ldap_assign_userpassword"); + return NSS_TRYAGAIN; + } + + *valptr = *buffer; + + strncpy (*valptr, pwd, vallen); + (*valptr)[vallen] = '\0'; + + *buffer += vallen + 1; + *buflen -= vallen + 1; + + if (vals != NULL) + { + ldap_value_free (vals); + } + + debug ("<== _nss_ldap_assign_userpassword"); + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_oc_check (LDAPMessage * e, const char *oc) +{ + char **vals, **valiter; + NSS_STATUS ret = NSS_NOTFOUND; + + if (__session.ls_conn == NULL) + { + return NSS_UNAVAIL; + } + + vals = ldap_get_values (__session.ls_conn, e, AT (objectClass)); + if (vals != NULL) + { + for (valiter = vals; *valiter != NULL; valiter++) + { + if (strcasecmp (*valiter, oc) == 0) + { + ret = NSS_SUCCESS; + break; + } + } + } + + if (vals != NULL) + { + ldap_value_free (vals); + } + + return ret; +} + +#ifdef HAVE_SHADOW_H +int +_nss_ldap_shadow_date (const char *val) +{ + int date; + + if (__config->ldc_shadow_type == LS_AD_SHADOW) + { + date = atoll (val) / 864000000000LL - 134774LL; + date = (date > 99999) ? 99999 : date; + } + else + { + date = atol (val); + } + + return date; +} + +void +_nss_ldap_shadow_handle_flag (struct spwd *sp) +{ + if (__config->ldc_shadow_type == LS_AD_SHADOW) + { + if (sp->sp_flag & UF_DONT_EXPIRE_PASSWD) + sp->sp_max = 99999; + sp->sp_flag = 0; + } +} +#endif /* HAVE_SHADOW_H */ + +const char * +_nss_ldap_map_at (ldap_map_selector_t sel, const char *attribute) +{ + const char *mapped = NULL; + NSS_STATUS stat; + + stat = _nss_ldap_map_get (__config, sel, MAP_ATTRIBUTE, attribute, &mapped); + + return (stat == NSS_SUCCESS) ? mapped : attribute; +} + +const char * +_nss_ldap_unmap_at (ldap_map_selector_t sel, const char *attribute) +{ + const char *mapped = NULL; + NSS_STATUS stat; + + stat = _nss_ldap_map_get (__config, sel, MAP_ATTRIBUTE_REVERSE, attribute, &mapped); + + return (stat == NSS_SUCCESS) ? mapped : attribute; +} + +const char * +_nss_ldap_map_oc (ldap_map_selector_t sel, const char *objectclass) +{ + const char *mapped = NULL; + NSS_STATUS stat; + + stat = _nss_ldap_map_get (__config, sel, MAP_OBJECTCLASS, objectclass, &mapped); + + return (stat == NSS_SUCCESS) ? mapped : objectclass; +} + +const char * +_nss_ldap_unmap_oc (ldap_map_selector_t sel, const char *objectclass) +{ + const char *mapped = NULL; + NSS_STATUS stat; + + stat = _nss_ldap_map_get (__config, sel, MAP_OBJECTCLASS_REVERSE, objectclass, &mapped); + + return (stat == NSS_SUCCESS) ? mapped : objectclass; +} + +const char * +_nss_ldap_map_ov (const char *attribute) +{ + const char *value = NULL; + + _nss_ldap_map_get (__config, LM_NONE, MAP_OVERRIDE, attribute, &value); + + return value; +} + +const char * +_nss_ldap_map_df (const char *attribute) +{ + const char *value = NULL; + + _nss_ldap_map_get (__config, LM_NONE, MAP_DEFAULT, attribute, &value); + + return value; +} + +NSS_STATUS +_nss_ldap_map_put (ldap_config_t * config, + ldap_map_selector_t sel, + ldap_map_type_t type, + const char *from, + const char *to) +{ + ldap_datum_t key, val; + void **map; + NSS_STATUS stat; + + switch (type) + { + case MAP_ATTRIBUTE: + /* special handling for attribute mapping */ if (strcmp + (from, + "userPassword") == 0) + { + if (strcasecmp (to, "userPassword") == 0) + config->ldc_password_type = LU_RFC2307_USERPASSWORD; + else if (strcasecmp (to, "authPassword") == 0) + config->ldc_password_type = LU_RFC3112_AUTHPASSWORD; + else + config->ldc_password_type = LU_OTHER_PASSWORD; + } + else if (strcmp (from, "shadowLastChange") == 0) + { + if (strcasecmp (to, "shadowLastChange") == 0) + config->ldc_shadow_type = LS_RFC2307_SHADOW; + else if (strcasecmp (to, "pwdLastSet") == 0) + config->ldc_shadow_type = LS_AD_SHADOW; + else + config->ldc_shadow_type = LS_OTHER_SHADOW; + } + break; + case MAP_OBJECTCLASS: + case MAP_OVERRIDE: + case MAP_DEFAULT: + break; + default: + return NSS_NOTFOUND; + break; + } + + assert (sel <= LM_NONE); + map = &config->ldc_maps[sel][type]; + assert (*map != NULL); + + NSS_LDAP_DATUM_ZERO (&key); + key.data = (void *) from; + key.size = strlen (from) + 1; + + NSS_LDAP_DATUM_ZERO (&val); + val.data = (void *) to; + val.size = strlen (to) + 1; + + stat = _nss_ldap_db_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); + if (stat == NSS_SUCCESS && + (type == MAP_ATTRIBUTE || type == MAP_OBJECTCLASS)) + { + type = (type == MAP_ATTRIBUTE) ? MAP_ATTRIBUTE_REVERSE : MAP_OBJECTCLASS_REVERSE; + map = &config->ldc_maps[sel][type]; + + stat = _nss_ldap_db_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &val, &key); + } + + return stat; +} + +NSS_STATUS +_nss_ldap_map_get (ldap_config_t * config, + ldap_map_selector_t sel, + ldap_map_type_t type, + const char *from, const char **to) +{ + ldap_datum_t key, val; + void *map; + NSS_STATUS stat; + + if (config == NULL || sel > LM_NONE || type > MAP_MAX) + { + return NSS_NOTFOUND; + } + + map = config->ldc_maps[sel][type]; + assert (map != NULL); + + NSS_LDAP_DATUM_ZERO (&key); + key.data = (void *) from; + key.size = strlen (from) + 1; + + NSS_LDAP_DATUM_ZERO (&val); + + stat = _nss_ldap_db_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); + if (stat == NSS_NOTFOUND && sel != LM_NONE) + { + map = config->ldc_maps[LM_NONE][type]; + assert (map != NULL); + stat = _nss_ldap_db_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); + } + + if (stat == NSS_SUCCESS) + *to = (char *) val.data; + else + *to = NULL; + + return stat; +} + +/* + * Proxy bind support for AIX. Very simple, but should do + * the job. + */ + +#if LDAP_SET_REBIND_PROC_ARGS < 3 +static ldap_proxy_bind_args_t __proxy_args = { NULL, NULL }; +#endif + +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +#if LDAP_SET_REBIND_PROC_ARGS == 3 +static int +do_proxy_rebind (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, + ber_int_t msgid, void *arg) +#else +static int +do_proxy_rebind (LDAP * ld, LDAP_CONST char *url, int request, + ber_int_t msgid) +#endif +{ + int timelimit; +#if LDAP_SET_REBIND_PROC_ARGS == 3 + ldap_proxy_bind_args_t *who = (ldap_proxy_bind_args_t *) arg; +#else + ldap_proxy_bind_args_t *who = &__proxy_args; +#endif + + timelimit = __session.ls_config->ldc_bind_timelimit; + + return do_bind (ld, timelimit, who->binddn, who->bindpw, 0); +} +#else +#if LDAP_SET_REBIND_PROC_ARGS == 3 +static int +do_proxy_rebind (LDAP * ld, char **whop, char **credp, int *methodp, + int freeit, void *arg) +#elif LDAP_SET_REBIND_PROC_ARGS == 2 +static int +do_proxy_rebind (LDAP * ld, char **whop, char **credp, int *methodp, + int freeit) +#endif +{ +#if LDAP_SET_REBIND_PROC_ARGS == 3 + ldap_proxy_bind_args_t *who = (ldap_proxy_bind_args_t *) arg; +#else + ldap_proxy_bind_args_t *who = &__proxy_args; +#endif + if (freeit) + { + if (*whop != NULL) + free (*whop); + if (*credp != NULL) + free (*credp); + } + + *whop = who->binddn ? strdup (who->binddn) : NULL; + *credp = who->bindpw ? strdup (who->bindpw) : NULL; + + *methodp = LDAP_AUTH_SIMPLE; + + return LDAP_SUCCESS; +} +#endif + +NSS_STATUS +_nss_ldap_proxy_bind (const char *user, const char *password) +{ + ldap_args_t args; + LDAPMessage *res, *e; + NSS_STATUS stat; + int rc; +#if LDAP_SET_REBIND_PROC_ARGS == 3 + ldap_proxy_bind_args_t proxy_args_buf; + ldap_proxy_bind_args_t *proxy_args = &proxy_args_buf; +#else + ldap_proxy_bind_args_t *proxy_args = &__proxy_args; +#endif + + debug ("==> _nss_ldap_proxy_bind"); + + LA_INIT (args); + LA_TYPE (args) = LA_TYPE_STRING; + LA_STRING (args) = user; + + /* + * Binding with an empty password will always work, so don't let + * the user in if they try that. + */ + if (password == NULL || password[0] == '\0') + { + debug ("<== _nss_ldap_proxy_bind (empty password not permitted)"); + /* XXX overload */ + return NSS_TRYAGAIN; + } + + _nss_ldap_enter (); + + stat = _nss_ldap_search_s (&args, _nss_ldap_filt_getpwnam, + LM_PASSWD, NULL, 1, &res); + if (stat == NSS_SUCCESS) + { + e = _nss_ldap_first_entry (res); + if (e != NULL) + { + proxy_args->binddn = _nss_ldap_get_dn (e); + proxy_args->bindpw = password; + + if (proxy_args->binddn != NULL) + { + /* Use our special rebind procedure. */ +#if LDAP_SET_REBIND_PROC_ARGS == 3 + ldap_set_rebind_proc (__session.ls_conn, do_proxy_rebind, NULL); +#elif LDAP_SET_REBIND_PROC_ARGS == 2 + ldap_set_rebind_proc (__session.ls_conn, do_proxy_rebind); +#endif + + debug (":== _nss_ldap_proxy_bind: %s", proxy_args->binddn); + + rc = do_bind (__session.ls_conn, + __session.ls_config->ldc_bind_timelimit, + proxy_args->binddn, proxy_args->bindpw, 0); + switch (rc) + { + case LDAP_INVALID_CREDENTIALS: + /* XXX overload */ + stat = NSS_TRYAGAIN; + break; + case LDAP_NO_SUCH_OBJECT: + stat = NSS_NOTFOUND; + break; + case LDAP_SUCCESS: + stat = NSS_SUCCESS; + break; + default: + stat = NSS_UNAVAIL; + break; + } + /* + * Close the connection, don't want to continue + * being bound as this user or using this rebind proc. + */ + do_close (); + ldap_memfree (proxy_args->binddn); + } + else + { + stat = NSS_NOTFOUND; + } + proxy_args->binddn = NULL; + proxy_args->bindpw = NULL; + } + else + { + stat = NSS_NOTFOUND; + } + ldap_msgfree (res); + } + + _nss_ldap_leave (); + + debug ("<== _nss_ldap_proxy_bind"); + + return stat; +} + +#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) ||defined (HAVE_SASL_SASL_H)) +static int +do_sasl_interact (LDAP * ld, unsigned flags, void *defaults, void *_interact) +{ + char *authzid = (char *) defaults; + sasl_interact_t *interact = (sasl_interact_t *) _interact; + + while (interact->id != SASL_CB_LIST_END) + { + if (interact->id == SASL_CB_USER) + { + if (authzid != NULL) + { + interact->result = authzid; + interact->len = strlen (authzid); + } + else if (interact->defresult != NULL) + { + interact->result = interact->defresult; + interact->len = strlen (interact->defresult); + } + else + { + interact->result = ""; + interact->len = 0; + } +#if SASL_VERSION_MAJOR < 2 + interact->result = strdup (interact->result); + if (interact->result == NULL) + { + return LDAP_NO_MEMORY; + } +#endif /* SASL_VERSION_MAJOR < 2 */ + } + else + { + return LDAP_PARAM_ERROR; + } + interact++; + } + return LDAP_SUCCESS; +} +#endif + +const char ** +_nss_ldap_get_attributes (ldap_map_selector_t sel) +{ + const char **attrs = NULL; + + debug ("==> _nss_ldap_get_attributes"); + + if (sel < LM_NONE) + { + if (do_init () != NSS_SUCCESS) + { + debug ("<== _nss_ldap_get_attributes (init failed)"); + return NULL; + } + + attrs = __session.ls_config->ldc_attrtab[sel]; + } + + debug ("<== _nss_ldap_get_attributes"); + + return attrs; +} + +int +_nss_ldap_test_config_flag (unsigned int flag) +{ + if (__config != NULL && (__config->ldc_flags & flag) != 0) + return 1; + + return 0; +} + +int +_nss_ldap_test_initgroups_ignoreuser (const char *user) +{ + char **p; + + if (__config == NULL) + return 0; + + if (__config->ldc_initgroups_ignoreusers == NULL) + return 0; + + for (p = __config->ldc_initgroups_ignoreusers; *p != NULL; p++) + { + if (strcmp (*p, user) == 0) + return 1; + } + + return 0; +} + +int +_nss_ldap_get_ld_errno (char **m, char **s) +{ +#ifdef HAVE_LDAP_GET_OPTION + int rc; +#endif + int lderrno; + + if (__session.ls_conn == NULL) + { + return LDAP_UNAVAILABLE; + } + +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) + /* is this needed? */ + rc = ldap_get_option (__session.ls_conn, LDAP_OPT_ERROR_NUMBER, &lderrno); + if (rc != LDAP_SUCCESS) + return rc; +#else + lderrno = ld->ld_errno; +#endif + + if (s != NULL) + { +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_STRING) + rc = ldap_get_option (__session.ls_conn, LDAP_OPT_ERROR_STRING, s); + if (rc != LDAP_SUCCESS) + return rc; +#else + *s = ld->ld_error; +#endif + } + + if (m != NULL) + { +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_MATCHED_DN) + rc = ldap_get_option (__session.ls_conn, LDAP_OPT_MATCHED_DN, m); + if (rc != LDAP_SUCCESS) + return rc; +#else + *m = ld->ld_matched; +#endif + } + + return lderrno; +} + + diff --git a/ldap-nss.h b/ldap-nss.h new file mode 100644 index 0000000..ccea0d2 --- /dev/null +++ b/ldap-nss.h @@ -0,0 +1,903 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-nss.h,v 2.136 2006/01/13 16:15:34 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_NSS_H +#define _LDAP_NSS_LDAP_LDAP_NSS_H + +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif + +/* for glibc, use weak aliases to pthreads functions */ +#ifdef HAVE_LIBC_LOCK_H +#include <libc-lock.h> +#elif defined(HAVE_BITS_LIBC_LOCK_H) +#include <bits/libc-lock.h> +#endif + +#include <errno.h> +#include <time.h> +#include <sys/socket.h> +#include <netinet/in.h> +#ifdef HAVE_SHADOW_H +#include <shadow.h> +#endif + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +#include <netdb.h> +#include <netinet/in.h> +#include <syslog.h> + +#ifdef HAVE_NSSWITCH_H +#include <nss_common.h> +#include <nss_dbdefs.h> +#include <nsswitch.h> +#elif defined(HAVE_NSS_H) +#include <nss.h> +#elif defined(HAVE_IRS_H) +#include "irs-nss.h" +#endif + +#include "ldap-schema.h" + +#ifndef NSS_BUFSIZ +#define NSS_BUFSIZ 1024 +#endif + +#ifndef NSS_BUFLEN_GROUP +#define NSS_BUFLEN_GROUP LDAP_NSS_BUFLEN_GROUP +#endif + +#ifndef NSS_BUFLEN_PASSWD +#define NSS_BUFLEN_PASSWD NSS_BUFSIZ +#endif + +#ifndef HAVE_NSSWITCH_H +#define NSS_BUFLEN_HOSTS (NSS_BUFSIZ + (MAXALIASES + MAXALIASES + 2) * sizeof (char *)) +#define NSS_BUFLEN_NETGROUP (MAXHOSTNAMELEN * 2 + LOGNAME_MAX + 3) +#define NSS_BUFLEN_NETWORKS NSS_BUFSIZ +#define NSS_BUFLEN_PROTOCOLS NSS_BUFSIZ +#define NSS_BUFLEN_RPC NSS_BUFSIZ +#define NSS_BUFLEN_SERVICES NSS_BUFSIZ +#define NSS_BUFLEN_SHADOW NSS_BUFSIZ +#define NSS_BUFLEN_ETHERS NSS_BUFSIZ +#define NSS_BUFLEN_BOOTPARAMS NSS_BUFSIZ +#endif /* HAVE_NSSWITCH_H */ + +/* + * Timeouts for reconnecting code. Similar to rebind + * logic in Darwin NetInfo. Some may find sleeping + * unacceptable, in which case you may wish to adjust + * the constants below. + */ +#define LDAP_NSS_TRIES 5 /* number of sleeping reconnect attempts */ +#define LDAP_NSS_SLEEPTIME 4 /* seconds to sleep; doubled until max */ +#define LDAP_NSS_MAXSLEEPTIME 64 /* maximum seconds to sleep */ +#define LDAP_NSS_MAXCONNTRIES 2 /* reconnect attempts before sleeping */ + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) +#define LDAP_NSS_MAXNETGR_DEPTH 16 /* maximum depth of netgroup nesting for innetgr() */ +#endif /* HAVE_NSSWITCH_H */ + +#define LDAP_NSS_MAXGR_DEPTH 16 /* maximum depth of group nesting for getgrent()/initgroups() */ + +#if LDAP_NSS_NGROUPS > 64 +#define LDAP_NSS_BUFLEN_GROUP (NSS_BUFSIZ + (LDAP_NSS_NGROUPS * (sizeof (char *) + LOGNAME_MAX))) +#else +#define LDAP_NSS_BUFLEN_GROUP NSS_BUFSIZ +#endif /* LDAP_NSS_NGROUPS > 64 */ + +#define LDAP_NSS_BUFLEN_DEFAULT 0 + +#ifdef HAVE_USERSEC_H +#define LDAP_NSS_MAXUESS_ATTRS 8 /* maximum number of attributes in a getentry call */ +#endif /* HAVE_USERSEC_H */ + +#define LDAP_PAGESIZE 1000 + +#ifndef LDAP_FILT_MAXSIZ +#define LDAP_FILT_MAXSIZ 1024 +#endif /* !LDAP_FILT_MAXSIZ */ + +#ifndef LDAPS_PORT +#define LDAPS_PORT 636 +#endif /* !LDAPS_PORT */ + +#ifndef LOGNAME_MAX +#define LOGNAME_MAX 8 +#endif /* LOGNAME_MAX */ + +#ifndef MAP_KEY_MAXSIZ +#define MAP_KEY_MAXSIZ 64 +#endif + +#ifdef DEBUG +#ifdef DEBUG_SYSLOG +#ifdef HAVE_NSSWITCH_H +#define debug(fmt, args...) syslog(LOG_DEBUG, "nss_ldap: %s:%d thread %u - " fmt, __FILE__, __LINE__, thr_self() , ## args) +#else +#define debug(fmt, args...) syslog(LOG_DEBUG, "nss_ldap: %s:%d thread %u - " fmt, __FILE__, __LINE__, pthread_self() , ## args) +#endif /* HAVE_NSSWITCH_H */ +#else +#ifndef __GNUC__ +#include <stdarg.h> +#include <stdio.h> +static void +debug (char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + fprintf (stderr, "nss_ldap: "); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, "\n"); +} +#else +#define debug(fmt, args...) fprintf(stderr, "nss_ldap: " fmt "\n" , ## args) +#endif /* __GNUC__ */ +#endif /* DEBUG_SYSLOG */ +#else +#ifndef __GNUC__ +static void +debug (char *fmt, ...) +{ +} +#else +#define debug(fmt, args...) +#endif /* __GNUC__ */ +#endif /* DEBUG */ + +#ifdef __GNUC__ +#define alignof(ptr) __alignof__(ptr) +#define INLINE inline +#elif defined(HAVE_ALIGNOF_H) +#include <alignof.h> +#define INLINE +#else +#define alignof(ptr) (sizeof(char *)) +#define INLINE +#endif /* __GNUC__ */ + +#define align(ptr, blen, TYPE) do { \ + char *qtr = ptr; \ + ptr += alignof(TYPE) - 1; \ + ptr -= ((ptr - (char *)NULL) % alignof(TYPE)); \ + blen -= (ptr - qtr); \ + } while (0) + +/* worst case */ +#define bytesleft(ptr, blen, TYPE) ( (blen < alignof(TYPE)) ? \ + 0 : (blen - alignof(TYPE) + 1)) + +/* 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_NETMASKS, + LM_BOOTPARAMS, + LM_ALIASES, + LM_NETGROUP, + LM_AUTOMOUNT, + LM_NONE +}; + +typedef enum ldap_map_selector ldap_map_selector_t; + +enum ldap_userpassword_selector +{ + LU_RFC2307_USERPASSWORD, + LU_RFC3112_AUTHPASSWORD, + LU_OTHER_PASSWORD +}; + +typedef enum ldap_userpassword_selector ldap_userpassword_selector_t; + +enum ldap_shadow_selector +{ + LS_RFC2307_SHADOW, + LS_AD_SHADOW, + LS_OTHER_SHADOW +}; + +typedef enum ldap_shadow_selector ldap_shadow_selector_t; + +#ifndef UF_DONT_EXPIRE_PASSWD +#define UF_DONT_EXPIRE_PASSWD 0x10000 +#endif + +enum ldap_ssl_options +{ + SSL_OFF, + SSL_LDAPS, + SSL_START_TLS +}; + +typedef enum ldap_ssl_options ldap_ssl_options_t; + +enum ldap_reconnect_policy +{ + LP_RECONNECT_HARD_INIT, + LP_RECONNECT_HARD_OPEN, + LP_RECONNECT_SOFT +}; + +typedef enum ldap_reconnect_policy ldap_reconnect_policy_t; + +/* + * POSIX profile information (not used yet) + * see draft-joslin-config-schema-00.txt + */ +struct ldap_service_search_descriptor +{ + /* search base, qualified */ + char *lsd_base; + /* scope */ + int lsd_scope; + /* filter */ + char *lsd_filter; + /* next */ + struct ldap_service_search_descriptor *lsd_next; +}; + +typedef struct ldap_service_search_descriptor + ldap_service_search_descriptor_t; + +/* maximum number of URIs */ +#define NSS_LDAP_CONFIG_URI_MAX 31 + +/* + * linked list of configurations pointing to LDAP servers. The first + * which has a successful ldap_open() is used. Conceivably the rest + * could be used after a failed or exhausted search. + */ +struct ldap_config +{ + /* NULL terminated list of URIs */ + char *ldc_uris[NSS_LDAP_CONFIG_URI_MAX + 1]; + /* default port, if not specified in URI */ + int ldc_port; + /* base DN, eg. dc=gnu,dc=org */ + char *ldc_base; + /* scope for searches */ + int ldc_scope; + /* dereference aliases/links */ + int ldc_deref; + /* bind DN */ + char *ldc_binddn; + /* bind cred */ + char *ldc_bindpw; + /* sasl auth id */ + char *ldc_saslid; + /* do we use sasl when binding? */ + int ldc_usesasl; + /* shadow bind DN */ + char *ldc_rootbinddn; + /* shadow bind cred */ + char *ldc_rootbindpw; + /* shadow sasl auth id */ + char *ldc_rootsaslid; + /* do we use sasl for root? */ + int ldc_rootusesasl; + /* protocol version */ + int ldc_version; + /* search timelimit */ + int ldc_timelimit; + /* bind timelimit */ + int ldc_bind_timelimit; + /* SSL enabled */ + ldap_ssl_options_t ldc_ssl_on; + /* SSL certificate path */ + char *ldc_sslpath; + /* Chase referrals */ + int ldc_referrals; + int ldc_restart; + /* naming contexts */ + ldap_service_search_descriptor_t *ldc_sds[LM_NONE]; + /* tls check peer */ + int ldc_tls_checkpeer; + /* tls ca certificate file */ + char *ldc_tls_cacertfile; + /* tls ca certificate dir */ + char *ldc_tls_cacertdir; + /* tls ciphersuite */ + char *ldc_tls_ciphers; + /* tls certificate */ + char *ldc_tls_cert; + /* tls key */ + char *ldc_tls_key; + /* tls randfile */ + char *ldc_tls_randfile; + /* idle timeout */ + time_t ldc_idle_timelimit; + /* reconnect policy */ + ldap_reconnect_policy_t ldc_reconnect_pol; + int ldc_reconnect_tries; + int ldc_reconnect_sleeptime; + int ldc_reconnect_maxsleeptime; + int ldc_reconnect_maxconntries; + + /* sasl security */ + char *ldc_sasl_secprops; + /* DNS SRV RR domain */ + char *ldc_srv_domain; + /* directory for debug files */ + char *ldc_logdir; + /* LDAP debug level */ + int ldc_debug; + int ldc_pagesize; +#ifdef CONFIGURE_KRB5_CCNAME + /* krb5 ccache name */ + char *ldc_krb5_ccname; +#endif /* CONFIGURE_KRB5_CCNAME */ + /* + * attribute/objectclass maps relative to this config + */ + void *ldc_maps[LM_NONE + 1][6]; /* must match MAP_MAX */ + + /* + * is userPassword "userPassword" or not? + * ie. do we need {crypt} to be stripped + */ + ldap_userpassword_selector_t ldc_password_type; + /* + * Use active directory time offsets? + */ + ldap_shadow_selector_t ldc_shadow_type; + + /* + * attribute table for ldap search requensts + */ + const char **ldc_attrtab[LM_NONE + 1]; + + unsigned int ldc_flags; + + /* last modification time */ + time_t ldc_mtime; + + char **ldc_initgroups_ignoreusers; +}; + +typedef struct ldap_config ldap_config_t; + +#ifdef HAVE_SOCKLEN_T +typedef socklen_t NSS_LDAP_SOCKLEN_T; +#else +typedef int NSS_LDAP_SOCKLEN_T; +#endif /* HAVE_SOCKLEN_T */ + +#if defined(__GLIBC__) && __GLIBC_MINOR__ > 1 +typedef struct sockaddr_storage NSS_LDAP_SOCKADDR_STORAGE; +#else +typedef struct sockaddr NSS_LDAP_SOCKADDR_STORAGE; +#define ss_family sa_family +#endif /* __GLIBC__ */ + +enum ldap_session_state +{ + LS_UNINITIALIZED = -1, + LS_INITIALIZED, + LS_CONNECTED_TO_DSA +}; + +typedef enum ldap_session_state ldap_session_state_t; + +/* + * convenient wrapper around pointer into global config list, and a + * connection to an LDAP server. + */ +struct ldap_session +{ + /* the connection */ + LDAP *ls_conn; + /* pointer into config table */ + ldap_config_t *ls_config; + /* timestamp of last activity */ + time_t ls_timestamp; + /* has session been connected? */ + ldap_session_state_t ls_state; + /* keep track of the LDAP sockets */ + NSS_LDAP_SOCKADDR_STORAGE ls_sockname; + NSS_LDAP_SOCKADDR_STORAGE ls_peername; + /* index into ldc_uris: currently connected DSA */ + int ls_current_uri; +}; + +typedef struct ldap_session ldap_session_t; + +#ifndef HAVE_NSSWITCH_H +#ifndef UID_NOBODY +#define UID_NOBODY (-2) +#endif +#endif + +#ifndef GID_NOBODY +#define GID_NOBODY UID_NOBODY +#endif + +enum ldap_args_types +{ + LA_TYPE_STRING, + LA_TYPE_NUMBER, + LA_TYPE_STRING_AND_STRING, + LA_TYPE_NUMBER_AND_STRING, + LA_TYPE_TRIPLE, + LA_TYPE_STRING_LIST_OR, + LA_TYPE_STRING_LIST_AND, + LA_TYPE_NONE +}; + +typedef enum ldap_args_types ldap_args_types_t; + +enum ldap_map_type +{ + MAP_ATTRIBUTE = 0, + MAP_OBJECTCLASS, + MAP_OVERRIDE, + MAP_DEFAULT, + MAP_ATTRIBUTE_REVERSE, + MAP_OBJECTCLASS_REVERSE, /* XXX not used yet? */ + MAP_MAX = MAP_OBJECTCLASS_REVERSE +}; + +typedef enum ldap_map_type ldap_map_type_t; + +struct ldap_args +{ + ldap_args_types_t la_type; + union + { + const char *la_string; + long la_number; + struct { + /* for Solaris netgroup support */ + const char *host; + const char *user; + const char *domain; + } la_triple; + const char **la_string_list; + } + la_arg1; + union + { + const char *la_string; + } + la_arg2; + const char *la_base; /* override default base */ +}; + +typedef struct ldap_args ldap_args_t; + +#define LA_INIT(q) do { \ + (q).la_type = LA_TYPE_STRING; \ + (q).la_arg1.la_string = NULL; \ + (q).la_arg2.la_string = NULL; \ + (q).la_base = NULL; \ + } while (0) +#define LA_TYPE(q) ((q).la_type) +#define LA_STRING(q) ((q).la_arg1.la_string) +#define LA_NUMBER(q) ((q).la_arg1.la_number) +#define LA_TRIPLE(q) ((q).la_arg1.la_triple) +#define LA_STRING_LIST(q) ((q).la_arg1.la_string_list) +#define LA_STRING2(q) ((q).la_arg2.la_string) +#define LA_BASE(q) ((q).la_base) + +#include "ldap-parse.h" + +/* + * the state consists of the desired attribute value or an offset into a list of + * values for the desired attribute. This is necessary to support services. + * + * Be aware of the arbitary distinction between state and context. Context is + * the enumeration state of a lookup subsystem (which may be per-subsystem, + * or per-subsystem/per-thread, depending on the OS). State is the state + * of a particular lookup, and is only concerned with resolving and enumerating + * services. State is represented as instances of ldap_state_t; context as + * instances of ent_context_t. The latter contains the former. + */ +struct ldap_state +{ + int ls_type; + int ls_retry; +#define LS_TYPE_KEY (0) +#define LS_TYPE_INDEX (1) + union + { + /* ls_key is the requested attribute value. + ls_index is the desired offset into the value list. + */ + const char *ls_key; + int ls_index; + } + ls_info; +}; + +typedef struct ldap_state ldap_state_t; +/* + * LS_INIT only used for enumeration contexts + */ +#define LS_INIT(state) do { state.ls_type = LS_TYPE_INDEX; state.ls_retry = 0; state.ls_info.ls_index = -1; } while (0) + +/* + * thread specific context: result chain, and state data + */ +struct ent_context +{ + ldap_state_t ec_state; /* eg. for services */ + int ec_msgid; /* message ID */ + LDAPMessage *ec_res; /* result chain */ + ldap_service_search_descriptor_t *ec_sd; /* current sd */ + struct berval *ec_cookie; /* cookie for paged searches */ +}; + +typedef struct ent_context ent_context_t; + +struct name_list +{ + char *name; + struct name_list *next; +}; + +#ifdef HAVE_NSSWITCH_H + +struct nss_ldap_backend +{ + nss_backend_op_t *ops; + int n_ops; + ent_context_t *state; +}; + +typedef struct nss_ldap_backend nss_ldap_backend_t; + +struct nss_ldap_netgr_backend +{ + nss_backend_op_t *ops; + int n_ops; + ent_context_t *state; + struct name_list *known_groups; /* netgroups seen, for loop detection */ + struct name_list *needed_groups; /* nested netgroups to chase */ +}; + +typedef struct nss_ldap_netgr_backend nss_ldap_netgr_backend_t; + +typedef nss_status_t NSS_STATUS; + +#define NSS_RETURN NSS_UNAVAIL + +#elif defined(HAVE_IRS_H) + +typedef enum +{ + NSS_TRYAGAIN = -2, + NSS_UNAVAIL, + NSS_NOTFOUND, + NSS_SUCCESS, + NSS_RETURN +} +NSS_STATUS; + +struct nss_ldap_netgr_backend +{ + char buffer[NSS_BUFLEN_NETGROUP]; + ent_context_t *state; + struct name_list *known_groups; /* netgroups seen, for loop detection */ + struct name_list *needed_groups; /* nested netgroups to chase */ +}; + +typedef struct nss_ldap_netgr_backend nss_ldap_netgr_backend_t; +#elif defined(HAVE_NSS_H) + +typedef enum nss_status NSS_STATUS; + +#define NSS_SUCCESS NSS_STATUS_SUCCESS +#define NSS_NOTFOUND NSS_STATUS_NOTFOUND +#define NSS_UNAVAIL NSS_STATUS_UNAVAIL +#define NSS_TRYAGAIN NSS_STATUS_TRYAGAIN +#define NSS_RETURN NSS_STATUS_RETURN + +/* to let us index a lookup table on NSS_STATUSes */ + +#define _NSS_LOOKUP_OFFSET NSS_STATUS_TRYAGAIN + +#endif /* HAVE_NSSWITCH_H */ + +#ifndef _NSS_LOOKUP_OFFSET +#define _NSS_LOOKUP_OFFSET (0) +#endif + +typedef NSS_STATUS (*parser_t) (LDAPMessage *, ldap_state_t *, void *, + char *, size_t); + +#ifdef HPUX +extern int __thread_mutex_lock(pthread_mutex_t *); +extern int __thread_mutex_unlock(pthread_mutex_t *); +#endif /* HPUX */ + +#ifdef _AIX +extern int __multi_threaded; +#endif /* _AIX */ + +/* + * Portable locking macro. + */ +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#define NSS_LDAP_LOCK(m) mutex_lock(&m) +#define NSS_LDAP_UNLOCK(m) mutex_unlock(&m) +#define NSS_LDAP_DEFINE_LOCK(m) static mutex_t m = DEFAULTMUTEX +#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) +#define NSS_LDAP_LOCK(m) __libc_lock_lock(m) +#define NSS_LDAP_UNLOCK(m) __libc_lock_unlock(m) +#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER +#elif defined(HAVE_PTHREAD_H) +#ifdef HPUX +# define NSS_LDAP_LOCK(m) __thread_mutex_lock(&m) +# define NSS_LDAP_UNLOCK(m) __thread_mutex_unlock(&m) +# define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER +#elif defined(_AIX) +# define NSS_LDAP_LOCK(m) do { \ + if (__multi_threaded) \ + pthread_mutex_lock(&m); \ + } while (0) +# define NSS_LDAP_UNLOCK(m) do { \ + if (__multi_threaded) \ + pthread_mutex_unlock(&m); \ + } while (0) +# define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER +#else +# define NSS_LDAP_LOCK(m) pthread_mutex_lock(&m) +# define NSS_LDAP_UNLOCK(m) pthread_mutex_unlock(&m) +# define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER +#endif /* HPUX || _AIX */ +#else +#define NSS_LDAP_LOCK(m) +#define NSS_LDAP_UNLOCK(m) +#define NSS_LDAP_DEFINE_LOCK(m) +#endif + +/* + * Acquire global nss_ldap lock and blocks SIGPIPE. + * Generally this should only be done within ldap-nss.c. + */ +void _nss_ldap_enter (void); + +/* + * Release global nss_ldap lock and blocks SIGPIPE. + * Generally this should only be done within ldap-nss.c. + */ +void _nss_ldap_leave (void); + +#ifdef LDAP_OPT_THREAD_FN_PTRS +/* + * Netscape's libldap is threadsafe, but we use a + * lock before it is initialized + */ + +struct ldap_error +{ + int le_errno; + char *le_matched; + char *le_errmsg; +}; + +typedef struct ldap_error ldap_error_t; + +#endif /* LDAP_OPT_THREAD_FN_PTRS */ + +#ifdef HAVE_NSSWITCH_H +NSS_STATUS _nss_ldap_default_destr (nss_backend_t *, void *); +#endif + +/* + * context management routines. + * _nss_ldap_default_constr() is called once in the constructor + */ +#ifdef HAVE_NSSWITCH_H +NSS_STATUS _nss_ldap_default_constr (nss_ldap_backend_t * be); +#endif + +/* + * _nss_ldap_ent_context_init() is called for each getXXent() call + * This will acquire the global mutex. + */ +ent_context_t *_nss_ldap_ent_context_init (ent_context_t **); + +/* + * _nss_ldap_ent_context_init_locked() has the same behaviour + * as above, except it assumes that the caller has acquired + * the lock + */ + +ent_context_t *_nss_ldap_ent_context_init_locked (ent_context_t **); + +/* + * _nss_ldap_ent_context_release() is used to manually free a context + */ +void _nss_ldap_ent_context_release (ent_context_t *); + +/* + * these are helper functions for ldap-grp.c only on Solaris + */ +char **_nss_ldap_get_values (LDAPMessage * e, const char *attr); +char *_nss_ldap_get_dn (LDAPMessage * e); +LDAPMessage *_nss_ldap_first_entry (LDAPMessage * res); +LDAPMessage *_nss_ldap_next_entry (LDAPMessage * res); +char *_nss_ldap_first_attribute (LDAPMessage * entry, BerElement **berptr); +char *_nss_ldap_next_attribute (LDAPMessage * entry, BerElement *ber); +const char **_nss_ldap_get_attributes (ldap_map_selector_t sel); + +/* + * Synchronous search cover (caller acquires lock). + */ +NSS_STATUS _nss_ldap_search_s (const ldap_args_t * args, /* IN */ + const char *filterprot, /* IN */ + ldap_map_selector_t sel, /* IN */ + const char **user_attrs, /* IN */ + int sizelimit, /* IN */ + LDAPMessage ** pRes /* OUT */ ); + +/* + * Asynchronous search cover (caller acquires lock). + */ +NSS_STATUS _nss_ldap_search (const ldap_args_t * args, /* IN */ + const char *filterprot, /* IN */ + ldap_map_selector_t sel, /* IN */ + const char **user_attrs, /* IN */ + int sizelimit, /* IN */ + int *pMsgid, /* OUT */ + ldap_service_search_descriptor_t **s /*IN/OUT*/ ); + +/* + * Emulate X.500 read operation. + */ +NSS_STATUS _nss_ldap_read (const char *dn, /* IN */ + const char **attributes, /* IN */ + LDAPMessage ** pRes /* OUT */ ); + +/* + * extended enumeration routine; uses asynchronous API. + * Caller must have acquired the global mutex + */ +NSS_STATUS _nss_ldap_getent_ex (ldap_args_t * args, /* IN */ + ent_context_t ** key, /* IN/OUT */ + void *result, /* IN/OUT */ + char *buffer, /* IN */ + size_t buflen, /* IN */ + int *errnop, /* OUT */ + const char *filterprot, /* IN */ + ldap_map_selector_t sel, /* IN */ + const char **user_attrs, /* IN */ + parser_t parser /* IN */ ); + +/* + * common enumeration routine; uses asynchronous API. + * Acquires the global mutex + */ +NSS_STATUS _nss_ldap_getent (ent_context_t ** key, /* IN/OUT */ + void *result, /* IN/OUT */ + char *buffer, /* IN */ + size_t buflen, /* IN */ + int *errnop, /* OUT */ + const char *filterprot, /* IN */ + ldap_map_selector_t sel, /* IN */ + parser_t parser /* IN */ ); + +/* + * common lookup routine; uses synchronous API. + */ +NSS_STATUS _nss_ldap_getbyname (ldap_args_t * args, /* IN/OUT */ + void *result, /* IN/OUT */ + char *buffer, /* IN */ + size_t buflen, /* IN */ + int *errnop, /* OUT */ + const char *filterprot, /* IN */ + ldap_map_selector_t sel, /* IN */ + parser_t parser /* IN */ ); + +/* parsing utility functions */ +NSS_STATUS _nss_ldap_assign_attrvals (LDAPMessage * e, /* IN */ + const char *attr, /* IN */ + const char *omitvalue, /* IN */ + char ***valptr, /* OUT */ + char **buffer, /* IN/OUT */ + size_t * buflen, /* IN/OUT */ + size_t * pvalcount /* OUT */ ); + +NSS_STATUS _nss_ldap_assign_attrval (LDAPMessage * e, /* IN */ + const char *attr, /* IN */ + char **valptr, /* OUT */ + char **buffer, /* IN/OUT */ + size_t * buflen /* IN/OUT */ ); + + +const char *_nss_ldap_locate_userpassword (char **vals); + +NSS_STATUS _nss_ldap_assign_userpassword (LDAPMessage * e, /* IN */ + const char *attr, /* IN */ + char **valptr, /* OUT */ + char **buffer, /* IN/OUT */ + size_t * buflen); /* IN/OUT */ + +NSS_STATUS _nss_ldap_oc_check (LDAPMessage * e, const char *oc); + +#if defined(HAVE_SHADOW_H) +int _nss_ldap_shadow_date(const char *val); +void _nss_ldap_shadow_handle_flag(struct spwd *sp); +#else +#define _nss_ldap_shadow_date(_v) atol((_v)) +#define _nss_ldap_shadow_handle_flag(_sp) do { /* nothing */ } while (0) +#endif /* HAVE_SHADOW_H */ + +NSS_STATUS _nss_ldap_map_put (ldap_config_t * config, + ldap_map_selector_t sel, + ldap_map_type_t map, + const char *key, const char *value); + +NSS_STATUS _nss_ldap_map_get (ldap_config_t * config, + ldap_map_selector_t sel, + ldap_map_type_t map, + const char *key, const char **value); + +const char *_nss_ldap_map_at (ldap_map_selector_t sel, const char *pChar2); +const char *_nss_ldap_unmap_at (ldap_map_selector_t sel, const char *attribute); + +const char *_nss_ldap_map_oc (ldap_map_selector_t sel, const char *pChar); +const char *_nss_ldap_unmap_oc (ldap_map_selector_t sel, const char *pChar); + +const char *_nss_ldap_map_ov (const char *pChar); +const char *_nss_ldap_map_df (const char *pChar); + +/* + * Proxy bind support for AIX. + */ +struct ldap_proxy_bind_args +{ + char *binddn; + const char *bindpw; +}; + +typedef struct ldap_proxy_bind_args ldap_proxy_bind_args_t; + +NSS_STATUS _nss_ldap_proxy_bind (const char *user, const char *password); + +NSS_STATUS _nss_ldap_init (void); +void _nss_ldap_close (void); + +int _nss_ldap_test_config_flag (unsigned int flag); +int _nss_ldap_test_initgroups_ignoreuser (const char *user); +int _nss_ldap_get_ld_errno (char **m, char **s); + +#endif /* _LDAP_NSS_LDAP_LDAP_NSS_H */ diff --git a/ldap-parse.h b/ldap-parse.h new file mode 100644 index 0000000..b8d5e90 --- /dev/null +++ b/ldap-parse.h @@ -0,0 +1,202 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-parse.h,v 2.21 2005/05/20 05:30:41 lukeh Exp $ + */ + + +#ifndef _LDAP_NSS_LDAP_LDAP_PARSE_H +#define _LDAP_NSS_LDAP_LDAP_PARSE_H + +#if defined(HAVE_NSSWITCH_H) +#define NSS_ARGS(args) ((nss_XbyY_args_t *)args) + +#define LOOKUP_NAME(args, filter, selector, parser, req_buflen) \ + ldap_args_t a; \ + NSS_STATUS s; \ + if (NSS_ARGS(args)->buf.buflen < req_buflen) { \ + NSS_ARGS(args)->erange = 1; \ + return NSS_TRYAGAIN; \ + } \ + LA_INIT(a); \ + LA_STRING(a) = NSS_ARGS(args)->key.name; \ + LA_TYPE(a) = LA_TYPE_STRING; \ + s = _nss_ldap_getbyname(&a, \ + NSS_ARGS(args)->buf.result, \ + NSS_ARGS(args)->buf.buffer, \ + NSS_ARGS(args)->buf.buflen, \ + &NSS_ARGS(args)->erange, \ + filter, \ + selector, \ + parser); \ + if (s == NSS_SUCCESS) { \ + NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; \ + } \ + return s +#define LOOKUP_NUMBER(args, field, filter, selector, parser, req_buflen) \ + ldap_args_t a; \ + NSS_STATUS s; \ + if (NSS_ARGS(args)->buf.buflen < req_buflen) { \ + NSS_ARGS(args)->erange = 1; \ + return NSS_TRYAGAIN; \ + } \ + LA_INIT(a); \ + LA_NUMBER(a) = NSS_ARGS(args)->field; \ + LA_TYPE(a) = LA_TYPE_NUMBER; \ + s = _nss_ldap_getbyname(&a, \ + NSS_ARGS(args)->buf.result, \ + NSS_ARGS(args)->buf.buffer, \ + NSS_ARGS(args)->buf.buflen, \ + &NSS_ARGS(args)->erange, \ + filter, \ + selector, \ + parser); \ + if (s == NSS_SUCCESS) { \ + NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; \ + } \ + return s +#define LOOKUP_GETENT(args, be, filter, selector, parser, req_buflen) \ + NSS_STATUS s; \ + if (NSS_ARGS(args)->buf.buflen < req_buflen) { \ + NSS_ARGS(args)->erange = 1; \ + return NSS_TRYAGAIN; \ + } \ + s = _nss_ldap_getent(&((nss_ldap_backend_t *)be)->state, \ + NSS_ARGS(args)->buf.result, \ + NSS_ARGS(args)->buf.buffer, \ + NSS_ARGS(args)->buf.buflen, \ + &NSS_ARGS(args)->erange, \ + filter, \ + selector, \ + parser); \ + if (s == NSS_SUCCESS) { \ + NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; \ + } \ + return s + +#elif defined(HAVE_NSS_H) + +#define LOOKUP_NAME(name, result, buffer, buflen, errnop, filter, selector, parser, req_buflen) \ + ldap_args_t a; \ + if (buflen < req_buflen) { \ + *errnop = ERANGE; \ + return NSS_TRYAGAIN; \ + } \ + LA_INIT(a); \ + LA_STRING(a) = name; \ + LA_TYPE(a) = LA_TYPE_STRING; \ + return _nss_ldap_getbyname(&a, result, buffer, buflen, errnop, filter, selector, parser); +#define LOOKUP_NUMBER(number, result, buffer, buflen, errnop, filter, selector, parser, req_buflen) \ + ldap_args_t a; \ + if (buflen < req_buflen) { \ + *errnop = ERANGE; \ + return NSS_TRYAGAIN; \ + } \ + LA_INIT(a); \ + LA_NUMBER(a) = number; \ + LA_TYPE(a) = LA_TYPE_NUMBER; \ + return _nss_ldap_getbyname(&a, result, buffer, buflen, errnop, filter, selector, parser) +#define LOOKUP_GETENT(key, result, buffer, buflen, errnop, filter, selector, parser, req_buflen) \ + if (buflen < req_buflen) { \ + *errnop = ERANGE; \ + return NSS_TRYAGAIN; \ + } \ + return _nss_ldap_getent(&key, result, buffer, buflen, errnop, filter, selector, parser) + +#elif defined(HAVE_IRS_H) + +#define LOOKUP_NAME(name, this, filter, selector, parser, req_buflen) \ + ldap_args_t a; \ + struct pvt *pvt = (struct pvt *)this->private; \ + NSS_STATUS s; \ + LA_INIT(a); \ + LA_STRING(a) = name; \ + LA_TYPE(a) = LA_TYPE_STRING; \ + s = _nss_ldap_getbyname(&a, &pvt->result, pvt->buffer, sizeof(pvt->buffer), &errno, filter, \ + selector, parser); \ + if (s != NSS_SUCCESS) { \ + MAP_ERRNO(s, errno); \ + return NULL; \ + } \ + return &pvt->result; +#define LOOKUP_NUMBER(number, this, filter, selector, parser, req_buflen) \ + ldap_args_t a; \ + struct pvt *pvt = (struct pvt *)this->private; \ + NSS_STATUS s; \ + LA_INIT(a); \ + LA_NUMBER(a) = number; \ + LA_TYPE(a) = LA_TYPE_NUMBER; \ + s = _nss_ldap_getbyname(&a, &pvt->result, pvt->buffer, sizeof(pvt->buffer), &errno, filter, \ + selector, parser); \ + if (s != NSS_SUCCESS) { \ + MAP_ERRNO(s, errno); \ + return NULL; \ + } \ + return &pvt->result; +#define LOOKUP_GETENT(this, filter, selector, parser, req_buflen) \ + struct pvt *pvt = (struct pvt *)this->private; \ + NSS_STATUS s; \ + s = _nss_ldap_getent(&pvt->state, &pvt->result, pvt->buffer, \ + sizeof(pvt->buffer), &errno, filter, \ + selector, parser); \ + if (s != NSS_SUCCESS) { \ + MAP_ERRNO(s, errno); \ + return NULL; \ + } \ + return &pvt->result; +#endif /* HAVE_NSSWITCH_H */ + +#if defined(HAVE_NSSWITCH_H) + +#define LOOKUP_SETENT(key) \ + if (_nss_ldap_ent_context_init(&((nss_ldap_backend_t *)key)->state) == NULL) \ + return NSS_UNAVAIL; \ + return NSS_SUCCESS +#define LOOKUP_ENDENT(key) \ + _nss_ldap_enter(); \ + _nss_ldap_ent_context_release(((nss_ldap_backend_t *)key)->state); \ + _nss_ldap_leave(); \ + return NSS_SUCCESS + +#elif defined(HAVE_NSS_H) + +#define LOOKUP_SETENT(key) \ + if (_nss_ldap_ent_context_init(&key) == NULL) \ + return NSS_UNAVAIL; \ + return NSS_SUCCESS +#define LOOKUP_ENDENT(key) \ + _nss_ldap_enter(); \ + _nss_ldap_ent_context_release(key); \ + _nss_ldap_leave(); \ + return NSS_SUCCESS + +#elif defined(HAVE_IRS_H) + +#define LOOKUP_SETENT(this) \ + struct pvt *pvt = (struct pvt *)this->private; \ + (void) _nss_ldap_ent_context_init(&pvt->state) +#define LOOKUP_ENDENT(this) \ + struct pvt *pvt = (struct pvt *)this->private; \ + _nss_ldap_enter(); \ + _nss_ldap_ent_context_release(pvt->state); \ + _nss_ldap_leave(); + +#endif /* HAVE_NSSWITCH_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_PARSE_H */ diff --git a/ldap-proto.c b/ldap-proto.c new file mode 100644 index 0000000..1d86ef6 --- /dev/null +++ b/ldap-proto.c @@ -0,0 +1,218 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-proto.c,v 2.30 2006/01/11 18:03:49 lukeh Exp $ + */ + +/* + Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(), + and assign any values of "cn" which do NOT match this canonical name + as aliases. + */ + + +static char rcsId[] = + "$Id: ldap-proto.c,v 2.30 2006/01/11 18:03:49 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-proto.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *proto_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_proto (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + + struct protoent *proto = (struct protoent *) result; + char *number; + NSS_STATUS stat; + + stat = + _nss_ldap_getrdnvalue (e, ATM (LM_PROTOCOLS, cn), &proto->p_name, + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrval (e, AT (ipProtocolNumber), &number, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + + proto->p_proto = atoi (number); + + stat = + _nss_ldap_assign_attrvals (e, ATM (LM_PROTOCOLS, cn), proto->p_name, + &proto->p_aliases, &buffer, &buflen, NULL); + if (stat != NSS_SUCCESS) + return stat; + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getprotobyname_r (nss_backend_t * be, void *args) +{ + LOOKUP_NAME (args, _nss_ldap_filt_getprotobyname, LM_PROTOCOLS, + _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getprotobyname_r (const char *name, struct protoent *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, + _nss_ldap_filt_getprotobyname, LM_PROTOCOLS, + _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getprotobynumber_r (nss_backend_t * be, void *args) +{ + LOOKUP_NUMBER (args, key.number, _nss_ldap_filt_getprotobynumber, + LM_PROTOCOLS, _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getprotobynumber_r (int number, struct protoent *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NUMBER (number, result, buffer, buflen, errnop, + _nss_ldap_filt_getprotobynumber, LM_PROTOCOLS, + _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_setprotoent_r (nss_backend_t * proto_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_setprotoent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_SETENT (proto_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_endprotoent_r (nss_backend_t * proto_context, void *fakeargs) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_endprotoent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_ENDENT (proto_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getprotoent_r (nss_backend_t * proto_context, void *args) +{ + LOOKUP_GETENT (args, proto_context, _nss_ldap_filt_getprotoent, + LM_PROTOCOLS, _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getprotoent_r (struct protoent *result, char *buffer, size_t buflen, + int *errnop) +{ + LOOKUP_GETENT (proto_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getprotoent, LM_PROTOCOLS, + _nss_ldap_parse_proto, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_protocols_destr (nss_backend_t * proto_context, void *args) +{ + return _nss_ldap_default_destr (proto_context, args); +} + +static nss_backend_op_t proto_ops[] = { + _nss_ldap_protocols_destr, + _nss_ldap_endprotoent_r, + _nss_ldap_setprotoent_r, + _nss_ldap_getprotoent_r, + _nss_ldap_getprotobyname_r, + _nss_ldap_getprotobynumber_r +}; + +nss_backend_t * +_nss_ldap_protocols_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = proto_ops; + be->n_ops = sizeof (proto_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_IRS_H +#include "irs-proto.c" +#endif diff --git a/ldap-proto.h b/ldap-proto.h new file mode 100644 index 0000000..e213de4 --- /dev/null +++ b/ldap-proto.h @@ -0,0 +1,55 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-proto.h,v 2.17 2005/05/20 05:30:41 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_PROTO_H +#define _LDAP_NSS_LDAP_LDAP_PROTO_H + +/* + Determine the canonical name of the protocol with _nss_ldap_getrdnvalue(), + and assign any values of "cn" which do NOT match this canonical name + as aliases. + */ + + +static NSS_STATUS _nss_ldap_parse_proto (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_getprotobyname_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_getprotobynumber_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_setprotoent_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_endprotoent_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_getprotoent_r (nss_backend_t * be, + void *fakeargs); + +nss_backend_t *_nss_ldap_protocols_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif /* HAVE_NSSWITCH_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_PROTO_H */ diff --git a/ldap-pwd.c b/ldap-pwd.c new file mode 100644 index 0000000..59f1167 --- /dev/null +++ b/ldap-pwd.c @@ -0,0 +1,325 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +static char rcsId[] = + "$Id: ldap-pwd.c,v 2.46 2006/01/11 18:03:49 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/param.h> +#include <string.h> +#include <pwd.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-pwd.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *pw_context = NULL; +#endif + +static INLINE NSS_STATUS _nss_ldap_assign_emptystring (char **valptr, + char **buffer, + size_t * buflen); + +static INLINE NSS_STATUS +_nss_ldap_assign_emptystring (char **valptr, char **buffer, size_t * buflen) +{ + if (*buflen < 2) + return NSS_TRYAGAIN; + + *valptr = *buffer; + + **valptr = '\0'; + + (*buffer)++; + (*buflen)--; + + return NSS_SUCCESS; +} + +static NSS_STATUS +_nss_ldap_parse_pw (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + struct passwd *pw = (struct passwd *) result; + char *uid, *gid; + NSS_STATUS stat; + char tmpbuf[sizeof "-4294967295"]; + size_t tmplen; + char *tmp; + + if (_nss_ldap_oc_check (e, "shadowAccount") == NSS_SUCCESS) + { + /* don't include password for shadowAccount */ + if (buflen < 3) + return NSS_TRYAGAIN; + + pw->pw_passwd = buffer; + strcpy (buffer, "x"); + buffer += 2; + buflen -= 2; + } + else + { + stat = + _nss_ldap_assign_userpassword (e, ATM (LM_PASSWD, userPassword), + &pw->pw_passwd, &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + } + + stat = + _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, uid), &pw->pw_name, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + + tmp = tmpbuf; + tmplen = sizeof (tmpbuf); + stat = + _nss_ldap_assign_attrval (e, AT (uidNumber), &uid, &tmp, &tmplen); + if (stat != NSS_SUCCESS) + return stat; + pw->pw_uid = (*uid == '\0') ? UID_NOBODY : (uid_t) atol (uid); + + tmp = tmpbuf; + tmplen = sizeof (tmpbuf); + stat = + _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, gidNumber), &gid, &tmp, + &tmplen); + if (stat != NSS_SUCCESS) + return stat; + pw->pw_gid = (*gid == '\0') ? GID_NOBODY : (gid_t) atol (gid); + + stat = + _nss_ldap_assign_attrval (e, AT (gecos), &pw->pw_gecos, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + { + pw->pw_gecos = NULL; + stat = + _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, cn), &pw->pw_gecos, + &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + } + + stat = + _nss_ldap_assign_attrval (e, AT (homeDirectory), &pw->pw_dir, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + (void) _nss_ldap_assign_emptystring (&pw->pw_dir, &buffer, &buflen); + + stat = + _nss_ldap_assign_attrval (e, AT (loginShell), &pw->pw_shell, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + (void) _nss_ldap_assign_emptystring (&pw->pw_shell, &buffer, &buflen); + +#ifdef HAVE_NSSWITCH_H + stat = + _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, description), + &pw->pw_comment, &buffer, &buflen); + if (stat != NSS_SUCCESS) + { + /* + * Fix for recall #233 + */ + pw->pw_comment = pw->pw_gecos; + } + (void) _nss_ldap_assign_emptystring (&pw->pw_age, &buffer, &buflen); +#endif /* HAVE_NSSWITCH_H */ + +#ifdef HAVE_PASSWD_PW_CHANGE + tmp = NULL; + stat = + _nss_ldap_assign_attrval (e, AT (shadowMax), &tmp, &buffer, &buflen); + pw->pw_change = (stat == NSS_SUCCESS) ? atol(tmp) * (24*60*60) : 0; + + if (pw->pw_change > 0) + { + tmp = NULL; + stat = + _nss_ldap_assign_attrval (e, AT (shadowLastChange), &tmp, &buffer, + &buflen); + if (stat == NSS_SUCCESS) + pw->pw_change += atol(tmp); + else + pw->pw_change = 0; + } +#endif /* HAVE_PASSWD_PW_CHANGE */ + +#ifdef HAVE_PASSWD_PW_EXPIRE + tmp = NULL; + stat = + _nss_ldap_assign_attrval (e, AT (shadowExpire), &tmp, &buffer, &buflen); + pw->pw_expire = (stat == NSS_SUCCESS) ? atol(tmp) * (24*60*60) : 0; +#endif /* HAVE_PASSWD_PW_EXPIRE */ + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getpwnam_r (const char *name, + struct passwd * result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, _nss_ldap_filt_getpwnam, + LM_PASSWD, _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getpwnam_r (nss_backend_t * be, void *args) +{ + LOOKUP_NAME (args, _nss_ldap_filt_getpwnam, LM_PASSWD, _nss_ldap_parse_pw, + LDAP_NSS_BUFLEN_DEFAULT); +} +#endif /* HAVE_NSS_H */ + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getpwuid_r (uid_t uid, + struct passwd *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NUMBER (uid, result, buffer, buflen, errnop, _nss_ldap_filt_getpwuid, + LM_PASSWD, _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getpwuid_r (nss_backend_t * be, void *args) +{ + LOOKUP_NUMBER (args, key.uid, _nss_ldap_filt_getpwuid, LM_PASSWD, + _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#if defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_setpwent (void) +{ + LOOKUP_SETENT (pw_context); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_setpwent_r (nss_backend_t * be, void *args) +{ + LOOKUP_SETENT (be); +} +#endif + +#if defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_endpwent (void) +{ + LOOKUP_ENDENT (pw_context); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_endpwent_r (nss_backend_t * be, void *args) +{ + LOOKUP_ENDENT (be); +} +#endif + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getpwent_r (struct passwd *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_GETENT (pw_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getpwent, LM_PASSWD, _nss_ldap_parse_pw, + LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getpwent_r (nss_backend_t * be, void *args) +{ + LOOKUP_GETENT (args, be, _nss_ldap_filt_getpwent, LM_PASSWD, + _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_passwd_destr (nss_backend_t * pw_context, void *args) +{ + return _nss_ldap_default_destr (pw_context, args); +} + +static nss_backend_op_t passwd_ops[] = { + _nss_ldap_passwd_destr, + _nss_ldap_endpwent_r, /* NSS_DBOP_ENDENT */ + _nss_ldap_setpwent_r, /* NSS_DBOP_SETENT */ + _nss_ldap_getpwent_r, /* NSS_DBOP_GETENT */ + _nss_ldap_getpwnam_r, /* NSS_DBOP_PASSWD_BYNAME */ + _nss_ldap_getpwuid_r /* NSS_DBOP_PASSWD_BYUID */ +}; + +nss_backend_t * +_nss_ldap_passwd_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = passwd_ops; + be->n_ops = sizeof (passwd_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} + + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_IRS_H +#include "irs-pwd.c" +#endif /* HAVE_IRS_H */ diff --git a/ldap-pwd.h b/ldap-pwd.h new file mode 100644 index 0000000..e6c8b81 --- /dev/null +++ b/ldap-pwd.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-pwd.h,v 2.20 2005/05/20 05:30:42 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_PWD_H +#define _LDAP_NSS_LDAP_LDAP_PWD_H + +static NSS_STATUS _nss_ldap_parse_pw (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_getpwnam_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getpwuid_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_setpwent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_endpwent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getpwent_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_passwd_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif + +#endif /* _LDAP_NSS_LDAP_LDAP_PWD_H */ diff --git a/ldap-rpc.c b/ldap-rpc.c new file mode 100644 index 0000000..f613ec6 --- /dev/null +++ b/ldap-rpc.c @@ -0,0 +1,222 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-rpc.c,v 2.29 2006/01/11 18:03:49 lukeh Exp $ + */ + +/* + Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(), + and assign any values of "cn" which do NOT match this canonical name + as aliases. + */ + + +static char rcsId[] = + "$Id: ldap-rpc.c,v 2.29 2006/01/11 18:03:49 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef HAVE_RPC_RPCENT_H +#include <rpc/rpcent.h> +#else +#include <netdb.h> +#endif + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-rpc.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) + +#ifdef HAVE_NSS_H +static ent_context_t *rpc_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_rpc (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + + struct rpcent *rpc = (struct rpcent *) result; + char *number; + NSS_STATUS stat; + + stat = + _nss_ldap_getrdnvalue (e, ATM (LM_RPC, cn), &rpc->r_name, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrval (e, AT (oncRpcNumber), &number, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + + rpc->r_number = atol (number); + + stat = + _nss_ldap_assign_attrvals (e, ATM (LM_RPC, cn), rpc->r_name, + &rpc->r_aliases, &buffer, &buflen, NULL); + if (stat != NSS_SUCCESS) + return stat; + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getrpcbyname_r (nss_backend_t * be, void *args) +{ + LOOKUP_NAME (args, _nss_ldap_filt_getrpcbyname, LM_RPC, + _nss_ldap_parse_rpc, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getrpcbyname_r (const char *name, struct rpcent *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, + _nss_ldap_filt_getrpcbyname, LM_RPC, _nss_ldap_parse_rpc, + LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getrpcbynumber_r (nss_backend_t * be, void *args) +{ + LOOKUP_NUMBER (args, key.number, _nss_ldap_filt_getrpcbynumber, LM_RPC, + _nss_ldap_parse_rpc, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getrpcbynumber_r (int number, struct rpcent *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NUMBER (number, result, buffer, buflen, errnop, + _nss_ldap_filt_getrpcbynumber, LM_RPC, _nss_ldap_parse_rpc, + LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_setrpcent_r (nss_backend_t * rpc_context, void *args) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_setrpcent (void) +#endif +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) +{ + LOOKUP_SETENT (rpc_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_endrpcent_r (nss_backend_t * rpc_context, void *args) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_endrpcent (void) +#endif +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) +{ + LOOKUP_ENDENT (rpc_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getrpcent_r (nss_backend_t * rpc_context, void *args) +{ + LOOKUP_GETENT (args, rpc_context, _nss_ldap_filt_getrpcent, LM_RPC, + _nss_ldap_parse_rpc, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getrpcent_r (struct rpcent *result, char *buffer, size_t buflen, + int *errnop) +{ + LOOKUP_GETENT (rpc_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getrpcent, LM_RPC, _nss_ldap_parse_rpc, + LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_rpc_destr (nss_backend_t * rpc_context, void *args) +{ + return _nss_ldap_default_destr (rpc_context, args); +} + +static nss_backend_op_t rpc_ops[] = { + _nss_ldap_rpc_destr, + _nss_ldap_endrpcent_r, + _nss_ldap_setrpcent_r, + _nss_ldap_getrpcent_r, + _nss_ldap_getrpcbyname_r, + _nss_ldap_getrpcbynumber_r +}; + +nss_backend_t * +_nss_ldap_rpc_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = rpc_ops; + be->n_ops = sizeof (rpc_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} +#endif /* HAVE_NSSWITCH_H */ + +#endif /* !HAVE_IRS_H */ diff --git a/ldap-rpc.h b/ldap-rpc.h new file mode 100644 index 0000000..57267f6 --- /dev/null +++ b/ldap-rpc.h @@ -0,0 +1,53 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-rpc.h,v 2.17 2005/05/20 05:30:42 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_RPC_H +#define _LDAP_NSS_LDAP_LDAP_RPC_H + +/* + * Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(), + * and assign any values of "cn" which do NOT match this canonical name + * as aliases. + */ + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) +static NSS_STATUS _nss_ldap_parse_rpc (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_getrpcbyname_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_getrpcbynumber_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_setrpcent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_endrpcent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getrpcent_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_rpc_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif /* !HAVE_IRS_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_RPC_H */ diff --git a/ldap-schema.c b/ldap-schema.c new file mode 100644 index 0000000..90a7425 --- /dev/null +++ b/ldap-schema.c @@ -0,0 +1,499 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 2000. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-schema.c,v 2.33 2006/05/15 08:13:44 lukeh Exp $ + */ + +static char rcsId[] = + "$Id: ldap-schema.c,v 2.33 2006/05/15 08:13:44 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <syslog.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif /* HAVE_SNPRINTF */ +#include "ldap-nss.h" +#include "ldap-schema.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + + +/** + * declare filters formerly declared in ldap-*.h + */ + +/* rfc822 mail aliases */ +char _nss_ldap_filt_getaliasbyname[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getaliasent[LDAP_FILT_MAXSIZ]; + +/* boot parameters */ +char _nss_ldap_filt_getbootparamsbyname[LDAP_FILT_MAXSIZ]; + +/* MAC address mappings */ +char _nss_ldap_filt_gethostton[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getntohost[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getetherent[LDAP_FILT_MAXSIZ]; + +/* groups */ +char _nss_ldap_filt_getgrnam[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getgrgid[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getgrent[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getgroupsbymemberanddn[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getgroupsbydn[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getpwnam_groupsbymember[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getgroupsbymember[LDAP_FILT_MAXSIZ]; + +/* IP hosts */ +char _nss_ldap_filt_gethostbyname[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_gethostbyaddr[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_gethostent[LDAP_FILT_MAXSIZ]; + +/* IP networks */ +char _nss_ldap_filt_getnetbyname[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getnetbyaddr[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getnetent[LDAP_FILT_MAXSIZ]; + +/* IP protocols */ +char _nss_ldap_filt_getprotobyname[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getprotobynumber[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getprotoent[LDAP_FILT_MAXSIZ]; + +/* users */ +char _nss_ldap_filt_getpwnam[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getpwuid[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getpwent[LDAP_FILT_MAXSIZ]; + +/* RPCs */ +char _nss_ldap_filt_getrpcbyname[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getrpcbynumber[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getrpcent[LDAP_FILT_MAXSIZ]; + +/* IP services */ +char _nss_ldap_filt_getservbyname[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getservbynameproto[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getservbyport[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getservbyportproto[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getservent[LDAP_FILT_MAXSIZ]; + +/* shadow users */ +char _nss_ldap_filt_getspnam[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getspent[LDAP_FILT_MAXSIZ]; + +/* netgroups */ +char _nss_ldap_filt_getnetgrent[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_innetgr[LDAP_FILT_MAXSIZ]; + +/* automount */ +char _nss_ldap_filt_setautomntent[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getautomntent[LDAP_FILT_MAXSIZ]; +char _nss_ldap_filt_getautomntbyname[LDAP_FILT_MAXSIZ]; + +/** + * lookup filter initialization + */ +void +_nss_ldap_init_filters () +{ + /* rfc822 mail aliases */ + snprintf (_nss_ldap_filt_getaliasbyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (nisMailAlias), + ATM (LM_ALIASES, cn), "%s"); + snprintf (_nss_ldap_filt_getaliasent, LDAP_FILT_MAXSIZ, + "(%s=%s)", AT (objectClass), OC (nisMailAlias)); + + /* boot parameters */ + snprintf (_nss_ldap_filt_getbootparamsbyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (bootableDevice), + ATM (LM_BOOTPARAMS, cn), "%d"); + + /* MAC address mappings */ + snprintf (_nss_ldap_filt_gethostton, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ieee802Device), + ATM (LM_ETHERS, cn), "%s"); + snprintf (_nss_ldap_filt_getntohost, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ieee802Device), AT (macAddress), + "%s"); + snprintf (_nss_ldap_filt_getetherent, LDAP_FILT_MAXSIZ, "(%s=%s)", + AT (objectClass), OC (ieee802Device)); + + /* groups */ + snprintf (_nss_ldap_filt_getgrnam, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixGroup), + ATM (LM_GROUP, cn), "%s"); + snprintf (_nss_ldap_filt_getgrgid, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixGroup), + ATM (LM_GROUP, gidNumber), "%d"); + snprintf (_nss_ldap_filt_getgrent, LDAP_FILT_MAXSIZ, "(&(%s=%s))", + AT (objectClass), OC (posixGroup)); + snprintf (_nss_ldap_filt_getgroupsbymemberanddn, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(|(%s=%s)(%s=%s)))", + AT (objectClass), OC (posixGroup), AT (memberUid), "%s", AT (uniqueMember), "%s"); + snprintf (_nss_ldap_filt_getgroupsbydn, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", + AT (objectClass), OC (posixGroup), AT (uniqueMember), "%s"); + snprintf (_nss_ldap_filt_getpwnam_groupsbymember, LDAP_FILT_MAXSIZ, + "(|(&(%s=%s)(%s=%s))(&(%s=%s)(%s=%s)))", + AT (objectClass), OC (posixGroup), AT (memberUid), "%s", + AT (objectClass), OC (posixAccount), ATM (LM_PASSWD, uid), "%s"); + snprintf (_nss_ldap_filt_getgroupsbymember, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixGroup), AT (memberUid), + "%s"); + + /* IP hosts */ + snprintf (_nss_ldap_filt_gethostbyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipHost), ATM (LM_HOSTS, cn), + "%s"); + snprintf (_nss_ldap_filt_gethostbyaddr, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipHost), AT (ipHostNumber), + "%s"); + snprintf (_nss_ldap_filt_gethostent, LDAP_FILT_MAXSIZ, "(%s=%s)", + AT (objectClass), OC (ipHost)); + + /* IP networks */ + snprintf (_nss_ldap_filt_getnetbyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipNetwork), + ATM (LM_NETWORKS, cn), "%s"); + snprintf (_nss_ldap_filt_getnetbyaddr, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipNetwork), + AT (ipNetworkNumber), "%s"); + snprintf (_nss_ldap_filt_getnetent, LDAP_FILT_MAXSIZ, "(%s=%s)", + AT (objectClass), OC (ipNetwork)); + + /* IP protocols */ + snprintf (_nss_ldap_filt_getprotobyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipProtocol), + ATM (LM_PROTOCOLS, cn), "%s"); + snprintf (_nss_ldap_filt_getprotobynumber, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipProtocol), + AT (ipProtocolNumber), "%d"); + snprintf (_nss_ldap_filt_getprotoent, LDAP_FILT_MAXSIZ, "(%s=%s)", + AT (objectClass), OC (ipProtocol)); + + /* users */ + snprintf (_nss_ldap_filt_getpwnam, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixAccount), + ATM (LM_PASSWD, uid), "%s"); + snprintf (_nss_ldap_filt_getpwuid, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", + AT (objectClass), OC (posixAccount), AT (uidNumber), "%d"); + snprintf (_nss_ldap_filt_getpwent, LDAP_FILT_MAXSIZ, + "(%s=%s)", AT (objectClass), OC (posixAccount)); + + /* RPCs */ + snprintf (_nss_ldap_filt_getrpcbyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (oncRpc), ATM (LM_RPC, cn), "%s"); + snprintf (_nss_ldap_filt_getrpcbynumber, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (oncRpc), AT (oncRpcNumber), + "%d"); + snprintf (_nss_ldap_filt_getrpcent, LDAP_FILT_MAXSIZ, "(%s=%s)", + AT (objectClass), OC (oncRpc)); + + /* IP services */ + snprintf (_nss_ldap_filt_getservbyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipService), ATM (LM_SERVICES, cn), + "%s"); + snprintf (_nss_ldap_filt_getservbynameproto, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s)(%s=%s))", + AT (objectClass), OC (ipService), ATM (LM_SERVICES, cn), "%s", AT (ipServiceProtocol), + "%s"); + snprintf (_nss_ldap_filt_getservbyport, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipService), AT (ipServicePort), + "%d"); + snprintf (_nss_ldap_filt_getservbyportproto, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s)(%s=%s))", AT (objectClass), OC (ipService), + AT (ipServicePort), "%d", AT (ipServiceProtocol), "%s"); + snprintf (_nss_ldap_filt_getservent, LDAP_FILT_MAXSIZ, "(%s=%s)", + AT (objectClass), OC (ipService)); + + /* shadow users */ + snprintf (_nss_ldap_filt_getspnam, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (shadowAccount), + ATM (LM_SHADOW, uid), "%s"); + snprintf (_nss_ldap_filt_getspent, LDAP_FILT_MAXSIZ, + "(%s=%s)", AT (objectClass), OC (shadowAccount)); + + /* netgroups */ + snprintf (_nss_ldap_filt_getnetgrent, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (nisNetgroup), + ATM (LM_NETGROUP, cn), "%s"); + snprintf (_nss_ldap_filt_innetgr, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (nisNetgroup), AT (memberNisNetgroup), "%s"); + + /* automounts */ + snprintf (_nss_ldap_filt_setautomntent, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (automountMap), AT (automountMapName), "%s"); + snprintf (_nss_ldap_filt_getautomntent, LDAP_FILT_MAXSIZ, + "(%s=%s)", AT (objectClass), OC (automount)); + snprintf (_nss_ldap_filt_getautomntbyname, LDAP_FILT_MAXSIZ, + "(&(%s=%s)(%s=%s))", AT (objectClass), OC (automount), AT (automountKey), "%s"); +} + +static void init_pwd_attributes (const char ***pwd_attrs); +static void init_sp_attributes (const char ***sp_attrs); +static void init_grp_attributes (const char ***grp_attrs); +static void init_hosts_attributes (const char ***hosts_attrs); +static void init_services_attributes (const char ***services_attrs); +static void init_network_attributes (const char ***network_attrs); +static void init_proto_attributes (const char ***proto_attrs); +static void init_rpc_attributes (const char ***rpc_attrs); +static void init_ethers_attributes (const char ***ethers_attrs); +static void init_bp_attributes (const char ***bp_attrs); +static void init_alias_attributes (const char ***alias_attrs); +static void init_netgrp_attributes (const char ***netgrp_attrs); +static void init_automount_attributes (const char ***automount_attrs); + +/** + * attribute table initialization routines + */ +void +_nss_ldap_init_attributes (const char ***attrtab) +{ + init_pwd_attributes (&attrtab[LM_PASSWD]); + init_sp_attributes (&attrtab[LM_SHADOW]); + init_grp_attributes (&attrtab[LM_GROUP]); + init_hosts_attributes (&attrtab[LM_HOSTS]); + init_services_attributes (&attrtab[LM_SERVICES]); + init_network_attributes (&attrtab[LM_NETWORKS]); + init_proto_attributes (&attrtab[LM_PROTOCOLS]); + init_rpc_attributes (&attrtab[LM_RPC]); + init_ethers_attributes (&attrtab[LM_ETHERS]); + init_network_attributes (&attrtab[LM_NETMASKS]); + init_bp_attributes (&attrtab[LM_BOOTPARAMS]); + init_alias_attributes (&attrtab[LM_ALIASES]); + init_netgrp_attributes (&attrtab[LM_NETGROUP]); + init_automount_attributes (&attrtab[LM_AUTOMOUNT]); + + attrtab[LM_NONE] = NULL; +} + +static void +init_pwd_attributes (const char ***pwd_attrs) +{ + int i = 0; + static const char *__pwd_attrs[ATTRTAB_SIZE + 1]; + + (*pwd_attrs) = __pwd_attrs; + + (*pwd_attrs)[i++] = ATM (LM_PASSWD, uid); + (*pwd_attrs)[i++] = ATM (LM_PASSWD, userPassword); + (*pwd_attrs)[i++] = AT (uidNumber); + (*pwd_attrs)[i++] = ATM (LM_PASSWD, gidNumber); + (*pwd_attrs)[i++] = ATM (LM_PASSWD, cn); + (*pwd_attrs)[i++] = AT (homeDirectory); + (*pwd_attrs)[i++] = AT (loginShell); + (*pwd_attrs)[i++] = AT (gecos); + (*pwd_attrs)[i++] = ATM (LM_PASSWD, description); + (*pwd_attrs)[i++] = AT (objectClass); +#ifdef HAVE_PASSWD_PW_CHANGE + (*pwd_attrs)[i++] = AT (shadowLastChange); + (*pwd_attrs)[i++] = AT (shadowMax); +#endif /* HAVE_PASSWD_PW_CHANGE */ +#ifdef HAVE_PASSWD_PW_EXPIRE + (*pwd_attrs)[i++] = AT (shadowExpire); +#endif /* HAVE_PASSWD_PW_EXPIRE */ + (*pwd_attrs)[i] = NULL; +} + +static void +init_sp_attributes (const char ***sp_attrs) +{ + static const char *__sp_attrs[ATTRTAB_SIZE + 1]; + + (*sp_attrs) = __sp_attrs; + + (*sp_attrs)[0] = (char *) ATM (LM_SHADOW, uid); + (*sp_attrs)[1] = (char *) ATM (LM_SHADOW, userPassword); + (*sp_attrs)[2] = (char *) AT (shadowLastChange); + (*sp_attrs)[3] = (char *) AT (shadowMax); + (*sp_attrs)[4] = (char *) AT (shadowMin); + (*sp_attrs)[5] = (char *) AT (shadowWarning); + (*sp_attrs)[6] = (char *) AT (shadowInactive); + (*sp_attrs)[7] = (char *) AT (shadowExpire); + (*sp_attrs)[8] = (char *) AT (shadowFlag); + (*sp_attrs)[9] = NULL; +} + +static void +init_grp_attributes (const char ***grp_attrs) +{ + int i = 0; + static const char *__grp_attrs[ATTRTAB_SIZE + 1]; + + (*grp_attrs) = __grp_attrs; + + (*grp_attrs)[i++] = (char *) ATM (LM_GROUP, cn); + (*grp_attrs)[i++] = (char *) ATM (LM_GROUP, userPassword); + (*grp_attrs)[i++] = (char *) AT (memberUid); + if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) + (*grp_attrs)[i++] = (char *) AT (uniqueMember); + (*grp_attrs)[i++] = (char *) ATM (LM_GROUP, gidNumber); + (*grp_attrs)[i] = NULL; +} + +static void +init_hosts_attributes (const char ***hosts_attrs) +{ + static const char *__hosts_attrs[ATTRTAB_SIZE + 1]; + + (*hosts_attrs) = __hosts_attrs; + + (*hosts_attrs)[0] = (char *) ATM (LM_HOSTS, cn); + (*hosts_attrs)[1] = (char *) AT (ipHostNumber); + (*hosts_attrs)[2] = NULL; +} + +static void +init_services_attributes (const char ***services_attrs) +{ + static const char *__services_attrs[ATTRTAB_SIZE + 1]; + + (*services_attrs) = __services_attrs; + + (*services_attrs)[0] = ATM (LM_SERVICES, cn); + (*services_attrs)[1] = AT (ipServicePort); + (*services_attrs)[2] = AT (ipServiceProtocol); + (*services_attrs)[3] = NULL; +} + +static void +init_network_attributes (const char ***network_attrs) +{ + static const char *__network_attrs[ATTRTAB_SIZE + 1]; + + (*network_attrs) = __network_attrs; + + (*network_attrs)[0] = ATM (LM_NETWORKS, cn); + (*network_attrs)[1] = AT (ipNetworkNumber); + (*network_attrs)[2] = AT (ipNetmaskNumber); + (*network_attrs)[3] = NULL; +} + +static void +init_proto_attributes (const char ***proto_attrs) +{ + static const char *__proto_attrs[ATTRTAB_SIZE + 1]; + + (*proto_attrs) = __proto_attrs; + + (*proto_attrs)[0] = ATM (LM_PROTOCOLS, cn); + (*proto_attrs)[1] = AT (ipProtocolNumber); + (*proto_attrs)[2] = NULL; +} + +static void +init_rpc_attributes (const char ***rpc_attrs) +{ + static const char *__rpc_attrs[ATTRTAB_SIZE + 1]; + + (*rpc_attrs) = __rpc_attrs; + + (*rpc_attrs)[0] = ATM (LM_RPC, cn); + (*rpc_attrs)[1] = AT (oncRpcNumber); + (*rpc_attrs)[2] = NULL; +} + +static void +init_ethers_attributes (const char ***ethers_attrs) +{ + static const char *__ethers_attrs[ATTRTAB_SIZE + 1]; + + (*ethers_attrs) = __ethers_attrs; + + (*ethers_attrs)[0] = ATM (LM_ETHERS, cn); + (*ethers_attrs)[1] = AT (macAddress); + (*ethers_attrs)[2] = NULL; +} + +static void +init_bp_attributes (const char ***bp_attrs) +{ + static const char *__bp_attrs[ATTRTAB_SIZE + 1]; + + (*bp_attrs) = __bp_attrs; + + (*bp_attrs)[0] = ATM (LM_BOOTPARAMS, cn); + (*bp_attrs)[1] = AT (bootParameter); + (*bp_attrs)[2] = NULL; +} + +static void +init_alias_attributes (const char ***alias_attrs) +{ + static const char *__alias_attrs[ATTRTAB_SIZE + 1]; + + (*alias_attrs) = __alias_attrs; + + (*alias_attrs)[0] = ATM (LM_ALIASES, cn); + (*alias_attrs)[1] = AT (rfc822MailMember); + (*alias_attrs)[2] = NULL; +} + +static void +init_netgrp_attributes (const char ***netgrp_attrs) +{ + static const char *__netgrp_attrs[ATTRTAB_SIZE + 1]; + + (*netgrp_attrs) = __netgrp_attrs; + + (*netgrp_attrs)[0] = ATM (LM_NETGROUP, cn); + (*netgrp_attrs)[1] = AT (nisNetgroupTriple); + (*netgrp_attrs)[2] = AT (memberNisNetgroup); + (*netgrp_attrs)[3] = NULL; +} + +static void +init_automount_attributes (const char ***automount_attrs) +{ + static const char *__automount_attrs[ATTRTAB_SIZE + 1]; + + (*automount_attrs) = __automount_attrs; + + (*automount_attrs)[0] = AT (automountKey); + (*automount_attrs)[1] = AT (automountInformation); + (*automount_attrs)[2] = ATM (LM_AUTOMOUNT, description); + (*automount_attrs)[3] = NULL; +} + diff --git a/ldap-schema.h b/ldap-schema.h new file mode 100644 index 0000000..106b06f --- /dev/null +++ b/ldap-schema.h @@ -0,0 +1,317 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1999. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-schema.h,v 1.37 2006/01/13 10:24:58 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_SCHEMA_H +#define _LDAP_NSS_LDAP_LDAP_SCHEMA_H + +/* max number of attributes per object class */ +#define ATTRTAB_SIZE 15 + +/** + * function to initialize global lookup filters. + */ +void _nss_ldap_init_filters (); +void _nss_ldap_init_attributes (const char ***attrtab); + +/** + * make filters formerly declared in ldap-*.h globally available. + */ + +/* rfc822 mail aliases */ +extern char _nss_ldap_filt_getaliasbyname[]; +extern char _nss_ldap_filt_getaliasent[]; + +/* boot parameters */ +extern char _nss_ldap_filt_getbootparamsbyname[]; + +/* MAC address mappings */ +extern char _nss_ldap_filt_gethostton[]; +extern char _nss_ldap_filt_getntohost[]; +extern char _nss_ldap_filt_getetherent[]; + +/* groups */ +extern char _nss_ldap_filt_getgrnam[]; +extern char _nss_ldap_filt_getgrgid[]; +extern char _nss_ldap_filt_getgrent[]; +extern char _nss_ldap_filt_getgroupsbymemberanddn[]; +extern char _nss_ldap_filt_getgroupsbydn[]; +extern char _nss_ldap_filt_getpwnam_groupsbymember[]; +extern char _nss_ldap_filt_getgroupsbymember[]; + +/* IP hosts */ +extern char _nss_ldap_filt_gethostbyname[]; +extern char _nss_ldap_filt_gethostbyaddr[]; +extern char _nss_ldap_filt_gethostent[]; + +/* IP networks */ +extern char _nss_ldap_filt_getnetbyname[]; +extern char _nss_ldap_filt_getnetbyaddr[]; +extern char _nss_ldap_filt_getnetent[]; + +/* IP protocols */ +extern char _nss_ldap_filt_getprotobyname[]; +extern char _nss_ldap_filt_getprotobynumber[]; +extern char _nss_ldap_filt_getprotoent[]; + +/* users */ +extern char _nss_ldap_filt_getpwnam[]; +extern char _nss_ldap_filt_getpwuid[]; +extern char _nss_ldap_filt_getpwent[]; + +/* RPCs */ +extern char _nss_ldap_filt_getrpcbyname[]; +extern char _nss_ldap_filt_getrpcbynumber[]; +extern char _nss_ldap_filt_getrpcent[]; + +/* IP services */ +extern char _nss_ldap_filt_getservbyname[]; +extern char _nss_ldap_filt_getservbynameproto[]; +extern char _nss_ldap_filt_getservbyport[]; +extern char _nss_ldap_filt_getservbyportproto[]; +extern char _nss_ldap_filt_getservent[]; + +/* shadow users */ +extern char _nss_ldap_filt_getspnam[]; +extern char _nss_ldap_filt_getspent[]; + +/* netgroups */ +extern char _nss_ldap_filt_getnetgrent[]; +extern char _nss_ldap_filt_innetgr[]; + +/* automounts */ +extern char _nss_ldap_filt_setautomntent[]; +extern char _nss_ldap_filt_getautomntent[]; +extern char _nss_ldap_filt_getautomntbyname[]; + +/** + * Initialize attribute vector table indexed by map + * selector (eg. LM_PASSWD) relative to an "ldap_config" + */ + +/** + * Lookup (potentially mapped) + * objectclass/attribute. + */ +#define OC(oc) _nss_ldap_map_oc(LM_NONE, OC##_##oc) +#define OCM(map, at) _nss_ldap_map_oc(map, AT##_##at) +#define AT(at) _nss_ldap_map_at(LM_NONE, AT##_##at) +#define ATM(map, at) _nss_ldap_map_at(map, AT##_##at) +#define DF(at) _nss_ldap_map_df(at) +#define OV(at) _nss_ldap_map_ov(at) + +/** + * Common attributes, not from RFC 2307. + */ +#define AT_objectClass "objectClass" +#define AT_cn "cn" +#define AT_description "description" +#define AT_l "l" +#define AT_manager "manager" + +/** + * Vendor-specific attributes and object classes. + * (Mainly from Sun.) + */ +#define OC_nisMailAlias "nisMailAlias" +#define AT_rfc822MailMember "rfc822MailMember" + +/** + * RFC 2307 attributes and object classes. + */ + +/* + * ( 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 ) ) + */ +#define OC_posixAccount "posixAccount" +#define AT_uid "uid" +#define AT_userPassword "userPassword" +#define AT_uidNumber "uidNumber" +#define AT_gidNumber "gidNumber" +#define AT_loginShell "loginShell" +#define AT_gecos "gecos" +#define AT_homeDirectory "homeDirectory" + +/* + * ( 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 ) ) + */ +#define OC_shadowAccount "shadowAccount" +#define AT_shadowLastChange "shadowLastChange" +#define AT_shadowMin "shadowMin" +#define AT_shadowMax "shadowMax" +#define AT_shadowWarning "shadowWarning" +#define AT_shadowInactive "shadowInactive" +#define AT_shadowExpire "shadowExpire" +#define AT_shadowFlag "shadowFlag" + +/* + * ( nisSchema.2.2 NAME 'posixGroup' SUP top STRUCTURAL + * DESC 'Abstraction of a group of accounts' + * MUST ( cn $ gidNumber ) + * MAY ( userPassword $ uidMember $ description ) ) + */ +#define OC_posixGroup "posixGroup" +#define AT_gidNumber "gidNumber" +#define AT_memberUid "memberUid" +#define AT_uniqueMember "uniqueMember" +#define AT_memberOf "memberOf" + +/* + * ( 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 ) ) + */ +#define OC_ipService "ipService" +#define AT_ipServicePort "ipServicePort" +#define AT_ipServiceProtocol "ipServiceProtocol" + +/* + * ( 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 ) + */ +#define OC_ipProtocol "ipProtocol" +#define AT_ipProtocolNumber "ipProtocolNumber" + +/* + * ( 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 ) + */ +#define OC_oncRpc "oncRpc" +#define AT_oncRpcNumber "oncRpcNumber" + +/* + * ( 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 ) ) + */ +#define OC_ipHost "ipHost" +#define AT_ipHostNumber "ipHostNumber" + +/* + * ( 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 ) ) + */ +#define OC_ipNetwork "ipNetwork" +#define AT_ipNetworkNumber "ipNetworkNumber" +#define AT_ipNetmaskNumber "ipNetmaskNumber" + +/* + * ( nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL + * DESC 'Abstraction of a netgroup. May refer to other netgroups' + * MUST cn + * MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) + */ +#define OC_nisNetgroup "nisNetgroup" +#define AT_nisNetgroupTriple "nisNetgroupTriple" +#define AT_memberNisNetgroup "memberNisNetgroup" + +/* + * ( nisSchema.2.09 NAME 'nisMap' SUP top STRUCTURAL + * DESC 'A generic abstraction of a NIS map' + * MUST nisMapName + * MAY description ) + */ +#define OC_nisMap "nisMap" +#define AT_nisMapName "nisNapName" + +/* + * ( nisSchema.2.10 NAME 'nisObject' SUP top STRUCTURAL + * DESC 'An entry in a NIS map' + * MUST ( cn $ nisMapEntry $ nisMapName ) + * MAY description ) + */ +#define OC_nisObject "nisObject" +#define AT_nisMapEntry "nisMapEntry" + +/* + * ( 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 ) + */ +#define OC_ieee802Device "ieee802Device" +#define AT_macAddress "macAddress" + +/* + * ( nisSchema.2.12 NAME 'bootableDevice' SUP top AUXILIARY + * DESC 'A device with boot parameters; device SHOULD be + * used as a structural class' + * MAY ( bootFile $ bootParameter ) ) + */ +#define OC_bootableDevice "bootableDevice" +#define AT_bootFile "bootFile" +#define AT_bootParameter "bootParameter" + +#define OC_automountMap "automountMap" +#define AT_automountMapName "automountMapName" + +#define OC_automount "automount" +#define AT_automountKey "automountKey" +#define AT_automountInformation "automountInformation" + +/* + * Map names + */ + +#define MP_passwd "passwd" +#define MP_shadow "shadow" +#define MP_group "group" +#define MP_hosts "hosts" +#define MP_services "services" +#define MP_networks "networks" +#define MP_protocols "protocols" +#define MP_rpc "rpc" +#define MP_ethers "ethers" +#define MP_netmasks "netmasks" +#define MP_bootparams "bootparams" +#define MP_aliases "aliases" +#define MP_netgroup "netgroup" +#define MP_automount "automount" + +#endif /* _LDAP_NSS_LDAP_LDAP_SCHEMA_H */ diff --git a/ldap-service.c b/ldap-service.c new file mode 100644 index 0000000..8c90ad7 --- /dev/null +++ b/ldap-service.c @@ -0,0 +1,368 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-service.c,v 2.32 2006/01/11 18:03:49 lukeh Exp $ + */ + +/* + Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(), + and assign any values of "cn" which do NOT match this canonical name + as aliases. + */ + + +static char rcsId[] = + "$Id: ldap-service.c,v 2.32 2006/01/11 18:03:49 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> +#include <netinet/in.h> + +#ifdef HAVE_SYS_BYTEORDER_H +#include <sys/byteorder.h> +#endif + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-service.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSS_H +static ent_context_t *serv_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_serv (LDAPMessage * e, + ldap_state_t * state, + void *result, char *buffer, size_t buflen) +{ + struct servent *service = (struct servent *) result; + char *port; + NSS_STATUS stat = NSS_SUCCESS; + + /* this is complicated and ugly, because some git (me) specified that service + * entries should expand to two entities (or more) if they have multi-valued + * ipServiceProtocol fields. + */ + + if (state->ls_type == LS_TYPE_KEY) + { + if (state->ls_info.ls_key == NULL) + { + /* non-deterministic behaviour is ok */ + stat = + _nss_ldap_assign_attrval (e, AT (ipServiceProtocol), + &service->s_proto, &buffer, &buflen); + if (stat != NSS_SUCCESS) + { + return stat; + } + } + else + { + register int len; + len = strlen (state->ls_info.ls_key); + if (buflen < (size_t) (len + 1)) + { + return NSS_TRYAGAIN; + } + strncpy (buffer, state->ls_info.ls_key, len); + buffer[len] = '\0'; + service->s_proto = buffer; + buffer += len + 1; + buflen -= len + 1; + } + } + else + { + char **vals = _nss_ldap_get_values (e, AT (ipServiceProtocol)); + int len; + if (vals == NULL) + { + state->ls_info.ls_index = -1; + return NSS_NOTFOUND; + } + + switch (state->ls_info.ls_index) + { + case 0: + /* last time. decrementing ls_index to -1 AND returning !NSS_SUCCESS + will force this entry to be discarded. + */ + stat = NSS_NOTFOUND; + break; + case -1: + /* first time */ + state->ls_info.ls_index = ldap_count_values (vals); + /* fall off to default ... */ + default: + len = strlen (vals[state->ls_info.ls_index - 1]); + if (buflen < (size_t) (len + 1)) + { + return NSS_TRYAGAIN; + } + strncpy (buffer, vals[state->ls_info.ls_index - 1], len); + buffer[len] = '\0'; + service->s_proto = buffer; + buffer += len + 1; + buflen -= len + 1; + stat = NSS_SUCCESS; + } + + ldap_value_free (vals); + state->ls_info.ls_index--; + } + + if (stat != NSS_SUCCESS) + { + return stat; + } + + stat = + _nss_ldap_getrdnvalue (e, ATM (LM_SERVICES, cn), &service->s_name, + &buffer, &buflen); + if (stat != NSS_SUCCESS) + { + return stat; + } + + stat = + _nss_ldap_assign_attrvals (e, ATM (LM_SERVICES, cn), service->s_name, + &service->s_aliases, &buffer, &buflen, NULL); + if (stat != NSS_SUCCESS) + { + return stat; + } + + stat = + _nss_ldap_assign_attrval (e, AT (ipServicePort), &port, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + { + return stat; + } + + service->s_port = htons (atoi (port)); + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getservbyname_r (nss_backend_t * be, void *args) +{ + ldap_args_t a; + NSS_STATUS status; + + LA_INIT (a); + LA_STRING (a) = NSS_ARGS (args)->key.serv.serv.name; + LA_TYPE (a) = (NSS_ARGS (args)->key.serv.proto == NULL) ? + LA_TYPE_STRING : LA_TYPE_STRING_AND_STRING; + LA_STRING2 (a) = NSS_ARGS (args)->key.serv.proto; + + status = _nss_ldap_getbyname (&a, + NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + (NSS_ARGS (args)->key.serv.proto == NULL) ? + _nss_ldap_filt_getservbyname : + _nss_ldap_filt_getservbynameproto, LM_SERVICES, + _nss_ldap_parse_serv); + + if (status == NSS_SUCCESS) + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getservbyname_r (const char *name, + const char *proto, + struct servent * result, + char *buffer, size_t buflen, int *errnop) +{ + ldap_args_t a; + + LA_INIT (a); + LA_STRING (a) = name; + LA_TYPE (a) = (proto == NULL) ? LA_TYPE_STRING : LA_TYPE_STRING_AND_STRING; + LA_STRING2 (a) = proto; + + return _nss_ldap_getbyname (&a, result, buffer, buflen, errnop, + ((proto == NULL) ? _nss_ldap_filt_getservbyname + : _nss_ldap_filt_getservbynameproto), + LM_SERVICES, _nss_ldap_parse_serv); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getservbyport_r (nss_backend_t * be, void *args) +{ + ldap_args_t a; + NSS_STATUS status; + + LA_INIT (a); + LA_NUMBER (a) = htons (NSS_ARGS (args)->key.serv.serv.port); + LA_TYPE (a) = (NSS_ARGS (args)->key.serv.proto == NULL) ? + LA_TYPE_NUMBER : LA_TYPE_NUMBER_AND_STRING; + LA_STRING2 (a) = NSS_ARGS (args)->key.serv.proto; + + status = _nss_ldap_getbyname (&a, + NSS_ARGS (args)->buf.result, + NSS_ARGS (args)->buf.buffer, + NSS_ARGS (args)->buf.buflen, + &NSS_ARGS (args)->erange, + (NSS_ARGS (args)->key.serv.proto == NULL) ? + _nss_ldap_filt_getservbyport : + _nss_ldap_filt_getservbyportproto, LM_SERVICES, + _nss_ldap_parse_serv); + + if (status == NSS_SUCCESS) + NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result; + + return status; +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getservbyport_r (int port, + const char *proto, + struct servent * result, + char *buffer, size_t buflen, int *errnop) +{ + ldap_args_t a; + + LA_INIT (a); + LA_NUMBER (a) = htons (port); + LA_TYPE (a) = (proto == NULL) ? LA_TYPE_NUMBER : LA_TYPE_NUMBER_AND_STRING; + LA_STRING2 (a) = proto; + return _nss_ldap_getbyname (&a, result, buffer, buflen, errnop, + (proto == + NULL) ? _nss_ldap_filt_getservbyport : + _nss_ldap_filt_getservbyportproto, + LM_SERVICES, _nss_ldap_parse_serv); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_setservent_r (nss_backend_t * serv_context, void *args) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_setservent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_SETENT (serv_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_endservent_r (nss_backend_t * serv_context, void *args) +#elif defined(HAVE_NSS_H) + NSS_STATUS _nss_ldap_endservent (void) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_ENDENT (serv_context); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_getservent_r (nss_backend_t * serv_context, void *args) +{ + LOOKUP_GETENT (args, serv_context, _nss_ldap_filt_getservent, LM_SERVICES, + _nss_ldap_parse_serv, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSS_H) +NSS_STATUS +_nss_ldap_getservent_r (struct servent *result, char *buffer, size_t buflen, + int *errnop) +{ + LOOKUP_GETENT (serv_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getservent, LM_SERVICES, + _nss_ldap_parse_serv, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_services_destr (nss_backend_t * serv_context, void *args) +{ + return _nss_ldap_default_destr (serv_context, args); +} + +static nss_backend_op_t services_ops[] = { + _nss_ldap_services_destr, + _nss_ldap_endservent_r, + _nss_ldap_setservent_r, + _nss_ldap_getservent_r, + _nss_ldap_getservbyname_r, + _nss_ldap_getservbyport_r +}; + +nss_backend_t * +_nss_ldap_services_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = services_ops; + be->n_ops = sizeof (services_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} + +#endif /* !HAVE_NSS_H */ + +#ifdef HAVE_IRS_H +#include "irs-service.c" +#endif diff --git a/ldap-service.h b/ldap-service.h new file mode 100644 index 0000000..ac7b328 --- /dev/null +++ b/ldap-service.h @@ -0,0 +1,56 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-service.h,v 2.17 2005/05/20 05:30:42 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_SERVICE_H +#define _LDAP_NSS_LDAP_LDAP_SERVICE_H + +/* + * Determine the canonical name of the service with _nss_ldap_getrdnvalue(), + * and assign any values of "cn" which do NOT match this canonical name + * as aliases. + * + * You can use the ec_state in the context to derive multiple service + * entries from one LDAP entry. See the example in draft-...-nis-schema-xx.txt. + * + */ + + +static NSS_STATUS _nss_ldap_parse_serv (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_getservbyname_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_getservbyport_r (nss_backend_t * be, + void *fakeargs); +static NSS_STATUS _nss_ldap_setservent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_endservent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getservent_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_services_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif /* !HAVE_NSS_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_SERVICE_H */ diff --git a/ldap-sldap.c b/ldap-sldap.c new file mode 100644 index 0000000..5f8f85f --- /dev/null +++ b/ldap-sldap.c @@ -0,0 +1,1320 @@ +/* Copyright (C) 2006 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 2006. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-sldap.c,v 2.12 2006/01/13 10:35:16 lukeh Exp $ + */ + + +static char rcsId[] = + "$Id: ldap-sldap.c,v 2.12 2006/01/13 10:35:16 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> +#include <assert.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#ifdef HAVE_NET_ROUTE_H +#include <net/route.h> +#endif +#include <net/if.h> +#include <netinet/in.h> + +#include "ldap-nss.h" +#include "ldap-automount.h" +#include "ldap-sldap.h" +#include "util.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#ifdef HAVE_NSSWITCH_H + +/* + * This implements enough of the Solaris libsldap interface in order + * for the automounter to work. + */ + +static ns_ldap_return_code __ns_ldap_initResult (ns_ldap_result_t ** pResult); +static ns_ldap_return_code __ns_ldap_initSearch (ns_ldap_cookie_t * cookie); +static ldap_map_selector_t __ns_ldap_str2selector (const char *map); +static ns_ldap_return_code __ns_ldap_unmapObjectClasses (ns_ldap_cookie_t * + cookie, + char **mappedClasses, + char + ***pOrigClasses); + +#ifdef DEBUG +static const char * +NS_LDAP_ERR2STR (ns_ldap_return_code err) +{ + char *str = NULL; + + __ns_ldap_err2str (err, &str); + + return str; +} +#endif /* DEBUG */ + +static void ** +__ns_ldap_makeStringParam (const char *string) +{ + void **p; + + p = (void **) malloc (2 * sizeof (void *)); + if (p == NULL) + { + return NULL; + } + p[0] = strdup (string); + if (p[0] == NULL) + { + free (p); + return NULL; + } + p[1] = NULL; + + return p; +} + +char ** +__ns_ldap_getMappedAttributes (const char *service, const char *attribute) +{ + const char *mapped; + + mapped = _nss_ldap_map_at (__ns_ldap_str2selector (service), attribute); + if (mapped == NULL) + { + return NULL; + } + + return (char **) __ns_ldap_makeStringParam (mapped); +} + +char ** +__ns_ldap_getMappedObjectClass (const char *service, const char *objectClass) +{ + const char *mapped; + + mapped = _nss_ldap_map_oc (__ns_ldap_str2selector (service), objectClass); + if (mapped == NULL) + { + return NULL; + } + + return (char **) __ns_ldap_makeStringParam (mapped); +} + +static ns_ldap_return_code +__ns_ldap_mapError (NSS_STATUS error) +{ + ns_ldap_return_code code; + + switch (error) + { + case NSS_SUCCESS: + code = NS_LDAP_SUCCESS; + break; + case NSS_TRYAGAIN: + code = NS_LDAP_MEMORY; + break; + case NSS_NOTFOUND: + code = NS_LDAP_NOTFOUND; + break; + case NSS_UNAVAIL: + default: + code = NS_LDAP_OP_FAILED; + break; + } + + return code; +} + +static ns_ldap_return_code +__ns_ldap_mapErrorDetail (ns_ldap_return_code code, ns_ldap_error_t ** errorp) +{ + char *m = NULL; + char *s = NULL; + + *errorp = (ns_ldap_error_t *) calloc (1, sizeof (ns_ldap_error_t)); + if (*errorp == NULL) + { + return NS_LDAP_MEMORY; + } + + (*errorp)->status = _nss_ldap_get_ld_errno (&m, &s); + (*errorp)->message = (m != NULL) ? strdup (m) : NULL; + + return code; +} + +ns_ldap_return_code +__ns_ldap_freeError (ns_ldap_error_t ** errorp) +{ + if (errorp == NULL) + { + return NS_LDAP_INVALID_PARAM; + } + if (*errorp != NULL) + { + if ((*errorp)->message != NULL) + { + free ((*errorp)->message); + (*errorp)->message = NULL; + } + free (*errorp); + *errorp = NULL; + } + return NS_LDAP_SUCCESS; +} + +ns_ldap_return_code +__ns_ldap_freeParam (void ***data) +{ + void **p; + + if (*data != NULL) + { + for (p = *data; *p != NULL; p++) + { + free (*p); + *p = NULL; + } + free (*data); + *data = NULL; + } + + return NS_LDAP_SUCCESS; +} + + +ns_ldap_return_code +__ns_ldap_getParam (const ParamIndexType type, void ***data, + ns_ldap_error_t ** errorp) +{ + ns_ldap_return_code ret; + + *errorp = NULL; + + debug ("==> __ns_ldap_getParam (param=%d)", type); + + switch (type) + { + case NS_LDAP_FILE_VERSION_P: + *data = __ns_ldap_makeStringParam (NS_LDAP_VERSION); + ret = NS_LDAP_SUCCESS; + break; + default: + ret = NS_LDAP_INVALID_PARAM; + break; + } + + debug ("<== __ns_ldap_getParam (ret=%s)", NS_LDAP_ERR2STR (ret)); + + return ret; +} + +ns_ldap_return_code +__ns_ldap_freeAttr (ns_ldap_attr_t ** pAttr) +{ + int i; + ns_ldap_attr_t *attr = *pAttr; + + if (attr != NULL) + { + if (attr->attrname != NULL) + { + free (attr->attrname); + } + if (attr->attrvalue != NULL) + { + for (i = 0; i < attr->value_count; i++) + { + free (attr->attrvalue[i]); + } + free (attr->attrvalue); + } + } + + return NS_LDAP_SUCCESS; +} + +ns_ldap_return_code +__ns_ldap_freeEntry (ns_ldap_entry_t ** pentry) +{ + int i; + ns_ldap_entry_t *entry = *pentry; + + if (entry != NULL) + { + if (entry->attr_pair != NULL) + { + for (i = 0; i < entry->attr_count; i++) + { + __ns_ldap_freeAttr (&entry->attr_pair[i]); + } + free (entry->attr_pair); + } + free (entry); + *pentry = NULL; + } + + return NS_LDAP_SUCCESS; +} + +ns_ldap_return_code +__ns_ldap_freeResult (ns_ldap_result_t ** pResult) +{ + ns_ldap_result_t *result; + ns_ldap_entry_t *entry, *next = NULL; + + if (pResult == NULL) + { + return NS_LDAP_INVALID_PARAM; + } + + result = *pResult; + if (result == NULL) + { + return NS_LDAP_SUCCESS; + } + + entry = result->entry; + + while (entry != NULL) + { + next = entry->next; + __ns_ldap_freeEntry (&entry); + entry = next; + } + + free (result); + *pResult = NULL; + + return NS_LDAP_SUCCESS; +} + +ns_ldap_return_code +__ns_ldap_allocAttr (ns_ldap_attr_t ** pAttr) +{ + ns_ldap_attr_t *attr; + + *pAttr = NULL; + + attr = (ns_ldap_attr_t *) malloc (sizeof (*attr)); + if (attr == NULL) + { + return NS_LDAP_MEMORY; + } + + attr->attrname = NULL; + attr->attrvalue = NULL; + attr->value_count = 0; + + *pAttr = attr; + + return NS_LDAP_SUCCESS; +} + +ns_ldap_return_code +__ns_ldap_parseAttr (ns_ldap_cookie_t * cookie, + LDAPMessage * entry, + const char *attribute, ns_ldap_attr_t ** pAttr) +{ + ns_ldap_attr_t *attr; + const char *unmappedAttribute; + ns_ldap_return_code ret; + char **values; + int freeValues = 1; + + ret = __ns_ldap_allocAttr (&attr); + if (ret != NS_LDAP_SUCCESS) + { + return ret; + } + + if ((cookie->flags & NS_LDAP_NOMAP) == 0) + { + unmappedAttribute = _nss_ldap_unmap_at (cookie->sel, attribute); + if (unmappedAttribute == NULL) + { + __ns_ldap_freeAttr (&attr); + return NS_LDAP_INVALID_PARAM; + } + } + else + { + unmappedAttribute = attribute; + } + + attr->attrname = strdup (unmappedAttribute); + if (attr->attrname == NULL) + { + __ns_ldap_freeAttr (&attr); + return NS_LDAP_MEMORY; + } + attr->attrvalue = NULL; + + values = _nss_ldap_get_values (entry, attribute); + + if ((cookie->flags & NS_LDAP_NOMAP) == 0) + { + if (strcasecmp (attribute, "objectClass") == 0) + { + /* Map object class values */ + ret = + __ns_ldap_unmapObjectClasses (cookie, values, &attr->attrvalue); + if (ret != NS_LDAP_SUCCESS) + { + __ns_ldap_freeAttr (&attr); + return ret; + } + } + } + + if (attr->attrvalue == NULL) + { + attr->attrvalue = values; + freeValues = 0; + } + + attr->value_count = + (attr->attrvalue != NULL) ? ldap_count_values (attr->attrvalue) : 0; + + if (freeValues) + { + ldap_value_free (values); + } + + *pAttr = attr; + + return NS_LDAP_SUCCESS; +} + +ns_ldap_return_code +__ns_ldap_parseDn (ns_ldap_cookie_t * cookie, LDAPMessage * entry, + ns_ldap_attr_t ** pAttr) +{ + ns_ldap_attr_t *attr; + ns_ldap_return_code ret; + + ret = __ns_ldap_allocAttr (&attr); + if (ret != NS_LDAP_SUCCESS) + { + return ret; + } + + attr->attrname = strdup ("dn"); + if (attr->attrname == NULL) + { + __ns_ldap_freeAttr (&attr); + return NS_LDAP_MEMORY; + } + + attr->value_count = 1; + + attr->attrvalue = (char **) malloc (1 * sizeof (char *)); + if (attr->attrvalue == NULL) + { + __ns_ldap_freeAttr (&attr); + return NS_LDAP_MEMORY; + } + + attr->attrvalue[0] = _nss_ldap_get_dn (entry); + if (attr->attrvalue[0] == NULL) + { + __ns_ldap_freeAttr (&attr); + return NS_LDAP_MEMORY; + } + + *pAttr = attr; + + return NS_LDAP_SUCCESS; +} + +NSS_STATUS +__ns_ldap_parseEntry (LDAPMessage * msg, ldap_state_t * state, + void *result, char *buffer, size_t buflen) +{ + ns_ldap_cookie_t *cookie = (ns_ldap_cookie_t *) result; + char *attribute; + BerElement *ber = NULL; + ns_ldap_return_code ret = NS_LDAP_SUCCESS; + ns_ldap_entry_t *entry; + int attr_count; + +#ifdef DEBUG + { + char *dn = _nss_ldap_get_dn (msg); + debug ("==> __ns_ldap_parseEntry (%s)", dn); + ldap_memfree (dn); + } +#endif + + entry = (ns_ldap_entry_t *) malloc (sizeof (*entry)); + if (entry == NULL) + { + cookie->ret = NS_LDAP_MEMORY; + debug ("<== __ns_ldap_parseEntry (no memory)"); + return NSS_NOTFOUND; + } + + entry->attr_count = 0; + entry->attr_pair = NULL; + entry->next = NULL; + + attr_count = 1; /* for DN */ + + for (attribute = _nss_ldap_first_attribute (msg, &ber); + attribute != NULL; attribute = _nss_ldap_next_attribute (msg, ber)) + { + attr_count++; +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (attribute); +#endif + } + + if (ber != NULL) + ber_free (ber, 0); + + entry->attr_pair = + (ns_ldap_attr_t **) calloc (attr_count, sizeof (ns_ldap_attr_t *)); + if (entry->attr_pair == NULL) + { + __ns_ldap_freeEntry (&entry); + cookie->ret = NS_LDAP_MEMORY; + debug ("<== __ns_ldap_parseEntry (no memory)"); + return NSS_NOTFOUND; + } + + ret = __ns_ldap_parseDn (cookie, msg, &entry->attr_pair[entry->attr_count]); + if (ret != NS_LDAP_SUCCESS) + { + __ns_ldap_freeEntry (&entry); + cookie->ret = ret; + debug ("<== __ns_ldap_parseEntry (failed to parse DN)"); + return ret; + } + + entry->attr_count++; + + for (attribute = _nss_ldap_first_attribute (msg, &ber); + attribute != NULL; attribute = _nss_ldap_next_attribute (msg, ber)) + { + ns_ldap_attr_t *attr; + + ret = __ns_ldap_parseAttr (cookie, msg, attribute, &attr); +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (attribute); +#endif + if (ret != NS_LDAP_SUCCESS) + { + continue; + } + entry->attr_pair[entry->attr_count++] = attr; + } + + if (ber != NULL) + ber_free (ber, 0); + + if (ret == NS_LDAP_SUCCESS) + { + ns_ldap_entry_t *last; + + if (cookie->result == NULL) + { + ret = __ns_ldap_initResult (&cookie->result); + if (ret != NS_LDAP_SUCCESS) + { + __ns_ldap_freeEntry (&entry); + cookie->ret = ret; + debug ("<== __ns_ldap_parseEntry (failed to init result: %s)", + NS_LDAP_ERR2STR (ret)); + return __ns_ldap_mapError (ret); + } + cookie->result->entry = entry; + } + else + { + assert (cookie->entry != NULL); + + for (last = cookie->entry; last->next != NULL; last = last->next) + ; + last->next = entry; + } + + cookie->entry = entry; + + if (cookie->callback != NULL) + { + cookie->cb_ret = (*cookie->callback) (entry, cookie->userdata); + } + + cookie->result->entries_count++; + } + else + { + __ns_ldap_freeEntry (&entry); + } + + cookie->ret = ret; + + debug ("<== __ns_ldap_parseEntry (ret=%s)", NS_LDAP_ERR2STR (ret)); + + return __ns_ldap_mapError (ret); +} + +static ns_ldap_return_code +__ns_ldap_initResult (ns_ldap_result_t ** pResult) +{ + ns_ldap_result_t *result; + + result = (ns_ldap_result_t *) malloc (sizeof (ns_ldap_result_t)); + if (result == NULL) + { + return NS_LDAP_MEMORY; + } + + result->entries_count = 0; + result->entry = NULL; + + *pResult = result; + + return NS_LDAP_SUCCESS; +} + +static ldap_map_selector_t +__ns_ldap_str2selector (const char *map) +{ + ldap_map_selector_t sel; + + if (map == NULL) + { + sel = LM_NONE; + } + else + { + sel = _nss_ldap_str2selector (map); + + if (strcmp (map, "automount") == 0) + { + sel = LM_NONE; /* for enumeration only */ + } + else if (sel == LM_NONE && (strncmp (map, "auto_", 5)) == 0) + { + sel = LM_AUTOMOUNT; + } + else + { + sel = _nss_ldap_str2selector (map); + } + } + + return sel; +} + +static ns_ldap_return_code +__ns_ldap_unmapObjectClasses (ns_ldap_cookie_t * cookie, char **mappedClasses, + char ***pOrigClasses) +{ + char **origClasses = NULL; + int count, i; + + count = ldap_count_values (mappedClasses); + origClasses = (char **) calloc (count + 1, sizeof (char *)); + if (origClasses == NULL) + { + return NS_LDAP_MEMORY; + } + + for (i = 0; i < count; i++) + { + origClasses[i] = + strdup (_nss_ldap_unmap_oc (cookie->sel, mappedClasses[i])); + if (origClasses[i] == NULL) + { + ldap_value_free (origClasses); + return NS_LDAP_MEMORY; + } + } + origClasses[i] = NULL; + *pOrigClasses = origClasses; + + return NS_LDAP_SUCCESS; +} + +static ns_ldap_return_code +__ns_ldap_mapAttributes (ns_ldap_cookie_t * cookie, const char ***pAttributes) +{ + const char **attributes; + int i; + + *pAttributes = NULL; + + if (cookie->attribute == NULL) + { + return NS_LDAP_SUCCESS; + } + + for (i = 0; cookie->attribute[i] != NULL; i++) + ; + + attributes = (const char **) calloc (i + 1, sizeof (char **)); + if (attributes == NULL) + { + return NS_LDAP_MEMORY; + } + + for (i = 0; cookie->attribute[i] != NULL; i++) + { + attributes[i] = _nss_ldap_map_at (cookie->sel, cookie->attribute[i]); + assert (attributes[i] != NULL); + } + attributes[i] = NULL; + *pAttributes = attributes; + + return NS_LDAP_SUCCESS; +} + +static ns_ldap_return_code +__ns_ldap_emitFilterString (char **pFilter, size_t * len, size_t * size, + const char *s) +{ + size_t slen = strlen (s); + char *filter; + + if (*len + slen >= *size) + { + /* need some more space */ + size_t newSize = *size; + char *newFilter; + + if (newSize == 0) + newSize = NSS_BUFSIZ; + else + newSize *= 2; + + newFilter = realloc (*pFilter, newSize); + if (newFilter == NULL) + { + return NS_LDAP_MEMORY; + } + *pFilter = newFilter; + *size = newSize; + } + + filter = *pFilter; + + memcpy (&filter[*len], s, slen); + filter[*len + slen] = '\0'; + + *len += slen; + + return NS_LDAP_SUCCESS; +} + + +#define EMIT_STRING(_s) do { \ + ns_ldap_return_code ret = __ns_ldap_emitFilterString(&filter, &len, &size, (_s)); \ + if (ret != NS_LDAP_SUCCESS) { \ + if (filter != NULL) free(filter); \ + return ret; \ + } \ + } while (0) + +#define EMIT_CHAR(_c) do { \ + char _s[2]; \ + ns_ldap_return_code ret; \ + _s[0] = _c; \ + _s[1] = '\0'; \ + ret = __ns_ldap_emitFilterString(&filter, &len, &size, (_s)); \ + if (ret != NS_LDAP_SUCCESS) { \ + if (filter != NULL) free(filter); \ + return ret; \ + } \ + } while (0) + + +static ns_ldap_return_code +__ns_ldap_mapFilter (ns_ldap_cookie_t * cookie, char **pFilter) +{ + enum + { EXPECT_LHS, FOUND_LHS, EXPECT_RHS, FOUND_RHS } state; + char *lhs = NULL; + char *rhs = NULL; + size_t len = 0, size = 0; + char tmp; + size_t i; + char *filter = NULL; + size_t filterLen = strlen (cookie->filter); + + state = EXPECT_LHS; + + for (i = 0; i <= filterLen; i++) + { + switch (state) + { + case EXPECT_LHS: + switch (cookie->filter[i]) + { + case '(': + case ')': + case '&': + case '|': + case '!': + EMIT_CHAR (cookie->filter[i]); + break; + default: + state = FOUND_LHS; + lhs = &cookie->filter[i]; + break; + } + break; + case FOUND_LHS: + switch (cookie->filter[i]) + { + case '<': + case '=': + case '>': + case '~': + state = EXPECT_RHS; + tmp = cookie->filter[i]; + cookie->filter[i] = '\0'; + /* map LHS (attribute type) */ + EMIT_STRING (_nss_ldap_map_at (cookie->sel, lhs)); + EMIT_CHAR (tmp); + break; + default: + break; + } + break; + case EXPECT_RHS: + switch (cookie->filter[i]) + { + case '<': + case '=': + case '>': + case '~': + EMIT_CHAR (cookie->filter[i]); + break; + default: + state = FOUND_RHS; + rhs = &cookie->filter[i]; + break; + } + break; + case FOUND_RHS: + switch (cookie->filter[i]) + { + case '&': + case '|': + case '!': + case ')': + case '\0': + state = EXPECT_LHS; + tmp = cookie->filter[i];; + cookie->filter[i] = '\0'; + if (strcasecmp (lhs, "objectClass") == 0) + EMIT_STRING (_nss_ldap_map_oc (cookie->sel, rhs)); + else + EMIT_STRING (rhs); + if (strcasecmp (rhs, "automount") == 0) + cookie->sel = LM_AUTOMOUNT; + EMIT_CHAR (tmp); + break; + default: + break; + } + break; + } + } + + *pFilter = filter; + + return NS_LDAP_SUCCESS; +} + +static ns_ldap_return_code +__ns_ldap_freeCookie (ns_ldap_cookie_t ** pCookie) +{ + ns_ldap_cookie_t *cookie; + + cookie = *pCookie; + + if (cookie != NULL) + { + if (cookie->map != NULL) + free (cookie->map); + if (cookie->filter != NULL) + free (cookie->filter); + if (cookie->attribute != NULL) + ldap_value_free (cookie->attribute); + if (cookie->state != NULL) + { + _nss_ldap_ent_context_release (cookie->state); + free (cookie->state); + } + if (cookie->mapped_filter != NULL) + free (cookie->mapped_filter); + if (cookie->mapped_attribute != NULL) + free (cookie->mapped_attribute); + _nss_ldap_am_context_free (&cookie->am_state); + __ns_ldap_freeResult (&cookie->result); + free (cookie); + } + + *pCookie = NULL; + + return NS_LDAP_SUCCESS; +} + +static ns_ldap_return_code +__ns_ldap_initCookie (const char *map, + const char *filter, + int (*init_filter_cb) (const ns_ldap_search_desc_t * + desc, char **realfilter, + const void *userdata), + const char *const *attribute, const ns_cred_t * cred, + const int flags, ns_ldap_cookie_t ** pCookie, + int (*callback) (const ns_ldap_entry_t * entry, + const void *userdata), + const void *userdata) +{ + ns_ldap_cookie_t *cookie; + ns_ldap_return_code ret; + size_t i; + + assert (pCookie != NULL && *pCookie == NULL); + + ret = __ns_ldap_mapError (_nss_ldap_init ()); + if (ret != NS_LDAP_SUCCESS) + { + return ret; + } + + cookie = (ns_ldap_cookie_t *) calloc (1, sizeof (*cookie)); + if (cookie == NULL) + { + return NS_LDAP_MEMORY; + } + + if (filter == NULL) + { + __ns_ldap_freeCookie (&cookie); + return NS_LDAP_INVALID_PARAM; + } + + if (map != NULL) + { + cookie->map = strdup (map); + if (cookie->map == NULL) + { + __ns_ldap_freeCookie (&cookie); + return NS_LDAP_MEMORY; + } + } + + cookie->filter = strdup (filter); + if (cookie->filter == NULL) + { + __ns_ldap_freeCookie (&cookie); + return NS_LDAP_MEMORY; + } + + if (attribute != NULL) + { + for (i = 0; attribute[i] != NULL; i++) + ; + + cookie->attribute = (char **) calloc (i + 1, sizeof (char *)); + if (cookie->attribute == NULL) + { + __ns_ldap_freeCookie (&cookie); + return NS_LDAP_MEMORY; + } + + for (i = 0; attribute[i] != NULL; i++) + { + cookie->attribute[i] = strdup (attribute[i]); + if (cookie->attribute[i] == NULL) + { + __ns_ldap_freeCookie (&cookie); + return NS_LDAP_MEMORY; + } + } + cookie->attribute[i] = NULL; + } + + cookie->flags = flags; + cookie->init_filter_cb = init_filter_cb; + cookie->callback = callback; + cookie->userdata = userdata; + cookie->ret = -1; + cookie->cb_ret = NS_LDAP_CB_NEXT; + cookie->erange = 0; + cookie->sel = __ns_ldap_str2selector (map); + + if (_nss_ldap_ent_context_init_locked (&cookie->state) == NULL) + { + __ns_ldap_freeCookie (&cookie); + return NS_LDAP_INTERNAL; + } + + cookie->result = NULL; + cookie->entry = NULL; + + ret = __ns_ldap_initSearch (cookie); + if (ret != NS_LDAP_SUCCESS) + { + __ns_ldap_freeCookie (&cookie); + return ret; + } + + *pCookie = cookie; + + return NS_LDAP_SUCCESS; +} + +static ns_ldap_return_code +__ns_ldap_initSearch (ns_ldap_cookie_t * cookie) +{ + ns_ldap_return_code ret; + NSS_STATUS stat; + + assert (cookie != NULL); + assert (cookie->state != NULL); + + ret = __ns_ldap_mapAttributes (cookie, &cookie->mapped_attribute); + if (ret != NS_LDAP_SUCCESS) + { + return ret; + } + + ret = __ns_ldap_mapFilter (cookie, &cookie->mapped_filter); + if (ret != NS_LDAP_SUCCESS) + { + return ret; + } + + /* + * In the automount case, we need to do a search for a list of + * search bases + */ + if (cookie->sel == LM_AUTOMOUNT) + { + assert (cookie->am_state == NULL); + assert (cookie->map != NULL); + + stat = _nss_ldap_am_context_init (cookie->map, &cookie->am_state); + if (stat != NSS_SUCCESS) + { + return __ns_ldap_mapError (stat); + } + } + + return ret; +} + +/* + * Performs a search given an existing cookie + * + * If cookie->result != NULL then the entry will be appended to + * the result list. Use this for implementing __ns_ldap_list(). + * + * If cookie->result == NULL then a new result list will be + * allocated. Use this for implementing __ns_ldap_nextEntry(). + * + * cookie->entry always points to the last entry in cookie->result + * + * Caller should acquire global lock + */ +static ns_ldap_return_code +__ns_ldap_search (ns_ldap_cookie_t * cookie) +{ + ldap_args_t a; + NSS_STATUS stat; + ldap_automount_context_t *am = cookie->am_state; + + LA_INIT (a); + LA_TYPE (a) = LA_TYPE_NONE; + + if (cookie->sel == LM_AUTOMOUNT) + { + assert (am != NULL); + assert (am->lac_dn_count > 0); + + LA_BASE (a) = am->lac_dn_list[am->lac_dn_index]; + } /* XXX todo is support maps that are RDNs relative to default search base */ + + assert (cookie->mapped_filter != NULL); + +retry_search: + cookie->ret = -1; + + stat = _nss_ldap_getent_ex (&a, &cookie->state, cookie, + NULL, 0, &cookie->erange, + cookie->mapped_filter, + cookie->sel, + cookie->mapped_attribute, __ns_ldap_parseEntry); + + if (stat == NSS_NOTFOUND && + cookie->sel == LM_AUTOMOUNT && am->lac_dn_index < am->lac_dn_count - 1) + { + am->lac_dn_index++; + goto retry_search; + } + + if (cookie->ret < 0) + { + cookie->ret = __ns_ldap_mapError (stat); + } + + return cookie->ret; +} + +ns_ldap_return_code +__ns_ldap_firstEntry (const char *service, + const char *filter, + int (*init_filter_cb) (const ns_ldap_search_desc_t * + desc, char **realfilter, + const void *userdata), + const char *const *attribute, const ns_cred_t * cred, + const int flags, void **pCookie, + ns_ldap_result_t ** result, ns_ldap_error_t ** errorp, + const void *userdata) +{ + ns_ldap_return_code ret; + ns_ldap_cookie_t *cookie = NULL; + + *pCookie = NULL; + *result = NULL; + *errorp = NULL; + + debug ("==> __ns_ldap_firstEntry (map=%s filter=%s)", + service != NULL ? service : "(null)", filter); + + _nss_ldap_enter (); + + ret = __ns_ldap_initCookie (service, filter, init_filter_cb, + attribute, cred, flags, &cookie, NULL, + userdata); + if (ret == NS_LDAP_SUCCESS) + { + ret = __ns_ldap_search (cookie); + + *result = cookie->result; + cookie->result = NULL; + } + + __ns_ldap_mapErrorDetail (ret, errorp); + + _nss_ldap_leave (); + + *pCookie = cookie; + + debug ("<== __ns_ldap_firstEntry ret=%s cookie=%p", NS_LDAP_ERR2STR (ret), + cookie); + + return ret; +} + +ns_ldap_return_code +__ns_ldap_nextEntry (void *_cookie, + ns_ldap_result_t ** result, ns_ldap_error_t ** errorp) +{ + ns_ldap_return_code ret; + ns_ldap_cookie_t *cookie; + + *result = NULL; + *errorp = NULL; + + cookie = (ns_ldap_cookie_t *) _cookie; + if (cookie == NULL) + { + return NS_LDAP_INVALID_PARAM; + } + + debug ("==> __ns_ldap_nextEntry cookie=%p", cookie); + + _nss_ldap_enter (); + + ret = __ns_ldap_search (cookie); + + *result = cookie->result; + cookie->result = NULL; + + __ns_ldap_mapErrorDetail (ret, errorp); + + _nss_ldap_leave (); + + debug ("<== __ns_ldap_nextEntry ret=%s", NS_LDAP_ERR2STR (ret)); + + return ret; +} + +ns_ldap_return_code +__ns_ldap_endEntry (void **pCookie, ns_ldap_error_t ** errorp) +{ + ns_ldap_cookie_t *cookie; + + _nss_ldap_enter (); + + cookie = (ns_ldap_cookie_t *) * pCookie; + + debug ("==> __ns_ldap_freeEntry cookie=%p", cookie); + + __ns_ldap_mapErrorDetail (cookie->ret, errorp); + __ns_ldap_freeCookie (&cookie); + + *pCookie = NULL; + + _nss_ldap_leave (); + + debug ("<== __ns_ldap_freeEntry"); + + return NS_LDAP_SUCCESS; +} + +ns_ldap_return_code +__ns_ldap_list (const char *map, + const char *filter, + int (*init_filter_cb) (const ns_ldap_search_desc_t * desc, + char **realfilter, + const void *userdata), + const char *const *attribute, const ns_cred_t * cred, + const int flags, ns_ldap_result_t ** pResult, + ns_ldap_error_t ** errorp, + int (*callback) (const ns_ldap_entry_t * entry, + const void *userdata), const void *userdata) +{ + ns_ldap_cookie_t *cookie = NULL; + ns_ldap_result_t *result = NULL; + ns_ldap_return_code ret; + + debug ("==> __ns_ldap_list map=%s filter=%s", + map != NULL ? map : "(null)", filter); + + *pResult = NULL; + *errorp = NULL; + + _nss_ldap_enter (); + + ret = __ns_ldap_initCookie (map, filter, init_filter_cb, + attribute, cred, flags, &cookie, callback, + userdata); + + while (ret == NS_LDAP_SUCCESS) + { + ret = __ns_ldap_search (cookie); + + if (result == NULL) + { + result = cookie->result; + } + + if (cookie->cb_ret != NS_LDAP_CB_NEXT) + { + assert (cookie->callback != NULL); + break; + } + } + + if (cookie != NULL) + { + if (ret == NS_LDAP_NOTFOUND && cookie->entry != NULL) + { + ret = NS_LDAP_SUCCESS; + } + + *pResult = result; + cookie->result = NULL; + } + + __ns_ldap_freeCookie (&cookie); + __ns_ldap_mapErrorDetail (ret, errorp); + + _nss_ldap_leave (); + + debug ("<== __ns_ldap_list ret=%s", NS_LDAP_ERR2STR (ret)); + + return ret; +} + +ns_ldap_return_code +__ns_ldap_err2str (ns_ldap_return_code err, char **strmsg) +{ + switch (err) + { + case NS_LDAP_SUCCESS: + case NS_LDAP_SUCCESS_WITH_INFO: + *strmsg = "Success"; + break; + case NS_LDAP_OP_FAILED: + *strmsg = "Operation failed"; + break; + case NS_LDAP_NOTFOUND: + *strmsg = "Not found"; + break; + case NS_LDAP_MEMORY: + *strmsg = "Out of memory"; + break; + case NS_LDAP_CONFIG: + *strmsg = "Configuration error"; + break; + case NS_LDAP_PARTIAL: + *strmsg = "Partial results received"; + break; + case NS_LDAP_INTERNAL: + *strmsg = "Internal LDAP error"; + break; + case NS_LDAP_INVALID_PARAM: + *strmsg = "Invalid parameter"; + break; + default: + *strmsg = "Unknown error"; + return NS_LDAP_INVALID_PARAM; + break; + } + + return NS_LDAP_SUCCESS; +} + +#endif /* HAVE_NSSWITCH_H */ diff --git a/ldap-sldap.h b/ldap-sldap.h new file mode 100644 index 0000000..f2278fc --- /dev/null +++ b/ldap-sldap.h @@ -0,0 +1,172 @@ +/* Copyright (C) 1997-2006 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 2006. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-sldap.h,v 2.4 2006/01/12 13:06:23 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_SLDAP_H +#define _LDAP_NSS_LDAP_LDAP_SLDAP_H + +#define NS_LDAP_VERSION NS_LDAP_VERSION_2 +#define NS_LDAP_VERSION_1 "1.0" +#define NS_LDAP_VERSION_2 "2.0" + +typedef enum { + NS_LDAP_FILE_VERSION_P = 0 +} ParamIndexType; + +typedef enum { + NS_LDAP_SUCCESS = 0, + NS_LDAP_OP_FAILED, + NS_LDAP_NOTFOUND, + NS_LDAP_MEMORY, + NS_LDAP_CONFIG, + NS_LDAP_PARTIAL, + NS_LDAP_INTERNAL, + NS_LDAP_INVALID_PARAM, + NS_LDAP_SUCCESS_WITH_INFO +} ns_ldap_return_code; + +typedef struct ns_ldap_search_desc { + char *basedn; + int scope; + char *filter; +} ns_ldap_search_desc_t; + +typedef struct ns_ldap_attribute_map { + char *origAttr; + char **mappedAttr; +} ns_ldap_attribute_map_t; + +typedef struct ns_ldap_objectclass_map { + char *origOC; + char *mappedOC; +} ns_ldap_objectclass_map_t; + +typedef struct ns_ldap_passwd_mgmt { + int pad[2]; +} ns_ldap_passwd_mgmt_t; + +typedef struct ns_ldap_error { + int status; + char *message; + ns_ldap_passwd_mgmt_t pwd_mgmt; +} ns_ldap_error_t; + +typedef struct ns_ldap_attr { + char *attrname; + unsigned int value_count; + char **attrvalue; +} ns_ldap_attr_t; + +typedef struct ns_ldap_entry { + unsigned int attr_count; + ns_ldap_attr_t **attr_pair; + struct ns_ldap_entry *next; +} ns_ldap_entry_t; + +typedef struct ns_ldap_result { + unsigned int entries_count; + ns_ldap_entry_t *entry; +} ns_ldap_result_t; + +#define NS_LDAP_HARD 0x001 +#define NS_LDAP_ALL_RES 0x002 +#define NS_LDAP_FOLLOWREF 0x004 +#define NS_LDAP_NOREF 0x008 +#define NS_LDAP_SCOPE_BASE 0x010 +#define NS_LDAP_SCOPE_ONELEVEL 0x020 +#define NS_LDAP_SCOPE_SUBTREE 0x040 +#define NS_LDAP_KEEP_CONN 0x080 +#define NS_LDAP_NEW_CONN 0x400 +#define NS_LDAP_NOMAP 0x800 + +#define NS_LDAP_CB_NEXT 0 +#define NS_LDAP_CB_DONE 1 + +typedef struct ns_ldap_cookie { + char *map; + char *filter; + char **attribute; + int flags; + + int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, char **realfilter, const void *userdata); + int (*callback)(const ns_ldap_entry_t *entry, const void *userdata); + const void *userdata; + + char *mapped_filter; + const char **mapped_attribute; + + int ret; + int cb_ret; + int erange; + ldap_map_selector_t sel; + ent_context_t *state; + ldap_automount_context_t *am_state; + + ns_ldap_result_t *result; + ns_ldap_entry_t *entry; +} ns_ldap_cookie_t; + +char **__ns_ldap_getMappedAttributes(const char *service, const char *attribute); +char **__ns_ldap_getMappedObjectClass(const char *service, const char *attribute); + +ns_ldap_return_code __ns_ldap_getParam(const ParamIndexType type, void ***data, ns_ldap_error_t **errorp); +ns_ldap_return_code __ns_ldap_freeError(ns_ldap_error_t **errorp); +ns_ldap_return_code __ns_ldap_freeEntry(ns_ldap_entry_t **pentry); +ns_ldap_return_code __ns_ldap_freeResult(ns_ldap_result_t **result); + +typedef void ns_cred_t; + +ns_ldap_return_code __ns_ldap_firstEntry(const char *service, + const char *filter, + int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, + char **realfilter, const void *userdata), + const char * const *attribute, + const ns_cred_t *cred, + const int flags, + void **cookie, + ns_ldap_result_t ** result, + ns_ldap_error_t **errorp, + const void *userdata); + +ns_ldap_return_code __ns_ldap_nextEntry( + void *cookie, + ns_ldap_result_t ** result, + ns_ldap_error_t **errorp); + +ns_ldap_return_code __ns_ldap_endEntry( + void **cookie, + ns_ldap_error_t **errorp); + +ns_ldap_return_code __ns_ldap_list( + const char *service, + const char *filter, + int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, char **realfilter, const void *userdata), + const char * const *attribute, + const ns_cred_t *cred, + const int flags, + ns_ldap_result_t **result, + ns_ldap_error_t **errorp, + int (*callback)(const ns_ldap_entry_t *entry, const void *userdata), + const void *userdata); + +ns_ldap_return_code __ns_ldap_err2str(ns_ldap_return_code err, char **strmsg); + +#endif /* _LDAP_NSS_LDAP_LDAP_SLDAP_H */ diff --git a/ldap-spwd.c b/ldap-spwd.c new file mode 100644 index 0000000..db1d731 --- /dev/null +++ b/ldap-spwd.c @@ -0,0 +1,220 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +static char rcsId[] = + "$Id: ldap-spwd.c,v 2.34 2006/01/11 18:03:49 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_SHADOW_H + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_PROT_H +#define _PROT_INCLUDED +#endif +#include <shadow.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "ldap-spwd.h" + +#ifdef HAVE_PORT_AFTER_H +#include <port_after.h> +#endif + +#if defined(HAVE_NSSWITCH_H) || defined(HAVE_NSS_H) + +#ifdef HAVE_NSS_H +static ent_context_t *sp_context = NULL; +#endif + +static NSS_STATUS +_nss_ldap_parse_sp (LDAPMessage * e, + ldap_state_t * pvt, + void *result, char *buffer, size_t buflen) +{ + struct spwd *sp = (struct spwd *) result; + NSS_STATUS stat; + char *tmp = NULL; + + stat = + _nss_ldap_assign_userpassword (e, ATM (LM_SHADOW, userPassword), + &sp->sp_pwdp, &buffer, &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrval (e, ATM (LM_SHADOW, uid), &sp->sp_namp, &buffer, + &buflen); + if (stat != NSS_SUCCESS) + return stat; + + stat = + _nss_ldap_assign_attrval (e, AT (shadowLastChange), &tmp, &buffer, + &buflen); + sp->sp_lstchg = (stat == NSS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; + + stat = + _nss_ldap_assign_attrval (e, AT (shadowMax), &tmp, &buffer, &buflen); + sp->sp_max = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + + stat = + _nss_ldap_assign_attrval (e, AT (shadowMin), &tmp, &buffer, &buflen); + sp->sp_min = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + + stat = + _nss_ldap_assign_attrval (e, AT (shadowWarning), &tmp, &buffer, + &buflen); + sp->sp_warn = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + + stat = + _nss_ldap_assign_attrval (e, AT (shadowInactive), &tmp, &buffer, + &buflen); + sp->sp_inact = (stat == NSS_SUCCESS) ? atol (tmp) : -1; + + stat = + _nss_ldap_assign_attrval (e, AT (shadowExpire), &tmp, &buffer, + &buflen); + sp->sp_expire = (stat == NSS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; + + stat = + _nss_ldap_assign_attrval (e, AT (shadowFlag), &tmp, &buffer, &buflen); + sp->sp_flag = (stat == NSS_SUCCESS) ? atol (tmp) : 0; + + _nss_ldap_shadow_handle_flag(sp); + + return NSS_SUCCESS; +} + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getspnam_r (const char *name, + struct spwd * result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_NAME (name, result, buffer, buflen, errnop, _nss_ldap_filt_getspnam, + LM_SHADOW, _nss_ldap_parse_sp, LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getspnam_r (nss_backend_t * be, void *args) +{ + LOOKUP_NAME (args, _nss_ldap_filt_getspnam, LM_SHADOW, _nss_ldap_parse_sp, + LDAP_NSS_BUFLEN_DEFAULT); +} +#endif /* HAVE_NSS_H */ + +#if defined(HAVE_NSS_H) +NSS_STATUS _nss_ldap_setspent (void) +#else +static NSS_STATUS +_nss_ldap_setspent_r (nss_backend_t * sp_context, void *args) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_SETENT (sp_context); +} +#endif + +#if defined(HAVE_NSS_H) +NSS_STATUS _nss_ldap_endspent (void) +#else +static NSS_STATUS +_nss_ldap_endspent_r (nss_backend_t * sp_context, void *args) +#endif +#if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H) +{ + LOOKUP_ENDENT (sp_context); +} +#endif + +#ifdef HAVE_NSS_H +NSS_STATUS +_nss_ldap_getspent_r (struct spwd *result, + char *buffer, size_t buflen, int *errnop) +{ + LOOKUP_GETENT (sp_context, result, buffer, buflen, errnop, + _nss_ldap_filt_getspent, LM_SHADOW, _nss_ldap_parse_sp, + LDAP_NSS_BUFLEN_DEFAULT); +} +#elif defined(HAVE_NSSWITCH_H) +static NSS_STATUS +_nss_ldap_getspent_r (nss_backend_t * sp_context, void *args) +{ + LOOKUP_GETENT (args, sp_context, _nss_ldap_filt_getspent, LM_SHADOW, + _nss_ldap_parse_sp, LDAP_NSS_BUFLEN_DEFAULT); +} +#endif + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS +_nss_ldap_shadow_destr (nss_backend_t * sp_context, void *args) +{ + return _nss_ldap_default_destr (sp_context, args); +} + +static nss_backend_op_t shadow_ops[] = { + _nss_ldap_shadow_destr, + _nss_ldap_endspent_r, /* NSS_DBOP_ENDENT */ + _nss_ldap_setspent_r, /* NSS_DBOP_SETENT */ + _nss_ldap_getspent_r, /* NSS_DBOP_GETENT */ + _nss_ldap_getspnam_r /* NSS_DBOP_SHADOW_BYNAME */ +}; + + +nss_backend_t * +_nss_ldap_shadow_constr (const char *db_name, + const char *src_name, const char *cfg_args) +{ + nss_ldap_backend_t *be; + + if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be)))) + return NULL; + + be->ops = shadow_ops; + be->n_ops = sizeof (shadow_ops) / sizeof (nss_backend_op_t); + + if (_nss_ldap_default_constr (be) != NSS_SUCCESS) + return NULL; + + return (nss_backend_t *) be; +} + +#endif /* !HAVE_NSS_H */ +#endif + +#endif /* HAVE_SHADOW_H */ diff --git a/ldap-spwd.h b/ldap-spwd.h new file mode 100644 index 0000000..bd4ec53 --- /dev/null +++ b/ldap-spwd.h @@ -0,0 +1,42 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + $Id: ldap-spwd.h,v 2.17 2005/05/20 05:30:42 lukeh Exp $ + */ + +#ifndef _LDAP_NSS_LDAP_LDAP_SPWD_H +#define _LDAP_NSS_LDAP_LDAP_SPWD_H + +static NSS_STATUS _nss_ldap_parse_sp (LDAPMessage * e, + ldap_state_t * pvt, + void *result, + char *buffer, size_t buflen); + +#ifdef HAVE_NSSWITCH_H +static NSS_STATUS _nss_ldap_getspnam_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_setspent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_endspent_r (nss_backend_t * be, void *fakeargs); +static NSS_STATUS _nss_ldap_getspent_r (nss_backend_t * be, void *fakeargs); + +nss_backend_t *_nss_ldap_shadow_constr (const char *db_name, + const char *src_name, + const char *cfg_args); +#endif /* !HAVE_NSS_H */ + +#endif /* _LDAP_NSS_LDAP_LDAP_SPWD_H */ diff --git a/ldap.conf b/ldap.conf new file mode 100644 index 0000000..64a11c7 --- /dev/null +++ b/ldap.conf @@ -0,0 +1,313 @@ + @(#)$Id: ldap.conf,v 2.47 2006/05/15 08:13:44 lukeh Exp $ +# +# This is the configuration file for the LDAP nameservice +# switch library and the LDAP PAM module. +# +# PADL Software +# http://www.padl.com +# + +# Your LDAP server. Must be resolvable without using LDAP. +# Multiple hosts may be specified, each separated by a +# space. How long nss_ldap takes to failover depends on +# whether your LDAP client library supports configurable +# network or connect timeouts (see bind_timelimit). +host 127.0.0.1 + +# The distinguished name of the search base. +base dc=padl,dc=com + +# Another way to specify your LDAP server is to provide an +# uri with the server name. This allows to use +# Unix Domain Sockets to connect to a local LDAP Server. +#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 + +# The LDAP version to use (defaults to 3 +# if supported by client library) +#ldap_version 3 + +# The distinguished name to bind to the server with. +# Optional: default is to bind anonymously. +#binddn cn=proxyuser,dc=padl,dc=com + +# The credentials to bind with. +# Optional: default is no credential. +#bindpw secret + +# The distinguished name to bind to the server with +# if the effective user ID is root. Password is +# stored in /etc/ldap.secret (mode 600) +#rootbinddn cn=manager,dc=padl,dc=com + +# The port. +# Optional: default is 389. +#port 389 + +# The search scope. +#scope sub +#scope one +#scope base + +# Search timelimit +#timelimit 30 + +# Bind/connect timelimit +#bind_timelimit 30 + +# Reconnect policy: +# hard_open: reconnect to DSA with exponential backoff if +# opening connection failed +# hard_init: reconnect to DSA with exponential backoff if +# initializing connection failed +# hard: alias for hard_open +# soft: return immediately on server failure +#bind_policy hard + +# Connection policy: +# persist: DSA connections are kept open (default) +# oneshot: DSA connections destroyed after request +#nss_connect_policy persist + +# Idle timelimit; client will close connections +# (nss_ldap only) if the server has not been contacted +# for the number of seconds specified below. +#idle_timelimit 3600 + +# Use paged rseults +#nss_paged_results yes + +# Pagesize: when paged results enable, used to set the +# pagesize to a custom value +#pagesize 1000 + +# Filter to AND with uid=%s +#pam_filter objectclass=account + +# The user ID attribute (defaults to uid) +#pam_login_attribute uid + +# Search the root DSE for the password policy (works +# with Netscape Directory Server) +#pam_lookup_policy yes + +# Check the 'host' attribute for access control +# Default is no; if set to yes, and user has no +# value for the host attribute, and pam_ldap is +# configured for account management (authorization) +# then the user will not be allowed to login. +#pam_check_host_attr yes + +# Check the 'authorizedService' attribute for access +# control +# Default is no; if set to yes, and the user has no +# value for the authorizedService attribute, and +# pam_ldap is configured for account management +# (authorization) then the user will not be allowed +# to login. +#pam_check_service_attr yes + +# Group to enforce membership of +#pam_groupdn cn=PAM,ou=Groups,dc=padl,dc=com + +# Group member attribute +#pam_member_attribute uniquemember + +# Specify a minium or maximum UID number allowed +#pam_min_uid 0 +#pam_max_uid 0 + +# Template login attribute, default template user +# (can be overriden by value of former attribute +# in user's entry) +#pam_login_attribute userPrincipalName +#pam_template_login_attribute uid +#pam_template_login nobody + +# HEADS UP: the pam_crypt, pam_nds_passwd, +# and pam_ad_passwd options are no +# longer supported. +# +# Do not hash the password at all; presume +# the directory server will do it, if +# necessary. This is the default. +#pam_password clear + +# Hash password locally; required for University of +# Michigan LDAP server, and works with Netscape +# Directory Server if you're using the UNIX-Crypt +# hash mechanism and not using the NT Synchronization +# service. +#pam_password crypt + +# Remove old password first, then update in +# cleartext. Necessary for use with Novell +# Directory Services (NDS) +#pam_password nds + +# RACF is an alias for the above. For use with +# IBM RACF +#pam_password racf + +# Update Active Directory password, by +# creating Unicode password and updating +# unicodePwd attribute. +#pam_password ad + +# Use the OpenLDAP password change +# extended operation to update the password. +#pam_password exop + +# Redirect users to a URL or somesuch on password +# changes. +#pam_password_prohibit_message Please visit http://internal to change your password. + +# Use backlinks for answering initgroups() +#nss_initgroups backlink + +# Enable support for RFC2307bis (distinguished names in group +# members) +#nss_schema rfc2307bis + +# RFC2307bis naming contexts +# Syntax: +# nss_base_XXX base?scope?filter +# where scope is {base,one,sub} +# and filter is a filter to be &'d with the +# default filter. +# You can omit the suffix eg: +# nss_base_passwd ou=People, +# to append the default base DN but this +# may incur a small performance impact. +#nss_base_passwd ou=People,dc=padl,dc=com?one +#nss_base_shadow ou=People,dc=padl,dc=com?one +#nss_base_group ou=Group,dc=padl,dc=com?one +#nss_base_hosts ou=Hosts,dc=padl,dc=com?one +#nss_base_services ou=Services,dc=padl,dc=com?one +#nss_base_networks ou=Networks,dc=padl,dc=com?one +#nss_base_protocols ou=Protocols,dc=padl,dc=com?one +#nss_base_rpc ou=Rpc,dc=padl,dc=com?one +#nss_base_ethers ou=Ethers,dc=padl,dc=com?one +#nss_base_netmasks ou=Networks,dc=padl,dc=com?ne +#nss_base_bootparams ou=Ethers,dc=padl,dc=com?one +#nss_base_aliases ou=Aliases,dc=padl,dc=com?one +#nss_base_netgroup ou=Netgroup,dc=padl,dc=com?one + +# attribute/objectclass mapping +# Syntax: +#nss_map_attribute rfc2307attribute mapped_attribute +#nss_map_objectclass rfc2307objectclass mapped_objectclass + +# configure --enable-nds is no longer supported. +# NDS mappings +#nss_map_attribute uniqueMember member + +# Services for UNIX 3.5 mappings +#nss_map_objectclass posixAccount User +#nss_map_objectclass shadowAccount User +#nss_map_attribute uid msSFU30Name +#nss_map_attribute uniqueMember msSFU30PosixMember +#nss_map_attribute userPassword msSFU30Password +#nss_map_attribute homeDirectory msSFU30HomeDirectory +#nss_map_attribute homeDirectory msSFUHomeDirectory +#nss_map_objectclass posixGroup Group +#pam_login_attribute msSFU30Name +#pam_filter objectclass=User +#pam_password ad + +# configure --enable-mssfu-schema is no longer supported. +# Services for UNIX 2.0 mappings +#nss_map_objectclass posixAccount User +#nss_map_objectclass shadowAccount user +#nss_map_attribute uid msSFUName +#nss_map_attribute uniqueMember posixMember +#nss_map_attribute userPassword msSFUPassword +#nss_map_attribute homeDirectory msSFUHomeDirectory +#nss_map_attribute shadowLastChange pwdLastSet +#nss_map_objectclass posixGroup Group +#nss_map_attribute cn msSFUName +#pam_login_attribute msSFUName +#pam_filter objectclass=User +#pam_password ad + +# RFC 2307 (AD) mappings +#nss_map_objectclass posixAccount user +#nss_map_objectclass shadowAccount user +#nss_map_attribute uid sAMAccountName +#nss_map_attribute homeDirectory unixHomeDirectory +#nss_map_attribute shadowLastChange pwdLastSet +#nss_map_objectclass posixGroup group +#nss_map_attribute uniqueMember member +#pam_login_attribute sAMAccountName +#pam_filter objectclass=User +#pam_password ad + +# configure --enable-authpassword is no longer supported +# AuthPassword mappings +#nss_map_attribute userPassword authPassword + +# AIX SecureWay mappings +#nss_map_objectclass posixAccount aixAccount +#nss_base_passwd ou=aixaccount,?one +#nss_map_attribute uid userName +#nss_map_attribute gidNumber gid +#nss_map_attribute uidNumber uid +#nss_map_attribute userPassword passwordChar +#nss_map_objectclass posixGroup aixAccessGroup +#nss_base_group ou=aixgroup,?one +#nss_map_attribute cn groupName +#nss_map_attribute uniqueMember member +#pam_login_attribute userName +#pam_filter objectclass=aixAccount +#pam_password clear + +# For pre-RFC2307bis automount schema +#nss_map_objectclass automountMap nisMap +#nss_map_attribute automountMapName nisMapName +#nss_map_objectclass automount nisObject +#nss_map_attribute automountKey cn +#nss_map_attribute automountInformation nisMapEntry + +# Netscape SDK LDAPS +#ssl on + +# Netscape SDK SSL options +#sslpath /etc/ssl/certs + +# OpenLDAP SSL mechanism +# start_tls mechanism uses the normal LDAP port, LDAPS typically 636 +#ssl start_tls +#ssl on + +# OpenLDAP SSL options +# Require and verify server certificate (yes/no) +# Default is to use libldap's default behavior, which can be configured in +# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for +# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". +#tls_checkpeer yes + +# CA certificates for server certificate verification +# At least one of these are required if tls_checkpeer is "yes" +#tls_cacertfile /etc/ssl/ca.cert +#tls_cacertdir /etc/ssl/certs + +# 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 + +# Disable SASL security layers. This is needed for AD. +#sasl_secprops maxssf=0 + +# Override the default Kerberos ticket cache location. +#krb5_ccname FILE:/etc/.ldapcache + @@ -0,0 +1,355 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +static char rcsId[] = "$Id: ltf.c,v 2.29 2005/05/20 05:30:42 lukeh Exp $"; + +#include "config.h" + +#ifdef HAVE_PORT_BEFORE_H +#include <port_before.h> +#endif + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" + +#if defined(LDAP_OPT_THREAD_FN_PTRS) && (defined(HAVE_THREAD_H) || defined(HAVE_PTHREAD_H)) + +static void *ltf_mutex_alloc (void); +static void ltf_mutex_free (void *m); +static NSS_STATUS ltf_tsd_setup (void); +static void ltf_set_ld_error (int err, char *matched, char *errmsg, + void *dummy); +static int ltf_get_ld_error (char **matched, char **errmsg, void *dummy); +static void ltf_set_errno (int err); +static int ltf_get_errno (void); + +#ifndef HAVE_THREAD_H /* thus, pthreads */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +static int ltf_mutex_lock (void *); +static int ltf_mutex_unlock (void *); + +static pthread_key_t key; + +NSS_STATUS _nss_ldap_ltf_thread_init (LDAP * ld) +{ + struct ldap_thread_fns tfns; + + /* set mutex pointers */ + memset (&tfns, '\0', sizeof (struct ldap_thread_fns)); + tfns.ltf_mutex_alloc = ltf_mutex_alloc; + tfns.ltf_mutex_free = ltf_mutex_free; + tfns.ltf_mutex_lock = ltf_mutex_lock; + tfns.ltf_mutex_unlock = ltf_mutex_unlock; + tfns.ltf_get_errno = ltf_get_errno; + tfns.ltf_set_errno = ltf_set_errno; + tfns.ltf_get_lderrno = ltf_get_ld_error; + tfns.ltf_set_lderrno = ltf_set_ld_error; + tfns.ltf_lderrno_arg = NULL; + /* set ld_errno pointers */ + if (ldap_set_option (ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns) != 0) + { + return NSS_UNAVAIL; + } + + return ltf_tsd_setup (); +} + +static void * +ltf_mutex_alloc (void) +{ + pthread_mutex_t *mutexp; + + if ((mutexp = malloc (sizeof (pthread_mutex_t))) != NULL) + { + pthread_mutex_init (mutexp, NULL); + } + + return (mutexp); +} + +static void +ltf_mutex_free (void *mutexp) +{ + pthread_mutex_destroy ((pthread_mutex_t *) mutexp); +} + +static int +ltf_mutex_lock (void *mutexp) +{ +#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + return __libc_lock_lock (*(pthread_mutex_t *) mutexp); +#elif defined(HPUX) + return __thread_mutex_lock ((pthread_mutex_t *) mutexp); +#else +# ifdef _AIX + if (__multi_threaded == 0) + return 0; +# endif + return pthread_mutex_lock ((pthread_mutex_t *) mutexp); +#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ +} + +static int +ltf_mutex_unlock (void *mutexp) +{ +#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + return __libc_lock_unlock (*(pthread_mutex_t *) mutexp); +#elif defined(HPUX) + return __thread_mutex_unlock ((pthread_mutex_t *) mutexp); +#else +# ifdef _AIX + if (__multi_threaded == 0) + return 0; +# endif + return pthread_mutex_unlock ((pthread_mutex_t *) mutexp); +#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ +} + +static NSS_STATUS +ltf_tsd_setup (void) +{ + void *tsd; + +#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + if (__libc_key_create (&key, free) != 0) + { + return NSS_UNAVAIL; + } + tsd = (void *) calloc (1, sizeof (struct ldap_error)); + __libc_setspecific (key, tsd); +#else + if (pthread_key_create (&key, free) != 0) + { + return NSS_UNAVAIL; + } + tsd = pthread_getspecific (key); + if (tsd != NULL) + { + pthread_exit (NULL); + } + tsd = (void *) calloc (1, sizeof (struct ldap_error)); + pthread_setspecific (key, tsd); +#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ + + return NSS_SUCCESS; +} + +static void +ltf_set_ld_error (int err, char *matched, char *errmsg, void *dummy) +{ + struct ldap_error *le; + +#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + le = __libc_getspecific (key); +#else + le = pthread_getspecific (key); +#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ + + le->le_errno = err; + + if (le->le_matched != NULL) + ldap_memfree (le->le_matched); + le->le_matched = matched; + + if (le->le_errmsg != NULL) + ldap_memfree (le->le_errmsg); + le->le_errmsg = errmsg; +} + +static int +ltf_get_ld_error (char **matched, char **errmsg, void *dummy) +{ + struct ldap_error *le; + +#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) + le = __libc_getspecific (key); +#else + le = pthread_getspecific (key); +#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ + if (le == NULL) + return LDAP_LOCAL_ERROR; + + if (matched != NULL) + *matched = le->le_matched; + + if (errmsg != NULL) + *errmsg = le->le_errmsg; + + return (le->le_errno); +} + +static void +ltf_set_errno (int err) +{ + errno = err; +} + +static int +ltf_get_errno (void) +{ + return (errno); +} +#else +static thread_key_t ltf_key = 0; + +static void * +ltf_mutex_alloc (void) +{ + mutex_t *m; + + m = (mutex_t *) malloc (sizeof (*m)); + if (m == NULL) + return NULL; + + if (mutex_init (m, USYNC_THREAD, NULL) < 0) + return NULL; + + return m; +} + +static void +ltf_mutex_free (void *m) +{ + mutex_destroy ((mutex_t *) m); +/* free(m); */ +} + +void +ltf_destr (void *tsd) +{ + free (tsd); +} + +static NSS_STATUS +ltf_tsd_setup (void) +{ + void *tsd; + + (void) thr_keycreate (<f_key, ltf_destr); + tsd = (void *) calloc (1, sizeof (ldap_error_t)); + thr_setspecific (ltf_key, tsd); + return NSS_SUCCESS; +} + +static void +ltf_set_ld_error (int err, char *matched, char *errmsg, void *dummy) +{ + ldap_error_t *le; + + (void) thr_getspecific (ltf_key, (void **) &le); + if (le == NULL) + return; + + le->le_errno = err; + + if (le->le_matched != NULL) + ldap_memfree (le->le_matched); + le->le_matched = matched; + + if (le->le_errmsg != NULL) + ldap_memfree (le->le_errmsg); + le->le_errmsg = errmsg; +} + +static int +ltf_get_ld_error (char **matched, char **errmsg, void *dummy) +{ + ldap_error_t *le = NULL; + + (void) thr_getspecific (ltf_key, (void **) &le); + if (le == NULL) + return LDAP_LOCAL_ERROR; + + if (matched != NULL) + *matched = le->le_matched; + + if (errmsg != NULL) + *errmsg = le->le_errmsg; + + return le->le_errno; +} + +static void +ltf_set_errno (int err) +{ + errno = err; +} + +static int +ltf_get_errno (void) +{ + return errno; +} + +NSS_STATUS _nss_ldap_ltf_thread_init (LDAP * ld) +{ + struct ldap_thread_fns tfns; + + memset (&tfns, '\0', sizeof (tfns)); + tfns.ltf_mutex_alloc = ltf_mutex_alloc; + tfns.ltf_mutex_free = ltf_mutex_free; + tfns.ltf_mutex_lock = (int (*)(void *)) mutex_lock; + tfns.ltf_mutex_unlock = (int (*)(void *)) mutex_unlock; + tfns.ltf_get_errno = ltf_get_errno; + tfns.ltf_set_errno = ltf_set_errno; + tfns.ltf_get_lderrno = ltf_get_ld_error; + tfns.ltf_set_lderrno = ltf_set_ld_error; + tfns.ltf_lderrno_arg = NULL; + + if (ldap_set_option (ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns) != 0) + return NSS_UNAVAIL; + + return ltf_tsd_setup (); +} +#endif /* !HAVE_THREAD_H */ +#endif /* LDAP_OPT_THREAD_FN_PTRS */ @@ -0,0 +1,29 @@ +/* Copyright (C) 1997-2005 Luke Howard. + Portions Copyright (C) 1997-2002 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef _LDAP_NSS_LDAP_LTF_H +#define _LDAP_NSS_LDAP_LTF_H + +#ifdef LDAP_OPT_THREAD_FN_PTRS +NSS_STATUS _nss_ldap_ltf_thread_init (LDAP * ld); +#endif + +#endif /* _LDAP_NSS_LDAP_LTF_H */ @@ -0,0 +1,283 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# 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=: + +# 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 + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --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' + 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]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.3 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_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 missing on your system. 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 missing on your system. 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 missing on your system. 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 + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. 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 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # 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 ${1+"$@"} && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar ${1+"$@"} && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" ${1+"$@"} && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" ${1+"$@"} && 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 you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..57b5951 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman <friedman@prep.ai.mit.edu> +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 2.1 2001/01/09 00:21:16 lukeh Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/nss_common.h b/nss_common.h new file mode 100644 index 0000000..137b791 --- /dev/null +++ b/nss_common.h @@ -0,0 +1,50 @@ +/* + Donated by HP to enable Winbindd to build on HPUX 11.x. + Copyright (C) Jeremy Allison 2002. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _NSS_COMMON_H +#define _NSS_COMMON_H + +#ifdef HAVE_SYNCH_H +#include <synch.h> +#endif +#ifdef HAVE_PTHREAD_H +#include <pthread.h> +#endif + +typedef enum { + NSS_SUCCESS, + NSS_NOTFOUND, + NSS_UNAVAIL, + NSS_TRYAGAIN +} nss_status_t; + +struct nss_backend; + +typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args); + +struct nss_backend { + nss_backend_op_t *ops; + int n_ops; +}; +typedef struct nss_backend nss_backend_t; +typedef int nss_dbop_t; + +#endif /* _NSS_COMMON_H */ + diff --git a/nss_dbdefs.h b/nss_dbdefs.h new file mode 100644 index 0000000..7fc4655 --- /dev/null +++ b/nss_dbdefs.h @@ -0,0 +1,134 @@ +/* + Donated by HP to enable Winbindd to build on HPUX 11.x. + Copyright (C) Jeremy Allison 2002. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _NSS_DBDEFS_H +#define _NSS_DBDEFS_H + +#include <errno.h> +#include <netdb.h> +#include <limits.h> + +#ifndef NSS_INCLUDE_UNSAFE +#define NSS_INCLUDE_UNSAFE 1 /* Build old, MT-unsafe interfaces, */ +#endif /* NSS_INCLUDE_UNSAFE */ + +enum nss_netgr_argn { + NSS_NETGR_MACHINE, + NSS_NETGR_USER, + NSS_NETGR_DOMAIN, + NSS_NETGR_N +}; + +enum nss_netgr_status { + NSS_NETGR_FOUND, + NSS_NETGR_NO, + NSS_NETGR_NOMEM +}; + +struct nss_setnetgrent_args { + const char *netgroup; + nss_backend_t *iterator; +}; + +struct nss_getnetgrent_args { + char *buffer; + int buflen; + enum nss_netgr_status status; + char *retp[NSS_NETGR_N]; +}; + +typedef unsigned nss_innetgr_argc; +typedef char **nss_innetgr_argv; + +struct nss_innetgr_1arg { + nss_innetgr_argc argc; + nss_innetgr_argv argv; +}; + +struct nss_innetgr_args { + struct nss_innetgr_1arg arg[NSS_NETGR_N]; + struct nss_innetgr_1arg groups; + enum nss_netgr_status status; +}; + +typedef struct { + void *result; /* "result" parameter to getXbyY_r() */ + char *buffer; /* "buffer" " " */ + int buflen; /* "buflen" " " */ +} nss_XbyY_buf_t; + +extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int struct_size, int buffer_size); +extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *); + +union nss_XbyY_key { + uid_t uid; + gid_t gid; + const char *name; + int number; + struct { + long net; /* int on Solaris */ + int type; + } netaddr; + struct { + const char *addr; + int len; + int type; + } hostaddr; + struct { + union { + const char *name; + int port; + } serv; + const char *proto; + } serv; + void *ether; + /* Solaris has private key args here */ +}; + +typedef struct nss_XbyY_args { + nss_XbyY_buf_t buf; + int stayopen; + /* + * Support for setXXXent(stayopen) + * Used only in hosts, protocols, + * networks, rpc, and services. + */ + int (*str2ent)(const char *instr, int instr_len, void *ent, char *buffer, int buflen); + union nss_XbyY_key key; + + void *returnval; + int erange; +#undef h_errno + int h_errno; + nss_status_t status; +} nss_XbyY_args_t; + +struct nss_groupsbymem { + const char *username; + gid_t *gid_array; + int maxgids; + int force_slow_way; + int (*str2ent)(const char *instr, int instr_len, void *ent, char *buffer, int buflen); + nss_status_t (*process_cstr)(const char *instr, int instr_len, struct nss_groupsbymem *); + int numgids; +}; + +#endif /* _NSS_DBDEFS_H */ + diff --git a/nss_ldap.5 b/nss_ldap.5 new file mode 100644 index 0000000..4a94630 --- /dev/null +++ b/nss_ldap.5 @@ -0,0 +1,460 @@ +.TH nss_ldap 5 +.\" Copyright 1997-2005 Luke Howard." +.\" Copying restrictions apply. See COPYING. +.\" $Id: nss_ldap.5,v 2.14 2006/03/09 03:48:34 lukeh Exp $ +.SH NAME +nss_ldap \- LDAP nameservice provider +.SH DESCRIPTION +The +.B nss_ldap +module is a set of C library extensions which allows X.500 and 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.) +.LP +Features of the PADL nss_ldap module include support for both the +RFC 2307 and RFC 2307bis schema, a common implementation across multiple +platforms, Kerberos and SSL security, configurable schema mapping, +and configuration file compatibility with the +.BR pam_ldap (5) +module. +.LP +Because LDAP is a hierarchical directory service, one can distribute the +information in a manner which reflects organizational 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. +.LP +.B +nss_ldap +will work alongside existing NIS, NIS+, DNS and flat file +name services. More importantly, because it builds as a shared library, +it is not necessary to recompile any applications to take advantage +of LDAP. +.LP +The present version of +.B +nss_ldap +supports AIX 4.3.3 and above, FreeBSD 5.1, HP-UX 11i, Linux and +Solaris 2.6 and above. Many vendors provide their own LDAP nameservice +providers, often also called nss_ldap. This manual page applies to the +PADL +.B +nss_ldap +module only. If you are using a vendor provided module, consult the +relevant documentation instead. +.LP +The features supported by the version of +.B +nss_ldap +depend on which flags +were enabled when the software was built. Most features are enabled +in the configuration file, described below. (The location of the +configuration file is +configurable at compile time; the default path is /etc/ldap.conf.) +Also, some features may be unavailable on certain +operating systems or with certain LDAP libraries. For more information, +consult your vendor. +.SH CONFIGURATION +.B +nss_ldap +stores its configuration in the +.B +ldap.conf +file, the location of which is configurable at compile time. +(It should be noted that some LDAP client libraries, such as +OpenLDAP, also use a configuration file of the same name. +.B +nss_ldap +supports many of the same configuration file options as OpenLDAP, +but it adds several that are specific to the functionality it provides. +Additionally, it is not guaranteed that +.B +nss_ldap +will continue to match the configuration file semantics of OpenLDAP. +You may wish to use different files.) +.LP +Configuration file options consist of a keyword followed by a +space and any arguments. The following options are supported by +both +.B +nss_ldap +and the PADL +.B +pam_ldap +module: +.B +.TP +.B host <name:port ...> +Specifies the name(s) or IP address(es) of the +.I +LDAP +server(s) to connect to. In the case that +.B +nss_ldap +is used for host name resolution, each server should be specified as an +IP address or name that can be resolved without using +.I +LDAP. +Multiple servers may be specified, each separated by a space. +The failover time depends on whether the +.I +LDAP +client library supports configurable network or connect timeouts +(see +.B +bind_timelimit +below). +.TP +.B base <base> +Specifies the default base distinguished name (DN) to use for searches. +.TP +.B uri <ldap[is]://[name[:port]] ...> +For +.I +LDAP +client libraries that support it, specifies the URI(s) of the LDAP +server(s) to connect to. The URI scheme may be +.B +ldap, +.B +ldapi, +or +.B +ldaps, +specifying LDAP over TCP, IPC and SSL respectively. If applicable, +a port number can be specified; the default port number for the +selected protocol is used if omitted. This option takes +precedence over the +.B +host +option; it is not possible to combine the two. +.TP +.B +ldap_version <version> +Specifies the version of the +.I +LDAP +protocol to use. Presently +.B +version +must be 2 or 3. The default is to use the maximum version supported +by the client library. +.TP +.B binddn <binddn> +Specifies the distinguished name with which to bind to the directory +server(s). This option is optional; the default is to bind +anonymously. +.TP +.B bindpw <bindpw> +Specifies the cleartext credentials with which to bind. This option +is only applicable when used with +.B binddn +above. The default is no credential (anonymous bind). When binding to +the directory using +.I +SASL +or other authentication mechanisms apart from simple binds, this +option is not used. +.TP +.B rootbinddn <binddn> +This option has the same syntax and effect as the +.B binddn +option above, except it applies when the effective user ID is +zero. If not specified, then the identity specified in +.B binddn +is used instead. Because the configuration file may be readable by +many users, the root bind DN credentials are stored in the +.B ldap.secret +file instead. This file is usually in the same directory as the +configuration file. +.TP +.B port <port> +Specifies the port to connect to; this option is used with the +.B host +option, and is ignored with the +.B uri +option. +.TP +.B scope <sub|one|base> +Specifies the search scope (subtree, one level or base object). The +default scope is subtree; base scope is almost never useful for +nameservice lookups. +.TP +.B deref <never|searching|finding|always> +Specifies the policy for dereferencing aliases. The default policy is +to never dereference aliases. +.TP +.B timelimit <timelimit> +Specifies the time limit (in seconds) to use when performing searches. A value +of zero (0), which is the default, is to wait indefinitely for +searches to be completed. +.TP +.B bind_timelimit <timelimit> +Specifies the time limit (in seconds) to use when connecting to the directory +server. This is distinct from the time limit specified in +.B timelimit +and affects the initial server connection only. (Server connections +are otherwise cached.) Only some +.I +LDAP +client libraries have the underlying functionality necessary to +support this option. The default bind timelimit is 30 seconds. +.TP +.B referrals <yes|no> +Specifies whether automatic referral chasing should be enabled. The +default behaviour is specifed by the +.I +LDAP +client library. +.TP +.B restart <yes|no> +Specifies whether the +.I LDAP +client library should restart the +.BR +select(2) +system call when interrupted. This feature is not supported by all +client libraries. +.TP +.B logdir <directory> +Specifies the directory used for logging by the +.I LDAP +client library. This feature is not supported by all client +libraries. +.TP +.B debug <level> +Specifies the debug level used for logging by the +.I LDAP +client library. This feature is not supported by all client +libraries, and does not apply to the +.B nss_ldap +and +.B pam_ldap +modules themselves (debugging, if any, is configured separately +and usually at compile time). +.TP +.B ssl <on|off|start_tls> +Specifies whether to use SSL/TLS or not (the default is not to). If +.B +start_tls +is specified then StartTLS is used rather than raw LDAP over SSL. +Not all +.I LDAP +client libraries support both SSL and StartTLS, and all related +configuration options. +.TP +.B sslpath <cert7_path> +For the Netscape and Mozilla +.I +LDAP +client libraries only, this specifies the path to the X.509 +certificate database. +.TP +.B tls_checkpeer <yes|no> +Specifies whether to require and verify the server certificate +or not, when using SSL/TLS with the OpenLDAP client library. +The default is to use the default behaviour of the client +library; for OpenLDAP 2.0 and earlier it is "no", for OpenLDAP +2.1 and later it is "yes". At least one of +.B tls_cacertdir +and +.B tls_cacertfile +is required if peer verification is enabled. +.TP +.B tls_cacertdir <certificate_dir> +Specifies the directory containing X.509 certificates for peer +authentication. +.TP +.B tls_cacertfile <certificate_file> +Specifies the path to the X.509 certificate for peer authentication. +.TP +.B tls_randfile <entropy_file> +Specifies the path to an entropy source. +.TP +.B tls_ciphers <ciphers> +Specifies the ciphers to use for TLS. See your TLS implementation's +documentation for further information. +.TP +.B tls_cert <certificate_file> +Specifies the path to the file containing the local certificate for +client TLS authentication. +.TP +.B tls_key <key_file> +Specifies the path to the file containing the private key for client +TLS authentication. +.TP +The following configuration options apply to nss_ldap only: +.TP +.B bind_policy <hard_open|hard_init|soft> +Specifies the policy to use for reconnecting to an unavailable +.I +LDAP +server. The default is +.B hard_open, +which reconnects if opening the connection to the directory server +failed. By contrast, +.B hard_init +reconnects if initializing the connection failed. Initializing may not +actually contact the directory server, and it is possible that a +malformed configuration file will trigger reconnection. If +.B soft +is specified, then +.B nss_ldap +will return immediately on server failure. All "hard" reconnect +policies block with exponential backoff before retrying. +.TP +.B nss_connect_policy <persist|oneshot> +Determines whether nss_ldap persists connections. The default +is for the connection to the LDAP server to remain open after +the first request. +.TP +.B idle_timelimit <timelimit> +Specifies the time (in seconds) after which +.B +nss_ldap +will close connections to the directory server. The default is not to +time out connections. +.TP +.B sasl_authid <authid> +Specifies the authorization identity to be used when performing SASL +authentication. +.TP +.B rootsasl_auth_id <authid> +Specifies the authorization identity to be used when performing SASL +authentication as root (when the effective user ID is zero). +.TP +.B sasl_secprops <properties> +Specifies Cyrus SASL security properties. Allowed values are described +in the +.BR +ldap.conf(5) +manual page. +.TP +.B rootuse_sasl <yes|no> +Specifies whether SASL authentication should be used when the effective +user ID is zero. +.TP +.B krb5_ccname <PREFIX:args> +If +.B nss_ldap +is built with configurable GSS-API credentials cache name support, +specifies the Kerberos credentials cache to use. +.TP +.B nss_paged_results <yes|no> +.BR +Enables support for paged results. +.TP +.B pagesize <pagesize> +When paged results are enabled (see above), specifies the number of +entries to return in a single page. The default is 1000. +.TP +.B nss_base_<map> <basedn?scope?filter> +Specify the search base, scope and filter to be used for specific +maps. (Note that +.B map +forms part of the configuration file keyword and is one of +passwd, shadow, group, hosts, services, networks, protocols, +rpc, ethers, netmasks, bootparams, aliases and netgroup.) +The syntax of +.B basedn +and +.B scope +are the same as for the configuration file options of the same +name, with the addition of being able to omit the trailing suffix +of the base DN (in which case the global base DN will be appended +instead). The +.B filter +is a search filter to be added to the default search filter for a +specific map, such that the effective filter is the logical +intersection of the two. The base DN, scope and filter are separated +with literal question marks (?) as given above; this is for +compatibility with the DUA configuration profile schema and the +.B +ldapprofile +tool. This option may be specified multiple times. +.TP +.B nss_map_attribute <from_attribute> <to_attribute> +This option may be specified multiple times, and directs +.B nss_ldap +to use the attribute +.B to_attribute +instead of the RFC 2307 attribute +.B from_attribute +in all lookups. +If +.B nss_ldap +was built without schema mapping support, then this option +is ignored. +.TP +.B nss_map_objectclass <from_objectclass> <to_objectclass> +This option may be specified multiple times, and directs +.B nss_ldap +to use the object class +.B to_objectclass +instead of the RFC 2307 object class +.B from_objectclass +in all lookups. +If +.B nss_ldap +was built without schema mapping support, then this option +is ignored. +.TP +.B nss_default_attribute_value <attribute> <value> +Specifies the default value to use for entries that lack the +specified attribute. This option may be specified multiple times, +for different attributes. +If +.B nss_ldap +was built without schema mapping support, then this option +is ignored. +.TP +.B nss_override_attribute_value <attribute> <value> +Specifies a value to use for the specified attribute in preference +to that contained in the actual entry. This option may be specified +multiple times, for different attributes. +If +.B nss_ldap +was built without schema mapping support, then this option +is ignored. +.TP +.B nss_schema <rfc2307bis|rfc2307> +If the value of this option is +.BR +rfc2307bis +then support for the RFC2307bis schema (distinguished names in +groups) will be enabled. +.TP +.B nss_initgroups <backlink> +This option directs the +.B nss_ldap +implementation of +.BR initgroups(3) +to determine a user's group membership by reading the memberOf +attribute of their directory entry (and of any nested groups), +rather than querying on uniqueMember. This may provide increased +performance with certain directory servers that have peculiar +indexing configurations. +If RFC2307bis support is disabled, then this option is ignored. +.TP +.B nss_initgroups_ignoreusers <user1,user2,...,userN> +This option directs the +.B nss_ldap +implementation of +.BR initgroups(3) +to return NSS_STATUS_NOTFOUND if called with a listed users as +its argument. +.TP +.B nss_srv_domain <domain> +This option determines the DNS domain used for performing SRV +lookups. +.SH AUTHOR +The +.B nss_ldap +module was developed by PADL Software Pty Ltd (www.padl.com). + +.SH FILES +.TP +/etc/ldap.conf, /etc/ldap.secret, /etc/nsswitch.conf +.SH SEE ALSO +.BR nsswitch.conf (5) diff --git a/nss_ldap.spec b/nss_ldap.spec new file mode 100644 index 0000000..a511586 --- /dev/null +++ b/nss_ldap.spec @@ -0,0 +1,161 @@ +Summary: NSS library for LDAP. +Name: nss_ldap +Version: 251 +Release: 1 +Source0: ftp://ftp.padl.com/pub/%{name}-%{version}.tar.gz +Source1: ldap.conf +URL: http://www.padl.com/ +Copyright: LGPL +Group: System Environment/Base +BuildRoot: %{_tmppath}/%{name}-root +BuildPrereq: openldap-devel +Requires: openldap cyrus-sasl openssl + +%description +This package includes a LDAP access client: nss_ldap. +Nss_ldap is a set of C library extensions which allows X.500 and LDAP +directory servers to be used as a primary source of aliases, ethers, +groups, hosts, networks, protocol, users, RPCs, services and shadow +passwords (instead of or in addition to using flat files or NIS). + + +Install nss_ldap if you need LDAP access clients. + +%prep +%setup -q -a 0 + + +%build +./configure +make + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/{etc,lib,usr/lib} +make DESTDIR=$RPM_BUILD_ROOT install + +install -m 644 %{SOURCE1} $RPM_BUILD_ROOT/etc/ldap.conf + +chmod 755 $RPM_BUILD_ROOT/lib/*.so* + +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%attr(0755,root,root) /lib/*.so* +%attr(0755,root,root) /usr/lib/*.so* +%attr(0644,root,root) %config(noreplace) /etc/ldap.conf +%doc ANNOUNCE README ChangeLog AUTHORS NEWS COPYING +%doc nsswitch.ldap + +%changelog +* Mon Jan 08 2001 Joe Little <jlittle@open-it.org> +- First attempt at split nss/pam_ldap RPM generation on new nss_ldap branch + from PADL. (Autoconfed, no explicit Makefile) + +* Thu Jan 04 2001 Joe Little <jlittle@open-it.org> +- changed Makefile.RPM.openldap2 to a patch instead of a source file +- updated to pam_ldap 86 and nss_ldap 126 + +* Wed Jan 03 2001 Joe Little <jlittle@open-it.org> +- update to pam_ldap 84 and a change in the included Makefile to have libnss + instead of just nss* in /usr/lib + +* Tue Jan 02 2001 Joe Little <jlittle@open-it.org> +- update to pam_ldap 82 and nss_ldap 124 + +* Tue Dec 05 2000 Joe Little <jlittle@open-it.org> +- changed provided nss-Makefile to use dynamic lber/ldap libs; fixes nss_ldap + +* Fri Oct 27 2000 Joe Little <jlittle@open-it.org> +- updated my build for nss_ldap and pam_ldap to solve race condition as told by + Luke Howard + +* Thu Oct 19 2000 Joe Little <jlittle@open-it.org> +- insured install uses openldap2 specific makefile +- fixed doc inclusion issue - which affect pam.d samples being provided + +* Wed Oct 11 2000 Joe Little <jlittle@open-it.org> +- updated for latest nss/pam versions, and for building against openldap 2.x +- also added req for cyrus-sasl + +* Thu Jul 27 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to pam_ldap 67 to fix a bug in template user code +- convert symlink in /usr/lib to a relative one (#16132) + +* Thu Jul 27 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 113 and pam_ldap 66 + +* Wed Jul 12 2000 Prospector <bugzilla@redhat.com> +- automatic rebuild + +* Tue Jun 27 2000 Matt Wilson <msw@redhat.com> +- changed all the -,- in attr statements to root,root + +* Tue Jun 27 2000 Nalin Dahyabhai <nalin@redhat.com> +- update pam_ldap to 63 + +* Wed May 31 2000 Nalin Dahyabhai <nalin@redhat.com> +- update pam_ldap to 56 + +* Tue May 30 2000 Nalin Dahyabhai <nalin@redhat.com> +- update pam_ldap to 55 +- back out no-threads patch for pam_ldap, not needed any more + +* Thu May 25 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to 110 +- revert prototype patch, looks like a problem with the new glibc after all + +* Fri May 19 2000 Nalin Dahyabhai <nalin@redhat.com> +- get libpthread out of the NSS module +- fix prototype problems in getpwXXX() + +* Mon May 15 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 109 + +* Sat Apr 29 2000 Nalin Dahyabhai <nalin@redhat.com> +- update pam_ldap 51 + +* Tue Apr 25 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 108 and pam_ldap 49 + +* Thu Apr 20 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to pam_ldap 48 + +* Thu Mar 30 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 107 +- note: check http://www.advogato.org/person/lukeh/ for Luke's changelog + +* Tue Mar 21 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 106 + +* Wed Feb 9 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 105 + +* Mon Feb 7 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 104 and pam_ldap 46 +- disable link against libpthread in pam_ldap + +* Tue Feb 1 2000 Nalin Dahyabhai <nalin@redhat.com> +- remove migration tools, because this package requires openldap now, which + also includes them + +* Fri Jan 28 2000 Nalin Dahyabhai <nalin@redhat.com> +- update to nss_ldap 103 + +* Mon Jan 24 2000 Preston Brown <pbrown@redhat.com> +- fix typo in linuxconf-pair pam cfg file (#7800) + +* Tue Jan 11 2000 Preston Brown <pbrown@redhat.com> +- v99, made it require pam_ldap +- added perl migration tools +- integrate pam_ldap stuff + +* Fri Oct 22 1999 Bill Nottingham <notting@redhat.com> +- statically link ldap libraries (they're in /usr/lib) + +* Tue Aug 10 1999 Cristian Gafton <gafton@redhat.com> +- use the ldap.conf file as an external source +- don't forcibly build the support for version 3 +- imported the default spec file from the tarball and fixed it up for RH 6.1 diff --git a/nsswitch.ldap b/nsswitch.ldap new file mode 100644 index 0000000..3daad54 --- /dev/null +++ b/nsswitch.ldap @@ -0,0 +1,39 @@ +#ident $Id: nsswitch.ldap,v 2.4 2003/10/02 02:36:25 lukeh Exp $ +# +# An example file that could be copied over to /etc/nsswitch.conf; it +# uses LDAP conjunction with files. +# +# "hosts:" and "services:" in this file are used only if the +# /etc/netconfig file has a "-" for nametoaddr_libs of "inet" transports. + +# the following two lines obviate the "+" entry in /etc/passwd and /etc/group. +passwd: files ldap +group: files ldap + +# consult DNS first, we will need it to resolve the LDAP host. (If we +# can't resolve it, we're in infinite recursion, because libldap calls +# gethostbyname(). Careful!) +hosts: dns ldap + +# LDAP is nominally authoritative for the following maps. +services: ldap [NOTFOUND=return] files +networks: ldap [NOTFOUND=return] files +protocols: ldap [NOTFOUND=return] files +rpc: ldap [NOTFOUND=return] files +ethers: ldap [NOTFOUND=return] files + +# no support for netmasks, bootparams, publickey yet. +netmasks: files +bootparams: files +publickey: files +automount: files + +# I'm pretty sure nsswitch.conf is consulted directly by sendmail, +# here, so we can't do much here. Instead, use bbense's LDAP +# rules ofr sendmail. +aliases: files +sendmailvars: files + +# Note: there is no support for netgroups on Solaris (yet) +netgroup: ldap [NOTFOUND=return] files + diff --git a/pagectrl.c b/pagectrl.c new file mode 100644 index 0000000..8862281 --- /dev/null +++ b/pagectrl.c @@ -0,0 +1,226 @@ +/* Copyright (C) 2002 Max Caines, All Rights Reserved. + This file is part of the nss_ldap library. + Contributed by Max Caines, <Max.Caines@wlv.ac.uk>, April 2002. + This software is not subject to any license of the University + of Wolverhampton. + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +static char rcsId[] = "$Id: pagectrl.c,v 2.4 2006/01/13 10:24:59 lukeh Exp $"; + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include <lber.h> +#include <ldap.h> + +#include "pagectrl.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. + + ---*/ + +#ifndef HAVE_LDAP_CREATE_CONTROL +#error LDAP client library does not support ldap_create_control() +#else +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 /* HAVE_LDAP_CREATE_CONTROL */ +#endif /* 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. + +---*/ + +#ifndef HAVE_LDAP_CREATE_CONTROL +#error LDAP client library does not support ldap_create_control() +#else +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 /* HAVE_LDAP_CREATE_CONTROL */ +#endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */ diff --git a/pagectrl.h b/pagectrl.h new file mode 100644 index 0000000..c5af8db --- /dev/null +++ b/pagectrl.h @@ -0,0 +1,44 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + (The author maintains a non-exclusive licence to distribute this file + under their own conditions.) + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef _LDAP_NSS_LDAP_PAGECTRL_H +#define _LDAP_NSS_LDAP_PAGECTRL_H + +#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL +int +ldap_create_page_control( LDAP *ld, + unsigned long pagesize, + struct berval *cookiep, + int iscritical, + LDAPControl **ctrlp ); +#endif /* 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 /* HAVE_LDAP_PARSE_PAGE_CONTROL */ + +#endif /* _LDAP_NSS_LDAP_UTIL_H */ diff --git a/resolve.c b/resolve.c new file mode 100644 index 0000000..83e7e0b --- /dev/null +++ b/resolve.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hvgskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Hvgskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <string.h> +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif + +#include <resolv.h> + +#include "resolve.h" + +static char rcsId[] = "$Id: resolve.c,v 2.10 2004/06/29 16:09:57 lukeh Exp $"; + +#if defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) + +#define DECL(X) {#X, T_##X} + +static struct stot +{ + char *name; + int type; +} +stot[] = +{ + DECL (A), + DECL (NS), + DECL (CNAME), DECL (PTR), DECL (MX), DECL (TXT), DECL (AFSDB), DECL (SRV), + { + NULL, 0} +}; + +static int +string_to_type (const char *name) +{ + struct stot *p = stot; + for (p = stot; p->name; p++) + if (strcasecmp (name, p->name) == 0) + return p->type; + return -1; +} + +#if 0 +static char * +type_to_string (int type) +{ + struct stot *p = stot; + for (p = stot; p->name; p++) + if (type == p->type) + return p->name; + return NULL; +} +#endif + +void +dns_free_data (struct dns_reply *r) +{ + struct resource_record *rr; + if (r->q.domain) + free (r->q.domain); + for (rr = r->head; rr;) + { + struct resource_record *tmp = rr; + if (rr->domain) + free (rr->domain); + if (rr->u.data) + free (rr->u.data); + rr = rr->next; + free (tmp); + } + free (r); +} + +static struct dns_reply * +parse_reply (unsigned char *data, int len) +{ + unsigned char *p; + char host[128]; + int status; + int query, response; + + struct dns_reply *r; + struct resource_record **rr; + + r = (struct dns_reply *) malloc (sizeof (struct dns_reply)); + memset (r, 0, sizeof (struct dns_reply)); + r->q.domain = NULL; + + p = data; + memcpy (&r->h, p, sizeof (HEADER)); + p += sizeof (HEADER); + for (query = 0; query < ntohs(r->h.qdcount); query++) + { + status = dn_expand (data, data + len, p, host, sizeof (host)); + if (status < 0) + { + dns_free_data (r); + return NULL; + } + p += status; + if (p + 4 > data + len) + { + dns_free_data (r); + return NULL; + } + if (r->q.domain == NULL) + { + r->q.domain = strdup (host); + r->q.type = (p[0] << 8 | p[1]); + r->q.class = (p[2] << 8 | p[3]); + } + p += 4; + } + rr = &r->head; + for (response = 0; (response < ntohs(r->h.ancount)) && (p < data + len); response++) + { + unsigned int type, class, ttl, size; + status = dn_expand (data, data + len, p, host, sizeof (host)); + if (status < 0) + { + dns_free_data (r); + return NULL; + } + p += status; + if (p + 10 > data + len) + { + dns_free_data (r); + return NULL; + } + type = (p[0] << 8) | p[1]; + p += 2; + class = (p[0] << 8) | p[1]; + p += 2; + ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + p += 4; + size = (p[0] << 8) | p[1]; + p += 2; + if (p + size > data + len) + { + dns_free_data (r); + return NULL; + } + *rr = (struct resource_record *) calloc (1, + sizeof (struct + resource_record)); + (*rr)->domain = strdup (host); + (*rr)->type = type; + (*rr)->class = class; + (*rr)->ttl = ttl; + (*rr)->size = size; + switch (type) + { + case T_NS: + case T_CNAME: + case T_PTR: + status = dn_expand (data, data + len, p, host, sizeof (host)); + if (status < 0) + { + dns_free_data (r); + return NULL; + } + (*rr)->u.txt = strdup (host); + break; + case T_MX: + case T_AFSDB: + { + if (p + 2 > data + len) + { + dns_free_data (r); + return NULL; + } + status = dn_expand (data, data + len, p + 2, host, sizeof (host)); + if (status < 0) + { + dns_free_data (r); + return NULL; + } + + (*rr)->u.mx = + (struct mx_record *) malloc (sizeof (struct mx_record) + + strlen (host)); + (*rr)->u.mx->preference = (p[0] << 8) | p[1]; + strcpy ((*rr)->u.mx->domain, host); + break; + } + case T_SRV: + { + if (p + 6 > data + len) + { + dns_free_data (r); + return NULL; + } + status = dn_expand (data, data + len, p + 6, host, sizeof (host)); + if (status < 0) + { + dns_free_data (r); + return NULL; + } + (*rr)->u.srv = + (struct srv_record *) malloc (sizeof (struct srv_record) + + strlen (host)); + (*rr)->u.srv->priority = (p[0] << 8) | p[1]; + (*rr)->u.srv->weight = (p[2] << 8) | p[3]; + (*rr)->u.srv->port = (p[4] << 8) | p[5]; + strcpy ((*rr)->u.srv->target, host); + break; + } + case T_TXT: + { + if (p + *p > data + len) + { + dns_free_data (r); + return NULL; + } + (*rr)->u.txt = (char *) malloc (size + 1); + strncpy ((*rr)->u.txt, (char *) p + 1, *p); + (*rr)->u.txt[*p] = 0; + break; + } + + default: + (*rr)->u.data = (unsigned char *) malloc (size); + memcpy ((*rr)->u.data, p, size); + } + p += size; + rr = &(*rr)->next; + } + *rr = NULL; + return r; +} + + + +struct dns_reply * +dns_lookup (const char *domain, const char *type_name) +{ + unsigned char *reply = NULL; + int len, rlen; + int type; + struct dns_reply *r = NULL; + + type = string_to_type (type_name); + rlen = 1024; + reply = malloc(rlen); + do + { + len = res_search (domain, C_IN, type, reply, rlen); + if ((len == -1) || (len < rlen)) + { + break; + } + reply = realloc (reply, len + 1024); + rlen = len + 1024; + } + while (1); + if (len >= 0) + r = parse_reply (reply, len); + free(reply); + return r; +} + +#else /* defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */ + +struct dns_reply * +dns_lookup (const char *domain, const char *type_name) +{ + return NULL; +} + +void +dns_free_data (struct dns_reply *r) +{ +} + +#endif + +#ifdef TEST + +int +main (int argc, char **argv) +{ + struct dns_reply *r; + struct resource_record *rr; + r = dns_lookup (argv[1], argv[2]); + if (r == NULL) + { + printf ("No reply.\n"); + return 1; + } + for (rr = r->head; rr; rr = rr->next) + { + printf ("%s %s %d ", rr->domain, type_to_string (rr->type), rr->ttl); + switch (rr->type) + { + case T_NS: + printf ("%s\n", (char *) rr->data); + break; + case T_A: + printf ("%d.%d.%d.%d\n", + ((unsigned char *) rr->data)[0], + ((unsigned char *) rr->data)[1], + ((unsigned char *) rr->data)[2], + ((unsigned char *) rr->data)[3]); + break; + case T_MX: + case T_AFSDB: + { + struct mx_record *mx = (struct mx_record *) rr->data; + printf ("%d %s\n", mx->preference, mx->domain); + break; + } + case T_SRV: + { + struct srv_record *srv = (struct srv_record *) rr->data; + printf ("%d %d %d %s\n", srv->priority, srv->weight, + srv->port, srv->target); + break; + } + default: + printf ("\n"); + break; + } + } + + return 0; +} +#endif diff --git a/resolve.h b/resolve.h new file mode 100644 index 0000000..c678911 --- /dev/null +++ b/resolve.h @@ -0,0 +1,123 @@ + + +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hvgskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Hvgskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: resolve.h,v 2.5 2001/08/17 05:30:13 lukeh Exp $ */ + +/* THIS IS NOT (yet) A PUBLIC INTERFACE */ + +#ifndef __RESOLVE_H__ +#define __RESOLVE_H__ + +/* when would this *not* be defined? */ +#define HAVE_ARPA_NAMESER_H + +/* We use these, but they are not always present in <arpa/nameser.h> */ + +#ifndef T_TXT +#define T_TXT 16 +#endif +#ifndef T_AFSDB +#define T_AFSDB 18 +#endif +#ifndef T_SRV +#define T_SRV 33 +#endif + +struct dns_query +{ + char *domain; + unsigned type; + unsigned class; +}; + +struct mx_record +{ + unsigned preference; + char domain[1]; +}; + +struct srv_record +{ + unsigned priority; + unsigned weight; + unsigned port; + char target[1]; +}; + +struct resource_record +{ + char *domain; + unsigned type; + unsigned class; + unsigned ttl; + unsigned size; + union + { + void *data; + struct mx_record *mx; + struct mx_record *afsdb; /* mx and afsdb are identical */ + struct srv_record *srv; + struct in_addr *a; + char *txt; + } + u; + struct resource_record *next; +}; + + +#ifndef HAVE_ARPA_NAMESER_H /* XXX */ +typedef int HEADER; /* will never be used */ +#endif + +struct dns_reply +{ + HEADER h; + struct dns_query q; + struct resource_record *head; +}; + +#define dns_lookup _nss_ldap_dns_lookup +#define dns_free_data _nss_ldap_dns_free_data + +struct dns_reply *dns_lookup (const char *, const char *); + +void dns_free_data (struct dns_reply *r); + +#endif /* __RESOLVE_H__ */ diff --git a/snprintf.c b/snprintf.c new file mode 100644 index 0000000..d57e90f --- /dev/null +++ b/snprintf.c @@ -0,0 +1,374 @@ +static char rcsId[] = "$Id: snprintf.c,v 2.9 2001/08/17 05:30:14 lukeh Exp $"; + +#include "config.h" + +#ifndef HAVE_SNPRINTF + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + **************************************************************/ + +static void dopr (); +static char *end; + +#include "snprintf.h" +#include <string.h> + +#ifdef HAVE_CTYPE_H +#include <ctype.h> +#endif + +/* varargs declarations: */ + +#if defined(HAVE_STDARG_H) +#include <stdarg.h> +#define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +#define VA_LOCAL_DECL va_list ap; +#define VA_START(f) va_start(ap, f) +#define VA_SHIFT(v,t) ; /* no-op for ANSI */ +#define VA_END va_end(ap) +#else +#if defined(HAVE_VARARGS_H) +#include <varargs.h> +#undef HAVE_STDARGS +#define VA_LOCAL_DECL va_list ap; +#define VA_START(f) va_start(ap) /* f is ignored! */ +#define VA_SHIFT(v,t) v = va_arg(ap,t) +#define VA_END va_end(ap) +#else +XX **NO VARARGS ** XX +#endif +#endif +#ifdef HAVE_STDARGS +int snprintf (char *str, size_t count, const char *fmt, ...); +int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); +#else +int snprintf (); +int vsnprintf (); +#endif + +int +vsnprintf (str, count, fmt, args) + char *str; + size_t count; + const char *fmt; + va_list args; +{ + str[0] = 0; + end = str + count - 1; + dopr (str, fmt, args); + if (count > 0) + { + end[0] = 0; + } + return (strlen (str)); +} + +/* VARARGS3 */ +#ifdef HAVE_STDARGS +int +snprintf (char *str, size_t count, const char *fmt, ...) +#else +int +snprintf (va_alist) + va_dcl +#endif +{ +#ifndef HAVE_STDARGS + char *str; + size_t count; + char *fmt; +#endif + VA_LOCAL_DECL VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t); + VA_SHIFT (fmt, char *); + (void) vsnprintf (str, count, fmt, ap); + VA_END; + return (strlen (str)); +} + +/* + * dopr(): poor man's version of doprintf + */ + +static void fmtstr (char *value, int ljust, int len, int zpad); +static void fmtnum (long value, int base, int dosign, + int ljust, int len, int zpad); +static void dostr (char *); +static char *output; +static void dopr_outch (int c); + +static void +dopr (buffer, format, args) + char *buffer; + char *format; + va_list args; +{ + int ch; + long value; + int longflag = 0; + char *strvalue; + int ljust; + int len; + int zpad; + + output = buffer; + while ((ch = *format++)) + { + switch (ch) + { + case '%': + ljust = len = zpad = 0; + nextch: + ch = *format++; + switch (ch) + { + case 0: + dostr ("**end of format**"); + return; + case '-': + ljust = 1; + goto nextch; + case '0': /* set zero padding if len not set */ + if (len == 0) + zpad = '0'; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + len = len * 10 + ch - '0'; + goto nextch; + case 'l': + longflag = 1; + goto nextch; + case 'u': + case 'U': + /*fmtnum(value,base,dosign,ljust,len,zpad) */ + if (longflag) + { + value = va_arg (args, long); + } + else + { + value = va_arg (args, int); + } + fmtnum (value, 10, 0, ljust, len, zpad); + break; + case 'o': + case 'O': + /*fmtnum(value,base,dosign,ljust,len,zpad) */ + if (longflag) + { + value = va_arg (args, long); + } + else + { + value = va_arg (args, int); + } + fmtnum (value, 8, 0, ljust, len, zpad); + break; + case 'd': + case 'D': + if (longflag) + { + value = va_arg (args, long); + } + else + { + value = va_arg (args, int); + } + fmtnum (value, 10, 1, ljust, len, zpad); + break; + case 'x': + if (longflag) + { + value = va_arg (args, long); + } + else + { + value = va_arg (args, int); + } + fmtnum (value, 16, 0, ljust, len, zpad); + break; + case 'X': + if (longflag) + { + value = va_arg (args, long); + } + else + { + value = va_arg (args, int); + } + fmtnum (value, -16, 0, ljust, len, zpad); + break; + case 's': + strvalue = va_arg (args, char *); + fmtstr (strvalue, ljust, len, zpad); + break; + case 'c': + ch = va_arg (args, int); + dopr_outch (ch); + break; + case '%': + dopr_outch (ch); + continue; + default: + dostr ("???????"); + } + longflag = 0; + break; + default: + dopr_outch (ch); + break; + } + } + *output = 0; +} + +static void +fmtstr (value, ljust, len, zpad) + char *value; + int ljust, len, zpad; +{ + int padlen, strlen; /* amount to pad */ + + if (value == 0) + { + value = "<NULL>"; + } + for (strlen = 0; value[strlen]; ++strlen); /* strlen */ + padlen = len - strlen; + if (padlen < 0) + padlen = 0; + if (ljust) + padlen = -padlen; + while (padlen > 0) + { + dopr_outch (' '); + --padlen; + } + dostr (value); + while (padlen < 0) + { + dopr_outch (' '); + ++padlen; + } +} + +static void +fmtnum (value, base, dosign, ljust, len, zpad) + long value; + int base, dosign, ljust, len, zpad; +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int padlen = 0; /* amount to pad */ + int caps = 0; + + /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", + value, base, dosign, ljust, len, zpad )); */ + uvalue = value; + if (dosign) + { + if (value < 0) + { + signvalue = '-'; + uvalue = -value; + } + } + if (base < 0) + { + caps = 1; + base = -base; + } + do + { + convert[place++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned) base]; + uvalue = (uvalue / (unsigned) base); + } + while (uvalue); + convert[place] = 0; + padlen = len - place; + if (padlen < 0) + padlen = 0; + if (ljust) + padlen = -padlen; + /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", + convert,place,signvalue,padlen)); */ + if (zpad && padlen > 0) + { + if (signvalue) + { + dopr_outch (signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) + { + dopr_outch (zpad); + --padlen; + } + } + while (padlen > 0) + { + dopr_outch (' '); + --padlen; + } + if (signvalue) + dopr_outch (signvalue); + while (place > 0) + dopr_outch (convert[--place]); + while (padlen < 0) + { + dopr_outch (' '); + ++padlen; + } +} + +static void +dostr (str) + char *str; +{ + while (*str) + dopr_outch (*str++); +} + +static void +dopr_outch (c) + int c; +{ + if (iscntrl (c) && c != '\n' && c != '\t') + { + c = '@' + (c & 0x1F); + if (end == 0 || output < end) + { + *output++ = '^'; + } + } + if (end == 0 || output < end) + { + *output++ = c; + } +} + +#endif /* !HAVE_SNPRINTF */ diff --git a/snprintf.h b/snprintf.h new file mode 100644 index 0000000..b61d037 --- /dev/null +++ b/snprintf.h @@ -0,0 +1,52 @@ +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + **************************************************************/ + +/* keep namespace tidy */ +#define vsnprintf _nss_ldap_vsnprintf +#define snprintf _nss_ldap_snprintf + +#define HAVE_STDARG_H +#include <sys/types.h> +/* varargs declarations: */ +/* you might have to hand force this by doing #define HAVE_STDARG_H */ + +#if defined(HAVE_STDARG_H) +#include <stdarg.h> +#define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +#define VA_LOCAL_DECL va_list ap; +#define VA_START(f) va_start(ap, f) +#define VA_SHIFT(v,t) ; /* no-op for ANSI */ +#define VA_END va_end(ap) +#else +#if defined(HAVE_VARARGS_H) +#include <varargs.h> +#undef HAVE_STDARGS +#define VA_LOCAL_DECL va_list ap; +#define VA_START(f) va_start(ap) /* f is ignored! */ +#define VA_SHIFT(v,t) v = va_arg(ap,t) +#define VA_END va_end(ap) +#else +XX **NO VARARGS ** XX +#endif +#endif +/* you can have ANSI C definitions */ +#ifdef HAVE_STDARGS +int snprintf (char *str, size_t count, const char *fmt, ...); +int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); +void setproctitle (char *fmt, ...); +#else +int snprintf (); +int vsnprintf (); +void setproctitle (); +#endif diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/tests/ldaptest.pl b/tests/ldaptest.pl new file mode 100644 index 0000000..615e6b3 --- /dev/null +++ b/tests/ldaptest.pl @@ -0,0 +1,101 @@ +#!/usr/bin/perl + +# +# $Header: /home/project/cvs/nss_ldap/tests/ldaptest.pl,v 1.2 2001/01/09 00:21:21 lukeh Exp $ +# + + +sub printarr { + foreach (@_) { + print $_." "; + } + print "\n"; +} +sub printhost { + foreach (@_) { + if ($_ !~ /^[\w\.\d]+$/) { + @addr = unpack('C4',$_); + print $addr[0].".".$addr[1].".".$addr[2].".".$addr[3]." "; + } else { + print $_." "; + } + } + print "\n"; +} + + +print "*** getpwnam ***\n"; +printarr(getpwnam("root")); +print "*** getpwuid ***\n"; +printarr(getpwuid(0)); +print "*** setpwent ***\n"; +setpwent(); +print "*** getpwent ***\n"; +while(@ent = getpwent()) { + printarr(@ent); +} +print "*** endpwent ***\n"; +endpwent(); +print "*** getgrnam ***\n"; +printarr(getgrnam("wheel")); +print "*** getgrgid ***\n"; +printarr(getgrgid(10)); +print "*** setgrent ***\n"; +setgrent(); +print "*** getgrent ***\n"; +while(@ent = getgrent()) { + printarr(@ent); +} +print "*** endgrent ***\n"; +endgrent(); +print "*** gethostbyname ***\n"; +printhost(gethostbyname("localhost")); +print "*** gethostbyaddr ***\n"; +printhost(gethostbyaddr(pack(C4,(127,0,0,1)),2)); +print "*** sethostent ***\n"; +sethostent(0); +print "*** gethostent ***\n"; +while(@ent = gethostent()) { + printhost(@ent); +} +print "*** endhostent ***\n"; +endhostent(); +# I dont appear to have networks. but we'll try anyway. +print "*** getnetbyname ***\n"; +printhost(getnetbyname("localnet")); +print "*** getnetbyaddr ***\n"; +# this may not be the right call. who uses 'networks' anyways!? +printhost(getnetbyaddr(127,2)); +print "*** setnetent ***\n"; +setnetent(0); +print "*** getnetent ***\n"; +while(@ent = getnetent()) { + printhost(@ent); +} +print "*** endnetent ***\n"; +endnetent(); +print "*** getservbyname ***\n"; +printarr(getservbyname("telnet","tcp")); +print "*** getservbyport ***\n"; +printarr(getservbyport(23,"tcp")); +print "*** setservent ***\n"; +setservent(0); +print "*** getservent ***\n"; +while(@ent = getservent()) { + printarr(@ent); +} +print "*** endservent ***\n"; +endservent(); +print "*** getprotobyname ***\n"; +printarr(getprotobyname("icmp")); +print "*** getprotobynumber ***\n"; +printarr(getprotobynumber(1)); +print "*** setprotoent ***\n"; +setprotoent(0); +print "*** getprotoent ***\n"; +while(@ent = getprotoent()) { + printarr(@ent); +} +print "*** endprotoent ***\n"; +endprotoent(); + diff --git a/tests/nsswitch.test b/tests/nsswitch.test new file mode 100644 index 0000000..9240353 --- /dev/null +++ b/tests/nsswitch.test @@ -0,0 +1,40 @@ +#ident $Id: nsswitch.test,v 1.2 2001/01/09 00:21:22 lukeh Exp $ +# +# An example file that could be copied over to /etc/nsswitch.conf; it +# uses LDAP conjunction with files. +# +# "hosts:" and "services:" in this file are used only if the +# /etc/netconfig file has a "-" for nametoaddr_libs of "inet" transports. + +# the following two lines obviate the "+" entry in /etc/passwd and /etc/group. +passwd: ldap +group: ldap + +# consult DNS first, we will need it to resolve the LDAP host. (If we +# can't resolve it, we're in infinite recursion, because libldap calls +# gethostbyname(). Careful!) +hosts: files ldap + +# LDAP is nominally authoritative for the following maps. +services: ldap +networks: ldap +protocols: ldap +rpc: ldap +ethers: ldap + +# no support for netmasks, bootparams, publickey yet. +netmasks: files +bootparams: files +publickey: files +automount: files + +# I'm pretty sure nsswitch.conf is consulted directly by sendmail, +# here, so we can't do much here. Instead, use bbense's LDAP +# rules ofr sendmail. +aliases: files +sendmailvars: files + +# No one has written the LDAP support for netgroups yet, so we'll +# have to stick with NIS. +netgroup: files nis + diff --git a/tests/testd.c b/tests/testd.c new file mode 100644 index 0000000..f47081a --- /dev/null +++ b/tests/testd.c @@ -0,0 +1,41 @@ + +#import <lber.h> +#import <ldap.h> +#import "ldap-nss.h" +#import "util.h" +#import "dnsconfig.h" + +void +printcf (ldap_config_t * cf) +{ + printf ("host %s\n", cf->ldc_host); + printf ("port %d\n", cf->ldc_port); + printf ("base %s\n", cf->ldc_base); +#if 0 + char *ldc_host; + int ldc_port; + char *ldc_base; + int ldc_scope; + char *ldc_binddn; + char *ldc_bindpw; + struct ldap_config *ldc_next; +#endif +} + +void +main (void) +{ +/* + NSS_STATUS _nss_ldap_readconfigfromdns( + ldap_config_t *result, + char *buf, + size_t buflen + */ + ldap_config_t cf; + char buf[1024]; + + _nss_ldap_readconfigfromdns (&cf, buf, sizeof (buf)); + printcf (&cf); + printcf (cf.ldc_next); + exit (0); +} diff --git a/tests/testgr.c b/tests/testgr.c new file mode 100644 index 0000000..4907238 --- /dev/null +++ b/tests/testgr.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <grp.h> +#include <signal.h> + +void +main (int argc, char **argv) +{ +#if 0 + struct group + { /* see getgrent(3) */ + char *gr_name; + char *gr_passwd; + gid_t gr_gid; + char **gr_mem; + }; +#endif + + scan_group (); + exit (0); +} + +void +dump (struct group *g) +{ + char mem[2048]; + char **p; + + int doit = (g->gr_mem && *(g->gr_mem)); + p = g->gr_mem; + strcpy (mem, ""); + while (doit) + { + if (p != g->gr_mem) + strcat (mem, ","); + strcat (mem, *p); + if (*(++p) == NULL) + break; + } + printf ("%s:%s:%d:%s\n", g->gr_name, g->gr_passwd, g->gr_gid, mem); + +} + +scan_group () +{ + struct group *g; + + signal(SIGPIPE, SIG_IGN); + + setgrent (); + + while ((g = getgrent ()) != NULL) + { + dump (g); + } + + endgrent (); + + sleep(10); + + printf ("==> getgrnam(qmail)\n"); + g = getgrnam ("qmail"); + if (g != NULL) + dump (g); +#if 0 + printf ("==> getgrnam(testgroup)\n"); + g = getgrnam ("testgroup"); + if (g != NULL) + dump (g); +#endif + +} diff --git a/tests/testpw.c b/tests/testpw.c new file mode 100644 index 0000000..e65f986 --- /dev/null +++ b/tests/testpw.c @@ -0,0 +1,151 @@ + +/* $Id: testpw.c,v 1.2 2001/01/09 00:21:22 lukeh Exp $ */ + +/* This program just tests getpwent/getpwnam. You want to have nss_ldap + * plugged in, so to speak, to test anything useful. + */ + +#include "config.h" + +#ifdef _REENTRANT +#ifdef HAVE_PTHREAD_H +#include <pthread.h> +#else +#include <thread.h> +#endif /* _REENTRANT */ + +#endif /* HAVE_PTHREAD_H */ +#include <stdio.h> +#include <pwd.h> +#include <sys/types.h> + +#if NeXT +#define uid_t int +#else +#include <dlfcn.h> /* why? */ +#endif + +void test_passwd (void); +void scan_passwd (void); + +int ARGC; +char **ARGV; + +#define MAX_THREADS 16 + +void +main (int argc, char **argv) +{ +#ifdef _REENTRANT + int i; +#endif + ARGC = argc; + ARGV = argv; + +#ifdef _REENTRANT + for (i = 0; i < MAX_THREADS; i++) + { +#ifdef HAVE_PTHREAD_H + pthread_t tid; + pthread_create (NULL, 0, test_passwd, NULL, 0, &tid); + pthread_continue (tid); +#else + thread_t tid; + thr_create (NULL, 0, test_passwd, NULL, 0, &tid); + thr_continue (tid); +#endif /* HAVE_PTHREAD_H */ + } + while (thr_join (NULL, NULL, NULL) == 0); +#else + test_passwd (); +#endif + exit (0); +} + +#ifdef _REENTRANT +static void +ret (int status) +{ + thr_exit (&status); +} +#else +#define ret exit +#endif + +void +test_passwd (void) +{ + struct passwd *pw; + uid_t uid; +#ifdef _REENTRANT + char buf[1024]; + struct passwd pbuf; +#endif + + printf (">>>>>> getpwnam(\"%s\")\n", ARGC > 1 ? ARGV[1] : "root"); +#ifdef _REENTRANT + pw = getpwnam_r (ARGC > 1 ? ARGV[1] : "root", &pbuf, buf, sizeof (buf)); +#else + pw = getpwnam (ARGC > 1 ? ARGV[1] : "root"); +#endif + + if (!pw) + ret (1); + + printf ("%s:%s:%d:%d:%s:%s:%s\n", pw->pw_name, pw->pw_passwd, pw->pw_uid, + pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); + uid = pw->pw_uid; + + printf (">>>>>> getpwuid(%d)\n", uid); + +#ifdef _REENTRANT + pw = getpwuid_r (uid, &pbuf, buf, sizeof (buf)); +#else + pw = getpwuid (uid); +#endif + + if (!pw) + ret (1); + + printf ("%s:%s:%d:%d:%s:%s:%s\n", pw->pw_name, pw->pw_passwd, pw->pw_uid, + pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); + + if (ARGC > 2 && !strcmp (ARGV[2], "no")) + { + printf (">>>>>> Enumeration skipped.\n"); + } + else + { + printf (">>>>>> setpwent()\n"); + setpwent (); + + printf (">>>>>> getpwent()\n"); + scan_passwd (); + + printf (">>>>>> endpwent()\n"); + endpwent (); + } + + ret (0); +} + +void +scan_passwd (void) +{ + int i = 1; + struct passwd *p; +#ifdef _REENTRANT + char buf[1024]; + struct passwd pbuf; + while ((p = getpwent_r (&pbuf, buf, sizeof (buf))) != NULL) +#else + while ((p = getpwent ()) != NULL) +#endif + { + printf ("%s:%s:%d:%d:%s:%s:%s\n", + p->pw_name, + p->pw_passwd, + p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); + i++; + } +} diff --git a/tests/testpw3.c b/tests/testpw3.c new file mode 100644 index 0000000..35cc855 --- /dev/null +++ b/tests/testpw3.c @@ -0,0 +1,48 @@ +#include <stdio.h> +#include <pwd.h> + +void +main (int argc, char **argv) +{ + scan_passwd (); + + exit (0); +} +scan_passwd () +{ + struct passwd p; + char buf[1024]; + int i = 1; + +#ifdef WEIRD_GETPWENT + FILE *fp = NULL; +#endif + memset (buf, 0xFF, sizeof (buf)); + +#ifdef WEIRD_GETPWENT + setpwent_r (&fp); +#else + setpwent_r (); +#endif + +#ifdef WEIRD_GETPWENT + while (getpwent_r (&p, buf, (int) sizeof (buf), &fp) == 0) +#else + while (getpwent_r (&p, buf, (int) sizeof (buf)) == 0) +#endif + { + printf ("%s:%s:%d:%d:%s:%s:%s\n", + p.pw_name, + p.pw_passwd, + p.pw_uid, p.pw_gid, p.pw_gecos, p.pw_dir, p.pw_shell); + i++; + } + +#ifdef WEIRD_GETPWENT + endpwent_r (&fp); +#else + endpwent_r (); +#endif + fprintf (stderr, ">>>>>>> %d\n", i); + +} diff --git a/tests/testpw4.c b/tests/testpw4.c new file mode 100644 index 0000000..bf6f234 --- /dev/null +++ b/tests/testpw4.c @@ -0,0 +1,77 @@ +/* test IRS, independently of getpwnam et al. */ + +#include <stdio.h> +#include <pwd.h> +#include <bsd/netdb.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include "irs-nss.h" + +static const char *testhost = "davinci.eng.sun.com"; +static char rcsid[] = "$Id: testpw4.c,v 1.2 2001/01/09 00:21:22 lukeh Exp $"; + +void +main (void) +{ + + struct irs_pw *irs; + struct irs_ho *irs2; + struct passwd *pwd; + struct hostent *h; + + int i; + + i = 0; + + printf ("Testing irs_pw enumeration...\n"); + + /* test users */ + irs = irs_ldap_pw (NULL); + + (irs->rewind) (irs); + while ((pwd = (irs->next) (irs))) + { + printf ("%s:%s:%d:%d:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + pwd->pw_uid, + pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); + i++; + } + (irs->close) (irs); + free (irs); + + fprintf (stderr, ">>>>>>> %d entries\n", i); + + /* test hosts */ + + printf ("Testing irs_ho enumeration...\n"); + + irs2 = irs_ldap_ho (NULL); + i = 0; + + (irs2->rewind) (irs2); + while ((h = (irs2->next) (irs2))) + { + struct in_addr addr; + bcopy (h->h_addr, &addr.s_addr, h->h_length); + printf ("%s\t%s\n", (char *) inet_ntoa (addr), h->h_name); + i++; + } + (irs2->close) (irs2); + fprintf (stderr, ">>>>>>> %d entries\n", i); + + printf ("Testing irs_ho byname...\n"); + + h = (irs2->byname) (irs2, testhost); + if (h != NULL) + { + struct in_addr addr; + bcopy (h->h_addr, &addr.s_addr, h->h_length); + printf ("%s\t%s\n", (char *) inet_ntoa (addr), h->h_name); + } + + free (irs); + + exit (0); +} diff --git a/tests/testpw5.c b/tests/testpw5.c new file mode 100644 index 0000000..8daaca8 --- /dev/null +++ b/tests/testpw5.c @@ -0,0 +1,127 @@ + +/* $Id: testpw5.c,v 1.2 2001/01/09 00:21:22 lukeh Exp $ */ + +/* This program just tests getpwent/getpwnam. You want to have nss_ldap + * plugged in, so to speak, to test anything useful. + */ + +#include "config.h" + +#ifdef _REENTRANT +#ifdef HAVE_THREAD_H +#include <thread.h> +#else +#include <pthread.h> +#endif +#endif +#include <stdio.h> +#include <pwd.h> +#include <stdlib.h> + +#if NeXT +#define uid_t int +#else +#include <dlfcn.h> /* why? */ +#endif + +void test_passwd (void); + +int ARGC; +char **ARGV; + +#define MAX_THREADS 16 + +void +main (int argc, char **argv) +{ +#ifdef _REENTRANT + int i; +#endif + ARGC = argc; + ARGV = argv; + +#ifdef _REENTRANT + for (i = 0; i < MAX_THREADS; i++) + { + thread_t tid; + thr_create (NULL, 0, test_passwd, NULL, 0, &tid); + thr_continue (tid); + } + while (thr_join (NULL, NULL, NULL) == 0); +#else + test_passwd (); +#endif + exit (0); +} + +#ifdef _REENTRANT +static void +ret (int status) +{ + thr_exit (&status); +} +#else +#define ret exit +#endif + +void +test_passwd (void) +{ + struct passwd *pw; + uid_t uid; +#ifdef _REENTRANT + char buf[1024]; + struct passwd pbuf; +#endif + + + + printf (">>>>>> setpwent()\n"); + setpwent (); + + printf (">>>>>> getpwent()\n"); + scan_passwd (); + + printf (">>>>>> endpwent()\n"); + endpwent (); + + ret (0); +} + +scan_passwd () +{ + int i = 1; + struct passwd *p; +#ifdef _REENTRANT + char buf[1024]; + struct passwd pbuf; + while ((p = getpwent_r (&pbuf, buf, sizeof (buf))) != NULL) +#else + while ((p = getpwent ()) != NULL) +#endif + { + printf ("%s:%s:%d:%d:%s:%s:%s\n", + p->pw_name, + p->pw_passwd, + p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); + + if (p == NULL) + ret (1); + +#ifdef _REENTRANT + p = getpwnam_r (p->pw_name, &pbuf, buf, sizeof (buf)); +#else + p = getpwnam (p->pw_name); +#endif + + if (p == NULL) + ret (2); + + printf ("%s:%s:%d:%d:%s:%s:%s\n", + p->pw_name, + p->pw_passwd, + p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); + + i++; + } +} diff --git a/tests/testpw6.c b/tests/testpw6.c new file mode 100644 index 0000000..f3a1596 --- /dev/null +++ b/tests/testpw6.c @@ -0,0 +1,187 @@ + +/* $Id: testpw6.c,v 1.2 2006/01/10 18:06:39 lukeh Exp $ */ + +/* This program just tests getpwent/getpwnam. You want to have nss_ldap + * plugged in, so to speak, to test anything useful. + */ + +#include "config.h" + +#ifdef _REENTRANT +#ifdef HAVE_PTHREAD_H +#include <pthread.h> +#else +#include <thread.h> +#endif /* _REENTRANT */ + +#endif /* HAVE_PTHREAD_H */ +#include <stdio.h> +#include <pwd.h> +#include <sys/types.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +void test_passwd (void); +void scan_passwd (void); + +int ARGC; +char **ARGV; + +#define MAX_THREADS 8 + +void +main (int argc, char **argv) +{ +#ifdef _REENTRANT + int i; +#ifdef HAVE_PTHREAD_H + pthread_t tids[MAX_THREADS]; +#endif +#endif + pid_t pid; + ARGC = argc; + ARGV = argv; + + /* PRIME */ + scan_passwd(); + + pid = fork(); + if (pid == 0) { + printf("IN CHILD\n"); + } else { + printf("IN PARENT\n"); + } + +#ifdef _REENTRANT + for (i = 0; i < MAX_THREADS; i++) + { +#ifdef HAVE_PTHREAD_H + pthread_create(&tids[i], NULL, test_passwd, NULL); +#else + thread_t tid; + thr_create (NULL, 0, test_passwd, NULL, 0, &tid); + thr_continue (tid); +#endif /* HAVE_PTHREAD_H */ + } +#ifdef HAVE_PTHREAD_H + for (i = 0; i < MAX_THREADS; i++) pthread_join(tids[i], NULL); +#else + while (thr_join (NULL, NULL, NULL) == 0); +#endif +#else + test_passwd (); +#endif + exit (0); +} + +#ifdef _REENTRANT +static void +ret (int status) +{ +#ifdef HAVE_PTHREAD_H + pthread_exit(&status); +#else + thr_exit (&status); +#endif +} +#else +#define ret exit +#endif + +void +test_passwd (void) +{ + struct passwd *pw; + uid_t uid; +#ifdef _REENTRANT + char buf[1024]; + struct passwd pbuf; +#endif + int pid; + + printf (">>>>>> getpwnam(\"%s\")\n", ARGC > 1 ? ARGV[1] : "testuser"); +#ifdef _REENTRANT +#if GETHOSTBYNAME_R_ARGS == 6 + if (getpwnam_r (ARGC > 1 ? ARGV[1] : "testuser", &pbuf, buf, sizeof (buf), &pw) != 0) pw = NULL; +#else + pw = getpwnam_r (ARGC > 1 ? ARGV[1] : "testuser", &pbuf, buf, sizeof (buf)); +#endif +#else + pw = getpwnam (ARGC > 1 ? ARGV[1] : "testuser"); +#endif + + if (!pw) + ret (1); + + printf ("%s:%s:%d:%d:%s:%s:%s\n", pw->pw_name, pw->pw_passwd, pw->pw_uid, + pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); + uid = pw->pw_uid; + + + printf (">>>>>> getpwuid(%d)\n", uid); + +#ifdef _REENTRANT +#if GETHOSTBYNAME_R_ARGS == 6 + if (getpwuid_r (uid, &pbuf, buf, sizeof(buf), &pw) != 0) pw = NULL; +#else + pw = getpwuid_r (uid, &pbuf, buf, sizeof (buf)); +#endif +#else + pw = getpwuid (uid); +#endif + + if (!pw) + ret (1); + + + printf ("%s:%s:%d:%d:%s:%s:%s\n", pw->pw_name, pw->pw_passwd, pw->pw_uid, + pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); + + if (ARGC > 2 && !strcmp (ARGV[2], "no")) + { + printf (">>>>>> Enumeration skipped.\n"); + } + else + { + printf (">>>>>> setpwent()\n"); + setpwent (); + + printf (">>>>>> getpwent()\n"); + scan_passwd (); + + printf (">>>>>> endpwent()\n"); + endpwent (); + } + + ret (0); +} + +void +scan_passwd (void) +{ + int i = 1; + struct passwd *p; +#ifdef _REENTRANT + char buf[1024]; + struct passwd pbuf; +#endif + + +#ifdef _REENTRANT +#if GETHOSTBYNAME_R_ARGS == 6 + while (getpwent_r (&pbuf, buf, sizeof (buf), &p) == 0 && p != NULL) +#else + while ((p = getpwent_r (&pbuf, buf, sizeof (buf))) != NULL) +#endif +#else + while ((p = getpwent ()) != NULL) +#endif + { + printf ("%s:%s:%d:%d:%s:%s:%s\n", + p->pw_name, + p->pw_passwd, + p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); + i++; + } +} @@ -0,0 +1,1584 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + (The author maintains a non-exclusive licence to distribute this file + under their own conditions.) + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#if defined(HAVE_THREAD_H) && !defined(_AIX) +#include <thread.h> +#elif defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif + +#include <stdio.h> +#include <string.h> +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#include <stdlib.h> + +#include <sys/param.h> +#include <sys/stat.h> + +#include <netdb.h> +#include <syslog.h> +#include <string.h> +#include <fcntl.h> +#include <assert.h> + +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif + +#include "ldap-nss.h" +#include "util.h" + +static char rcsId[] = "$Id: util.c,v 2.132 2006/01/25 20:30:27 lukeh Exp $"; + +static NSS_STATUS do_getrdnvalue (const char *dn, + const char *rdntype, + char **rval, char **buffer, + size_t * buflen); + + +static NSS_STATUS do_parse_map_statement (ldap_config_t * cfg, + const char *statement, + ldap_map_type_t type); + +static NSS_STATUS do_searchdescriptorconfig (const char *key, + const char *value, + size_t valueLength, + ldap_service_search_descriptor_t + ** result, char **buffer, + size_t * buflen); + +#include <fcntl.h> +static void *__cache = NULL; + +NSS_LDAP_DEFINE_LOCK (__cache_lock); + +#define cache_lock() NSS_LDAP_LOCK(__cache_lock) +#define cache_unlock() NSS_LDAP_UNLOCK(__cache_lock) + +static NSS_STATUS +dn2uid_cache_put (const char *dn, const char *uid) +{ + NSS_STATUS stat; + ldap_datum_t key, val; + + cache_lock (); + + if (__cache == NULL) + { + __cache = _nss_ldap_db_open (); + if (__cache == NULL) + { + cache_unlock (); + return NSS_TRYAGAIN; + } + } + + key.data = (void *) dn; + key.size = strlen (dn); + val.data = (void *) uid; + val.size = strlen (uid); + + stat = _nss_ldap_db_put (__cache, 0, &key, &val); + + cache_unlock (); + + return stat; +} + +static NSS_STATUS +dn2uid_cache_get (const char *dn, char **uid, char **buffer, size_t * buflen) +{ + ldap_datum_t key, val; + NSS_STATUS stat; + + cache_lock (); + + if (__cache == NULL) + { + cache_unlock (); + return NSS_NOTFOUND; + } + + key.data = (void *) dn; + key.size = strlen (dn); + + stat = _nss_ldap_db_get (__cache, 0, &key, &val); + if (stat != NSS_SUCCESS) + { + cache_unlock (); + return stat; + } + + if (*buflen <= val.size) + { + cache_unlock (); + return NSS_TRYAGAIN; + } + + *uid = *buffer; + memcpy (*uid, (char *) val.data, val.size); + (*uid)[val.size] = '\0'; + *buffer += val.size + 1; + *buflen -= val.size + 1; + + cache_unlock (); + return NSS_SUCCESS; +} + +#ifdef HPUX +static int lock_inited = 0; +#endif + +NSS_STATUS +_nss_ldap_dn2uid (const char *dn, char **uid, char **buffer, size_t * buflen, + int *pIsNestedGroup, LDAPMessage ** pRes) +{ + NSS_STATUS stat; + + debug ("==> _nss_ldap_dn2uid"); + + *pIsNestedGroup = 0; + +#ifdef HPUX + /* XXX this is not thread-safe */ + if (!lock_inited) + { + __thread_mutex_init (&__cache_lock, NULL); + lock_inited = 1; + } +#endif + + stat = dn2uid_cache_get (dn, uid, buffer, buflen); + if (stat == NSS_NOTFOUND) + { + const char *attrs[4]; + LDAPMessage *res; + + attrs[0] = ATM (LM_PASSWD, uid); + attrs[1] = ATM (LM_GROUP, uniqueMember); + attrs[2] = AT (objectClass); + attrs[3] = NULL; + + if (_nss_ldap_read (dn, attrs, &res) == NSS_SUCCESS) + { + LDAPMessage *e = _nss_ldap_first_entry (res); + if (e != NULL) + { + if (_nss_ldap_oc_check (e, OC (posixGroup)) == NSS_SUCCESS) + { + *pIsNestedGroup = 1; + *pRes = res; + debug ("<== _nss_ldap_dn2uid (nested group)"); + return NSS_SUCCESS; + } + + stat = + _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, uid), uid, + buffer, buflen); + if (stat == NSS_SUCCESS) + dn2uid_cache_put (dn, *uid); + } + } + ldap_msgfree (res); + } + + debug ("<== _nss_ldap_dn2uid"); + + return stat; +} + +NSS_STATUS +_nss_ldap_getrdnvalue (LDAPMessage * entry, + const char *rdntype, + char **rval, char **buffer, size_t * buflen) +{ + char *dn; + NSS_STATUS status; + + dn = _nss_ldap_get_dn (entry); + if (dn == NULL) + { + return NSS_NOTFOUND; + } + + status = do_getrdnvalue (dn, rdntype, rval, buffer, buflen); +#ifdef HAVE_LDAP_MEMFREE + ldap_memfree (dn); +#else + free (dn); +#endif /* HAVE_LDAP_MEMFREE */ + + /* + * If examining the DN failed, then pick the nominal first + * value of cn as the canonical name (recall that attributes + * are sets, not sequences) + */ + if (status == NSS_NOTFOUND) + { + char **vals; + + vals = _nss_ldap_get_values (entry, rdntype); + + if (vals != NULL) + { + int rdnlen = strlen (*vals); + if (*buflen > rdnlen) + { + char *rdnvalue = *buffer; + strncpy (rdnvalue, *vals, rdnlen); + rdnvalue[rdnlen] = '\0'; + *buffer += rdnlen + 1; + *buflen -= rdnlen + 1; + *rval = rdnvalue; + status = NSS_SUCCESS; + } + else + { + status = NSS_TRYAGAIN; + } + ldap_value_free (vals); + } + } + + return status; +} + +static NSS_STATUS +do_getrdnvalue (const char *dn, + const char *rdntype, + char **rval, char **buffer, size_t * buflen) +{ + char **exploded_dn; + char *rdnvalue = NULL; + char rdnava[64]; + int rdnlen = 0, rdnavalen; + + snprintf (rdnava, sizeof rdnava, "%s=", rdntype); + rdnavalen = strlen (rdnava); + + exploded_dn = ldap_explode_dn (dn, 0); + + if (exploded_dn != NULL) + { + /* + * attempt to get the naming attribute's principal + * value by parsing the RDN. We need to support + * multivalued RDNs (as they're essentially mandated + * for services) + */ +#ifdef HAVE_LDAP_EXPLODE_RDN + /* + * use ldap_explode_rdn() API, as it's cleaner than + * strtok(). This code has not been tested! + */ + char **p, **exploded_rdn; + + exploded_rdn = ldap_explode_rdn (*exploded_dn, 0); + if (exploded_rdn != NULL) + { + for (p = exploded_rdn; *p != NULL; p++) + { + if (strncasecmp (*p, rdnava, rdnavalen) == 0) + { + char *r = *p + rdnavalen; + + rdnlen = strlen (r); + if (*buflen <= rdnlen) + { + ldap_value_free (exploded_rdn); + ldap_value_free (exploded_dn); + return NSS_TRYAGAIN; + } + rdnvalue = *buffer; + strncpy (rdnvalue, r, rdnlen); + break; + } + } + ldap_value_free (exploded_rdn); + } +#else + /* + * we don't have Netscape's ldap_explode_rdn() API, + * so we fudge it with strtok(). Note that this will + * not handle escaping properly. + */ + char *p, *r = *exploded_dn; +#ifdef HAVE_STRTOK_R + char *st = NULL; +#endif + +#ifndef HAVE_STRTOK_R + for (p = strtok (r, "+"); +#else + for (p = strtok_r (r, "+", &st); +#endif + p != NULL; +#ifndef HAVE_STRTOK_R + p = strtok (NULL, "+")) +#else + p = strtok_r (NULL, "+", &st)) +#endif + { + if (strncasecmp (p, rdnava, rdnavalen) == 0) + { + p += rdnavalen; + rdnlen = strlen (p); + if (*buflen <= rdnlen) + { + ldap_value_free (exploded_dn); + return NSS_TRYAGAIN; + } + rdnvalue = *buffer; + strncpy (rdnvalue, p, rdnlen); + break; + } + if (r != NULL) + r = NULL; + } +#endif /* HAVE_LDAP_EXPLODE_RDN */ + } + + if (exploded_dn != NULL) + { + ldap_value_free (exploded_dn); + } + + if (rdnvalue != NULL) + { + rdnvalue[rdnlen] = '\0'; + *buffer += rdnlen + 1; + *buflen -= rdnlen + 1; + *rval = rdnvalue; + return NSS_SUCCESS; + } + + return NSS_NOTFOUND; +} + +static NSS_STATUS +do_parse_map_statement (ldap_config_t * cfg, + const char *statement, ldap_map_type_t type) +{ + char *key, *val; + ldap_map_selector_t sel = LM_NONE; + + key = (char *) statement; + val = key; + while (*val != ' ' && *val != '\t') + val++; + *(val++) = '\0'; + + while (*val == ' ' || *val == '\t') + val++; + + { + char *p = strchr (key, ':'); + + if (p != NULL) + { + *p = '\0'; + sel = _nss_ldap_str2selector (key); + key = ++p; + } + } + + return _nss_ldap_map_put (cfg, sel, type, key, val); +} + +/* parse a comma-separated list */ +static NSS_STATUS +do_parse_list (char *values, char ***valptr, + char **pbuffer, size_t *pbuflen) +{ + char *s, **p; +#ifdef HAVE_STRTOK_R + char *tok_r; +#endif + int valcount; + + int buflen = *pbuflen; + char *buffer = *pbuffer; + + /* comma separated list of values to ignore on initgroups() */ + for (valcount = 1, s = values; *s != '\0'; s++) + { + if (*s == ',') + valcount++; + } + + if (bytesleft (buffer, buflen, char *) < (valcount + 1) * sizeof (char *)) + { + return NSS_UNAVAIL; + } + + align (buffer, buflen, char *); + p = *valptr = (char **) buffer; + + buffer += (valcount + 1) * sizeof (char *); + buflen -= (valcount + 1) * sizeof (char *); + +#ifdef HAVE_STRTOK_R + for (s = strtok_r(values, ",", &tok_r); s != NULL; + s = strtok_r(NULL, ",", &tok_r)) +#else + for (s = strtok(values, ","); s != NULL; s = strtok(NULL, ",")) +#endif + { + int vallen; + char *elt = NULL; + + vallen = strlen (s); + if (buflen < (size_t) (vallen + 1)) + { + return NSS_UNAVAIL; + } + + /* copy this value into the next block of buffer space */ + elt = buffer; + buffer += vallen + 1; + buflen -= vallen + 1; + + strncpy (elt, s, vallen); + elt[vallen] = '\0'; + *p++ = elt; + } + + *p = NULL; + *pbuffer = buffer; + *pbuflen = buflen; + + return NSS_SUCCESS; +} + +ldap_map_selector_t +_nss_ldap_str2selector (const char *key) +{ + ldap_map_selector_t sel; + + if (!strcasecmp (key, MP_passwd)) + sel = LM_PASSWD; + else if (!strcasecmp (key, MP_shadow)) + sel = LM_SHADOW; + else if (!strcasecmp (key, MP_group)) + sel = LM_GROUP; + else if (!strcasecmp (key, MP_hosts)) + sel = LM_HOSTS; + else if (!strcasecmp (key, MP_services)) + sel = LM_SERVICES; + else if (!strcasecmp (key, MP_networks)) + sel = LM_NETWORKS; + else if (!strcasecmp (key, MP_protocols)) + sel = LM_PROTOCOLS; + else if (!strcasecmp (key, MP_rpc)) + sel = LM_RPC; + else if (!strcasecmp (key, MP_ethers)) + sel = LM_ETHERS; + else if (!strcasecmp (key, MP_netmasks)) + sel = LM_NETMASKS; + else if (!strcasecmp (key, MP_bootparams)) + sel = LM_BOOTPARAMS; + else if (!strcasecmp (key, MP_aliases)) + sel = LM_ALIASES; + else if (!strcasecmp (key, MP_netgroup)) + sel = LM_NETGROUP; + else if (!strcasecmp (key, MP_automount)) + sel = LM_AUTOMOUNT; + else + sel = LM_NONE; + + return sel; +} + +static NSS_STATUS +do_searchdescriptorconfig (const char *key, const char *value, size_t len, + ldap_service_search_descriptor_t ** result, + char **buffer, size_t * buflen) +{ + ldap_service_search_descriptor_t **t, *cur; + char *base; + char *filter, *s; + int scope; + ldap_map_selector_t sel; + + t = NULL; + filter = NULL; + scope = -1; + + if (strncasecmp (key, NSS_LDAP_KEY_NSS_BASE_PREFIX, + NSS_LDAP_KEY_NSS_BASE_PREFIX_LEN) != 0) + return NSS_SUCCESS; + + sel = _nss_ldap_str2selector (&key[NSS_LDAP_KEY_NSS_BASE_PREFIX_LEN]); + t = (sel < LM_NONE) ? &result[sel] : NULL; + + if (t == NULL) + return NSS_SUCCESS; + + /* we have already checked for room for the value */ + /* len is set to the length of value */ + base = *buffer; + strncpy (base, value, len); + base[len] = '\0'; + + *buffer += len + 1; + *buflen -= len + 1; + + /* probably is some funky escaping needed here. later... */ + s = strchr (base, '?'); + if (s != NULL) + { + *s = '\0'; + s++; + if (!strcasecmp (s, "sub")) + scope = LDAP_SCOPE_SUBTREE; + else if (!strcasecmp (s, "one")) + scope = LDAP_SCOPE_ONELEVEL; + else if (!strcasecmp (s, "base")) + scope = LDAP_SCOPE_BASE; + filter = strchr (s, '?'); + if (filter != NULL) + { + *filter = '\0'; + filter++; + } + } + + if (bytesleft (*buffer, *buflen, ldap_service_search_descriptor_t) < + sizeof (ldap_service_search_descriptor_t)) + return NSS_UNAVAIL; + + align (*buffer, *buflen, ldap_service_search_descriptor_t); + + for (cur = *t; cur && cur->lsd_next; cur = cur->lsd_next) + ; + if (!cur) + { + *t = (ldap_service_search_descriptor_t *) * buffer; + cur = *t; + } + else + { + cur->lsd_next = (ldap_service_search_descriptor_t *) * buffer; + cur = cur->lsd_next; + } + + cur->lsd_base = base; + cur->lsd_scope = scope; + cur->lsd_filter = filter; + cur->lsd_next = NULL; + + *buffer += sizeof (ldap_service_search_descriptor_t); + *buflen -= sizeof (ldap_service_search_descriptor_t); + + return NSS_SUCCESS; +} + +NSS_STATUS _nss_ldap_init_config (ldap_config_t * result) +{ + int i, j; + + memset (result, 0, sizeof (*result)); + + result->ldc_scope = LDAP_SCOPE_SUBTREE; + result->ldc_deref = LDAP_DEREF_NEVER; + result->ldc_base = NULL; + result->ldc_binddn = NULL; + result->ldc_bindpw = NULL; + result->ldc_saslid = NULL; + result->ldc_usesasl = 0; + result->ldc_rootbinddn = NULL; + result->ldc_rootbindpw = NULL; + result->ldc_rootsaslid = NULL; + result->ldc_rootusesasl = 0; +#ifdef LDAP_VERSION3 + result->ldc_version = LDAP_VERSION3; +#else + result->ldc_version = LDAP_VERSION2; +#endif /* LDAP_VERSION3 */ + result->ldc_timelimit = LDAP_NO_LIMIT; + result->ldc_bind_timelimit = 30; + result->ldc_ssl_on = SSL_OFF; + result->ldc_sslpath = NULL; + result->ldc_referrals = 1; + result->ldc_restart = 1; + result->ldc_tls_checkpeer = -1; + result->ldc_tls_cacertfile = NULL; + result->ldc_tls_cacertdir = NULL; + result->ldc_tls_ciphers = NULL; + result->ldc_tls_cert = NULL; + result->ldc_tls_key = NULL; + result->ldc_tls_randfile = NULL; + result->ldc_idle_timelimit = 0; + result->ldc_reconnect_pol = LP_RECONNECT_HARD_OPEN; + result->ldc_sasl_secprops = NULL; + result->ldc_srv_domain = NULL; + result->ldc_logdir = NULL; + result->ldc_debug = 0; + result->ldc_pagesize = LDAP_PAGESIZE; +#ifdef CONFIGURE_KRB5_CCNAME + result->ldc_krb5_ccname = NULL; +#endif /* CONFIGURE_KRB5_CCNAME */ + result->ldc_flags = 0; +#ifdef RFC2307BIS + result->ldc_flags |= NSS_LDAP_FLAGS_RFC2307BIS; +#endif +#ifdef PAGE_RESULTS + result->ldc_flags |= NSS_LDAP_FLAGS_PAGED_RESULTS; +#endif + result->ldc_reconnect_tries = LDAP_NSS_TRIES; + result->ldc_reconnect_sleeptime = LDAP_NSS_SLEEPTIME; + result->ldc_reconnect_maxsleeptime = LDAP_NSS_MAXSLEEPTIME; + result->ldc_reconnect_maxconntries = LDAP_NSS_MAXCONNTRIES; + result->ldc_initgroups_ignoreusers = NULL; + + for (i = 0; i <= LM_NONE; i++) + { + for (j = 0; j <= MAP_MAX; j++) + { + result->ldc_maps[i][j] = _nss_ldap_db_open (); + if (result->ldc_maps[i][j] == NULL) + return NSS_UNAVAIL; + } + } + + return NSS_SUCCESS; +} + +NSS_STATUS +_nss_ldap_add_uri (ldap_config_t *result, const char *uri, + char **buffer, size_t *buflen) +{ + /* add a single URI to the list of URIs in the configuration */ + int i; + size_t uri_len; + + debug ("==> _nss_ldap_add_uri"); + + for (i = 0; result->ldc_uris[i] != NULL; i++) + ; + + if (i == NSS_LDAP_CONFIG_URI_MAX) + { + debug ("<== _nss_ldap_add_uri: maximum number of URIs exceeded"); + return NSS_UNAVAIL; + } + + assert (i < NSS_LDAP_CONFIG_URI_MAX); + + uri_len = strlen (uri); + + if (*buflen < uri_len + 1) + return NSS_TRYAGAIN; + + memcpy (*buffer, uri, uri_len + 1); + + result->ldc_uris[i] = *buffer; + result->ldc_uris[i + 1] = NULL; + + *buffer += uri_len + 1; + *buflen -= uri_len + 1; + + debug ("<== _nss_ldap_add_uri: added URI %s", uri); + + return NSS_SUCCESS; +} + +static NSS_STATUS +do_add_uris (ldap_config_t *result, char *uris, + char **buffer, size_t *buflen) +{ + /* Add a space separated list of URIs */ + char *p; + NSS_STATUS stat = NSS_SUCCESS; + + for (p = uris; p != NULL; ) + { + char *q = strchr (p, ' '); + if (q != NULL) + *q = '\0'; + + stat = _nss_ldap_add_uri (result, p, buffer, buflen); + + p = (q != NULL) ? ++q : NULL; + + if (stat != NSS_SUCCESS) + break; + } + + return stat; +} + +static NSS_STATUS +do_add_hosts (ldap_config_t *result, char *hosts, + char **buffer, size_t *buflen) +{ + /* Add a space separated list of hosts */ + char *p; + NSS_STATUS stat = NSS_SUCCESS; + + for (p = hosts; p != NULL; ) + { + char b[NSS_LDAP_CONFIG_BUFSIZ]; + char *q = strchr (p, ' '); + + if (q != NULL) + *q = '\0'; + + snprintf (b, sizeof(b), "ldap://%s", p); + + stat = _nss_ldap_add_uri (result, b, buffer, buflen); + + p = (q != NULL) ? ++q : NULL; + + if (stat != NSS_SUCCESS) + break; + } + + return stat; +} + +NSS_STATUS +_nss_ldap_readconfig (ldap_config_t ** presult, char **buffer, size_t *buflen) +{ + FILE *fp; + char b[NSS_LDAP_CONFIG_BUFSIZ]; + NSS_STATUS stat = NSS_SUCCESS; + ldap_config_t *result; + struct stat statbuf; + + if (bytesleft (*buffer, *buflen, ldap_config_t *) < sizeof (ldap_config_t)) + { + return NSS_TRYAGAIN; + } + align (*buffer, *buflen, ldap_config_t *); + result = *presult = (ldap_config_t *) *buffer; + *buffer += sizeof (ldap_config_t); + *buflen -= sizeof (ldap_config_t); + + stat = _nss_ldap_init_config (result); + if (stat != NSS_SUCCESS) + { + return NSS_SUCCESS; + } + + fp = fopen (NSS_LDAP_PATH_CONF, "r"); + if (fp == NULL) + { + return NSS_UNAVAIL; + } + + if (fstat (fileno (fp), &statbuf) == 0) + result->ldc_mtime = statbuf.st_mtime; + else + result->ldc_mtime = 0; + + while (fgets (b, sizeof (b), fp) != NULL) + { + char *k, *v; + int len; + char **t = NULL; + + if (*b == '\n' || *b == '\r' || *b == '#') + continue; + + k = b; + v = k; + + /* skip past all characters in keyword */ + while (*v != '\0' && *v != ' ' && *v != '\t') + v++; + + if (*v == '\0') + continue; + + /* terminate keyword */ + *(v++) = '\0'; + + /* skip empty lines with more than 3 spaces at the start of the line */ + /* rds.oliver@samera.com.py 01-set-2004 */ + if (*v == '\n') + continue; + + /* skip all whitespaces between keyword and value */ + /* Lars Oergel <lars.oergel@innominate.de>, 05.10.2000 */ + while (*v == ' ' || *v == '\t') + v++; + + /* kick off all whitespaces and newline at the end of value */ + /* Bob Guo <bob@mail.ied.ac.cn>, 08.10.2001 */ + + /* Also remove \r (CR) to be able to handle files in DOS format (lines + * terminated in CR LF). Alejandro Forero Cuervo + * <azul@freaks-unidos.net>, 10-may-2005 */ + + len = strlen (v) - 1; + while (v[len] == ' ' || v[len] == '\t' || v[len] == '\n' || v[len] == '\r') + --len; + v[++len] = '\0'; + + if (*buflen < (size_t) (len + 1)) + { + stat = NSS_TRYAGAIN; + break; + } + + if (!strcasecmp (k, NSS_LDAP_KEY_HOST)) + { + stat = do_add_hosts (result, v, buffer, buflen); + if (stat != NSS_SUCCESS) + break; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_URI)) + { + stat = do_add_uris (result, v, buffer, buflen); + if (stat != NSS_SUCCESS) + break; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_BASE)) + { + t = &result->ldc_base; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_BINDDN)) + { + t = &result->ldc_binddn; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_BINDPW)) + { + t = &result->ldc_bindpw; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_USESASL)) + { + result->ldc_usesasl = (!strcasecmp (v, "on") + || !strcasecmp (v, "yes") + || !strcasecmp (v, "true")); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_SASLID)) + { + t = &result->ldc_saslid; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_ROOTBINDDN)) + { + t = &result->ldc_rootbinddn; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_ROOTUSESASL)) + { + result->ldc_rootusesasl = (!strcasecmp (v, "on") + || !strcasecmp (v, "yes") + || !strcasecmp (v, "true")); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_ROOTSASLID)) + { + t = &result->ldc_rootsaslid; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_SSLPATH)) + { + t = &result->ldc_sslpath; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_SCOPE)) + { + if (!strcasecmp (v, "sub")) + { + result->ldc_scope = LDAP_SCOPE_SUBTREE; + } + else if (!strcasecmp (v, "one")) + { + result->ldc_scope = LDAP_SCOPE_ONELEVEL; + } + else if (!strcasecmp (v, "base")) + { + result->ldc_scope = LDAP_SCOPE_BASE; + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_DEREF)) + { + if (!strcasecmp (v, "never")) + { + result->ldc_deref = LDAP_DEREF_NEVER; + } + else if (!strcasecmp (v, "searching")) + { + result->ldc_deref = LDAP_DEREF_SEARCHING; + } + else if (!strcasecmp (v, "finding")) + { + result->ldc_deref = LDAP_DEREF_FINDING; + } + else if (!strcasecmp (v, "always")) + { + result->ldc_deref = LDAP_DEREF_ALWAYS; + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_PORT)) + { + result->ldc_port = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_SSL)) + { + if (!strcasecmp (v, "on") || !strcasecmp (v, "yes") + || !strcasecmp (v, "true")) + { + result->ldc_ssl_on = SSL_LDAPS; + } + else if (!strcasecmp (v, "start_tls")) + { + result->ldc_ssl_on = SSL_START_TLS; + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_REFERRALS)) + { + result->ldc_referrals = (!strcasecmp (v, "on") + || !strcasecmp (v, "yes") + || !strcasecmp (v, "true")); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_RESTART)) + { + result->ldc_restart = (!strcasecmp (v, "on") + || !strcasecmp (v, "yes") + || !strcasecmp (v, "true")); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_LDAP_VERSION)) + { + result->ldc_version = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_TIMELIMIT)) + { + result->ldc_timelimit = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_BIND_TIMELIMIT)) + { + result->ldc_bind_timelimit = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_IDLE_TIMELIMIT)) + { + result->ldc_idle_timelimit = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_POLICY)) + { + if (!strcasecmp (v, "hard") || + !strcasecmp (v, "hard_open")) + { + result->ldc_reconnect_pol = LP_RECONNECT_HARD_OPEN; + } + else if (!strcasecmp (v, "hard_init")) + { + result->ldc_reconnect_pol = LP_RECONNECT_HARD_INIT; + } + else if (!strcasecmp (v, "soft")) + { + result->ldc_reconnect_pol = LP_RECONNECT_SOFT; + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_TRIES)) + { + result->ldc_reconnect_tries = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_SLEEPTIME)) + { + result->ldc_reconnect_sleeptime = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_MAXSLEEPTIME)) + { + result->ldc_reconnect_maxsleeptime = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_MAXCONNTRIES)) + { + result->ldc_reconnect_maxconntries = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_SASL_SECPROPS)) + { + t = &result->ldc_sasl_secprops; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_LOGDIR)) + { + t = &result->ldc_logdir; + } + else if (!strcasecmp (k, NSS_LDAP_KEY_DEBUG)) + { + result->ldc_debug = atoi (v); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_PAGESIZE)) + { + result->ldc_pagesize = atoi (v); + } +#ifdef CONFIGURE_KRB5_CCNAME + else if (!strcasecmp (k, NSS_LDAP_KEY_KRB5_CCNAME)) + { + t = &result->ldc_krb5_ccname; + } +#endif /* CONFIGURE_KRB5_CCNAME */ + else if (!strcasecmp (k, "tls_checkpeer")) + { + if (!strcasecmp (v, "on") || !strcasecmp (v, "yes") + || !strcasecmp (v, "true")) + { + result->ldc_tls_checkpeer = 1; + } + else if (!strcasecmp (v, "off") || !strcasecmp (v, "no") + || !strcasecmp (v, "false")) + { + result->ldc_tls_checkpeer = 0; + } + } + else if (!strcasecmp (k, "tls_cacertfile")) + { + t = &result->ldc_tls_cacertfile; + } + else if (!strcasecmp (k, "tls_cacertdir")) + { + t = &result->ldc_tls_cacertdir; + } + else if (!strcasecmp (k, "tls_ciphers")) + { + t = &result->ldc_tls_ciphers; + } + else if (!strcasecmp (k, "tls_cert")) + { + t = &result->ldc_tls_cert; + } + else if (!strcasecmp (k, "tls_key")) + { + t = &result->ldc_tls_key; + } + else if (!strcasecmp (k, "tls_randfile")) + { + t = &result->ldc_tls_randfile; + } + else if (!strncasecmp (k, NSS_LDAP_KEY_MAP_ATTRIBUTE, + strlen (NSS_LDAP_KEY_MAP_ATTRIBUTE))) + { + do_parse_map_statement (result, v, MAP_ATTRIBUTE); + } + else if (!strncasecmp (k, NSS_LDAP_KEY_MAP_OBJECTCLASS, + strlen (NSS_LDAP_KEY_MAP_OBJECTCLASS))) + { + do_parse_map_statement (result, v, MAP_OBJECTCLASS); + } + else if (!strncasecmp (k, NSS_LDAP_KEY_SET_OVERRIDE, + strlen (NSS_LDAP_KEY_SET_OVERRIDE))) + { + do_parse_map_statement (result, v, MAP_OVERRIDE); + } + else if (!strncasecmp (k, NSS_LDAP_KEY_SET_DEFAULT, + strlen (NSS_LDAP_KEY_SET_DEFAULT))) + { + do_parse_map_statement (result, v, MAP_DEFAULT); + } + else if (!strcasecmp (k, NSS_LDAP_KEY_INITGROUPS)) + { + if (!strcasecmp (v, "backlink")) + { + result->ldc_flags |= NSS_LDAP_FLAGS_INITGROUPS_BACKLINK; + } + else + { + result->ldc_flags &= ~(NSS_LDAP_FLAGS_INITGROUPS_BACKLINK); + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_SCHEMA)) + { + if (!strcasecmp (v, "rfc2307bis")) + { + result->ldc_flags |= NSS_LDAP_FLAGS_RFC2307BIS; + } + else if (!strcasecmp (v, "rfc2307")) + { + result->ldc_flags &= ~(NSS_LDAP_FLAGS_RFC2307BIS); + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_PAGED_RESULTS)) + { + if (!strcasecmp (v, "on") + || !strcasecmp (v, "yes") + || !strcasecmp (v, "true")) + { + result->ldc_flags |= NSS_LDAP_FLAGS_PAGED_RESULTS; + } + else + { + result->ldc_flags &= ~(NSS_LDAP_FLAGS_PAGED_RESULTS); + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_INITGROUPS_IGNOREUSERS)) + { + stat = do_parse_list (v, &result->ldc_initgroups_ignoreusers, + buffer, buflen); + if (stat == NSS_UNAVAIL) + { + break; + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_CONNECT_POLICY)) + { + if (!strcasecmp (v, "oneshot")) + { + result->ldc_flags |= NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT; + } + else if (!strcasecmp (v, "persist")) + { + result->ldc_flags &= ~(NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT); + } + } + else if (!strcasecmp (k, NSS_LDAP_KEY_SRV_DOMAIN)) + { + t = &result->ldc_srv_domain; + } + else + { + /* + * check whether the key is a naming context key + * if yes, parse; otherwise just return NSS_SUCCESS + * so we can ignore keys we don't understand. + */ + stat = + do_searchdescriptorconfig (k, v, len, result->ldc_sds, + buffer, buflen); + if (stat == NSS_UNAVAIL) + { + break; + } + } + + if (t != NULL) + { + strncpy (*buffer, v, len); + (*buffer)[len] = '\0'; + *t = *buffer; + *buffer += len + 1; + *buflen -= len + 1; + } + } + + fclose (fp); + + if (stat != NSS_SUCCESS) + { + return stat; + } + + if (result->ldc_rootbinddn != NULL) + { + fp = fopen (NSS_LDAP_PATH_ROOTPASSWD, "r"); + if (fp) + { + if (fgets (b, sizeof (b), fp) != NULL) + { + int len; + + len = strlen (b); + /* BUG#138: check for newline before removing */ + if (len > 0 && b[len - 1] == '\n') + len--; + + if (*buflen < (size_t) (len + 1)) + { + return NSS_UNAVAIL; + } + + strncpy (*buffer, b, len); + (*buffer)[len] = '\0'; + result->ldc_rootbindpw = *buffer; + *buffer += len + 1; + *buflen -= len + 1; + } + fclose (fp); + } + else if (!result->ldc_rootusesasl) + { + result->ldc_rootbinddn = NULL; + } + } + + if (result->ldc_port == 0) + { + if (result->ldc_ssl_on == SSL_LDAPS) + { + result->ldc_port = LDAPS_PORT; + } + else + { + result->ldc_port = LDAP_PORT; + } + } + + if (result->ldc_uris[0] == NULL) + { + stat = NSS_NOTFOUND; + } + + return stat; +} + +NSS_STATUS +_nss_ldap_escape_string (const char *str, char *buf, size_t buflen) +{ + int ret = NSS_TRYAGAIN; + char *p = buf; + char *limit = p + buflen - 3; + const char *s = str; + + while (p < limit && *s) + { + switch (*s) + { + case '*': + strcpy (p, "\\2a"); + p += 3; + break; + case '(': + strcpy (p, "\\28"); + p += 3; + break; + case ')': + strcpy (p, "\\29"); + p += 3; + break; + case '\\': + strcpy (p, "\\5c"); + p += 3; + break; + default: + *p++ = *s; + break; + } + s++; + } + + if (*s == '\0') + { + /* got to end */ + *p = '\0'; + ret = NSS_SUCCESS; + } + + return ret; +} + +/* XXX just a linked list for now */ + +struct ldap_dictionary +{ + ldap_datum_t key; + ldap_datum_t value; + struct ldap_dictionary *next; +}; + +static struct ldap_dictionary * +do_alloc_dictionary (void) +{ + struct ldap_dictionary *dict; + + dict = malloc (sizeof (*dict)); + if (dict == NULL) + { + return NULL; + } + NSS_LDAP_DATUM_ZERO (&dict->key); + NSS_LDAP_DATUM_ZERO (&dict->value); + dict->next = NULL; + + return dict; +} + +static void +do_free_datum (ldap_datum_t * datum) +{ + if (datum->data != NULL) + { + free (datum->data); + datum->data = NULL; + } + datum->size = 0; +} + +static struct ldap_dictionary * +do_find_last (struct ldap_dictionary *dict) +{ + struct ldap_dictionary *p; + + for (p = dict; p->next != NULL; p = p->next) + ; + + return p; +} + +static void +do_free_dictionary (struct ldap_dictionary *dict) +{ + do_free_datum (&dict->key); + do_free_datum (&dict->value); + free (dict); +} + +static NSS_STATUS +do_dup_datum (unsigned flags, ldap_datum_t * dst, const ldap_datum_t * src) +{ + dst->data = malloc (src->size); + if (dst->data == NULL) + return NSS_TRYAGAIN; + + memcpy (dst->data, src->data, src->size); + dst->size = src->size; + + return NSS_SUCCESS; +} + +void * +_nss_ldap_db_open (void) +{ + return (void *) do_alloc_dictionary (); +} + +void +_nss_ldap_db_close (void *db) +{ + struct ldap_dictionary *dict; + + dict = (struct ldap_dictionary *) db; + + while (dict != NULL) + { + struct ldap_dictionary *next = dict->next; + + do_free_dictionary (dict); + + dict = next; + } +} + +NSS_STATUS +_nss_ldap_db_get (void *db, + unsigned flags, + const ldap_datum_t * key, + ldap_datum_t * value) +{ + struct ldap_dictionary *dict = (struct ldap_dictionary *) db; + struct ldap_dictionary *p; + + for (p = dict; p != NULL; p = p->next) + { + int cmp; + + if (p->key.size != key->size) + continue; + + if (flags & NSS_LDAP_DB_NORMALIZE_CASE) + cmp = strncasecmp ((char *)p->key.data, (char *)key->data, key->size); + else + cmp = memcmp (p->key.data, key->data, key->size); + + if (cmp == 0) + { + value->data = p->value.data; + value->size = p->value.size; + + return NSS_SUCCESS; + } + } + + return NSS_NOTFOUND; +} + +NSS_STATUS +_nss_ldap_db_put (void *db, + unsigned flags, + const ldap_datum_t * key, + const ldap_datum_t * value) +{ + struct ldap_dictionary *dict = (struct ldap_dictionary *) db; + struct ldap_dictionary *p, *q; + + assert (key != NULL); + assert (key->data != NULL); + + if (dict->key.data == NULL) + { + /* uninitialized */ + q = dict; + p = NULL; + } + else + { + p = do_find_last (dict); + assert (p != NULL); + assert (p->next == NULL); + q = do_alloc_dictionary (); + if (q == NULL) + return NSS_TRYAGAIN; + } + + if (do_dup_datum (flags, &q->key, key) != NSS_SUCCESS) + { + do_free_dictionary (q); + return NSS_TRYAGAIN; + } + + if (do_dup_datum (flags, &q->value, value) != NSS_SUCCESS) + { + do_free_dictionary (q); + return NSS_TRYAGAIN; + } + + if (p != NULL) + p->next = q; + + return NSS_SUCCESS; +} + +/* + * Add a nested netgroup or group to the namelist + */ +NSS_STATUS +_nss_ldap_namelist_push (struct name_list **head, const char *name) +{ + struct name_list *nl; + + debug ("==> _nss_ldap_namelist_push (%s)", name); + + nl = (struct name_list *) malloc (sizeof (*nl)); + if (nl == NULL) + { + debug ("<== _nss_ldap_namelist_push"); + return NSS_TRYAGAIN; + } + + nl->name = strdup (name); + if (nl->name == NULL) + { + debug ("<== _nss_ldap_namelist_push"); + free (nl); + return NSS_TRYAGAIN; + } + + nl->next = *head; + + *head = nl; + + debug ("<== _nss_ldap_namelist_push"); + + return NSS_SUCCESS; +} + +/* + * Remove last nested netgroup or group from the namelist + */ +void +_nss_ldap_namelist_pop (struct name_list **head) +{ + struct name_list *nl; + + debug ("==> _nss_ldap_namelist_pop"); + + assert (*head != NULL); + nl = *head; + + *head = nl->next; + + assert (nl->name != NULL); + free (nl->name); + free (nl); + + debug ("<== _nss_ldap_namelist_pop"); +} + +/* + * Cleanup nested netgroup or group namelist. + */ +void +_nss_ldap_namelist_destroy (struct name_list **head) +{ + struct name_list *p, *next; + + debug ("==> _nss_ldap_namelist_destroy"); + + for (p = *head; p != NULL; p = next) + { + next = p->next; + + if (p->name != NULL) + free (p->name); + free (p); + } + + *head = NULL; + + debug ("<== _nss_ldap_namelist_destroy"); +} + +/* + * Check whether we have already seen a netgroup or group, + * to avoid loops in nested netgroup traversal + */ +int +_nss_ldap_namelist_find (struct name_list *head, const char *netgroup) +{ + struct name_list *p; + int found = 0; + + debug ("==> _nss_ldap_namelist_find"); + + for (p = head; p != NULL; p = p->next) + { + if (strcasecmp (p->name, netgroup) == 0) + { + found++; + break; + } + } + + debug ("<== _nss_ldap_namelist_find"); + + return found; +} + +NSS_STATUS _nss_ldap_validateconfig (ldap_config_t *config) +{ + struct stat statbuf; + + if (config == NULL) + { + return NSS_UNAVAIL; + } + + if (config->ldc_mtime == 0) + { + return NSS_SUCCESS; + } + + if (stat (NSS_LDAP_PATH_CONF, &statbuf) == 0) + { + return (statbuf.st_mtime > config->ldc_mtime) ? NSS_TRYAGAIN : NSS_SUCCESS; + } + + return NSS_SUCCESS; +} + @@ -0,0 +1,216 @@ +/* Copyright (C) 1997-2005 Luke Howard. + This file is part of the nss_ldap library. + Contributed by Luke Howard, <lukeh@padl.com>, 1997. + (The author maintains a non-exclusive licence to distribute this file + under their own conditions.) + + The nss_ldap library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The nss_ldap 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the nss_ldap library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef _LDAP_NSS_LDAP_UTIL_H +#define _LDAP_NSS_LDAP_UTIL_H + +/* utility routines. */ + +#define CN_ATTR "CN" + +#define DC_ATTR "DC" +#define DC_ATTR_AVA DC_ATTR"=" +#define DC_ATTR_AVA_LEN (sizeof(DC_ATTR_AVA) - 1) + +/* + * get the RDN's value: eg. if the RDN was cn=lukeh, getrdnvalue(entry) + * would return lukeh. + */ +NSS_STATUS _nss_ldap_getrdnvalue (LDAPMessage * entry, + const char *rdntype, + char **rval, char **buf, size_t * len); + +/* + * map a distinguished name to a login name, or group entry + */ +NSS_STATUS _nss_ldap_dn2uid (const char *dn, + char **uid, char **buf, size_t * len, + int *pIsNestedGroup, LDAPMessage ** pRes); + +#define NSS_LDAP_KEY_MAP_ATTRIBUTE "nss_map_attribute" +#define NSS_LDAP_KEY_MAP_OBJECTCLASS "nss_map_objectclass" +#define NSS_LDAP_KEY_SET_OVERRIDE "nss_override_attribute_value" +#define NSS_LDAP_KEY_SET_DEFAULT "nss_default_attribute_value" + +#define NSS_LDAP_CONFIG_BUFSIZ 4096 +#define NSS_LDAP_KEY_HOST "host" +#define NSS_LDAP_KEY_SCOPE "scope" +#define NSS_LDAP_KEY_BASE "base" +#define NSS_LDAP_KEY_PORT "port" +#define NSS_LDAP_KEY_BINDDN "binddn" +#define NSS_LDAP_KEY_BINDPW "bindpw" +#define NSS_LDAP_KEY_USESASL "use_sasl" +#define NSS_LDAP_KEY_SASLID "sasl_auth_id" +#define NSS_LDAP_KEY_DEREF "deref" +#define NSS_LDAP_KEY_ROOTBINDDN "rootbinddn" +#define NSS_LDAP_KEY_ROOTUSESASL "rootuse_sasl" +#define NSS_LDAP_KEY_ROOTSASLID "rootsasl_auth_id" +#define NSS_LDAP_KEY_LDAP_VERSION "ldap_version" +#define NSS_LDAP_KEY_TIMELIMIT "timelimit" +#define NSS_LDAP_KEY_BIND_TIMELIMIT "bind_timelimit" +#define NSS_LDAP_KEY_SSL "ssl" +#define NSS_LDAP_KEY_SSLPATH "sslpath" +#define NSS_LDAP_KEY_REFERRALS "referrals" +#define NSS_LDAP_KEY_RESTART "restart" +#define NSS_LDAP_KEY_URI "uri" +#define NSS_LDAP_KEY_IDLE_TIMELIMIT "idle_timelimit" +#define NSS_LDAP_KEY_RECONNECT_POLICY "bind_policy" +#define NSS_LDAP_KEY_SASL_SECPROPS "sasl_secprops" +#ifdef CONFIGURE_KRB5_CCNAME +#define NSS_LDAP_KEY_KRB5_CCNAME "krb5_ccname" +#endif /* CONFIGURE_KRB5_CCNAME */ +#define NSS_LDAP_KEY_LOGDIR "logdir" +#define NSS_LDAP_KEY_DEBUG "debug" +#define NSS_LDAP_KEY_PAGESIZE "pagesize" +#define NSS_LDAP_KEY_INITGROUPS "nss_initgroups" +#define NSS_LDAP_KEY_INITGROUPS_IGNOREUSERS "nss_initgroups_ignoreusers" + +/* more reconnect policy fine-tuning */ +#define NSS_LDAP_KEY_RECONNECT_TRIES "nss_reconnect_tries" +#define NSS_LDAP_KEY_RECONNECT_SLEEPTIME "nss_reconnect_sleeptime" +#define NSS_LDAP_KEY_RECONNECT_MAXSLEEPTIME "nss_reconnect_maxsleeptime" +#define NSS_LDAP_KEY_RECONNECT_MAXCONNTRIES "nss_reconnect_maxconntries" + +#define NSS_LDAP_KEY_PAGED_RESULTS "nss_paged_results" +#define NSS_LDAP_KEY_SCHEMA "nss_schema" +#define NSS_LDAP_KEY_SRV_DOMAIN "nss_srv_domain" +#define NSS_LDAP_KEY_CONNECT_POLICY "nss_connect_policy" + +/* + * support separate naming contexts for each map + * eventually this will support the syntax defined in + * the DUAConfigProfile searchDescriptor attribute + */ +#define NSS_LDAP_KEY_NSS_BASE_PREFIX "nss_base_" +#define NSS_LDAP_KEY_NSS_BASE_PREFIX_LEN ( sizeof(NSS_LDAP_KEY_NSS_BASE_PREFIX) - 1 ) + +/* + * Flags that are exposed via _nss_ldap_test_config_flag() + */ +#define NSS_LDAP_FLAGS_INITGROUPS_BACKLINK 0x0001 +#define NSS_LDAP_FLAGS_PAGED_RESULTS 0x0002 +#define NSS_LDAP_FLAGS_RFC2307BIS 0x0004 +#define NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT 0x0008 + +/* + * There are a number of means of obtaining configuration information. + * + * (a) DHCP (Cf draft-hedstrom-dhc-ldap-00.txt) + * (b) a configuration file (/etc/ldap.conf) ** + * (c) a coldstart file & subsequent referrals from the LDAP server + * (d) a custom LDAP bind protocol + * (e) DNS ** + * + * This should be opaque to the rest of the library. + * ** implemented + */ + +NSS_STATUS _nss_ldap_init_config (ldap_config_t *); +NSS_STATUS _nss_ldap_readconfig (ldap_config_t ** result, char **buffer, size_t *buflen); +NSS_STATUS _nss_ldap_validateconfig (ldap_config_t *config); + +/* + * Escape '*' in a string for use as a filter + */ + +NSS_STATUS _nss_ldap_escape_string (const char *str, + char *buf, size_t buflen); + +#define MAP_H_ERRNO(nss_status, herr) do { \ + switch ((nss_status)) { \ + case NSS_SUCCESS: \ + (herr) = 0; \ + break; \ + case NSS_TRYAGAIN: \ + (herr) = TRY_AGAIN; \ + break; \ + case NSS_NOTFOUND: \ + (herr) = HOST_NOT_FOUND;\ + break; \ + case NSS_UNAVAIL: \ + default: \ + (herr) = NO_RECOVERY; \ + break; \ + } \ + } while (0) + +#ifdef HAVE_IRS_H +#define MAP_ERRNO(nss_status, err) do { \ + switch ((nss_status)) { \ + case NSS_SUCCESS: \ + (err) = 0; \ + break; \ + case NSS_TRYAGAIN: \ + (err) = ERANGE; \ + break; \ + case NSS_NOTFOUND: \ + (err) = ENOENT; \ + break; \ + case NSS_UNAVAIL: \ + default: \ + (err) = EPERM; \ + break; \ + } \ + } while (0) +#endif /* HAVE_IRS_H */ + +struct ldap_datum +{ + void *data; + size_t size; +}; + +typedef struct ldap_datum ldap_datum_t; + +#define NSS_LDAP_DATUM_ZERO(d) do { \ + (d)->data = NULL; \ + (d)->size = 0; \ + } while (0) + +#define NSS_LDAP_DB_NORMALIZE_CASE 0x1 + +void *_nss_ldap_db_open (void); +void _nss_ldap_db_close (void *db); +NSS_STATUS _nss_ldap_db_put (void *db, + unsigned flags, + const ldap_datum_t * key, + const ldap_datum_t * value); +NSS_STATUS _nss_ldap_db_get (void *db, + unsigned flags, + const ldap_datum_t * key, + ldap_datum_t * value); + +/* Routines for managing namelists */ + +NSS_STATUS _nss_ldap_namelist_push (struct name_list **head, const char *name); +void _nss_ldap_namelist_pop (struct name_list **head); +int _nss_ldap_namelist_find (struct name_list *head, const char *netgroup); +void _nss_ldap_namelist_destroy (struct name_list **head); + +NSS_STATUS +_nss_ldap_add_uri (ldap_config_t *result, const char *uri, + char **buffer, size_t *buflen); + +ldap_map_selector_t +_nss_ldap_str2selector (const char *key); + +#endif /* _LDAP_NSS_LDAP_UTIL_H */ |