pax_global_header00006660000000000000000000000064147265543300014523gustar00rootroot0000000000000052 comment=dd424497687eba6a0917e925a7ade09ddb2838e7 libnss-mysql-1.6.1/000077500000000000000000000000001472655433000141655ustar00rootroot00000000000000libnss-mysql-1.6.1/.gitignore000066400000000000000000000003551472655433000161600ustar00rootroot00000000000000#* *.la *.lo *.o *.tar.gz *~ .deps .libs Makefile Makefile Makefile.in Makefile.in TAGS aclocal.m4 autom4te.cache build-aux config.h config.h.in config.log config.status configure libnss-mysql-*.*.* libtool m4 stamp-h stamp-h1 version.c libnss-mysql-1.6.1/AUTHORS000066400000000000000000000015461472655433000152430ustar00rootroot00000000000000libnss-mysql is Copyright (C) 2002 Ben Goodwin It was created in May 2002, based upon much earlier, non-NSS code. So far, no one else has contributed. [[ Update: Until now in 2024. ]] The GNU Savannah Software Forge site is using this most excellent software. Maintenance changes are required to adapt it to the changing MariaDB. I have previously made minor build modifications in order to track system changes on OS releases. But now it needs more modification to build against current MariaDB versions. Therefore I am adopting in order to keep this running. Copyright 2024 Bob Proulx Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. libnss-mysql-1.6.1/COPYING000066400000000000000000000431101472655433000152170ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, 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 software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, 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 redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the Program a copy of this License along with the Program. 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 Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) 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; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, 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 executable. 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. If distribution of executable or 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 counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program 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. 5. 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 Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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. 7. 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 Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program. 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. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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. 9. The Free Software Foundation may publish revised and/or new versions of the 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 Program 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. libnss-mysql-1.6.1/ChangeLog000066400000000000000000000532631472655433000157500ustar00rootroot000000000000001.5 - 1.6 * CHANGE: Support MariaDB 10. Support current autotools versions. autoconf 2.71 automake 1.16.5 libtoolize 2.4.6 * BUGFIX: Bug ID 1504864 - Return Type Error on _nss_mysql_run_query * BUGFIX: Bug ID 1415600 - "DESTDIR=/another/root make install" fails * BUGFIX: Explicitly set auto-reconnect; default on MySQL 5.0.3 is now off 1.4 - 1.5 * BUGFIX: Bug ID 1244484 - Connect timeout broke ability to connect to MySQL server on some platforms. 1.3 - 1.4 * CHANGE: Read [libnss-mysql] and [client] sections in /etc/my.cnf; Removed these options from libnss-mysql.cfg: timeout, compress, initcmd 1.2 - 1.3 * NEW: Configuration file line continuation is now supported. See samples for examples. * NEW: Static allocation of query line (2048 chars) allows multiple references to the key being looked up - e.g. "SELECT ... FROM ... WHERE foo='%1$s' AND bar='%1$s'" * BUGFIX: Removed extraneous UNLOCK that caused thread instability due to changes in version 1.2 * BUGFIX: Added atexit() handler to close MySQL connection upon process exit. Should clear up any "Aborted connection [...] Got an error reading communication packets" messages in the MySQL server logs if you have warnings turned on * BUGFIX: Added missing Makefile path to .sym * CHANGE: Safely purge MySQL password at program exit * CHANGE: Big changes in config parsing; [section]'s are meaningless and safely ignored, but should be removed * CHANGE: Static allocation of configuration variables * CHANGE: Prefer static MySQL libraries over dynamic; Removed forced-static-link from RPM spec file since this change makes it unnecessary * CHANGE: Moved sources to src/ and aux files to aux/ * CHANGE: Send a syslog if number of columns returned != expected # * CHANGE: (Internal) code and support file cleanup; comments 1.1 - 1.2 * BUGFIX: euid-change detection was broken, causing things like privsep-enabled SSH daemons to be unable to log in a MySQL user. Thanks to Mike Noordermeer for the patch. * BUGFIX: Fixed broken 'initcmd' option * CHANGE: Minimum supported MySQL version is 3.23.09 * CHANGE: Removed 'ssl' config option - it's not supposed to be used by client programs 1.0 - 1.1 * CHANGE: 'configure' now takes just --with-mysql to specify MySQL location instead of two separate (--with-mysql-inc and --with-mysql-lib) options. The following base locations are automatically searched in this order: /usr, /usr/local, /usr/local/mysql, /opt/local, /opt/local/mysql. * BUGFIX: Try query a few more times if it fails; corrects issues with reset idle connections which should result in a valid reconnect and query, but caused 1 'user unknown' error. * BUGFIX: Groups without members weren't showing up in getgrent's * BUGFIX: Don't leak any symbols except what's necessary - prevents problems with differing MySQL library versions. Classic example is Apache/PHP using different version than the one statically linked in the libnss-mysql RPM. On Linux, this requires libtool >= 1.5.2 * DOCS: The FreeBSD sample now contains proper shadow implementation. ! PREVIOUS SAMPLES ALLOWED NON-ROOT USERS TO SEE ENCRYPTED ! PASSWORDS * DOCS: Updated README to better suit FreeBSD installations * DOCS: Added Q&A about -R necessity under older Solaris installations. 0.9 - 1.0 * NEW: FreeBSD (5.1+) is now supported * CHANGE: Solaris makes use of two new columns in the getpw* routines See the file UPGRADING for details * CHANGE: Installation of libraries is handled better; as a result, a 'make uninstall' will remove libnss-mysql (except config files) * CHANGE: -Bgroup and --allow-shlib-undefined linker options are no longer used. Hopefully these really aren't necessary anymore * CHANGE: Updated RPM SPEC file and removed the linker options above. Minor shortcuts added 0.8 - 0.9 * NEW: Several new sample database and configuration files * BUGFIX: Don't compile against threaded MySQL libraries. It was causing deadlocks * BUGFIX: Preallocate exactly as much memory as needed to create the MySQL query string; fixes loops/errors with usernames that were extra-long * BUGFIX: Fixed cosmetic error reporting queries missing from config * CHANGE: Only one server is supported. The multi-server code was always buggy so I've decided to remove it, at least for 1.0. It was also part of the looping mentioned above * CHANGE: Renamed module from libnss_mysql to libnss-mysql for consistency. This includes renaming configuration files. See UPGRADING for more information * CHANGE: Removed all dependencies from RPM spec file * CHANGE: Various documentation updates 0.7a - 0.8 * NEW: Added RPM SPEC file to distribution * NEW: Lots of additional debugging in the mysql-specific code * BUGFIX: Disable MySQL automatic reconnect. It's not safe in this environment * BUGFIX: Try server #0 if all servers are marked down. Was causing bogus NSS_UNAVAIL returns if connection had been lost * BUGFIX: Failover/retry wasn't quit right - could cause infinite loops and other erroneous conditions. * BUGFIX: Don't mess up syslog identification names with our own name. As such, there's no more 'configure' option to specify the syslog facility to use * BUGFIX: Fixed Solaris coredump when debug was on and a non-local MySQL server was specified * CHANGE: Create debug file with a umask of '000' so any process can write to it * CHANGE: Removed [libnss_mysql] section for 'my.cnf' - use new options directly in /etc/nss_mysql.cfg: ssl, timeout, compress, initcmd. These new options are specified within each server section (primary, secondary, etc). See sample configuration file for details * CHANGE: Added default connect timeout (override with 'timeout' option in config - see above) to prevent deadlock situations (could lock yourself out of a server if a server became unreachable). * CHANGE: Updated sample database: uid=primary autoincremeting key, gid=primary autoincrementing key, default values for password and shell, and cosmetic changes. Nothing major * CHANGE: port & socket are now optional parameters in the config file * CHANGE: Added another directory set to search for MySQL libs/includes * CHANGE: Many updates to various documentation 0.7 - 0.7a * CHANGE: Don't send syslog messages to *.EMERG (causing console spam) - send them to *.ALERT * BUGFIX: Detect various linker options. Important to get around inability to compile on slightly older Linux systems (IE RedHat 7.1 - 7.2). Also fixes broken compile on even older systems (RedHat 7.0, Corel 1.2/Debian 2.1) * BUGFIX: Fixed compiler warnings when using older versions of MySQL * BUGFIX: Properly detect MySQL 4 libraries 0.6 - 0.7 * NEW: Re-added debugging. You can send debug output to syslog, stderr, or a file. See DEBUGGING for more information. * CHANGE: CVS no longer includes files that can be generated using autoconf/automake/libtool/etc ... Install these utilities and use 'setup.sh' if you're building from CVS * CHANGE: GNU 'make' is no longer required * BUGFIX: Re-implemented uid check to make sure getsp* routines couldn't be called by non-root users (which would create syslog message regarding failed query attempts). * BUGFIX: Fix nscd coredump under Solaris. Any programs that tried to access pw->pw_comment and/or pw->pw_age would have suffered the same fate. * BUGFIX: Fixed crash/hang under certain circumstances (usually when forking). * BUGFIX: Don't re-create SQL query string every time we iterate through a get*ent routine - will result in speedier lookups * BUGFIX: Check for comment lines before checking for bracketed sections - minor speed improvement * BUGFIX: Reload config upon euid change - root privs are properly dropped * BUGFIX: Don't *close* the sql connection upon fork - just invalidate the child's version so it'll create a new connection. * BUGFIX: Fixed deadlock issue for forking, multithreaded apps 0.5 - 0.6 * NEW: Support for Sun Workshop compiler * NEW: Additional documentation on producing 64-bit version * BUGFIX: Handle program forks properly - used to cause hangs, improper data, crashes, etc ... * BUGFIX: getgrmem() would hang in multi-threaded environment * BUGFIX: Abort if Solaris backend couldn't be malloc'ed - was causing inability to log in at single-user root password prompt * BUGFIX: Correct handling of insufficient 'buffer' size. Would have caused long hangs (or infinite loops) in Solaris. * BUGFIX: Read my.cnf for EVERY server. Would cause ignored settings like connect-timeout, leading to infinite hangs in outtages. * BUGFIX: Don't attempt to run null/empty queries * BUGFIX: General compile cleanups, including upgrade to Automake 1.6 0.4 - 0.5 * NEW: initgroup/getgrmem support. Some programs need these routines to find out who's a member of what groups and what groups have what members. Especially important under Solaris where filesystem group access is done using these methods. THIS REQUIRES A CHANGE TO YOUR DATABASE. READ THE FILE "UPGRADING" FOR MORE INFORMATION. * NEW: Search for and use thread-safe MySQL library if available. * CHANGE: Removed all debug code - for now. See the file UPGRADING. * CHANGE: Syslog configuration done at compile-time. See the file UPGRADING. * CHANGE: Search a few more locations for MySQL library files. * CHANGE: Major internal rewrite - to enable me to support other NSS databases. * BUGFIX: specify '-L' before '-lmysqlclient' on link line; previously caused 'missing library' errors. * BUGFIX: Special linker options properly passed no matter what linker is used. * BUGFIX: Prevent any symbols from leaking outside this library. Previously caused unexplained errors or core dumps. * BUGFIX: Search for and use static MySQL libraries, too. * BUGFIX: Don't disconnect/deallocate upon 'destruct' call (Solaris). The code was not thread-safe, and is no longer necessary. This was preventing persistent connections in some cases, too. * BUGFIX: Store different MySQL results in different variables; Enables interleaved 'ent' access of different databases. * BUGFIX: Under certain circumstances, euid could be 0 but the process couldn't read a root-owned mode 600 file. Now we simply always try to open the file - meaning your nss_mysql_root.cfg file better be root-owned, mode 600! 0.3 - 0.4 * No special configure/make arguments are necessary for Solaris. You may, however, need to manually link the library. If you encounter an error with an undefined symbol, read the FAQ. * Fixed a couple of bus error conditions under Solaris/sparc. * Fixed memory leak under Solaris. * Fixed core dump with Solaris csh and ~username expansion. This fix probably fixed other core dumps as well. * Fixed compile error under Solaris 2.6 (no socklen_t) * Upgraded to autoconf 2.53 * Rewrote connection handlers. CONFIG FILE CHANGES ARE REQUIRED. See the file UPGRADING. * Read [libnss_mysql] group in my.cnf * Do some config validation before doing anything. Helps prevent mysterious core dumping. 2002-08-28 Ben Goodwin * *: CVS tag 0.3; Public release * nss_main.c, lookup.c, mysql.c, nss_config.c, nss_mysql.h, nss_support.c: turned 'conf' into a global variable instead of passing it around everywhere * configure.in: Removed "-z nodelete" hack - didn't work 2002-08-27 Ben Goodwin * configure.in: Added "-z nodelete" LD_OPTIONS hack to get around strange dlopen-related solaris memory leak bug * Automake.am: added -module arg to libtool 2002-08-23 Ben Goodwin * lookup.c, lookup.h, memory.c, nss_config.c, nss_main.c, nss_mysql.h, nss_support.h: Renamed memory functions to avoid clashes. * lookup.c: Fixed memory leak * lookup.h: Added CLOSE_RESULT in GET on the HAVE_NSS_COMMON_H side of the house (to match the HAVE_NSS_H side) * nss_main.c: (HAVE_NSS_COMMON_H) default destructor now closes MySQL link - required due to the fact that the module is unloaded and thus static vars are lost * nss_config.c: Close config file handle when done with it 2002-08-22 Ben Goodwin * mysql-grp.c, mysql-pwd.c, mysql-spwd.c: Added euid restrict - don't allow non-root access to certain functions * mysql.c: Added CLOSE_NOGRACE for when MySQL socket is stomped on Header cleanup * nss_main.c, lookup.c, nss_config.c, nss_support.c: Header cleanup * nss_mysql.h: Added CLOSE_NOGRACE flag. See mysql.h Header cleanup * README: Solaris changes. Info about sample MySQL database. Prefix changed. * Makefile.am, Makefile.in, configure.in, configure: Solaris support. *** NOTICE *** Default prefix has changed to / - configuration files go in /etc by default; Linux libraries go in /lib and the Solaris library goes in /usr/lib. * lookup.h: (HAVE_NSS_H) setDBent/endDBent and NOT setDBent_r/endDBent_r 2002-08-21 Ben Goodwin * nss_mysql.h: Added missing #ifdef HAVE_NSS_COMMON_H around a prototype 2002-08-20 Ben Goodwin * sample/nss_mysql.cfg: Back to %d (well, %u) for numerical formats. * nss_main.c: Removed all NSS API code and spread out to files below. * lookup.c, lookup.h, mysql-grp.c, mysql-pwd.c, mysql-spwd.c: NEW FILES. Moved most of the NSS API code out of nss_main.c to these files. Also introduced working Solaris pieces. * nss_mysql.h: moved pthread stuff here. Added include for nss_dbdefs.h for Solaris (nss_common.h). Added NSS_ARGS macro (ripped from padl's nss-ldap project). New source file (lookup.c) -> function proto's. * Makefile.am, Makefile.in: Several files added to project * mysql.c: _nss_mysql_run_query(): Don't check for valid query anymore * nss_mysql.h, nss_main.c: (const char *) for debug routine's FUNCTION arg 2002-08-19 Ben Goodwin * mysql.c: _nss_mysql_run_query(): Check for valid query ONCE before while loop 2002-08-17 Ben Goodwin * acconfig.h: Added HAVE_LOG_FTP - configure.in sets this value now * nss_config.c: Only use LOG_FTP on systems that have it. * nss_mysql.h: HAVE_NSSWITCH_H should have been HAVE_NSS_COMMON_H. Needed to define NSS_STATUS when HAVE_NSS_COMMON_H is defined. 2002-08-16 Ben Goodwin * mysql.c: Call mysql_escape_string if MYSQL_VERSION_ID < 32300. * configure, configure.in: New method for checking MySQL install location. * config.h.in, nss_mysql.h: No longer need mysql/mysql.h header check. * acinclude.m4: New file. Added mysql-finder function. * aclocal.m4: Re-generated due to new acinclude.m4. * TODO: The usual ... 2002-08-15 Ben Goodwin * nss_mysql.h: Added proto for _nss_mysql_escape_string(). * nss_support.c: Fixed segfault WRT loading an empty PTCHAR in _nss_mysql_liswb() and _nss_mysql_count_tokens(). * samples/sample_database.sql: New file * nss_main.c: Protect getspent from being used by euid != 0. Split #define's up for readability/flexibility. Run arg passed (username/uid/etc.) through MySQL's string cleanser; AS A RESULT ALL STRING FORMATS IN YOUR CONFIG MUST BE %s !!! * mysql.c: Check for euid change. Added _nss_mysql_escape_string(). * configure, configure.in: Version -> 0.3dev. * TODO: Couple new items, prioritization; Got most-needed items done! * README: Typo fix (s/DEBUG_NSS/debug_flags/). Better information RE: ld.so/ldconfig. 2002-08-14 Ben Goodwin * *: CVS tag 0.2; Public release 2002-05-31 Ben Goodwin * sample/nss_mysql.cfg: Added new debug_flags to [global] section * nss_support.c: Moved MySQL state information here. This means that ALL functions share the same state information (unlike before). So it's possible for poor code to step on it's own *ent routines; I found the glibc library uses the same state information for all functions, so I felt comfortable with this move. I may be proven wrong though ... Added a few functions so above state information can be accessed/set outside this source file. set ERANGE outside of find_eol Assume that buffer and structure are not NULL (nss_mysql.c now ensures this) CLOSE_ALL -> CLOSE_LINK; CLOSE_LINK now also CLOSE_RESULT's Removed unnecessary \n's on debug lines Check/set return types using enumerated constants instead of 0's and 1's _nss_mysql_log_error changed to _nss_mysql_log with prio arg removed debug - it's now in nss_mysql.c * nss_mysql.h: Moved syslog.h here Removed unused FSIZ macro Removed unused D_ERROR; renumbered D_* defines Removed unnecessary CLOSE_ALL. CLOSE_LINK must CLOSE_RESULT anyway Removed unnecessary \n's on debug lines Added #defines for some configuration defaults Lots of new comments Added boolean and return types so we check/set returns via enumurated constants instead of 0's and 1's ... Added debug_flags to conf.global Rearranged some stuff for better readability * nss_mysql.c: The ONLY static variable is conf now. All MySQL static information moved to nss_support.c Removed unnecessary \n's on debug lines Added _nss_mysql_log (replaces _nss_mysql_log_error) Set config defaults based on #defines in nss_mysql.h Debug logs to syslog instead of a file now * nss_config.c: Added "debug_flags" to config Removed unnecessary \n's on debug lines _nss_mysql_log_error changed to _nss_mysql_log with priority argument Use enumerated constants for checking/setting return types Set config defaults based on #defines in nss_mysql.h * config.h.in: Added missing HAVE_LOG_AUTHPRIV * acconfig.h, configure, configure.in: Debugging goes to syslog now. No need for DEBUG_FILE * TODO: I actually did a couple things on my list * README: Debugging method changed. Updated dox to reflect that. 2002-05-30 Ben Goodwin * nss_support.c: Syslogging moved to configurable component. Moved _nss_mysql_log_error to nss_mysql.c * nss_mysql.h: Syslogging moved to configurable component * nss_mysql.c: Added function enter/exit debugging. Moved _nss_mysql_log_error from nss_support.c to here * nss_config.c: Added support for syslog facility/priority from config file * acconfig.h, configure, configure.in: Added HAVE_LOG_AUTHPRIV 2002-05-29 Ben Goodwin * sample/nss_mysql.cfg: Added new facility & priority options * nss_config.c: Formatting * configure, configure.in: Added license and revision info. Version updated to 0.2d (in-development) * config.h.in, acconfig.h: Better name for what is now HAVE___FUNC__ * Makefile.am, Makefile.in: License and revision info * TODO: Let everyone know how I plan to take over the world * AUTHORS, ChangeLog, NEWS, README: First-pass * sample/nss_mysql_root.cfg: Added missing [server] entry * Makefile.am, Makefile.in: Additional file to dist * FAQ: New file. * sample/nss_mysql_root.cfg: changed default password 2002-05-28 Ben Goodwin * *: Tag/Release 0.1 * Makefile.am, Makefile.in: Specify files in the sample directory to keep 'make dist' from adding CVS files to the distfile * configure.in, configure: Added CVS revision tag * Makefile.in: This should have been 1.1.1.1; Makefile.am was edited but automake was never run. Oops .. * nss_mysql.h, nss_support.c, nss_structures.c: Added license and rcsid string * nss_mysql.c: Added license and rcsid string. Fixed some formatting issues * nss_config.c: Added license and rcsid string * *: Initial import of nss-mysql Copyright 2024 Bob Proulx Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. libnss-mysql-1.6.1/DEBUGGING000066400000000000000000000107411472655433000154060ustar00rootroot00000000000000Debugging libnss-mysql ====================== Serious problems will be sent to syslog, so check there first. If you're having problems with ProFTPD, check the FAQ. If you've just installed libnss-mysql but it's not working, make sure you've restarted any related daemons (IE ssh or nscd). It's probably best to reboot the system unless you know all the daemons to restart. Rebooting (or manually restarting just about everything) will help prevent strange problems. libnss-mysql has debug code available if you compile is by adding '--enable-debug' to the 'configure' line. Then, you have a choice as to where debug information goes. By default, it will go to the file '/tmp/libnss-mysql-debug.log'. Setting the environment variable 'LIBNSS_MYSQL_DEBUG' will change where debug information goes. 0 = /tmp/libnss-mysql-debug.log 1 = stderr 2 = syslog (prio = debug, same facility compiled with (default=auth)) Note that setting the environment variable will ONLY affect commands spawned from the same process the variable was set in. DO NOT LEAVE DEBUG SUPPORT COMPILED IN WHEN YOU'RE DONE - it's 3 times slower and is a security hazard. Make sure to remove the debug logfile when you're done, too. You can also trace your programs with 'strace' (Linux) or 'truss' (Solaris). This is especially useful if you get *no* debugging information (IE because the library isn't loading). Before we go down that road: - Make sure you've added 'mysql' to /etc/nsswitch.conf. - Note that daemons, including nscd, may not see changes to nsswitch.conf unless they're restarted. - Shut off nscd until you get things working (/etc/init.d/nscd stop). Trace a simple request like 'id username'. Here are command lines that will trace the heck out of everything. They will take some time to complete. The results will be in the file 'trace.out' Linux: strace -e read=all -e write=all -x -o trace.out id cinergi Solaris: truss -u '*' -u '\!libc' -wall -rall -vall -o trace.out id cinergi You'll want to verify that the library gets loaded, so search for 'nss_mysql' and make sure you see that the system attempts to open it: **************************************************************************** open("/usr/lib/nss_mysql.so.1", O_RDONLY) = 3 **************************************************************************** Soon after that line you should see further attempts to open other libraries such as libmysqlclient (if you're using a shared MySQL library). Make SURE the return code is NOT -1 (it is '3' in the example line above) - otherwise the system isn't finding the libraries it needs. After the libraries are opened, you should see the libnss-mysql.cfg file get opened and whatnot. If you get this far, we know that the library is properly installed. You can also check to see what the actual MySQL queries are like. Search for 'S E L' or 'SEL' in the output. Depending on your OS, you'll see something like: **************************************************************************** write(3, 0x00025220, 88) = 88 T\0\0\003 S E L E C T u s e r n a m e , ' x ' , u i d , g i d , g e c o s , h o m e d i r , s h e l l F R O M u s e r s W H E R E u i d = ' 5 0 0 0 ' L I M I T 1 **************************************************************************** or: **************************************************************************** write(3, "T\0\0\0\3SELECT username,\'x\',uid,gid"..., 88) = 88 | 00000 54 00 00 00 03 53 45 4c 45 43 54 20 75 73 65 72 T....SEL ECT user | | 00010 6e 61 6d 65 2c 27 78 27 2c 75 69 64 2c 67 69 64 name,'x' ,uid,gid | | 00020 2c 67 65 63 6f 73 2c 68 6f 6d 65 64 69 72 2c 73 ,gecos,h omedir,s | | 00030 68 65 6c 6c 20 46 52 4f 4d 20 75 73 65 72 73 20 hell FRO M users | | 00040 57 48 45 52 45 20 75 69 64 3d 27 35 30 30 30 27 WHERE ui d='5000' | | 00050 20 4c 49 4d 49 54 20 31 LIMIT 1 | **************************************************************************** Reading a little past that point, you should be able to see the response to your query. You can, of couse, use a debugger like gdb or adb, but I won't get into that here - it can get pretty complex. Feel free to ask for help if you're having problems. I try to help anyone who asks. libnss-mysql-1.6.1/FAQ000066400000000000000000000134061472655433000145230ustar00rootroot00000000000000Q: What is NSS? Q: What is PAM? Q: Which one do I need? One? Both? A: NSS stands for NameService Switch. NSS allows you to implement access to various data using any number of modules. This means that when the operating system wants to look up the user "cinergi", it doesn't have to know how - it calls upon the NSS system to perform the task. In turn, we can now configure NSS to look for users in traditional places like /etc/passwd, NIS, LDAP, and now (using this module), MySQL. The NSS API is the backend for traditional UNIX user lookup routines like 'getpwnam' - providing details such as username, uid, gid, gecos, shell, homedirectory, password, etc. It does *NOT* provide for changing user details. This is where PAM comes in handy. PAM stands for Pluggable Authentication Modules. Like the name suggests, PAM allows you to implement authentication (and data manipulation) using any number of modules. Note that this differs from NSS in that it ONLY provides authentication. It does not allow you to do such things as "finger username", or create files owned by "username". Unlike NSS, however, it can enable users to change their passwords using traditional methods like the 'passwd' command. The libnss_mysql library, like the name suggests, provides an NSS-based solution. Whether you also need PAM depends upon whether you need to enable users to change their password using traditional methods (you could always script a passwd-like utility that performs MySQL commands). PAM also allows more fine-grained setup than NSS does; you can specify which programs use which authentication methods - IE your FTP daemon could authenticate off a different database than SSH does. There are a few other things it can do, too. Try 'man pam' for more information. Most needs should be met using the NSS library. There are a few cases where it may not be enough. There is one MySQL PAM module available at the moment. I don't know if it can be made to work in conjunction this library (I don't really see why not). I may be writing my own module(s) in the future to address better integration as well as the Solaris PAM problem (See the file README). Q: Do I need to edit any PAM configuration files? A: Not likely. See the above question. Q: Can I get the system to automatically create a user's homedirectory? A: Yes. There's a PAM module, pam_mkhomedir, that allows just this. I know that on RedHat linux, you can simply add the following line to your /etc/pam.d/system-auth file: session optional /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022 Note that systems running ssh in privilege-separation mode (default in RedHat 8) will *NOT* be able to create homedirectories when logging in via ssh. You'll have to shut off priv-sep mode in /etc/ssh/sshd_config and restart ssh. There's no other known workaround at this time. Other programs that drop root privs before calling PAM/session (I've seen 'su' do this) will have similar troubles. Q: Are other databases (IE hosts, netgroup, automount, aliases, etc) supported? A: Not at this time. I plan to support these in the future, however. Q: I have a lot of open MySQL processes - why? A: libnss-mysql maintains a persistant connection - it's the only sane way to implement this library without a separate daemon. If you've got too many open processes, I recommend reducing the default (28800 seconds - 8 hours) timeout in MySQL to something like 60 seconds. You can do this by editing/creating /etc/my.cnf and adding the following: [mysqld] set-variable=wait_timeout=60 Q: Why isn't it working? A: See the file 'DEBUGGING' provided with the distribution. Q: Why doesn't ProFTPD see my accounts in the database? A: You must set 'PersistentPasswd' to 'Off' in your proftpd configuration. You may also need to set your PAM config to use pam_unix.so. Q: Why do I get the following message when I try to use 'passwd' on Solaris? "Supported configurations for passwd management are as follows" ... A: Sun chose to write their unix PAM module to only allow a very restrictive configuration in /etc/nsswitch.conf. You must now specify '-r files' on the 'passwd' command-line to manipulate the password file. For example: passwd -r files username I know this sucks, so figuring out a better workaround is on my TODO list. Q: Why do I get the following message when compiling on Solaris? Undefined first referenced symbol in file (some-symbol-here) /usr/local/lib/mysql/libmysqlclient.so A: There are a number of reasons for this, but basically you either need to: a) change the linker you're using b) add a library to the link line - To change the linker, simply set the environment variable 'LD' to the full path to the linker you want to use before running 'configure. Usually you'll need to download and install the GNU 'ld' from the GNU binutils package. - To use the same linker but add the missing library, locate your libgcc.a file from your GCC installation, and set the environment variable 'LDFLAGS' to the following before running 'configure': -L/directory/containing/libgcc.a -lgcc Q: I'm getting segfaults on Solaris; truss indicates a crash shortly after libz can't be found. A: If you're using Solaris 8+, this shouldn't be a problem as libz is included with the OS. On earlier versions, you've probably installed it into /usr/local/lib or somewhere in /opt. You need to make sure this directory is included in the linker search PRIOR to building libnss-mysql. If libz is installed in /usr/local/lib, you'd need to do the following: sh -c "LDFLAGS=-R/usr/local/lib ./configure" libnss-mysql-1.6.1/INSTALL000066400000000000000000000363321472655433000152250ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. libnss-mysql-1.6.1/Makefile.am000066400000000000000000000026651472655433000162320ustar00rootroot00000000000000# Copyright 2002 Ben Goodwin # Copyright 2024 Bob Proulx # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = foreign SUBDIRS = src EXTRA_DIST = FAQ UPGRADING DEBUGGING libnss-mysql.spec src/*.sym \ sample/README sample/complex/*.* sample/minimal/*.* \ sample/linux/*.* sample/solaris/*.* sample/freebsd/*.* install-data-hook: @if test ! -f ${DESTDIR}${sysconfdir}/libnss-mysql.cfg; then \ ${mkinstalldirs} ${DESTDIR}${sysconfdir}; \ ${INSTALL_DATA} ${srcdir}/sample/@OS@/libnss-mysql.cfg \ ${DESTDIR}${sysconfdir}/libnss-mysql.cfg; \ fi @if test ! -f ${DESTDIR}${sysconfdir}/libnss-mysql-root.cfg; then \ ${mkinstalldirs} ${DESTDIR}${sysconfdir}; \ ${INSTALL_DATA} -m 600 ${srcdir}/sample/@OS@/libnss-mysql-root.cfg \ ${DESTDIR}${sysconfdir}/libnss-mysql-root.cfg; \ fi libnss-mysql-1.6.1/NEWS000066400000000000000000000021301472655433000146600ustar00rootroot00000000000000Thu, 12 Dec 2024 21:29:46 +0900 libnss-mysql 1.6.1 released Thu, 12 Sep 2024 22:12:10 -0600 libnss-mysql 1.6.0 released September 3, 2005 libnss-mysql 1.5 released January 30, 2005 libnss-mysql 1.4 released November 13, 2004 libnss-mysql 1.3 released March 28, 2004 libnss-mysql 1.2 released March 6, 2004 libnss-mysql 1.1 released July 12, 2003 libnss-mysql 1.0 released June 18, 2003 libnss-mysql 0.9 released January 25, 2003 libnss-mysql 0.8 released December 14, 2002 libnss-mysql 0.7a released December 4, 2002 libnss-mysql 0.7 released November 5, 2002 libnss-mysql 0.6 released October 23, 2002 libnss-mysql 0.5 released September 21, 2002 libnss-mysql 0.4 released August 22, 2002 libnss-mysql 0.3 released August 14, 2002 libnss-mysql 0.2 released Copyright 2024 Bob Proulx Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. libnss-mysql-1.6.1/README000066400000000000000000000057011472655433000150500ustar00rootroot00000000000000 MariaDB/MySQL for NSS systems ============================= libnss-mysql is a Network Security Services library module interfacing user account information with a MariaDB/MySQL database. This allows keeping user account data in an SQL database authenticating user accounts on a system. This project is a continuation of the work of Ben Goodwin . The last commit in the version history from Ben was 2006. It is now 2024 some 18 years later. That this code held up so well for so many years is a testament to its quality and maturity. The motivation for code maintenance now is that MariaDB has changed interface specification and modifications are needed in order to keep this code working on current systems. Building from Source ==================== Building from a git source clone acts as a developer requires all three of the autotools to be installed as well as the C compiler and essential build environment. git clone git://git.savannah.gnu.org/administration/libnss-mysql.git cd libnss-mysql ./bootstrap ./configure make Building from a distribution tar bundle does not require any of the developer autotools and only requires the C compiler. This may be more suitable for non-developers. tar xzf libnss-mysql-X.Y.Z.tar.gz cd libnss-mysql ./configure make Configuration and Use ===================== Sample configurations for these files are available. Install a suitable version for your system environment. + /etc/libnss-mysql.cfg + /etc/libnss-mysql-root.cfg The /etc/nsswitch.conf is configured to use this library by adding "mysql" to the query sources fields. passwd: files mysql shadow: files mysql group: files mysql GNU Savannah Community ====================== You can communicate with me Bob Proulx and the GNU Savannah Hackers who are maintaining this version of the sofware by emailing the public mailing list. Program License =============== Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . File License ============ Copyright 2024 Bob Proulx Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. libnss-mysql-1.6.1/THANKS000066400000000000000000000004051472655433000150770ustar00rootroot00000000000000I'd like to thank: Len Rose Provided me with a Solaris/sparc testbed Luke Howard For unknowingly providing NSS reference material (nss_ldap) Clement Laforet For help on the FreeBSD port libnss-mysql-1.6.1/UPGRADING000066400000000000000000000143321472655433000154330ustar00rootroot00000000000000*** In all cases, you should at *least* restart any daemons that look up *** users, such as ssh, nscd, cron, etc. It's best if you simply reboot *** unless you know the complete list of daemons to restart. *** On Linux, try (as root) "lsof /lib/libnss_mysql.so" 1.4 -> 1.5 * This is a maintenance release. No changes are needed on your part. 1.3 -> 1.4 * No changes are *required* but the following options have been removed from libnss-mysql.cfg in favor of using "my.cnf" options: timeout, compress, initcmd. Specify them in either the [client] section or a new [libnss-mysql] section in my.cnf 1.2 -> 1.3 * No changes are *required* but the [section] names in the config files are now meaningless - remove them to avoid additional parsing overhead * You may want to take advantage of line continuation in the configuration files. See the samples for examples. 1.1 -> 1.2 * This is a maintenance release. No changes are needed on your part. 1.0 -> 1.1 * This is a maintenance release. No changes are needed on your part. If compiling from source, you should note that the new 'configure' option '--with-mysql=DIR' which replaces '--with-mysql-inc' and '--with-mysql-lib' 0.9 -> 1.0 * If you're running anything other than Linux, you *MUST* update your /etc/libnss-mysql.cfg file! Each operating system now has their own independant password fields. You'll need to add some columns to your queries; Solaris adds 'age' and 'comment'. This is the first version that supports FreeBSD so there's no upgrade concerns here. See the sample configs for details on where to put the new columns. 0.8 -> 0.9 * IMPORTANT: The filenames for the configuration files has changed. There's also been a slight change inside the configuration files. It's MANDATORY that you follow these upgrade procedures. * /etc/nss_mysql.cfg is now /etc/libnss-mysql.cfg * /etc/nss_mysql_root.cfg is now /etc/libnss-mysql-root.cfg * Only one server can be defined in your configuration files. Delete any [secondary] sections and rename your [primary] section to [server]. The [global] section no longer has any meaning. Remove it and any entries (IE 'retry') it has. See the sample configuration files for more information * A "make install" and RPM upgrades will NOT rename your existing configuration files. They will install new default ones under their new names. Overwrite them with your old files. 0.7a -> 0.8 * The /etc/my.cnf section, [libnss_mysql], is no longer supported. Use the new options in /etc/nss_mysql.cfg instead (see below). * The "port" and "socket" options are no longer required options in /etc/nss_mysql.cfg. Remove them from your config to use your MySQL client defaults. * New options in /etc/nss_mysql.cfg (that go in the [primary] and/or [secondary] sections): Option Values Default Description ----------------------------------------------------------------- ssl 0|1 0 Use SSL (MySQL 4.x only)? timeout 0+ 3 Connect timeout in seconds compress 0|1 0 Use MySQL compressed protocol? initcmd string "" Execute this statement at connect time 0.7 -> 0.7a This is a maintenance release. No changes are needed on your part. 0.6 -> 0.7 No changes are needed on your part. Simply install the new version! 0.5 -> 0.6 No changes are needed on your part. Simply install the new version! 0.4 -> 0.5 NOTE: This included a lot of redesign/rewriting. It's very possible I broke something that used to work. Please report bugs to me. Debugging support has been removed - for now. The config option 'debug_flags' is now ignored. The syslog config options, 'facility' and 'priority' have been removed. Specify the facility at build time using the --with-log-facility option to the 'configure' program. Not that it really eats that many CPU cycles, but I recommend deleting those 3 configuration options from your config file. Since this version supports initgroups, the design of the group database needs to be altered. You *must* alter your database/data in order for groups to work. If you're not using groups, then you can stop reading. * First, alter your database such that you have a way to associate gids with a username. Check the sample database for the 'grouplist' table to see what I mean. * Second, populate this new table with the appropriate data. * Third, REMOVE the fourth column in your SELECT statements for the getgr* configuration entries (getgrnam, getgrgid, & getgrent) * Fourth, add two new configuration entries for 'memsbygid' and 'gidsbymem'. See the new sample configuration file for examples. * Fifth, when you're comfortable you've converted the data, you can remove the fourth column mentioned above from your database - it's no longer needed. Two select calls will be made when retrieving group information - one for the getgr* call, and another to fetch the list of usernames that are members of that group (using the memsbygid call). The gidsbymem call is used for initgroups support. This allows the system to find out all the groups a user is a member of *much* more efficiently. In fact, some programs ONLY do it this way, and weren't seeing the supplemental groups users were in - until now. 0.3 -> 0.4 First, you should note that the code currently supports only TWO servers. That's easily changed, and I'll probably up it to a default of THREE later, but 0.4 is released with support for TWO. That said, the [server] section in BOTH of your config files must be changed to either [primary] or [secondary] as appropriate. See the sample config files if it's not clear. 0.2 -> 0.3 Simply change any '%d' you have in your configs to '%u' Copyright 2024 Bob Proulx Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. libnss-mysql-1.6.1/acinclude.m4000066400000000000000000000042361472655433000163630ustar00rootroot00000000000000dnl Copyright 2002 Ben Goodwin dnl Copyright 2024 Bob Proulx dnl dnl This program is free software; you can redistribute it and/or dnl modify it under the terms of the GNU General Public License dnl as published by the Free Software Foundation; either version 2 dnl of the License, or (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, see . AC_DEFUN([FIND_MYSQL],[ baselist="$with_mysql \ /usr \ /usr/local \ /usr/local/mysql \ /opt/local \ /opt/local/mysql" AC_MSG_CHECKING([for MySQL headers]) for f in $baselist; do if test -f "$f/include/mysql/mysql.h" then MYSQL_INC_DIR="$f/include/mysql" break fi if test -f "$f/include/mysql.h" then MYSQL_INC_DIR="$f/include" break fi done if test -n "$MYSQL_INC_DIR" then AC_MSG_RESULT([$MYSQL_INC_DIR]) CPPFLAGS="-I $MYSQL_INC_DIR $CPPFLAGS" else AC_MSG_ERROR([Cannot locate MySQL headers. Try using --with-mysql=DIR]) fi AC_MSG_CHECKING([for MySQL libraries]) dnl Check for share first, then static, such that static dnl will take precedence for f in $baselist; do if test -f "$f/lib/libmysqlclient.so" then MYSQL_LIB_DIR="$f/lib" break fi if test -f "$f/lib/mysql/libmysqlclient.so" then MYSQL_LIB_DIR="$f/lib/mysql" break fi done for f in $baselist; do if test -f "$f/lib/libmysqlclient.a" then MYSQL_LIB_DIR="$f/lib" break fi if test -f "$f/lib/mysql/libmysqlclient.a" then MYSQL_LIB_DIR="$f/lib/mysql" break fi done if test -n "$MYSQL_LIB_DIR" then AC_MSG_RESULT([$MYSQL_LIB_DIR]) LDFLAGS="-L$MYSQL_LIB_DIR $LDFLAGS" else AC_MSG_ERROR([Cannot locate MySQL libraries. Try using --with-mysql=DIR]) fi ]) libnss-mysql-1.6.1/bootstrap000077500000000000000000000025611472655433000161340ustar00rootroot00000000000000#!/bin/sh -x # Copyright 2024 Bob Proulx # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, see . # Since this bootstrap is a maintainer tool we assume that the user # running this script has the maintainer tools available. Force # removal of generated files and then bring everything up to date. for prog in autoconf automake libtoolize; do if ! ($prog --version) >/dev/null 2>&1; then echo "Error: Missing: $prog" 1>&2 exit 1 fi done # Remove generated files to force a complete rebuild. rm -f aclocal.m4 config.log config.status config.h stamp-h* rm -f Makefile Makefile.in configure rm -f src/Makefile src/Makefile.in rm -f t/Makefile t/Makefile.in rm -rf build-aux m4 # Bring the build framework up to date. mkdir -p build-aux m4 autoreconf --install # --verbose libnss-mysql-1.6.1/configure.ac000066400000000000000000000055261472655433000164630ustar00rootroot00000000000000dnl Copyright 2002 Ben Goodwin dnl Copyright 2024 Bob Proulx dnl dnl This program is free software; you can redistribute it and/or dnl modify it under the terms of the GNU General Public License dnl as published by the Free Software Foundation; either version 2 dnl of the License, or (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, see . AC_PREREQ([2.59]) AC_INIT([libnss-mysql],[1.6.1],[bob@proulx.com]) AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIRS([m4]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([-Wall]) AC_PROG_CC AM_PROG_AR case "$target_os" in linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" LIBVER=2 OS=linux RENAME=false test "$prefix" = "NONE" && prefix= ;; solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" LIBVER=1 OS=solaris RENAME=true test "$prefix" = "NONE" && prefix= && libdir=/usr/lib ;; freebsd*) CPPFLAGS="$CPPFLAGS -DPIC -D_REENTRANT" LIBVER=1 OS=freebsd RENAME=true test "$prefix" = "NONE" && prefix= && libdir=/usr/lib ;; *) OS=unknown ;; esac AM_CONDITIONAL(RENAME, test "$RENAME" = "true") AC_CACHE_CHECK([whether the linker accepts -znodelete], [nss_mysql_cv_cc_znodelete], [ SAVELIBS=$LIBS LIBS="-Wl,-znodelete $SAVELIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[nss_mysql_cv_cc_znodelete=yes],[nss_mysql_cv_cc_znodelete=no]) LIBS=$SAVELIBS]) if test $nss_mysql_cv_cc_znodelete = "yes"; then LIBS="-Wl,-znodelete $SAVELIBS" fi AC_SUBST(LIBVER) AC_SUBST(OS) AC_CHECK_LIB(socket, getsockname) AC_CHECK_LIB(nsl, gethostbyname) AC_CHECK_LIB(m, floor) AC_CHECK_LIB(dl, dlsym) AC_CHECK_LIB(z, compress) AC_CHECK_LIB(mysqlclient, main, , [AC_MSG_ERROR([Unable find a functioning MySQL library])]) CFLAGS="$CFLAGS $(mysql_config --cflags)" LDFLAGS="$LDFLAGS $(mysql_config --libs)" AC_CHECK_HEADER([mysql.h], , [AC_MSG_ERROR([Unable to find mysql.h])]) AC_CHECK_HEADERS([syslog.h stdint.h nss.h nss_common.h shadow.h]) AC_C_CONST AC_TYPE_UID_T AC_TYPE_SIZE_T AC_CHECK_TYPES([socklen_t], , , [ #include #include ]) EXPANDED_SYSCONFDIR=`eval echo $sysconfdir` AC_DEFINE_UNQUOTED([MAINCFG], "$EXPANDED_SYSCONFDIR/libnss-mysql.cfg", [Main config file]) AC_DEFINE_UNQUOTED([ROOTCFG],"$EXPANDED_SYSCONFDIR/libnss-mysql-root.cfg", [Root config file]) LT_INIT([disable-static]) AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT libnss-mysql-1.6.1/libnss-mysql.spec000066400000000000000000000044021472655433000174760ustar00rootroot00000000000000Summary: NSS library for MySQL. Name: libnss-mysql Version: 1.6.1 Release: 1 Source0: https://git.savannah.gnu.org/cgit/administration/libnss-mysql.git/snapshot/libnss-mysql-%{version}.tar.gz URL: https://git.savannah.gnu.org/cgit/administration/libnss-mysql.git/ License: GPL Group: System Environment/Base BuildRoot: %{_tmppath}/%{name}-root %description Store your UNIX user accounts in MySQL %prep %setup -q -a 0 %build ./configure make %install [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/{etc,lib} make DESTDIR=$RPM_BUILD_ROOT install %clean [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %attr(0755,root,root) /lib/*.so* %attr(0644,root,root) %config(noreplace) /etc/libnss-mysql.cfg %attr(0600,root,root) %config(noreplace) /etc/libnss-mysql-root.cfg %doc README ChangeLog AUTHORS THANKS NEWS COPYING FAQ DEBUGGING UPGRADING TODO %doc sample %changelog * Thu Dec 12 2024 Jing Luo 1.6.1-1 - Non-maintainer upload - Update to 1.6.1 * Thu Sep 12 2024 Bob Proulx 1.6.0-1 - Update to 1.6.0 * Sat Sep 3 2005 Ben Goodwin 1.5-1 - Update to 1.5 * Sat Apr 10 2004 Ben Goodwin 1.4-1 - Update to 1.4 * Sat Apr 10 2004 Ben Goodwin 1.3-1 - Update to 1.3 - Remove manual static re-link (1.3 relieves the need for this) - doc += TODO * Sun Mar 28 2004 Ben Goodwin 1.2-1 - Update to 1.2 * Tue Mar 02 2004 Ben Goodwin 1.1-1 - s#exports.linux#.libs/libnss_mysql.ver# - Oops, libs/*.o not *.lo * Sat Jul 12 2003 Ben Goodwin 1.0-2 - Link with version script * Sat Jul 12 2003 Ben Goodwin 1.0-1 - Update to 1.0 - Use *.lo instead of individual .lo names in re-link - Removed -Bgroup and --allow-shlib-undefined linker options * Thu Jun 19 2003 Ben Goodwin 0.9-2 - Added ugly hack to relink some libraries static. It will probably break rpm builds on some hosts ... * Wed Jun 18 2003 Ben Goodwin 0.9-1 - Update to 0.9 * Sun Dec 29 2002 Ben Goodwin 0.8-1 - Initial version libnss-mysql-1.6.1/sample/000077500000000000000000000000001472655433000154465ustar00rootroot00000000000000libnss-mysql-1.6.1/sample/README000066400000000000000000000010121472655433000163200ustar00rootroot00000000000000This directory contains default configurations for the operating systems supported, as well as two additional examples illustrating different ways to set up your database under Linux (THEY WILL NOT WORK UNDER ANOTHER OS WITHOUT MODIFICATION). These examples will create a user 'cinergi' with a password of 'cinergi'. Assuming all goes well you should be able to log in as cinergi. Remember, since you can specify the MySQL queries directly in the configuration, you can set up your database just about any way you like! libnss-mysql-1.6.1/sample/complex/000077500000000000000000000000001472655433000171155ustar00rootroot00000000000000libnss-mysql-1.6.1/sample/complex/libnss-mysql-root.cfg000066400000000000000000000000521472655433000232110ustar00rootroot00000000000000username nss-root password rootpass libnss-mysql-1.6.1/sample/complex/libnss-mysql.cfg000066400000000000000000000035071472655433000222400ustar00rootroot00000000000000getpwnam SELECT LOWER(services.username),'x',uid,gid, \ CONCAT_WS(' ',first_name,middle_initial,last_name), \ service_defs.homedir,service_defs.shell \ FROM services \ LEFT JOIN customer USING(cust_num) \ LEFT JOIN service_defs ON services.product=service_defs.name \ WHERE services.username='%1$s' AND \ expire > CURDATE() AND \ suspended='N' \ LIMIT 1 getpwuid SELECT LOWER(services.username),'x',uid,gid, \ CONCAT_WS(" ",first_name,middle_initial,last_name), \ service_defs.homedir,service_defs.shell \ FROM services \ LEFT JOIN customer USING(cust_num) \ LEFT JOIN service_defs ON services.product=service_defs.name \ WHERE services.uid='%1$u' AND \ expire > CURDATE() AND \ suspended='N' \ LIMIT 1 getspnam SELECT LOWER(username),password,1,0,99999,0,0,-1,0 \ FROM services \ WHERE username='%1$s' AND \ expire > CURDATE() AND \ suspended='N' \ LIMIT 1 getpwent SELECT LOWER(services.username),'x',uid,gid, \ CONCAT_WS(" ",first_name,middle_initial,last_name), \ service_defs.homedir,service_defs.shell \ FROM services \ LEFT JOIN customer USING(cust_num) \ LEFT JOIN service_defs ON services.product=service_defs.name \ WHERE expire > CURDATE() AND \ suspended='N' getspent SELECT LOWER(username),password,1,0,99999,0,0,-1,0 \ FROM services \ WHERE expire > CURDATE() AND \ suspended='N' host localhost database auth username nss-user password userpass libnss-mysql-1.6.1/sample/complex/sample_database.sql000066400000000000000000000077161472655433000227560ustar00rootroot00000000000000# # Complex sample libnss-mysql database # # sample_database.sql revision compatible libnss-mysql versions # ------------------------------------------------------------------- # 1.1 0.2+ # # Use 'mysql -u root -p < sample_database.sql' to load this example into MySQL # # This particular example is actually a modified version of the database # in use at the ISP I originally developed this for. It is designed this # way in order to be able to define one "person" and have that one "person" # have multiple "services" (accounts) without duplicating the "person" # over and over again. Services are linked to customers via the cust_num # field. The "service_defs" table enables you to define different # homedir and shell structures depending on the service ("product" in # their "services" entry) they purchased. This was useful to separate # dialup users and email-only users as I configured cistron radius to # disallow users with a certain shell. # Note that I do not make use of the shadow 'expire' field - instead, when # a user 'expires' the stop showing up in the system, as if deleted. # Setting the 'suspend' field for a user will do the same thing. I designed # it this way because, back when I implemented all of this, a lot of # software did not pay attention to the shadow expire field. create database auth; use auth; # The tables ... CREATE TABLE customer ( cust_num int(11) NOT NULL auto_increment, first_name varchar(25) NOT NULL default '', last_name varchar(25) NOT NULL default '', middle_initial char(1) default NULL, company varchar(50) default NULL, address_one varchar(35) default NULL, address_two varchar(35) default NULL, city varchar(25) default NULL, state char(2) default NULL, zip varchar(10) default NULL, home_phone varchar(20) default NULL, work_phone varchar(20) default NULL, notes text, signupdate date NOT NULL default '0000-00-00', PRIMARY KEY (cust_num) ) TYPE=MyISAM; CREATE TABLE service_defs ( name varchar(25) NOT NULL default '', shell varchar(255) NOT NULL default '/bin/date', homedir varchar(255) NOT NULL default '/tmp', PRIMARY KEY (name) ) TYPE=MyISAM; CREATE TABLE services ( cust_num int(11) NOT NULL default '0', username varchar(16) NOT NULL default '', uid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '100', password varchar(16) NOT NULL default '', product varchar(25) default NULL, created date NOT NULL default '0000-00-00', expire date NOT NULL default '0000-00-00', suspended set('Y','N') NOT NULL default 'N', notes text, PRIMARY KEY (uid), UNIQUE KEY username (username), KEY cust_num (cust_num) ) TYPE=MyISAM AUTO_INCREMENT=5000; # The data ... INSERT INTO customer (first_name,last_name,middle_initial) VALUES ('Benjamin','Goodwin','C'); INSERT INTO services (cust_num,username,password,product,created,expire) VALUES (LAST_INSERT_ID(),'cinergi',ENCRYPT('cinergi'),'Basic Dialup',NOW(), DATE_ADD(NOW(), INTERVAL 1 YEAR)); INSERT INTO service_defs (name) VALUES ('Basic Dialup'); # The permissions ... GRANT USAGE ON *.* TO `nss-root`@`localhost` IDENTIFIED BY 'rootpass'; GRANT USAGE ON *.* TO `nss-user`@`localhost` IDENTIFIED BY 'userpass'; GRANT Select (`cust_num`, `uid`, `gid`, `password`, `product`, `expire`, `suspended`, `username`) ON `auth`.`services` TO 'nss-root'@'localhost'; GRANT Select (`cust_num`, `first_name`, `last_name`, `middle_initial`) ON `auth`.`customer` TO 'nss-root'@'localhost'; GRANT Select (`name`,`shell`,`homedir`) ON `auth`.`service_defs` TO 'nss-root'@'localhost'; GRANT Select (`cust_num`, `uid`, `gid`, `product`, `expire`, `suspended`, `username`) ON `auth`.`services` TO 'nss-user'@'localhost'; GRANT Select (`cust_num`, `first_name`, `last_name`, `middle_initial`) ON `auth`.`customer` TO 'nss-user'@'localhost'; GRANT Select (`name`,`shell`,`homedir`) ON `auth`.`service_defs` TO 'nss-user'@'localhost'; libnss-mysql-1.6.1/sample/freebsd/000077500000000000000000000000001472655433000170605ustar00rootroot00000000000000libnss-mysql-1.6.1/sample/freebsd/libnss-mysql-root.cfg000066400000000000000000000010271472655433000231570ustar00rootroot00000000000000getpwnam SELECT username,password,uid,gid,pwchange,class,gecos,homedir, \ shell,expire \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwuid SELECT username,password,uid,gid,pwchange,class,gecos,homedir, \ shell,expire \ FROM users \ WHERE uid='%1$u' \ LIMIT 1 getpwent SELECT username,password,uid,gid,pwchange,class,gecos,homedir, \ shell,expire \ FROM users username nss-root password rootpass libnss-mysql-1.6.1/sample/freebsd/libnss-mysql.cfg000066400000000000000000000021001472655433000221670ustar00rootroot00000000000000getpwnam SELECT username,'*',uid,gid,pwchange,class,gecos,homedir,shell, \ expire \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwuid SELECT username,'*',uid,gid,pwchange,class,gecos,homedir,shell, \ expire \ FROM users \ WHERE uid='%1$u' \ LIMIT 1 getpwent SELECT username,'*',uid,gid,pwchange,class,gecos,homedir,shell, \ expire \ FROM users getgrnam SELECT name,password,gid \ FROM groups \ WHERE name='%1$s' \ LIMIT 1 getgrgid SELECT name,password,gid \ FROM groups \ WHERE gid='%1$u' \ LIMIT 1 getgrent SELECT name,password,gid \ FROM groups memsbygid SELECT username \ FROM grouplist \ WHERE gid='%1$u' gidsbymem SELECT gid \ FROM grouplist \ WHERE username='%1$s' host localhost database auth username nss-user password userpass #socket /var/lib/mysql/mysql.sock #port 3306 libnss-mysql-1.6.1/sample/freebsd/sample_database.sql000066400000000000000000000056171472655433000227170ustar00rootroot00000000000000# # THIS DATABASE IS INTENDED FOR FreeBSD # # Use 'mysql -u root -p < sample_database.sql' to load this example into your # MySQL server. # This example will: # 1) create a database called 'auth' # 2) add three tables: 'users', 'groups' and 'grouplist' # 3) add some data to each table # 4) create two MySQL users ('nss-user' and 'nss-root') with appropriate # SELECT privs. # # With a properly-functioning libnss-mysql, you should be able to log into # the system as 'cinergi' with a password of 'cinergi'. 'cinergi' should be # a member of the group 'foobaz' as well. # # This is intended as an *example* and is perhaps not the best use of # datatypes, space/size, data normalization, etc. # create database auth; use auth; # The tables ... CREATE TABLE groups ( name varchar(16) NOT NULL default '', password varchar(34) NOT NULL default 'x', gid int(11) NOT NULL auto_increment, PRIMARY KEY (gid) ) TYPE=MyISAM AUTO_INCREMENT=5000; CREATE TABLE grouplist ( rowid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '0', username char(16) NOT NULL default '', PRIMARY KEY (rowid) ) TYPE=MyISAM; CREATE TABLE users ( username varchar(16) NOT NULL default '', uid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '5000', pwchange int(11) NOT NULL default '0', class varchar(64) NOT NULL default '', gecos varchar(128) NOT NULL default '', homedir varchar(255) NOT NULL default '', shell varchar(64) NOT NULL default '/bin/sh', password varchar(34) NOT NULL default 'x', expire bigint(20) NOT NULL default '0', PRIMARY KEY (uid), UNIQUE KEY username (username), KEY uid (uid) ) TYPE=MyISAM AUTO_INCREMENT=5000; # The data ... INSERT INTO users (username,gecos,homedir,password) VALUES ('cinergi', 'Ben Goodwin', '/home/cinergi', ENCRYPT('cinergi')); INSERT INTO groups (name) VALUES ('foobaz'); INSERT INTO grouplist (gid,username) VALUES (5000,'cinergi'); # The permissions ... GRANT USAGE ON *.* TO `nss-root`@`localhost` IDENTIFIED BY 'rootpass'; GRANT USAGE ON *.* TO `nss-user`@`localhost` IDENTIFIED BY 'userpass'; GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`, `pwchange`,`class`,`expire`) ON `auth`.`users` TO 'nss-user'@'localhost'; GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`, `password`, `pwchange`,`class`,`expire`) ON `auth`.`users` TO 'nss-root'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-user'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-root'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-user'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-root'@'localhost'; libnss-mysql-1.6.1/sample/linux/000077500000000000000000000000001472655433000166055ustar00rootroot00000000000000libnss-mysql-1.6.1/sample/linux/libnss-mysql-root.cfg000066400000000000000000000000521472655433000227010ustar00rootroot00000000000000username nss-root password rootpass libnss-mysql-1.6.1/sample/linux/libnss-mysql.cfg000066400000000000000000000023231472655433000217230ustar00rootroot00000000000000getpwnam SELECT username,'x',uid,gid,gecos,homedir,shell \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwuid SELECT username,'x',uid,gid,gecos,homedir,shell \ FROM users \ WHERE uid='%1$u' \ LIMIT 1 getspnam SELECT username,password,lstchg,min,max,warn,inact,expire,flag \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwent SELECT username,'x',uid,gid,gecos,homedir,shell \ FROM users getspent SELECT username,password,lstchg,min,max,warn,inact,expire,flag \ FROM users getgrnam SELECT name,password,gid \ FROM groups \ WHERE name='%1$s' \ LIMIT 1 getgrgid SELECT name,password,gid \ FROM groups \ WHERE gid='%1$u' \ LIMIT 1 getgrent SELECT name,password,gid \ FROM groups memsbygid SELECT username \ FROM grouplist \ WHERE gid='%1$u' gidsbymem SELECT gid \ FROM grouplist \ WHERE username='%1$s' host localhost database auth username nss-user password userpass #socket /var/lib/mysql/mysql.sock #port 3306 libnss-mysql-1.6.1/sample/linux/sample_database.sql000066400000000000000000000060571472655433000224430ustar00rootroot00000000000000# # THIS DATABASE IS INTENDED FOR Linux # # Use 'mysql -u root -p < sample_database.sql' to load this example into your # MySQL server. # This example will: # 1) create a database called 'auth' # 2) add three tables: 'users', 'groups' and 'grouplist' # 3) add some data to each table # 4) create two MySQL users ('nss-user' and 'nss-root') with appropriate # SELECT privs. # # With a properly-functioning libnss-mysql, you should be able to log into # the system as 'cinergi' with a password of 'cinergi'. 'cinergi' should be # a member of the group 'foobaz' as well. # # This is intended as an *example* and is perhaps not the best use of # datatypes, space/size, data normalization, etc. # create database auth; use auth; # The tables ... CREATE TABLE groups ( name varchar(16) NOT NULL default '', password varchar(34) NOT NULL default 'x', gid int(11) NOT NULL auto_increment, PRIMARY KEY (gid) ) TYPE=MyISAM AUTO_INCREMENT=5000; CREATE TABLE grouplist ( rowid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '0', username char(16) NOT NULL default '', PRIMARY KEY (rowid) ) TYPE=MyISAM; CREATE TABLE users ( username varchar(16) NOT NULL default '', uid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '5000', gecos varchar(128) NOT NULL default '', homedir varchar(255) NOT NULL default '', shell varchar(64) NOT NULL default '/bin/bash', password varchar(34) NOT NULL default 'x', lstchg bigint(20) NOT NULL default '1', min bigint(20) NOT NULL default '0', max bigint(20) NOT NULL default '99999', warn bigint(20) NOT NULL default '0', inact bigint(20) NOT NULL default '0', expire bigint(20) NOT NULL default '-1', flag bigint(20) unsigned NOT NULL default '0', PRIMARY KEY (uid), UNIQUE KEY username (username), KEY uid (uid) ) TYPE=MyISAM AUTO_INCREMENT=5000; # The data ... INSERT INTO users (username,gecos,homedir,password) VALUES ('cinergi', 'Ben Goodwin', '/home/cinergi', ENCRYPT('cinergi')); INSERT INTO groups (name) VALUES ('foobaz'); INSERT INTO grouplist (gid,username) VALUES (5000,'cinergi'); # The permissions ... GRANT USAGE ON *.* TO `nss-root`@`localhost` IDENTIFIED BY 'rootpass'; GRANT USAGE ON *.* TO `nss-user`@`localhost` IDENTIFIED BY 'userpass'; GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`, `password`, `lstchg`, `min`, `max`, `warn`, `inact`, `expire`, `flag`) ON `auth`.`users` TO 'nss-root'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-root'@'localhost'; GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`) ON `auth`.`users` TO 'nss-user'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-user'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-user'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-root'@'localhost'; libnss-mysql-1.6.1/sample/minimal/000077500000000000000000000000001472655433000170745ustar00rootroot00000000000000libnss-mysql-1.6.1/sample/minimal/libnss-mysql-root.cfg000066400000000000000000000000521472655433000231700ustar00rootroot00000000000000username nss-root password rootpass libnss-mysql-1.6.1/sample/minimal/libnss-mysql.cfg000066400000000000000000000024701472655433000222150ustar00rootroot00000000000000getpwnam SELECT username,'x',uid,'5000','MySQL User', \ CONCAT('/home/',username),'/bin/bash' \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwuid SELECT username,'x',uid,'5000','MySQL User', \ CONCAT('/home/',username),'/bin/bash' \ FROM users \ WHERE uid='%1$u' \ LIMIT 1 getspnam SELECT username,password,'1','0','99999','0','0','-1','0' \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwent SELECT username,'x',uid,'5000','MySQL User', \ CONCAT('/home/',username),'/bin/bash' \ FROM users getspent SELECT username,password,'1','0','99999','0','0','-1','0' \ FROM users getgrnam SELECT name,password,gid \ FROM groups \ WHERE name='%1$s' \ LIMIT 1 getgrgid SELECT name,password,gid \ FROM groups \ WHERE gid='%1$u' \ LIMIT 1 getgrent SELECT name,password,gid \ FROM groups memsbygid SELECT username \ FROM grouplist \ WHERE gid='%1$u' gidsbymem SELECT gid \ FROM grouplist \ WHERE username='%1$s' host localhost database auth username nss-user password userpass libnss-mysql-1.6.1/sample/minimal/sample_database.sql000066400000000000000000000054001472655433000227210ustar00rootroot00000000000000# # Minimalist sample libnss-mysql database # # sample_database.sql revision compatible libnss-mysql versions # ------------------------------------------------------------------- # 1.1 0.5+ # # Use 'mysql -u root -p < sample_database.sql' to load this example into MySQL # # This particular example stores as little as possible in the MySQL database. # The 'users' table only has username/uid/password in it. The rest is # 'hard coded' via the configuration files. # The groups database remains unchanged from the main sample as it is # already pretty minimal. If you do not require MySQL group support, # simply delete the 'groups' and 'grouplist' tables and do not configure # /etc/nsswitch.conf with 'mysql' on the 'group' line # This configuration suits something like an ISP where all users may have # the same gid, home directory base, shell, etc. You can really do # some funky things inside the configuration files if you wanted to, such # as define a different shell depending on the uid returned; that just # takes a bit of SQL query magic... create database auth; use auth; # The tables ... CREATE TABLE groups ( name varchar(16) NOT NULL default '', password varchar(34) NOT NULL default 'x', gid int(11) NOT NULL auto_increment, PRIMARY KEY (gid) ) TYPE=MyISAM AUTO_INCREMENT=5000; CREATE TABLE grouplist ( rowid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '0', username char(16) NOT NULL default '', PRIMARY KEY (rowid) ) TYPE=MyISAM; CREATE TABLE users ( username varchar(16) NOT NULL default '', uid int(11) NOT NULL auto_increment, password varchar(34) NOT NULL default 'x', PRIMARY KEY (uid), UNIQUE KEY username (username), KEY uid (uid) ) TYPE=MyISAM AUTO_INCREMENT=5000; # The data ... INSERT INTO users (username,password) VALUES ('cinergi', ENCRYPT('cinergi')); INSERT INTO groups (name) VALUES ('foobaz'); INSERT INTO grouplist (gid,username) VALUES (5000,'cinergi'); # The permissions ... GRANT USAGE ON *.* TO `nss-root`@`localhost` IDENTIFIED BY 'rootpass'; GRANT USAGE ON *.* TO `nss-user`@`localhost` IDENTIFIED BY 'userpass'; GRANT Select (`username`, `uid`, `password`) ON `auth`.`users` TO 'nss-root'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-root'@'localhost'; GRANT Select (`username`, `uid`) ON `auth`.`users` TO 'nss-user'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-user'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-user'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-root'@'localhost'; libnss-mysql-1.6.1/sample/solaris/000077500000000000000000000000001472655433000171225ustar00rootroot00000000000000libnss-mysql-1.6.1/sample/solaris/libnss-mysql-root.cfg000066400000000000000000000000521472655433000232160ustar00rootroot00000000000000username nss-root password rootpass libnss-mysql-1.6.1/sample/solaris/libnss-mysql.cfg000066400000000000000000000023671472655433000222500ustar00rootroot00000000000000getpwnam SELECT username,'x',uid,gid,age,comment,gecos,homedir,shell \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwuid SELECT username,'x',uid,gid,age,comment,gecos,homedir,shell \ FROM users \ WHERE uid='%1$u' \ LIMIT 1 getspnam SELECT username,password,lstchg,min,max,warn,inact,expire,flag \ FROM users \ WHERE username='%1$s' \ LIMIT 1 getpwent SELECT username,'x',uid,gid,age,comment,gecos,homedir,shell \ FROM users getspent SELECT username,password,lstchg,min,max,warn,inact,expire,flag \ FROM users getgrnam SELECT name,password,gid \ FROM groups \ WHERE name='%1$s' \ LIMIT 1 getgrgid SELECT name,password,gid \ FROM groups \ WHERE gid='%1$u' \ LIMIT 1 getgrent SELECT name,password,gid \ FROM groups memsbygid SELECT username \ FROM grouplist \ WHERE gid='%1$u' gidsbymem SELECT gid \ FROM grouplist \ WHERE username='%1$s' host localhost database auth username nss-user password userpass #socket /var/lib/mysql/mysql.sock #port 3306 libnss-mysql-1.6.1/sample/solaris/sample_database.sql000066400000000000000000000063031472655433000227520ustar00rootroot00000000000000# # THIS DATABASE IS INTENDED FOR Solaris # # Use 'mysql -u root -p < sample_database.sql' to load this example into your # MySQL server. # This example will: # 1) create a database called 'auth' # 2) add three tables: 'users', 'groups' and 'grouplist' # 3) add some data to each table # 4) create two MySQL users ('nss-user' and 'nss-root') with appropriate # SELECT privs. # # With a properly-functioning libnss-mysql, you should be able to log into # the system as 'cinergi' with a password of 'cinergi'. 'cinergi' should be # a member of the group 'foobaz' as well. # # This is intended as an *example* and is perhaps not the best use of # datatypes, space/size, data normalization, etc. # create database auth; use auth; # The tables ... CREATE TABLE groups ( name varchar(16) NOT NULL default '', password varchar(34) NOT NULL default 'x', gid int(11) NOT NULL auto_increment, PRIMARY KEY (gid) ) TYPE=MyISAM AUTO_INCREMENT=5000; CREATE TABLE grouplist ( rowid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '0', username char(16) NOT NULL default '', PRIMARY KEY (rowid) ) TYPE=MyISAM; CREATE TABLE users ( username varchar(16) NOT NULL default '', uid int(11) NOT NULL auto_increment, gid int(11) NOT NULL default '5000', age varchar(32) NOT NULL default '', comment varchar(32) NOT NULL default '', gecos varchar(128) NOT NULL default '', homedir varchar(255) NOT NULL default '', shell varchar(64) NOT NULL default '/bin/bash', password varchar(34) NOT NULL default 'x', lstchg bigint(20) NOT NULL default '1', min bigint(20) NOT NULL default '0', max bigint(20) NOT NULL default '99999', warn bigint(20) NOT NULL default '0', inact bigint(20) NOT NULL default '0', expire bigint(20) NOT NULL default '-1', flag bigint(20) unsigned NOT NULL default '0', PRIMARY KEY (uid), UNIQUE KEY username (username), KEY uid (uid) ) TYPE=MyISAM AUTO_INCREMENT=5000; # The data ... INSERT INTO users (username,gecos,homedir,password) VALUES ('cinergi', 'Ben Goodwin', '/home/cinergi', ENCRYPT('cinergi')); INSERT INTO groups (name) VALUES ('foobaz'); INSERT INTO grouplist (gid,username) VALUES (5000,'cinergi'); # The permissions ... GRANT USAGE ON *.* TO `nss-root`@`localhost` IDENTIFIED BY 'rootpass'; GRANT USAGE ON *.* TO `nss-user`@`localhost` IDENTIFIED BY 'userpass'; GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`, `password`, `age`, `comment`, `lstchg`, `min`, `max`, `warn`, `inact`, `expire`, `flag`) ON `auth`.`users` TO 'nss-root'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-root'@'localhost'; GRANT Select (`username`, `uid`, `gid`, `gecos`, `homedir`, `shell`, `age`, `comment`) ON `auth`.`users` TO 'nss-user'@'localhost'; GRANT Select (`name`, `password`, `gid`) ON `auth`.`groups` TO 'nss-user'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-user'@'localhost'; GRANT Select (`username`, `gid`) ON `auth`.`grouplist` TO 'nss-root'@'localhost'; libnss-mysql-1.6.1/src/000077500000000000000000000000001472655433000147545ustar00rootroot00000000000000libnss-mysql-1.6.1/src/Makefile.am000066400000000000000000000024631472655433000170150ustar00rootroot00000000000000# Copyright 2002 Ben Goodwin # Copyright 2024 Bob Proulx # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . library_sources = nss_config.c nss_main.c \ nss_support.c mysql.c lookup.c \ mysql-pwd.c mysql-spwd.c mysql-grp.c library_ldflags = -module -version-info @LIBVER@:0:0 \ -export-symbols $(srcdir)/@OS@.sym if RENAME lib_LTLIBRARIES = nss_mysql.la nss_mysql_la_LDFLAGS = $(library_ldflags) nss_mysql_la_SOURCES = $(library_sources) else lib_LTLIBRARIES = libnss_mysql.la libnss_mysql_la_LDFLAGS = $(library_ldflags) libnss_mysql_la_SOURCES = $(library_sources) endif noinst_HEADERS = nss_mysql.h lookup.h libnss-mysql-1.6.1/src/freebsd.sym000066400000000000000000000000241472655433000171140ustar00rootroot00000000000000nss_module_register libnss-mysql-1.6.1/src/linux.sym000066400000000000000000000005021472655433000166420ustar00rootroot00000000000000_nss_mysql_endgrent _nss_mysql_endpwent _nss_mysql_endspent _nss_mysql_getgrent_r _nss_mysql_getgrgid_r _nss_mysql_getgrnam_r _nss_mysql_getpwent_r _nss_mysql_getpwnam_r _nss_mysql_getpwuid_r _nss_mysql_getspent_r _nss_mysql_getspnam_r _nss_mysql_initgroups_dyn _nss_mysql_setgrent _nss_mysql_setpwent _nss_mysql_setspent libnss-mysql-1.6.1/src/lookup.c000066400000000000000000000144261472655433000164400ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "nss_mysql.h" #include /* snprintf () */ #include /* strcpy () */ extern conf_t conf; /* * Take query from config, such as "SELECT x FROM foo WHERE bar = '%s'" * and replace "%s" with appropriate data * ltype = BYNAME, BYNUM, or BYNONE * name = username if this is a BYNAME * num = uid/gid if this is a BYNUM * qin = query in config to use * qout = string to send to MySQL server (after format string processing) * mresult = Current MySQL result (if any) * caller = calling function's name */ static NSS_STATUS _nss_mysql_build_query (lookup_t ltype, const char *name, unsigned int num, char *qin, char *qout, MYSQL_RES **mresult, const char *caller) { DN ("_nss_mysql_build_query"); char clean_name[MAX_NAME_SIZE * 2 + 1]; int retVal; DENTER; /* Verify existence of input query, lest we crash */ if (!qin || !qin[0]) { _nss_mysql_log (LOG_CRIT, "%s has no valid query in config", caller); DSRETURN (NSS_UNAVAIL); } switch (ltype) { case BYNAME: /* This lookup key is a name/string */ if (!name || !name[0]) DSRETURN (NSS_NOTFOUND); D ("%s: BYNAME, name = '%s'", FUNCNAME, name); if (strlen (name) >= MAX_NAME_SIZE) { _nss_mysql_log (LOG_CRIT, "%s: name '%s' too long (MAX = %d)", "_nss_mysql_build_query", name, MAX_NAME_SIZE); DSRETURN (NSS_UNAVAIL); } if (_nss_mysql_escape_string (clean_name, name, mresult) != NSS_SUCCESS) DSRETURN (NSS_UNAVAIL); retVal = snprintf (qout, MAX_QUERY_SIZE, qin, clean_name); if (retVal < 1 || retVal >= MAX_QUERY_SIZE) { _nss_mysql_log (LOG_CRIT, "%s: snprintf error: %d", "_nss_mysql_build_query", retVal); DSRETURN (NSS_UNAVAIL); } /* New lookup, reset any existing queries */ _nss_mysql_reset_ent (mresult); break; case BYNUM: /* This lookup key is a uid/gid/number */ D ("%s: BYNUM, num = '%u'", FUNCNAME, num); retVal = snprintf (qout, MAX_QUERY_SIZE, qin, num); if (retVal < 1 || retVal >= MAX_QUERY_SIZE) { _nss_mysql_log (LOG_CRIT, "%s: snprintf error: %d", "_nss_mysql_build_query", retVal); DSRETURN (NSS_UNAVAIL); } /* New lookup, reset any existing queries */ _nss_mysql_reset_ent (mresult); break; case BYNONE: /* This query has no key (e.g. a getpwent) */ D ("%s: BYNONE creating initial query", "_nss_mysql_build_query"); strcpy (qout, qin); break; default: _nss_mysql_log (LOG_ERR, "%s: default case reached - should never happen", "_nss_mysql_build_query"); DSRETURN (NSS_UNAVAIL); } DSRETURN (NSS_SUCCESS); } /* * The high-level function that does the actual lookup * Gets the query built and sent to the MySQL server, as well as * loads the result & buffer with the appropriate return data * * ltype = BYNAME, BYNUM, or BYNONE * name = name if BYNAME * num = uid/gid if BYNUM * q = unformatted query from config to use / build from * restricted = restrict this query to euid = 0? * result = NSS API result * buffer = NSS API buffer * buflen = NSS API length of buffer * errnop = NSS API errno pointer * load_func = pointer to function to load result/buffer with * mresult = current MySQL result set * caller = name of calling function */ NSS_STATUS _nss_mysql_lookup (lookup_t ltype, const char *name, unsigned int num, char *q, nboolean restricted, void *result, char *buffer, size_t buflen, int *errnop, NSS_STATUS (*load_func)(void *, char *, size_t, MYSQL_RES *, int *), MYSQL_RES **mresult, const char *caller) { DN ("_nss_mysql_lookup"); char query[MAX_QUERY_SIZE]; /* Query to send to MySQL */ int retVal; int attempts = MAX_QUERY_ATTEMPTS; /* Attempt # (countdown) */ static uid_t euid = -1; /* Last known euid for change detect */ uid_t cur_euid; /* CURRENT euid */ DENTER; cur_euid = geteuid (); D ("%s: restricted = %d, cur_euid = %u", FUNCNAME, restricted, cur_euid); if (restricted == ntrue && cur_euid != 0) DSRETURN (NSS_NOTFOUND); /* Make sure euid hasn't changed, thus changing our access abilities */ if (euid == -1) euid = cur_euid; else if (euid != cur_euid) { D ("%s:, euid changed: %u -> %u", FUNCNAME, euid, cur_euid); /* Close MySQL and config to force reload of config and reconnect */ _nss_mysql_close_sql (mresult, ntrue); conf.valid = nfalse; euid = cur_euid; } /* Required in case link & config were reset due to euid change */ if (_nss_mysql_init () != NSS_SUCCESS) DSRETURN (NSS_UNAVAIL); /* BYNONE indicates *ent; don't create/run the query since we already did */ if (!(ltype == BYNONE && mresult && *mresult)) { /* Create query string using config & args */ retVal = _nss_mysql_build_query (ltype, name, num, q, query, mresult, caller); if (retVal != NSS_SUCCESS) DSRETURN (retVal); retVal = _nss_mysql_run_query (query, mresult, &attempts); if (retVal != NSS_SUCCESS) DSRETURN (retVal); } /* Take result of query and load RESULT & BUFFER */ retVal = load_func (result, buffer, buflen, *mresult, errnop); /* BYNONE indicates *ent; don't kill the result here, endent does that */ if (ltype != BYNONE) _nss_mysql_close_result (mresult); DSRETURN (retVal); } libnss-mysql-1.6.1/src/lookup.h000066400000000000000000000117541472655433000164460ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "nss_mysql.h" #ifdef HAVE_NSS_H #define SETENT(type) \ NSS_STATUS \ _nss_mysql_set##type (void) \ { \ DN ("_nss_mysql_set" #type); \ DENTER; \ LOCK; \ _nss_mysql_reset_ent (&mresult_##type); \ UNLOCK; \ DSRETURN (NSS_SUCCESS); \ } #define ENDENT(type) \ NSS_STATUS \ _nss_mysql_end##type (void) \ { \ DN ("_nss_mysql_end" #type); \ DENTER; \ LOCK; \ _nss_mysql_reset_ent (&mresult_##type); \ UNLOCK; \ DSRETURN (NSS_SUCCESS); \ } #elif defined (HAVE_NSS_COMMON_H) #define SETENT(type) \ NSS_STATUS \ _nss_mysql_set##type (nss_backend_t *be, void *args) \ { \ DN ("_nss_mysql_set" #type); \ DENTER; \ LOCK; \ _nss_mysql_reset_ent (&mresult_##type); \ UNLOCK; \ DSRETURN (NSS_SUCCESS); \ } #define ENDENT(type) \ NSS_STATUS \ _nss_mysql_end##type (nss_backend_t *be, void *args) \ { \ DN ("_nss_mysql_end" #type); \ DENTER; \ LOCK; \ _nss_mysql_reset_ent (&mresult_##type); \ UNLOCK; \ DSRETURN (NSS_SUCCESS); \ } #define CONSTR(type) \ nss_backend_t * \ _nss_mysql_##type##_constr (const char *db_name, const char *src_name, \ const char *cfg_args) \ { \ DN ("_nss_mysql_" #type "_constr"); \ nss_backend_t *be; \ DENTER; \ be = (nss_backend_t *) malloc (sizeof (*be)); \ if (!be) \ DPRETURN (NULL); \ be->ops = type##_ops; \ be->n_ops = sizeof (type##_ops) / sizeof (nss_backend_op_t); \ DPRETURN (be); \ } #endif libnss-mysql-1.6.1/src/mysql-grp.c000066400000000000000000000151121472655433000170530ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "lookup.h" #include extern conf_t conf; MYSQL_RES *mresult_grent = NULL; /* * getgrnam */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getgrnam_r (const char *name, struct group *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getgrnam_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getgrnam_r"); int retVal; MYSQL_RES *mresult = NULL; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNAME, name, 0, conf.sql.query.getgrnam, nfalse, result, buffer, buflen, errnop, _nss_mysql_load_group, &mresult, "_nss_mysql_getgrnam_r"); #elif defined(HAVE_NSS_COMMON_H) retVal = _nss_mysql_lookup (BYNAME, NSS_ARGS(args)->key.name, 0, conf.sql.query.getgrnam, nfalse, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_group, &mresult, "_nss_mysql_getgrnam_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } /* * getgrgid */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getgrgid_r (uid_t uid, struct group *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getgrgid_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getgrgid_r"); int retVal; MYSQL_RES *mresult = NULL; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNUM, NULL, uid, conf.sql.query.getgrgid, nfalse, result, buffer, buflen, errnop, _nss_mysql_load_group, &mresult, "_nss_mysql_getgrgid_r"); #else retVal = _nss_mysql_lookup (BYNUM, NULL, NSS_ARGS(args)->key.uid, conf.sql.query.getgrgid, nfalse, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_group, &mresult, "_nss_mysql_getgrgid_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } /* * endgrent */ ENDENT(grent) /* * setgrent */ SETENT(grent) /* * getgrent */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getgrent_r (struct group *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getgrent_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getgrent_r"); int retVal; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNONE, NULL, 0, conf.sql.query.getgrent, nfalse, result, buffer, buflen, errnop, _nss_mysql_load_group, &mresult_grent, "_nss_mysql_getgrent_r"); #else retVal = _nss_mysql_lookup (BYNONE, NULL, 0, conf.sql.query.getgrent, nfalse, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_group, &mresult_grent, "_nss_mysql_getgrent_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } /* * initgroups/getgrmem */ #ifdef HAVE_NSS_H NSS_STATUS _nss_mysql_initgroups_dyn (const char *user, gid_t group, long int *start, long int *size, gid_t **groupsp, long int limit, int *errnop) { DN ("_nss_mysql_initgroups_dyn"); #endif #ifdef HAVE_NSS_COMMON_H NSS_STATUS _nss_mysql_getgrmem (nss_backend_t *be, void *args) { DN ("_nss_mysql_getgrmem"); #endif int retVal; MYSQL_RES *mresult = NULL; group_info_t gi; DENTER; #ifdef HAVE_NSS_H gi.start = start; gi.size = size; gi.limit = limit; gi.groupsp = groupsp; gi.group = (long int) group; #elif defined(HAVE_NSS_COMMON_H) gi.start = (long int *)&((struct nss_groupsbymem *)args)->numgids; gi.limit = ((struct nss_groupsbymem *)args)->maxgids; gi.size = &gi.limit; gi.groupsp = &(((struct nss_groupsbymem *)args)->gid_array); gi.group = -1; #endif LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNAME, user, 0, conf.sql.query.gidsbymem, nfalse, &gi, NULL, 0, errnop, _nss_mysql_load_gidsbymem, &mresult, "initgroups"); #else retVal = _nss_mysql_lookup (BYNAME, ((struct nss_groupsbymem *)args)->username, 0, conf.sql.query.gidsbymem, nfalse, &gi, NULL, 0, NULL, _nss_mysql_load_gidsbymem, &mresult, "initgroups"); #endif UNLOCK; if (retVal != NSS_SUCCESS) DSRETURN (retVal); #ifdef HAVE_NSS_COMMON_H DSRETURN (NSS_NOTFOUND); #else DSRETURN (NSS_SUCCESS); #endif } #ifdef HAVE_NSS_COMMON_H static nss_backend_op_t group_ops[] = { _nss_mysql_default_destr, /* NSS_DBOP_DESTRUCTOR */ _nss_mysql_endgrent, /* NSS_DBOP_ENDENT */ _nss_mysql_setgrent, /* NSS_DBOP_SETENT */ _nss_mysql_getgrent_r, /* NSS_DBOP_GETENT */ _nss_mysql_getgrnam_r, /* NSS_DBOP_GROUP_BYNAME */ _nss_mysql_getgrgid_r, /* NSS_DBOP_GROUP_BYGID */ _nss_mysql_getgrmem /* NSS_DBOP_GROUP_BYMEMBER */ }; CONSTR(group) #endif libnss-mysql-1.6.1/src/mysql-pwd.c000066400000000000000000000116211472655433000170560ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "lookup.h" #include extern conf_t conf; MYSQL_RES *mresult_pwent = NULL; /* * getpwnam */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getpwnam_r (const char *name, struct passwd *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getpwnam_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getpwnam_r"); int retVal; MYSQL_RES *mresult = NULL; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNAME, name, 0, conf.sql.query.getpwnam, nfalse, result, buffer, buflen, errnop, _nss_mysql_load_passwd, &mresult, "_nss_mysql_getpwnam_r"); #else retVal = _nss_mysql_lookup (BYNAME, NSS_ARGS(args)->key.name, 0, conf.sql.query.getpwnam, nfalse, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_passwd, &mresult, "_nss_mysql_getpwnam_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } /* * getpwuid */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getpwuid_r (uid_t uid, struct passwd *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getpwuid_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getpwuid_r"); int retVal; MYSQL_RES *mresult = NULL; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNUM, NULL, uid, conf.sql.query.getpwuid, nfalse, result, buffer, buflen, errnop, _nss_mysql_load_passwd, &mresult, "_nss_mysql_getpwuid_r"); #else retVal = _nss_mysql_lookup (BYNUM, NULL, NSS_ARGS(args)->key.uid, conf.sql.query.getpwuid, nfalse, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_passwd, &mresult, "_nss_mysql_getpwuid_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } /* * endpwent */ ENDENT(pwent); /* * setpwent */ SETENT(pwent); /* * getpwent */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getpwent_r (struct passwd *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getpwent_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getpwent_r"); int retVal; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNONE, NULL, 0, conf.sql.query.getpwent, nfalse, result, buffer, buflen, errnop, _nss_mysql_load_passwd, &mresult_pwent, "_nss_mysql_getpwent_r"); #else retVal = _nss_mysql_lookup (BYNONE, NULL, 0, conf.sql.query.getpwent, nfalse, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_passwd, &mresult_pwent, "_nss_mysql_getpwent_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } #ifdef HAVE_NSS_COMMON_H static nss_backend_op_t passwd_ops[] = { _nss_mysql_default_destr, /* NSS_DBOP_DESTRUCTOR */ _nss_mysql_endpwent, /* NSS_DBOP_ENDENT */ _nss_mysql_setpwent, /* NSS_DBOP_SETENT */ _nss_mysql_getpwent_r, /* NSS_DBOP_GETENT */ _nss_mysql_getpwnam_r, /* NSS_DBOP_PASSWD_BYNAME */ _nss_mysql_getpwuid_r /* NSS_DBOP_PASSWD_BYUID */ }; CONSTR(passwd) #endif libnss-mysql-1.6.1/src/mysql-spwd.c000066400000000000000000000072261472655433000172470ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "lookup.h" #ifdef HAVE_SHADOW_H #include extern conf_t conf; MYSQL_RES *mresult_spent = NULL; /* * getspnam */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getspnam_r (const char *name, struct spwd *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getspnam_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getspnam_r"); int retVal; MYSQL_RES *mresult = NULL; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNAME, name, 0, conf.sql.query.getspnam, ntrue, result, buffer, buflen, errnop, _nss_mysql_load_shadow, &mresult, "_nss_mysql_getspnam_r"); #else retVal = _nss_mysql_lookup (BYNAME, NSS_ARGS(args)->key.name, 0, conf.sql.query.getspnam, ntrue, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_shadow, &mresult, "_nss_mysql_getspnam_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } /* * endspent */ ENDENT(spent) /* * setspent */ SETENT(spent) /* * getspent */ NSS_STATUS #ifdef HAVE_NSS_H _nss_mysql_getspent_r (struct spwd *result, char *buffer, size_t buflen, int *errnop) #elif defined(HAVE_NSS_COMMON_H) _nss_mysql_getspent_r (nss_backend_t *be, void *args) #endif { DN ("_nss_mysql_getspent_r"); int retVal; DENTER; LOCK; #ifdef HAVE_NSS_H retVal = _nss_mysql_lookup (BYNONE, NULL, 0, conf.sql.query.getspent, ntrue, result, buffer, buflen, errnop, _nss_mysql_load_shadow, &mresult_spent, "_nss_mysql_getspent_r"); #else retVal = _nss_mysql_lookup (BYNONE, NULL, 0, conf.sql.query.getspent, ntrue, NSS_ARGS(args)->buf.result, NSS_ARGS(args)->buf.buffer, NSS_ARGS(args)->buf.buflen, &NSS_ARGS(args)->erange, _nss_mysql_load_shadow, &mresult_spent, "_nss_mysql_getspent_r"); if (retVal == NSS_SUCCESS) NSS_ARGS(args)->returnval = NSS_ARGS(args)->buf.result; #endif UNLOCK; DSRETURN (retVal); } #ifdef HAVE_NSS_COMMON_H static nss_backend_op_t shadow_ops[] = { _nss_mysql_default_destr, /* NSS_DBOP_DESTRUCTOR */ _nss_mysql_endspent, /* NSS_DBOP_ENDENT */ _nss_mysql_setspent, /* NSS_DBOP_SETENT */ _nss_mysql_getspent_r, /* NSS_DBOP_GETENT */ _nss_mysql_getspnam_r /* NSS_DBOP_SHADOW_BYNAME */ }; CONSTR(shadow) #endif #endif /* HAVE_SHADOW_H */ libnss-mysql-1.6.1/src/mysql.c000066400000000000000000000221261472655433000162700ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ /* * MySQL-specific functions; ALL MySQL calls that any other source functions * need should come from here. */ #include "nss_mysql.h" #include /* strlen() */ #include /* struct sockaddr_in */ con_info_t ci = { nfalse }; extern conf_t conf; /* * Immediately after connecting to a MySQL server, save the current * socket information for later comparison purposes */ static freturn_t _nss_mysql_save_socket_info (void) { DN ("_nss_mysql_save_socket_info"); socklen_t local_size = sizeof (struct sockaddr); socklen_t remote_size = sizeof (struct sockaddr); int r; DENTER; memset(&(ci.sock_info.local), 0, sizeof (ci.sock_info.local)); r = getsockname (ci.link.net.fd, &(ci.sock_info.local), &local_size); if (r != RETURN_SUCCESS) DFRETURN (RETURN_FAILURE); memset(&(ci.sock_info.remote), 0, sizeof (ci.sock_info.remote)); r = getpeername (ci.link.net.fd, &(ci.sock_info.remote), &remote_size); DFRETURN (r); } /* * Compare ORIG and CUR */ static nboolean _nss_mysql_is_same_sockaddr (struct sockaddr orig, struct sockaddr cur) { DN ("_nss_mysql_is_same_sockaddr"); DENTER; switch (((struct sockaddr_in *)&ci.sock_info.local)->sin_family) { case AF_INET: if ((*(struct sockaddr_in *) &orig).sin_port != (*(struct sockaddr_in *) &cur).sin_port) DBRETURN (nfalse); if ((*(struct sockaddr_in *) &orig).sin_addr.s_addr != (*(struct sockaddr_in *) &cur).sin_addr.s_addr) DBRETURN (nfalse); break; case AF_UNIX: if (memcmp (&orig, &cur, sizeof (struct sockaddr)) != 0) DBRETURN (nfalse); break; default: _nss_mysql_log (LOG_ERR, "%s: Unhandled sin_family", "_nss_mysql_is_same_sockaddr"); DBRETURN (nfalse); break; } DBRETURN (ntrue); } /* * Check to see what current socket info is and compare to the saved * socket info (from _nss_mysql_save_socket_info() above). Return * NTRUE if the current socket and saved socket match. */ static nboolean _nss_mysql_validate_socket (void) { DN ("_nss_mysql_validate_socket"); socklen_t local_size = sizeof (struct sockaddr); socklen_t remote_size = sizeof (struct sockaddr); struct sockaddr check; DENTER; memset(&check, 0, sizeof (check)); if (getpeername (ci.link.net.fd, &check, &remote_size) != RETURN_SUCCESS) DBRETURN (nfalse); if (_nss_mysql_is_same_sockaddr (ci.sock_info.remote, check) != ntrue) DBRETURN (nfalse); memset(&check, 0, sizeof (check)); if (getsockname (ci.link.net.fd, &check, &local_size) != RETURN_SUCCESS) DBRETURN (nfalse); if (_nss_mysql_is_same_sockaddr (ci.sock_info.local, check) != ntrue) DBRETURN (nfalse); DBRETURN (ntrue); } NSS_STATUS _nss_mysql_close_sql (MYSQL_RES **mresult, nboolean graceful) { DN ("_nss_mysql_close_sql"); DENTER; _nss_mysql_close_result (mresult); if (graceful && ci.valid) { D ("%s: calling mysql_close()", FUNCNAME); mysql_close (&ci.link); } ci.valid = nfalse; DSRETURN (NSS_SUCCESS); } static void _nss_mysql_set_options (sql_server_t *server) { DN ("_nss_mysql_set_options"); const unsigned int def_timeout = DEF_TIMEOUT; const my_bool reconnect = 1; DENTER; mysql_options(&ci.link, MYSQL_OPT_CONNECT_TIMEOUT, (const char *) &def_timeout); mysql_options(&ci.link, MYSQL_READ_DEFAULT_GROUP, "libnss-mysql"); mysql_options(&ci.link, MYSQL_OPT_RECONNECT, (const char *) &reconnect); DEXIT; } /* * Validate existing connection. * This does NOT run mysql_ping because that function is * extraordinarily slow (~doubles time to fetch a query) */ static nboolean _nss_mysql_check_existing_connection (MYSQL_RES **mresult) { DN ("_nss_mysql_check_existing_connection"); static pid_t pid = -1; DENTER; if (ci.valid == nfalse || conf.valid == nfalse) DBRETURN (nfalse); if (pid == -1) pid = getpid (); else if (pid == getppid ()) { /* saved pid == ppid = we've forked; We MUST create a new connection */ D ("%s: fork() detected", FUNCNAME); ci.valid = nfalse; pid = getpid (); DBRETURN (nfalse); } if (_nss_mysql_validate_socket () == nfalse) { /* Do *NOT* CLOSE_LINK - the socket is invalid! */ D ("%s: invalid socket detected", FUNCNAME); _nss_mysql_close_sql (mresult, nfalse); ci.valid = nfalse; DBRETURN (nfalse); } DBRETURN (ntrue); } /* * Connect to a MySQL server. */ static NSS_STATUS _nss_mysql_connect_sql (MYSQL_RES **mresult) { DN ("_nss_mysql_connect_sql"); int retval; sql_server_t *server = &conf.sql.server; unsigned int port; const my_bool noreconnect = 0; DENTER; if (_nss_mysql_check_existing_connection (mresult) == ntrue) { D ("%s: Using existing connection", FUNCNAME); DSRETURN (NSS_SUCCESS); } retval = _nss_mysql_load_config (); if (retval != NSS_SUCCESS) { _nss_mysql_log (LOG_ALERT, "Failed to load configuration"); DSRETURN (NSS_UNAVAIL); } if (mysql_init (&ci.link) == NULL) { _nss_mysql_log (LOG_ALERT, "mysql_init() failed"); DSRETURN (NSS_UNAVAIL); } _nss_mysql_set_options (server); D ("%s: Connecting to %s", FUNCNAME, server->host); if (server->port) port = atoi (server->port); else port = 0; if (mysql_real_connect (&ci.link, server->host, server->username[0] ? server->username : NULL, server->password[0] ? server->password : NULL, server->database, port, server->socket[0] ? server->socket : NULL, 0)) { if (_nss_mysql_save_socket_info () != RETURN_SUCCESS ) { _nss_mysql_log (LOG_ALERT, "Unable to save socket info"); _nss_mysql_close_sql (mresult, ntrue); DSRETURN (NSS_UNAVAIL); } ci.valid = ntrue; /* Safety: We can't let MySQL assume socket is still valid; see _nss_mysql_validate_socket */ mysql_options(&ci.link, MYSQL_OPT_RECONNECT, (const char *) &noreconnect); DSRETURN (NSS_SUCCESS); } _nss_mysql_log (LOG_ALERT, "Connection to server '%s' failed: %s", server->host, mysql_error (&ci.link)); DSRETURN (NSS_UNAVAIL); } void _nss_mysql_close_result (MYSQL_RES **mresult) { DN ("_nss_mysql_close_result"); DENTER; if (mresult && *mresult && ci.valid) { D ("%s, calling mysql_free_result()", FUNCNAME); mysql_free_result (*mresult); } if (mresult) *mresult = NULL; DEXIT; } /* * Run MySQL query */ NSS_STATUS _nss_mysql_run_query (char *query, MYSQL_RES **mresult, int *attempts) { DN ("_nss_mysql_run_query"); int retval; DENTER; if (!query) DSRETURN (NSS_NOTFOUND); D ("%s: Executing query: %s", FUNCNAME, query); retval = _nss_mysql_connect_sql (mresult); if (retval != NSS_SUCCESS) DSRETURN (retval);; retval = mysql_query (&ci.link, query); if (retval != RETURN_SUCCESS) { --(*attempts); if (*attempts > 0) { _nss_mysql_log (LOG_ALERT, "mysql_query failed: %s, trying again (%d)", mysql_error (&ci.link), *attempts); DSRETURN (_nss_mysql_run_query (query, mresult, attempts)); } else { _nss_mysql_log (LOG_ALERT, "mysql_query failed: %s", mysql_error (&ci.link)); DSRETURN (NSS_UNAVAIL); } } if ((*mresult = mysql_store_result (&ci.link)) == NULL) { _nss_mysql_log (LOG_ALERT, "mysql_store_result failed: %s", mysql_error (&ci.link)); DSRETURN (NSS_UNAVAIL); } DSRETURN (NSS_SUCCESS); } NSS_STATUS _nss_mysql_fetch_row (MYSQL_ROW *row, MYSQL_RES *mresult) { DN ("_nss_mysql_fetch_row"); DENTER; if ((*row = mysql_fetch_row (mresult)) == NULL) { if (mysql_errno (&ci.link)) { _nss_mysql_log (LOG_ALERT, "mysql_fetch_row() failed: %s", mysql_error (&ci.link)); DSRETURN (NSS_UNAVAIL); } else DSRETURN (NSS_NOTFOUND); } DSRETURN (NSS_SUCCESS); } NSS_STATUS _nss_mysql_escape_string (char *to, const char *from, MYSQL_RES **mresult) { DN ("_nss_mysql_escape_string"); DENTER; if (_nss_mysql_connect_sql (mresult) != NSS_SUCCESS) DSRETURN (NSS_UNAVAIL); mysql_real_escape_string (&ci.link, to, from, strlen(from)); DSRETURN (NSS_SUCCESS); } libnss-mysql-1.6.1/src/nss_config.c000066400000000000000000000146311472655433000172550ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "nss_mysql.h" #include /* fopen() */ #include /* strlen() */ /* global var 'conf' contains data loaded from config files */ conf_t conf; /* maps config key to spot in 'conf' */ typedef struct { char *name; /* key string */ char *ptr; /* where in 'conf' to load this string */ } config_info_t; /* * Get the next key/value pair from an open file * return NTRUE if a key/val pair is found * return NFALSE if EOF or error * Lines can begin (column 0) with a '#' for comments * key/val pairs must be in the following format * key = val * Whitespace can be spaces or tabs * Keys must be one word (no whitespace) * Values can be anything except CR/LF * Line continuation is supported if EOL is strictly a '\' * (no trailing whitespace) * * The in-memory copy of LINE is modified by this routine * * fh = open file handle * key = config key loaded here * key_size = storage size of key * val = config value loaded here * val_size = storage size of val */ static nboolean _nss_mysql_next_key (FILE *fh, char *key, int key_size, char *val, int val_size) { DN ("_nss_mysql_next_key"); char line[MAX_LINE_SIZE]; char *ccil; /* Current Character In Line */ char *cur; size_t size; nboolean fetch_key = ntrue; DENTER; *val = *key = '\0'; /* Loop through file until a key/val pair is found or EOF */ while (fgets (line, MAX_LINE_SIZE, fh) != NULL) { if (*line == '#') continue; ccil = line; if (fetch_key) { cur = ccil; /* Get key - anything but CR/LF or whitespace */ ccil += strcspn (ccil, "\n\r \t"); if (ccil == cur) continue; /* No key */ *ccil = '\0'; /* Null-terminate the key */ /* Key found, move on */ ++ccil; /* Save the key */ strncpy (key, cur, key_size); key[key_size - 1] = '\0'; /* strncpy doesn't guarantee null-term */ } /* Skip leading whitespace */ ccil += strspn (ccil, " \t"); cur = ccil; /* Get value - anything but CR/LF */ size = strcspn (ccil, "\n\r"); if (!size && fetch_key) continue; /* No value */ ccil += size; if (*(ccil - 1) == '\\') { fetch_key = nfalse; /* Next line continues a value */ *(ccil - 1) = '\0'; /* Remove the '\' */ size--; } else { fetch_key = ntrue; /* Next line starts with a key */ *ccil = '\0'; /* Null-terminate the value */ } /* Append what we just snarfed to VAL */ strncat (val, cur, val_size - 1); val_size -= size; if (val_size <= 0) { _nss_mysql_log (LOG_ERR, "%s: Config value too long", "_nss_mysql_next_key"); DBRETURN (nfalse); } if (!fetch_key) /* Next line continues a value */ continue; D ("%s: Found: %s -> %s", FUNCNAME, key, val); DBRETURN (ntrue); } DBRETURN (nfalse); } /* * Load configuration data from file * * file = full path of file to load */ static void _nss_mysql_load_config_file (char *file) { DN ("_nss_mysql_load_config_file"); FILE *fh; char key[MAX_KEY_SIZE]; char val[MAX_VAL_SIZE]; config_info_t *c; /* map config key to 'conf' location; must be NULL-terminated */ config_info_t config_fields[] = { {"getpwnam", conf.sql.query.getpwnam}, {"getpwuid", conf.sql.query.getpwuid}, {"getspnam", conf.sql.query.getspnam}, {"getpwent", conf.sql.query.getpwent}, {"getspent", conf.sql.query.getspent}, {"getgrnam", conf.sql.query.getgrnam}, {"getgrgid", conf.sql.query.getgrgid}, {"getgrent", conf.sql.query.getgrent}, {"memsbygid", conf.sql.query.memsbygid}, {"gidsbymem", conf.sql.query.gidsbymem}, {"host", conf.sql.server.host}, {"port", conf.sql.server.port}, {"socket", conf.sql.server.socket}, {"username", conf.sql.server.username}, {"password", conf.sql.server.password}, {"database", conf.sql.server.database}, {NULL} }; DENTER; D ("%s: Attempting to load: %s", FUNCNAME, file); /* No error-handling here; validate_config will catch missing data */ if ((fh = fopen (file, "r")) == NULL) DRETURN; D ("%s: fopen() successful", FUNCNAME); /* Step through all key/val pairs available */ while (_nss_mysql_next_key (fh, key, MAX_KEY_SIZE, val, MAX_VAL_SIZE)) for (c = config_fields; c->name; c++) if (!strcmp (key, c->name)) strncpy (c->ptr, val, MAX_VAL_SIZE); fclose (fh); DRETURN; } /* * Sanity-check the loaded configuration data * Make sure we have at least a host and database defined */ static nboolean _nss_mysql_validate_config (void) { DN ("_nss_mysql_validate_config"); DENTER; if (!conf.sql.server.host[0] || !conf.sql.server.database[0]) DBRETURN (nfalse);; DBRETURN (ntrue); } /* * Load our config files * Upon success, set conf.valid = ntrue */ NSS_STATUS _nss_mysql_load_config (void) { DN ("_nss_mysql_load_config"); DENTER; /* Config is already loaded, don't do it again */ if (conf.valid == ntrue) DSRETURN (NSS_SUCCESS); memset (&conf, 0, sizeof (conf)); /* Load main (world-readable) config */ _nss_mysql_load_config_file (MAINCFG); /* Load root (root-readable) config */ _nss_mysql_load_config_file (ROOTCFG); /* double-check our config */ if (_nss_mysql_validate_config () == nfalse) DSRETURN (NSS_UNAVAIL); /* Let the rest of the module know we've got a good config */ conf.valid = ntrue; DSRETURN (NSS_SUCCESS); } libnss-mysql-1.6.1/src/nss_main.c000066400000000000000000000155531472655433000167400ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ /* * Global variables and miscellaneous support routines */ #include "nss_mysql.h" #include /* fprintf() */ #include /* va_start() */ #include /* umask() */ /* * GNU source only defines RTLD_DEFAULT if __USE_GNU is set */ #ifndef __USE_GNU #define __USE_GNU #include #undef __USE_GNU #endif pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_once_t _nss_mysql_once_control = {PTHREAD_ONCE_INIT}; static int _nss_mysql_locked_by_atfork = 0; #define MAX_MSG_SIZE 1024 /* * Debugs to either a file, stderr, or syslog, depending on the environ var * LIBNSS_MYSQL_DEBUG * none or 0 = file (DEBUG_FILE, defined in nss_mysql.h) * 1 = stderr * 2 = syslog (facility defined at configure, priority DEBUG) */ #ifdef DEBUG void _nss_mysql_debug (char *fmt, ...) { va_list ap; char msg[MAX_MSG_SIZE]; FILE *fh; char *env; int type = 0; mode_t old_mask; va_start (ap, fmt); vsnprintf (msg, MAX_MSG_SIZE, fmt, ap); env = getenv ("LIBNSS_MYSQL_DEBUG"); if (env) type = atoi (env); if (type <= 1) { if (type == 0) { old_mask = umask (000); fh = fopen (DEBUG_FILE, "a"); umask (old_mask); } else fh = stderr; if (fh) { fprintf (fh, "[%d]: %s\n", getpid(), msg); if (type == 0) fclose (fh); } } else { _nss_mysql_log (LOG_DEBUG, "%s", msg); } va_end (ap); } #endif /* * THREADING NOTES * * libnss-mysql is *not* to be linked against any threading library. * Instead, check for pthread functions in the current namespace * by using dlsym() and RTLD_DEFAULT. This way we don't litter every * application with a thread library (since libnss-mysql would be linked * against it and so many applications would dlopen libnss-mysql). * Applications often misbehave when a thread environment is unexpected * * libnss-mysql is *not* to be linked against the threaded version * of MySQL for the same reasons. libnss-mysql is not coded in such * a way that a threaded MySQL library is needed, anyway. * * libnss-mysql locks just prior to calling _nss_mysql_lookup() and * unlocks when done with it and all data handled by it. Since the lock * occurs so early on and lasts so long, libnss-mysql doesn't perform * that well in a heavily threaded application (e.g. a threaded radius * server). Use of "nscd" is highly recommended. */ /* * Before fork() processing begins, the prepare fork handler is called */ static void _nss_mysql_atfork_prepare (void) { DN ("_nss_mysql_atfork_prepare"); int (*trylock)(); DENTER; trylock = (int (*)(int))dlsym (RTLD_DEFAULT, "pthread_mutex_trylock"); if (trylock) if ((*trylock) (&lock) == 0) _nss_mysql_locked_by_atfork = 1; DEXIT; } /* * The parent fork handler is called after fork() processing finishes * in the parent process */ static void _nss_mysql_atfork_parent (void) { DN ("_nss_mysql_atfork_parent"); DENTER; if (_nss_mysql_locked_by_atfork) { _nss_mysql_locked_by_atfork = 0; UNLOCK; } DEXIT; } /* * The child fork handler is called after fork() processing finishes in the * child process. */ static void _nss_mysql_atfork_child (void) { DN ("_nss_mysql_atfork_child"); DENTER; /* Don't close the link; just set it to invalid so we'll open a new one */ _nss_mysql_close_sql (NULL, nfalse); if (_nss_mysql_locked_by_atfork) { _nss_mysql_locked_by_atfork = 0; UNLOCK; } DEXIT; } /* Setup pthread_atfork if current namespace contains pthreads. */ static void _nss_mysql_pthread_once_init (void) { DN ("_nss_mysql_atfork_once_init"); int (*pthread_atfork)(); DENTER; pthread_atfork = (int (*)(int))dlsym (RTLD_DEFAULT, "pthread_atfork"); if (pthread_atfork) (*pthread_atfork) (_nss_mysql_atfork_prepare, _nss_mysql_atfork_parent, _nss_mysql_atfork_child); DEXIT; } /* * Prevent the "dead store removal" problem present with stock memset() */ static void * _nss_mysql_safe_memset (void *s, int c, size_t n) { DN ("_nss_mysql_safe_memset"); volatile char *p = s; DENTER; if (p) { while (n--) *p++ = c; } DPRETURN (s); } /* * Make an attempt to close the link when the process exits * Set in _nss_mysql_init() below */ static void _nss_mysql_atexit_handler (void) { DN ("_nss_mysql_atexit_handler"); extern conf_t conf; DENTER; _nss_mysql_close_sql (NULL, ntrue); _nss_mysql_safe_memset (conf.sql.server.password, 0, sizeof (conf.sql.server.password)); DEXIT; } /* * Setup pthread_once if it's available in the current namespace * Load config file(s) */ NSS_STATUS _nss_mysql_init (void) { DN ("_nss_mysql_init"); int (*pthread_once)(); static int atexit_isset = nfalse; DENTER; pthread_once = (int (*)(int))dlsym (RTLD_DEFAULT, "pthread_once"); if (pthread_once) (*pthread_once) (&_nss_mysql_once_control, _nss_mysql_pthread_once_init); if (atexit_isset == nfalse) { if (atexit(_nss_mysql_atexit_handler) == RETURN_SUCCESS) atexit_isset = ntrue; } DSRETURN (_nss_mysql_load_config ()); } /* * Syslog a message at PRIORITY. * Do *NOT* openlog/closelog as you'll mess up calling programs that * are syslogging their own stuff. */ void _nss_mysql_log (int priority, char *fmt, ...) { va_list ap; char msg[MAX_MSG_SIZE]; va_start (ap, fmt); vsnprintf (msg, MAX_MSG_SIZE, fmt, ap); syslog (priority, "%s: %s", PACKAGE, msg); va_end (ap); } #ifdef HAVE_NSS_COMMON_H NSS_STATUS _nss_mysql_default_destr (nss_backend_t *be, void *args) { DN ("_nss_mysql_default_destr"); DENTER; if (be) { free (be); be = NULL; } /* Closing link & freeing memory unnecessary due to link w/ '-znodelete' */ DSRETURN (NSS_SUCCESS); } #endif /* * SET/END ent's call this. While the definition of endent is to close * the "file", we need to keep the MySQL link persistent, so we just * clear any lingering MySQL result set. */ void _nss_mysql_reset_ent (MYSQL_RES **mresult) { DN ("_nss_mysql_reset_ent"); DENTER; _nss_mysql_close_result (mresult); DEXIT; } libnss-mysql-1.6.1/src/nss_mysql.h000066400000000000000000000260541472655433000171640ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_NSS_H #include #elif defined HAVE_NSS_COMMON_H #include #include #else #error I need either nss.h or nss_common.h! #endif #include #include #include #ifdef HAVE_SYSLOG_H #include #endif #include #include #ifdef HAVE_STDINT_H #include #endif #include /* realloc(), free(), malloc(), atoi() */ #include #ifdef HAVE_NSS_H #define NSS_SUCCESS NSS_STATUS_SUCCESS #define NSS_NOTFOUND NSS_STATUS_NOTFOUND #define NSS_UNAVAIL NSS_STATUS_UNAVAIL #define NSS_TRYAGAIN NSS_STATUS_TRYAGAIN typedef enum nss_status NSS_STATUS; #elif defined HAVE_NSS_COMMON_H typedef nss_status_t NSS_STATUS; #define NSS_ARGS(args) ((nss_XbyY_args_t *)args) #endif #define MAX_LINE_SIZE 1024 /* Max line length in config file */ #define MAX_QUERY_SIZE 2048 /* Max size of SQL query */ #define MAX_NAME_SIZE 128 /* Max username/groupname size */ #define MAX_KEY_SIZE 128 /* Max length of a key in cfg file */ #define MAX_VAL_SIZE 1024 /* Max length of a val in cfg file */ #define MAX_QUERY_ATTEMPTS 3 /* # of query retries */ /* Default initializers */ #define DEF_TIMEOUT 3 #ifdef DEBUG void _nss_mysql_debug (char *fmt, ...); #define DEBUG_FILE "/tmp/libnss-mysql-debug.log" #define D _nss_mysql_debug #define DN(n) static const char FUNCNAME[] = n #define DENTER do { D ("%s: ENTER", FUNCNAME); } while (0) #define DIRETURN(r) \ do { D ("%s: EXIT (%d)", FUNCNAME, r); return (r); } while (0) #define DFRETURN(r) \ do { \ D ("%s: EXIT (%s)", FUNCNAME, r == 0 ? "SUCCESS" : "FAIL"); \ return (r); \ } while (0) #define DBRETURN(r) \ do { \ D ("%s: EXIT (%s)", FUNCNAME, r == ntrue ? "TRUE" : "FALSE"); \ return (r); \ } while (0) #define DSRETURN(r) \ do { \ char *status; \ switch (r) \ { \ case NSS_SUCCESS: \ status = "NSS_SUCCESS"; \ break; \ case NSS_NOTFOUND: \ status = "NSS_NOTFOUND"; \ break; \ case NSS_UNAVAIL: \ status = "NSS_UNAVAIL"; \ break; \ case NSS_TRYAGAIN: \ status = "NSS_TRYAGAIN"; \ break; \ default: \ status = "UNKNOWN"; \ break; \ } \ D ("%s: EXIT (%s)", FUNCNAME, status); \ return (r); \ } while (0) #define DPRETURN(r) \ do { D ("%s: EXIT (%p)", FUNCNAME, r); return (r); } while (0) #define DRETURN do { D ("%s: EXIT", FUNCNAME); return; } while (0) #define DEXIT do { D ("%s: EXIT", FUNCNAME); } while (0) #else #define D(...) do {} while (0) #define DN(n) do {} while (0) #define DENTER do {} while (0) #define DIRETURN(r) do { return (r); } while (0) #define DPRETURN(r) do { return (r); } while (0) #define DFRETURN(r) do { return (r); } while (0) #define DBRETURN(r) do { return (r); } while (0) #define DSRETURN(r) do { return (r); } while (0) #define DRETURN do { return; } while (0) #define DEXIT do {} while (0) #endif extern pthread_mutex_t lock; #define LOCK do { pthread_mutex_lock (&lock); } while (0) #define UNLOCK do { pthread_mutex_unlock (&lock); } while (0) /* * Linux and Solaris handle buffer exhaustion differently. * Linux sets errno to ERANGE and returns TRYAGAIN, which results in * the NSS system trying with a buffer twice as big. * Solaris, however, doesn't seem to retry. I've checked the Solaris 8 * code for files/ldap/nisplus NSS and they all set NSS_ARGS(args)->erange * to 1 and return NOTFOUND. Note that this macro sets *errnop to 1, but * it's not really errnop, it's erange - see the calling functions. * In fact, my tests reveal that if you return TRYAGAIN, Solaris will try * over and over, without increasing the buffer - AKA infinite (or long) * loop. */ #ifdef HAVE_NSS_H #define EXHAUSTED_BUFFER \ do { \ *errnop = ERANGE; \ DSRETURN (NSS_TRYAGAIN); \ } while (0) #else #define EXHAUSTED_BUFFER \ do { \ if (errnop) \ *errnop = 1; \ DSRETURN (NSS_NOTFOUND); \ } while (0) #endif /* * To the untrained eye, this looks like my version of a boolean. It's * really my secret code for taking over the universe ... */ typedef enum { nfalse, ntrue } nboolean; /* * It's SO damn confusing when functions use a return of 0 for success and * 1 for failure, especially amidst functions that have a boolean return * type.. so use this instead. PLEASE. I BEG YOU. */ typedef enum { RETURN_SUCCESS, RETURN_FAILURE } freturn_t; typedef enum { BYNONE, BYNAME, BYNUM } lookup_t; typedef struct { gid_t **groupsp; long int group; long int *start; long int *size; long int limit; } group_info_t; /* Sql queries to execute for ... */ typedef struct { char getpwuid[MAX_VAL_SIZE]; char getpwnam[MAX_VAL_SIZE]; char getspnam[MAX_VAL_SIZE]; char getpwent[MAX_VAL_SIZE]; char getspent[MAX_VAL_SIZE]; char getgrnam[MAX_VAL_SIZE]; char getgrgid[MAX_VAL_SIZE]; char getgrent[MAX_VAL_SIZE]; char gidsbymem[MAX_VAL_SIZE]; /* list of gids a username belongs to */ char memsbygid[MAX_VAL_SIZE]; /* list of members a gid has */ } sql_query_t; typedef struct { char host[MAX_VAL_SIZE]; /* SQL Server to connect to */ char port[MAX_VAL_SIZE]; /* SQL port to connect to */ char socket[MAX_VAL_SIZE]; /* SQL socket path to use */ char username[MAX_VAL_SIZE]; /* Username to connect as */ char password[MAX_VAL_SIZE]; /* Password to connect with */ char database[MAX_VAL_SIZE]; /* SQL Database to open */ } sql_server_t; typedef struct { sql_query_t query; sql_server_t server; } sql_conf_t; typedef struct { nboolean valid; /* Have we loaded config yet? */ sql_conf_t sql; /* [server] section */ } conf_t; /* * As soon as a MySQL link is established, save the results of * getsockname and getpeername here so we can make sure our * socket hasn't been mutilated by an outside program. */ typedef struct { struct sockaddr local; /* getsockname */ struct sockaddr remote; /* getpeername */ } socket_info_t; /* All information regarding existing MySQL link */ typedef struct { nboolean valid; /* Are we connected to a server? */ MYSQL link; socket_info_t sock_info; /* See above */ } con_info_t; /* nss_main.c */ NSS_STATUS _nss_mysql_init (void); void _nss_mysql_log (int priority, char *fmt, ...); #ifdef HAVE_NSS_COMMON_H NSS_STATUS _nss_mysql_default_destr (nss_backend_t *be, void *args); #endif void _nss_mysql_reset_ent (MYSQL_RES **mresult); /* nss_support.c */ NSS_STATUS _nss_mysql_load_passwd (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop); NSS_STATUS _nss_mysql_load_shadow (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop); NSS_STATUS _nss_mysql_load_group (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop); NSS_STATUS _nss_mysql_load_gidsbymem (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop); /* mysql.c */ NSS_STATUS _nss_mysql_close_sql (MYSQL_RES **mresult, nboolean graceful); void _nss_mysql_close_result (MYSQL_RES **mresult); NSS_STATUS _nss_mysql_run_query (char *query, MYSQL_RES **mresult, int *attempts); NSS_STATUS _nss_mysql_fetch_row (MYSQL_ROW *row, MYSQL_RES *mresult); NSS_STATUS _nss_mysql_escape_string (char *to, const char *from, MYSQL_RES **mresult); #define _nss_mysql_num_rows(m) mysql_num_rows (m) #define _nss_mysql_fetch_lengths(m) mysql_fetch_lengths (m) #define _nss_mysql_num_fields(m) mysql_num_fields (m) /* nss_config.c */ NSS_STATUS _nss_mysql_load_config (void); /* lookup.c */ NSS_STATUS _nss_mysql_lookup (lookup_t ltype, const char *name, unsigned int num, char *q, nboolean restricted, void *result, char *buffer, size_t buflen, int *errnop, NSS_STATUS (*load_func)(void *, char *, size_t, MYSQL_RES *, int *), MYSQL_RES **mresult, const char *caller); libnss-mysql-1.6.1/src/nss_support.c000066400000000000000000000344331472655433000175260ustar00rootroot00000000000000/* Copyright 2002 Ben Goodwin Copyright 2024 Bob Proulx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "nss_mysql.h" #include /* memset() */ #include /* struct passwd */ #ifdef HAVE_SHADOW_H #include /* struct spwd */ #endif #include /* struct group */ extern conf_t conf; /* Alignment code adapted from padl.com's nss_ldap */ #ifdef __GNUC__ #define alignof(ptr) __alignof__(ptr) #else #define alignof(ptr) (sizeof(char *)) #endif #define align(ptr, blen, TYPE) \ do { \ char *qtr = ptr; \ ptr += alignof(TYPE) - 1; \ ptr -= ((ptr - (char *)NULL) % alignof(TYPE)); \ blen -= (ptr - qtr); \ } while (0) /* Password */ #if defined(__FreeBSD__) typedef enum { ROW_PW_NAME, ROW_PW_PASSWD, ROW_PW_UID, ROW_PW_GID, ROW_PW_CHANGE, ROW_PW_CLASS, ROW_PW_GECOS, ROW_PW_DIR, ROW_PW_SHELL, ROW_PW_EXPIRE, NUM_PW_ELEMENTS } pw_rows; #elif defined (sun) typedef enum { ROW_PW_NAME, ROW_PW_PASSWD, ROW_PW_UID, ROW_PW_GID, ROW_PW_AGE, ROW_PW_COMMENT, ROW_PW_GECOS, ROW_PW_DIR, ROW_PW_SHELL, NUM_PW_ELEMENTS } pw_rows; #else typedef enum { ROW_PW_NAME, ROW_PW_PASSWD, ROW_PW_UID, ROW_PW_GID, ROW_PW_GECOS, ROW_PW_DIR, ROW_PW_SHELL, NUM_PW_ELEMENTS } pw_rows; #endif /* Shadow */ typedef enum { ROW_SP_NAMP, ROW_SP_PWDP, ROW_SP_LSTCHG, ROW_SP_MIN, ROW_SP_MAX, ROW_SP_WARN, ROW_SP_INACT, ROW_SP_EXPIRE, ROW_SP_FLAG, NUM_SP_ELEMENTS } sp_rows; /* Group */ typedef enum { ROW_GR_NAME, ROW_GR_PASSWD, ROW_GR_GID, ROW_GR_MEM, NUM_GR_ELEMENTS } gr_rows; NSS_STATUS _nss_mysql_load_passwd (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop) { DN ("_nss_mysql_load_passwd"); MYSQL_ROW row; int retVal, i; struct passwd *pw = (struct passwd *)result; size_t offsets[NUM_PW_ELEMENTS]; unsigned long *lengths; unsigned int num_fields; DENTER; retVal = _nss_mysql_fetch_row (&row, mresult); if (retVal != NSS_SUCCESS) DSRETURN (retVal); num_fields = _nss_mysql_num_fields (mresult); if (num_fields != NUM_PW_ELEMENTS) { _nss_mysql_log (LOG_ALERT, "mysql_fetch_row() found %u rows (expecting %u).", num_fields, NUM_PW_ELEMENTS); DSRETURN (NSS_UNAVAIL); } /* Make sure we have enough room in 'buffer' for all our data */ lengths = (unsigned long *) _nss_mysql_fetch_lengths (mresult); offsets[ROW_PW_NAME] = 0; for (i = 1; i < NUM_PW_ELEMENTS; i++) offsets[i] = offsets[i - 1] + lengths[i - 1] + 1; if (offsets[NUM_PW_ELEMENTS - 1] > buflen) EXHAUSTED_BUFFER; /* Clear out buffer and copy in data */ memset (buffer, 0, buflen); pw->pw_name = memcpy (buffer + offsets[ROW_PW_NAME], row[ROW_PW_NAME], lengths[ROW_PW_NAME]); pw->pw_passwd = memcpy (buffer + offsets[ROW_PW_PASSWD], row[ROW_PW_PASSWD], lengths[ROW_PW_PASSWD]); pw->pw_uid = atoi (row[ROW_PW_UID]); pw->pw_gid = atoi (row[ROW_PW_GID]); pw->pw_gecos = memcpy (buffer + offsets[ROW_PW_GECOS], row[ROW_PW_GECOS], lengths[ROW_PW_GECOS]); pw->pw_dir = memcpy (buffer + offsets[ROW_PW_DIR], row[ROW_PW_DIR], lengths[ROW_PW_DIR]); pw->pw_shell = memcpy (buffer + offsets[ROW_PW_SHELL], row[ROW_PW_SHELL], lengths[ROW_PW_SHELL]); #if defined(__FreeBSD__) pw->pw_change = atoi (row[ROW_PW_CHANGE]); pw->pw_class = memcpy (buffer + offsets[ROW_PW_CLASS], row[ROW_PW_CLASS], lengths[ROW_PW_CLASS]); pw->pw_change = atoi (row[ROW_PW_EXPIRE]); #endif #if defined(sun) pw->pw_age = memcpy (buffer + offsets[ROW_PW_AGE], row[ROW_PW_AGE], lengths[ROW_PW_AGE]); pw->pw_comment = memcpy (buffer + offsets[ROW_PW_COMMENT], row[ROW_PW_COMMENT], lengths[ROW_PW_COMMENT]); #endif DSRETURN (NSS_SUCCESS); } #ifdef HAVE_SHADOW_H NSS_STATUS _nss_mysql_load_shadow (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop) { DN ("_nss_mysql_load_shadow"); MYSQL_ROW row; int retVal; struct spwd *sp = (struct spwd *)result; size_t offsets[NUM_SP_ELEMENTS]; unsigned long *lengths; unsigned int num_fields; DENTER; retVal = _nss_mysql_fetch_row (&row, mresult); if (retVal != NSS_SUCCESS) DSRETURN (retVal); num_fields = _nss_mysql_num_fields (mresult); if (num_fields != NUM_SP_ELEMENTS) { _nss_mysql_log (LOG_ALERT, "mysql_fetch_row() found %u rows (expecting %u).", num_fields, NUM_SP_ELEMENTS); DSRETURN (NSS_UNAVAIL); } /* Make sure we have enough room in 'buffer' for all our data */ lengths = (unsigned long *) _nss_mysql_fetch_lengths (mresult); offsets[ROW_SP_NAMP] = 0; offsets[ROW_SP_PWDP] = offsets[ROW_SP_NAMP] + lengths[ROW_SP_NAMP] + 1; if (offsets[ROW_SP_PWDP] + lengths[ROW_SP_PWDP] + 1 > buflen) EXHAUSTED_BUFFER; /* Clear out buffer and copy in data */ memset (buffer, 0, buflen); sp->sp_namp = memcpy (buffer + offsets[ROW_SP_NAMP], row[ROW_SP_NAMP], lengths[ROW_SP_NAMP]); sp->sp_pwdp = memcpy (buffer + offsets[ROW_SP_PWDP], row[ROW_SP_PWDP], lengths[ROW_SP_PWDP]); sp->sp_lstchg = atol (row[ROW_SP_LSTCHG]); sp->sp_min = atol (row[ROW_SP_MIN]); sp->sp_max = atol (row[ROW_SP_MAX]); sp->sp_warn = atol (row[ROW_SP_WARN]); sp->sp_inact = atol (row[ROW_SP_INACT]); sp->sp_expire = atol (row[ROW_SP_EXPIRE]); sp->sp_flag = (unsigned long) atol (row[ROW_SP_FLAG]); DSRETURN (NSS_SUCCESS); } #endif static NSS_STATUS _nss_mysql_load_memsbygid (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop) { DN ("_nss_mysql_load_memsbygid"); MYSQL_ROW row; int retVal; struct group *gr = (struct group *)result; char **members; unsigned long num_rows, i; unsigned long *lengths; size_t strings_offset; DENTER; num_rows = _nss_mysql_num_rows (mresult); align (buffer, buflen, char *); /* Return empty/NULL group list if no members */ if (num_rows == 0) { gr->gr_mem = (char **) (uintptr_t)buffer; DSRETURN (NSS_SUCCESS); } members = (char **)buffer; strings_offset = (num_rows + 1) * sizeof (char *); /* Allow room for NUM_ROWS + 1 pointers */ if (strings_offset > buflen) EXHAUSTED_BUFFER; buflen -= strings_offset; /* Load the first one */ retVal = _nss_mysql_fetch_row (&row, mresult); if (retVal != NSS_SUCCESS) DSRETURN (retVal); lengths = (unsigned long *) _nss_mysql_fetch_lengths (mresult); if (lengths[0] + 1 > buflen) EXHAUSTED_BUFFER; members[0] = buffer + strings_offset; strncpy (members[0], row[0], lengths[0]); buflen -= lengths[0] + 1; /* Load the rest */ for (i = 1; i < num_rows; i++) { /* Set pointer to one byte after the last string loaded */ members[i] = members[i - 1] + lengths[0] + 1; retVal = _nss_mysql_fetch_row (&row, mresult); if (retVal != NSS_SUCCESS) DSRETURN (retVal); lengths = (unsigned long *) _nss_mysql_fetch_lengths (mresult); if (lengths[0] + 1 > buflen) EXHAUSTED_BUFFER; strncpy (members[i], row[0], lengths[0]); buflen -= lengths[0] + 1; } /* Set the last pointer to NULL to terminate the pointer-list */ members[num_rows] = NULL; /* Set gr->gr_mem to point to start of our pointer-list */ gr->gr_mem = (char **) (uintptr_t)buffer; DSRETURN (NSS_SUCCESS); } NSS_STATUS _nss_mysql_load_group (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop) { DN ("_nss_mysql_load_group"); MYSQL_ROW row; MYSQL_RES *mresult_grmem = NULL; int retVal; struct group *gr = (struct group *)result; size_t offsets[NUM_GR_ELEMENTS]; unsigned long *lengths; unsigned int num_fields; DENTER; retVal = _nss_mysql_fetch_row (&row, mresult); if (retVal != NSS_SUCCESS) DSRETURN (retVal); num_fields = _nss_mysql_num_fields (mresult); if (num_fields != NUM_GR_ELEMENTS - 1) /* gr_mem not part of this query */ { _nss_mysql_log (LOG_ALERT, "mysql_fetch_row() found %u rows (expecting %u).", num_fields, NUM_GR_ELEMENTS - 1); DSRETURN (NSS_UNAVAIL); } /* * Make sure we have enough room in 'buffer' for all our data * (not including gr_mem - that's dealt with later */ lengths = (unsigned long *) _nss_mysql_fetch_lengths (mresult); offsets[ROW_GR_NAME] = 0; offsets[ROW_GR_PASSWD] = offsets[ROW_GR_NAME] + lengths[ROW_GR_NAME] + 1; offsets[ROW_GR_MEM] = offsets[ROW_GR_PASSWD] + lengths[ROW_GR_PASSWD] + 1; if (offsets[ROW_GR_MEM] + 1 > buflen) EXHAUSTED_BUFFER; /* Clear out buffer and copy in data (except gr_mem) */ memset (buffer, 0, buflen); gr->gr_name = memcpy (buffer + offsets[ROW_GR_NAME], row[ROW_GR_NAME], lengths[ROW_GR_NAME]); gr->gr_passwd = memcpy (buffer + offsets[ROW_GR_PASSWD], row[ROW_GR_PASSWD], lengths[ROW_GR_PASSWD]); gr->gr_gid = atoi (row[ROW_GR_GID]); /* Load gr_mem */ retVal = _nss_mysql_lookup (BYNUM, NULL, gr->gr_gid, conf.sql.query.memsbygid, nfalse, result, buffer + offsets[ROW_GR_MEM], buflen - offsets[ROW_GR_MEM], errnop, _nss_mysql_load_memsbygid, &mresult_grmem, "_nss_mysql_load_group"); DSRETURN (retVal); } NSS_STATUS _nss_mysql_load_gidsbymem (void *result, char *buffer, size_t buflen, MYSQL_RES *mresult, int *errnop) { DN ("_nss_mysql_load_gidsbymem"); MYSQL_ROW row; unsigned long num_rows, i; group_info_t *gi = (group_info_t *)result; gid_t *groups; int retVal; gid_t gid; DENTER; num_rows = _nss_mysql_num_rows (mresult); /* Nothing to load = success */ if (num_rows == 0) DSRETURN (NSS_SUCCESS); /* If we need more room and we're allowed to alloc it, alloc it */ if (num_rows + *gi->start > *gi->size) { long int newsize = *gi->size; if (gi->limit <= 0) /* Allocate as much as we need */ newsize = num_rows + *gi->start; else if (*gi->size != gi->limit) /* Allocate to limit */ newsize = gi->limit; if (newsize != *gi->size) /* If we've got more room, do it */ { gid_t *groups = *gi->groupsp; gid_t *newgroups; newgroups = realloc (groups, newsize * sizeof (*groups)); if (newgroups != NULL) { *gi->groupsp = groups = newgroups; *gi->size = newsize; } } } groups = *gi->groupsp; for (i = *gi->start; i < *gi->size; i++) { retVal = _nss_mysql_fetch_row (&row, mresult); if (retVal != NSS_SUCCESS) DSRETURN (retVal); gid = atoi (row[0]); if ((long int)gid != gi->group && (long int)gid != groups[0]) groups[(*gi->start)++] = gid; } DSRETURN (NSS_SUCCESS); } /* Thanks to Clement Laforet for most of this */ #if defined(__FreeBSD__) NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r); NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r); NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r); NSS_METHOD_PROTOTYPE(__nss_compat_setpwent); NSS_METHOD_PROTOTYPE(__nss_compat_endpwent); NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r); NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r); NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r); NSS_METHOD_PROTOTYPE(__nss_compat_setgrent); NSS_METHOD_PROTOTYPE(__nss_compat_endgrent); NSS_STATUS _nss_mysql_getpwnam_r (const char *, struct passwd *, char *, size_t, int *); NSS_STATUS _nss_mysql_getpwuid_r (uid_t, struct passwd *, char *, size_t, int *); NSS_STATUS _nss_mysql_getpwent_r (struct passwd *, char *, size_t, int *); NSS_STATUS _nss_mysql_setpwent (void); NSS_STATUS _nss_mysql_endpwent (void); NSS_STATUS _nss_mysql_getgrnam_r (const char *, struct group *, char *, size_t, int *); NSS_STATUS _nss_mysql_getgrgid_r (gid_t, struct group *, char *, size_t, int *); NSS_STATUS _nss_mysql_getgrent_r (struct group *, char *, size_t, int *); NSS_STATUS _nss_mysql_setgrent (void); NSS_STATUS _nss_mysql_endgrent (void); static ns_mtab methods[] = { { NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_mysql_getpwnam_r }, { NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_mysql_getpwuid_r }, { NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, _nss_mysql_getpwent_r }, { NSDB_PASSWD, "endpwent", __nss_compat_setpwent, _nss_mysql_setpwent }, { NSDB_PASSWD, "setpwent", __nss_compat_endpwent, _nss_mysql_endpwent }, { NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_mysql_getgrnam_r }, { NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, _nss_mysql_getgrgid_r }, { NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_mysql_getgrent_r }, { NSDB_GROUP, "endgrent", __nss_compat_setgrent, _nss_mysql_setgrent }, { NSDB_GROUP, "setgrent", __nss_compat_endgrent, _nss_mysql_endgrent }, }; ns_mtab * nss_module_register (const char *name, unsigned int *size, nss_module_unregister_fn *unregister) { *size = sizeof (methods) / sizeof (methods[0]); *unregister = NULL; return (methods); } #endif /* defined(__FreeBSD__) */ libnss-mysql-1.6.1/src/solaris.sym000066400000000000000000000001121472655433000171540ustar00rootroot00000000000000_nss_mysql_group_constr _nss_mysql_passwd_constr _nss_mysql_shadow_constr