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 static const char rcsid[] =
20 "$Id: nss_config.c,v 1.41 2005/01/31 02:16:46 cinergi Exp $";
22 #include "nss_mysql.h"
23 #include <stdio.h> /* fopen() */
24 #include <string.h> /* strlen() */
26 /* global var 'conf' contains data loaded from config files */
27 conf_t conf = CONF_INITIALIZER;
29 /* maps config key to spot in 'conf' */
31 char *name; /* key string */
32 char *ptr; /* where in 'conf' to load this string */
36 * Get the next key/value pair from an open file
37 * return NTRUE if a key/val pair is found
38 * return NFALSE if EOF or error
39 * Lines can begin (column 0) with a '#' for comments
40 * key/val pairs must be in the following format
42 * Whitespace can be spaces or tabs
43 * Keys must be one word (no whitespace)
44 * Values can be anything except CR/LF
45 * Line continuation is supported if EOL is strictly a '\'
46 * (no trailing whitespace)
48 * The in-memory copy of LINE is modified by this routine
50 * fh = open file handle
51 * key = config key loaded here
52 * key_size = storage size of key
53 * val = config value loaded here
54 * val_size = storage size of val
57 _nss_mysql_next_key (FILE *fh, char *key, int key_size, char *val,
60 DN ("_nss_mysql_next_key")
61 char line[MAX_LINE_SIZE];
62 char *ccil; /* Current Character In Line */
65 nboolean fetch_key = ntrue;
70 /* Loop through file until a key/val pair is found or EOF */
71 while (fgets (line, MAX_LINE_SIZE, fh) != NULL)
80 /* Get key - anything but CR/LF or whitespace */
81 ccil += strcspn (ccil, "\n\r \t");
83 continue; /* No key */
84 *ccil = '\0'; /* Null-terminate the key */
85 /* Key found, move on */
88 strncpy (key, cur, key_size);
89 key[key_size - 1] = '\0'; /* strncpy doesn't guarantee null-term */
92 /* Skip leading whitespace */
93 ccil += strspn (ccil, " \t");
95 /* Get value - anything but CR/LF */
96 size = strcspn (ccil, "\n\r");
97 if (!size && fetch_key)
98 continue; /* No value */
100 if (*(ccil - 1) == '\\')
102 fetch_key = nfalse; /* Next line continues a value */
103 *(ccil - 1) = '\0'; /* Remove the '\' */
108 fetch_key = ntrue; /* Next line starts with a key */
109 *ccil = '\0'; /* Null-terminate the value */
111 /* Append what we just snarfed to VAL */
112 strncat (val, cur, val_size - 1);
116 _nss_mysql_log (LOG_ERR, "%s: Config value too long", FUNCNAME);
120 if (!fetch_key) /* Next line continues a value */
123 D ("%s: Found: %s -> %s", FUNCNAME, key, val);
130 * Load configuration data from file
132 * file = full path of file to load
135 _nss_mysql_load_config_file (char *file)
137 DN ("_nss_mysql_load_config_file")
139 char key[MAX_KEY_SIZE];
140 char val[MAX_VAL_SIZE];
144 /* map config key to 'conf' location; must be NULL-terminated */
145 config_info_t config_fields[] =
147 {"getpwnam", conf.sql.query.getpwnam},
148 {"getpwuid", conf.sql.query.getpwuid},
149 {"getspnam", conf.sql.query.getspnam},
150 {"getpwent", conf.sql.query.getpwent},
151 {"getspent", conf.sql.query.getspent},
152 {"getgrnam", conf.sql.query.getgrnam},
153 {"getgrgid", conf.sql.query.getgrgid},
154 {"getgrent", conf.sql.query.getgrent},
155 {"memsbygid", conf.sql.query.memsbygid},
156 {"gidsbymem", conf.sql.query.gidsbymem},
157 {"host", conf.sql.server.host},
158 {"port", conf.sql.server.port},
159 {"socket", conf.sql.server.socket},
160 {"username", conf.sql.server.username},
161 {"password", conf.sql.server.password},
162 {"database", conf.sql.server.database},
168 D ("%s: Attempting to load: %s", FUNCNAME, file);
169 /* No error-handling here; validate_config will catch missing data */
170 if ((fh = fopen (file, "r")) == NULL)
173 D ("%s: fopen() successful", FUNCNAME);
175 /* Step through all key/val pairs available */
176 while (_nss_mysql_next_key (fh, key, MAX_KEY_SIZE, val, MAX_VAL_SIZE))
177 for (c = config_fields; c->name; c++)
178 if (!strcmp (key, c->name))
179 strncpy (c->ptr, val, MAX_VAL_SIZE);
186 * Sanity-check the loaded configuration data
187 * Make sure we have at least a host and database defined
190 _nss_mysql_validate_config (void)
192 DN ("_nss_mysql_validate_config")
195 if (!conf.sql.server.host[0] || !conf.sql.server.database[0])
202 * Load our config files
203 * Upon success, set conf.valid = ntrue
206 _nss_mysql_load_config (void)
208 DN ("_nss_mysql_load_config")
211 /* Config is already loaded, don't do it again */
212 if (conf.valid == ntrue)
213 DSRETURN (NSS_SUCCESS)
215 memset (&conf, 0, sizeof (conf));
217 /* Load main (world-readable) config */
218 _nss_mysql_load_config_file (MAINCFG);
220 /* Load root (root-readable) config */
221 _nss_mysql_load_config_file (ROOTCFG);
223 /* double-check our config */
224 if (_nss_mysql_validate_config () == nfalse)
225 DSRETURN (NSS_UNAVAIL)
227 /* Let the rest of the module know we've got a good config */
230 DSRETURN (NSS_SUCCESS)