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
19 /* $Id: nss_mysql.h,v 1.51 2005/09/04 03:34:02 cinergi Exp $ */
27 #elif defined HAVE_NSS_COMMON_H
28 #include <nss_common.h>
29 #include <nss_dbdefs.h>
31 #error I need either nss.h or nss_common.h!
36 #include <sys/socket.h>
44 #include <sys/types.h>
50 #include <stdlib.h> /* realloc(), free(), malloc(), atoi() */
55 #define NSS_SUCCESS NSS_STATUS_SUCCESS
56 #define NSS_NOTFOUND NSS_STATUS_NOTFOUND
57 #define NSS_UNAVAIL NSS_STATUS_UNAVAIL
58 #define NSS_TRYAGAIN NSS_STATUS_TRYAGAIN
59 typedef enum nss_status NSS_STATUS;
60 #elif defined HAVE_NSS_COMMON_H
61 typedef nss_status_t NSS_STATUS;
62 #define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
65 #define MAX_LINE_SIZE 1024 /* Max line length in config file */
66 #define MAX_QUERY_SIZE 2048 /* Max size of SQL query */
67 #define MAX_NAME_SIZE 128 /* Max username/groupname size */
68 #define MAX_KEY_SIZE 128 /* Max length of a key in cfg file */
69 #define MAX_VAL_SIZE 1024 /* Max length of a val in cfg file */
70 #define MAX_QUERY_ATTEMPTS 3 /* # of query retries */
72 /* Default initializers */
76 void _nss_mysql_debug (char *fmt, ...);
77 #define DEBUG_FILE "/tmp/libnss-mysql-debug.log"
78 #define D _nss_mysql_debug
79 #define DN(n) static const char FUNCNAME[] = n;
80 #define DENTER D ("%s: ENTER", FUNCNAME);
81 #define DIRETURN(r) { D ("%s: EXIT (%d)", FUNCNAME, r); return (r); }
84 D ("%s: EXIT (%s)", FUNCNAME, r == 0 ? "SUCCESS" : "FAIL"); \
89 D ("%s: EXIT (%s)", FUNCNAME, r == ntrue ? "TRUE" : "FALSE"); \
98 status = "NSS_SUCCESS"; \
101 status = "NSS_NOTFOUND"; \
104 status = "NSS_UNAVAIL"; \
107 status = "NSS_TRYAGAIN"; \
110 status = "UNKNOWN"; \
113 D ("%s: EXIT (%s)", FUNCNAME, status); \
116 #define DPRETURN(r) { D ("%s: EXIT (%p)", FUNCNAME, r); return (r); }
117 #define DRETURN { D ("%s: EXIT", FUNCNAME); return; }
118 #define DEXIT D ("%s: EXIT", FUNCNAME);
121 #define DN(n) static const char FUNCNAME[] = n;
123 #define DIRETURN(r) return (r);
124 #define DPRETURN(r) return (r);
125 #define DFRETURN(r) return (r);
126 #define DBRETURN(r) return (r);
127 #define DSRETURN(r) return (r);
128 #define DRETURN return;
132 extern pthread_mutex_t lock;
133 #define LOCK pthread_mutex_lock (&lock)
134 #define UNLOCK pthread_mutex_unlock (&lock)
137 * Linux and Solaris handle buffer exhaustion differently.
138 * Linux sets errno to ERANGE and returns TRYAGAIN, which results in
139 * the NSS system trying with a buffer twice as big.
140 * Solaris, however, doesn't seem to retry. I've checked the Solaris 8
141 * code for files/ldap/nisplus NSS and they all set NSS_ARGS(args)->erange
142 * to 1 and return NOTFOUND. Note that this macro sets *errnop to 1, but
143 * it's not really errnop, it's erange - see the calling functions.
144 * In fact, my tests reveal that if you return TRYAGAIN, Solaris will try
145 * over and over, without increasing the buffer - AKA infinite (or long)
149 #define EXHAUSTED_BUFFER \
152 DSRETURN (NSS_TRYAGAIN); \
155 #define EXHAUSTED_BUFFER \
159 DSRETURN (NSS_NOTFOUND); \
164 * To the untrained eye, this looks like my version of a boolean. It's
165 * really my secret code for taking over the universe ...
173 * It's SO damn confusing when functions use a return of 0 for success and
174 * 1 for failure, especially amidst functions that have a boolean return
175 * type.. so use this instead. PLEASE. I BEG YOU.
196 /* Sql queries to execute for ... */
198 char getpwuid[MAX_VAL_SIZE];
199 char getpwnam[MAX_VAL_SIZE];
200 char getspnam[MAX_VAL_SIZE];
201 char getpwent[MAX_VAL_SIZE];
202 char getspent[MAX_VAL_SIZE];
203 char getgrnam[MAX_VAL_SIZE];
204 char getgrgid[MAX_VAL_SIZE];
205 char getgrent[MAX_VAL_SIZE];
206 char gidsbymem[MAX_VAL_SIZE]; /* list of gids a username belongs to */
207 char memsbygid[MAX_VAL_SIZE]; /* list of members a gid has */
211 char host[MAX_VAL_SIZE]; /* SQL Server to connect to */
212 char port[MAX_VAL_SIZE]; /* SQL port to connect to */
213 char socket[MAX_VAL_SIZE]; /* SQL socket path to use */
214 char username[MAX_VAL_SIZE]; /* Username to connect as */
215 char password[MAX_VAL_SIZE]; /* Password to connect with */
216 char database[MAX_VAL_SIZE]; /* SQL Database to open */
225 nboolean valid; /* Have we loaded config yet? */
226 sql_conf_t sql; /* [server] section */
229 #define CONF_INITIALIZER {0}
232 * As soon as a MySQL link is established, save the results of
233 * getsockname and getpeername here so we can make sure our
234 * socket hasn't been mutilated by an outside program.
237 struct sockaddr local; /* getsockname */
238 struct sockaddr remote; /* getpeername */
241 /* All information regarding existing MySQL link */
243 nboolean valid; /* Are we connected to a server? */
245 socket_info_t sock_info; /* See above */
249 NSS_STATUS _nss_mysql_init (void);
250 void _nss_mysql_log (int priority, char *fmt, ...);
251 #ifdef HAVE_NSS_COMMON_H
252 NSS_STATUS _nss_mysql_default_destr (nss_backend_t *be, void *args);
254 void _nss_mysql_reset_ent (MYSQL_RES **mresult);
257 NSS_STATUS _nss_mysql_load_passwd (void *result, char *buffer, size_t buflen,
258 MYSQL_RES *mresult, int *errnop);
259 NSS_STATUS _nss_mysql_load_shadow (void *result, char *buffer, size_t buflen,
260 MYSQL_RES *mresult, int *errnop);
261 NSS_STATUS _nss_mysql_load_group (void *result, char *buffer, size_t buflen,
262 MYSQL_RES *mresult, int *errnop);
263 NSS_STATUS _nss_mysql_load_gidsbymem (void *result, char *buffer, size_t buflen,
264 MYSQL_RES *mresult, int *errnop);
267 NSS_STATUS _nss_mysql_close_sql (MYSQL_RES **mresult, nboolean graceful);
268 void _nss_mysql_close_result (MYSQL_RES **mresult);
269 NSS_STATUS _nss_mysql_run_query (char *query, MYSQL_RES **mresult,
271 NSS_STATUS _nss_mysql_fetch_row (MYSQL_ROW *row, MYSQL_RES *mresult);
272 NSS_STATUS _nss_mysql_escape_string (char *to, const char *from,
273 MYSQL_RES **mresult);
274 #define _nss_mysql_num_rows(m) mysql_num_rows (m)
275 #define _nss_mysql_fetch_lengths(m) mysql_fetch_lengths (m)
276 #define _nss_mysql_num_fields(m) mysql_num_fields (m)
279 NSS_STATUS _nss_mysql_load_config (void);
282 NSS_STATUS _nss_mysql_lookup (lookup_t ltype, const char *name,
283 unsigned int num, char *q, nboolean restricted,
284 void *result, char *buffer, size_t buflen,
286 NSS_STATUS (*load_func)(void *, char *, size_t,
288 MYSQL_RES **mresult, const char *caller);