1 /* Copyright (C) 2002 Ben Goodwin
2 This file is part of the nss-mysql library.
4 The nss-mysql library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as published
6 by the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 The nss-mysql library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with the nss-mysql library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Global variables and miscellaneous support routines
23 static const char rcsid[] =
24 "$Id: nss_main.c,v 1.31 2004/11/13 18:10:32 cinergi Exp $";
26 #include "nss_mysql.h"
27 #include <stdio.h> /* fprintf() */
28 #include <stdarg.h> /* va_start() */
29 #include <sys/stat.h> /* umask() */
32 * GNU source only defines RTLD_DEFAULT if __USE_GNU is set
40 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
41 pthread_once_t _nss_mysql_once_control = {PTHREAD_ONCE_INIT};
42 static int _nss_mysql_locked_by_atfork = 0;
44 #define MAX_MSG_SIZE 1024
47 * Debugs to either a file, stderr, or syslog, depending on the environ var
49 * none or 0 = file (DEBUG_FILE, defined in nss_mysql.h)
51 * 2 = syslog (facility defined at configure, priority DEBUG)
55 _nss_mysql_debug (char *fmt, ...)
58 char msg[MAX_MSG_SIZE];
65 vsnprintf (msg, MAX_MSG_SIZE, fmt, ap);
66 env = getenv ("LIBNSS_MYSQL_DEBUG");
74 old_mask = umask (000);
75 fh = fopen (DEBUG_FILE, "a");
82 fprintf (fh, "[%d]: %s\n", getpid(), msg);
89 _nss_mysql_log (LOG_DEBUG, "%s", msg);
98 * libnss-mysql is *not* to be linked against any threading library.
99 * Instead, check for pthread functions in the current namespace
100 * by using dlsym() and RTLD_DEFAULT. This way we don't litter every
101 * application with a thread library (since libnss-mysql would be linked
102 * against it and so many applications would dlopen libnss-mysql).
103 * Applications often misbehave when a thread environment is unexpected
105 * libnss-mysql is *not* to be linked against the threaded version
106 * of MySQL for the same reasons. libnss-mysql is not coded in such
107 * a way that a threaded MySQL library is needed, anyway.
109 * libnss-mysql locks just prior to calling _nss_mysql_lookup() and
110 * unlocks when done with it and all data handled by it. Since the lock
111 * occurs so early on and lasts so long, libnss-mysql doesn't perform
112 * that well in a heavily threaded application (e.g. a threaded radius
113 * server). Use of "nscd" is highly recommended.
117 * Before fork() processing begins, the prepare fork handler is called
120 _nss_mysql_atfork_prepare (void)
122 DN ("_nss_mysql_atfork_prepare")
126 trylock = (int (*)(int))dlsym (RTLD_DEFAULT, "pthread_mutex_trylock");
128 if ((*trylock) (&lock) == 0)
129 _nss_mysql_locked_by_atfork = 1;
134 * The parent fork handler is called after fork() processing finishes
135 * in the parent process
138 _nss_mysql_atfork_parent (void)
140 DN ("_nss_mysql_atfork_parent")
142 if (_nss_mysql_locked_by_atfork)
144 _nss_mysql_locked_by_atfork = 0;
151 * The child fork handler is called after fork() processing finishes in the
155 _nss_mysql_atfork_child (void)
157 DN ("_nss_mysql_atfork_child")
159 /* Don't close the link; just set it to invalid so we'll open a new one */
160 _nss_mysql_close_sql (NULL, nfalse);
161 if (_nss_mysql_locked_by_atfork)
163 _nss_mysql_locked_by_atfork = 0;
169 /* Setup pthread_atfork if current namespace contains pthreads. */
171 _nss_mysql_pthread_once_init (void)
173 DN ("_nss_mysql_atfork_once_init")
174 int (*pthread_atfork)();
177 pthread_atfork = (int (*)(int))dlsym (RTLD_DEFAULT, "pthread_atfork");
179 (*pthread_atfork) (_nss_mysql_atfork_prepare, _nss_mysql_atfork_parent,
180 _nss_mysql_atfork_child);
185 * Prevent the "dead store removal" problem present with stock memset()
188 _nss_mysql_safe_memset (void *s, int c, size_t n)
190 DN ("_nss_mysql_safe_memset")
191 volatile char *p = s;
203 * Make an attempt to close the link when the process exits
204 * Set in _nss_mysql_init() below
207 _nss_mysql_atexit_handler (void)
209 DN ("_nss_mysql_atexit_handler")
213 _nss_mysql_close_sql (NULL, ntrue);
214 _nss_mysql_safe_memset (conf.sql.server.password, 0,
215 sizeof (conf.sql.server.password));
220 * Setup pthread_once if it's available in the current namespace
221 * Load config file(s)
224 _nss_mysql_init (void)
226 DN ("_nss_mysql_init")
227 int (*pthread_once)();
228 static int atexit_isset = nfalse;
231 pthread_once = (int (*)(int))dlsym (RTLD_DEFAULT, "pthread_once");
233 (*pthread_once) (&_nss_mysql_once_control, _nss_mysql_pthread_once_init);
234 if (atexit_isset == nfalse)
236 if (atexit(_nss_mysql_atexit_handler) == RETURN_SUCCESS)
237 atexit_isset = ntrue;
239 DSRETURN (_nss_mysql_load_config ())
243 * Syslog a message at PRIORITY.
244 * Do *NOT* openlog/closelog as you'll mess up calling programs that
245 * are syslogging their own stuff.
248 _nss_mysql_log (int priority, char *fmt, ...)
250 DN ("_nss_mysql_log")
252 char msg[MAX_MSG_SIZE];
255 vsnprintf (msg, MAX_MSG_SIZE, fmt, ap);
256 syslog (priority, "%s: %s", PACKAGE, msg);
260 #ifdef HAVE_NSS_COMMON_H
262 _nss_mysql_default_destr (nss_backend_t *be, void *args)
264 DN ("_nss_mysql_default_destr")
271 /* Closing link & freeing memory unnecessary due to link w/ '-znodelete' */
272 DSRETURN (NSS_SUCCESS)
278 * SET/END ent's call this. While the definition of endent is to close
279 * the "file", we need to keep the MySQL link persistent, so we just
280 * clear any lingering MySQL result set.
283 _nss_mysql_reset_ent (MYSQL_RES **mresult)
285 DN ("_nss_mysql_reset_ent")
287 _nss_mysql_close_result (mresult);