1: /*************************************************************************
2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
6: * $Id: aitcfg.c,v 1.7.6.1 2012/09/18 08:44:19 misho Exp $
7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47: #include "aitcfg.h"
48: #include "aitpwd.h"
49:
50:
51: #pragma GCC visibility push(hidden)
52:
53: int cfg_Errno;
54: char cfg_Error[STRSIZ];
55:
56: inline int
57: cfg_tree_cmp(struct tagCfg *a, struct tagCfg *b)
58: {
59: int ret;
60:
61: assert(a && b);
62:
63: ret = ((AIT_KEY(&a->cfg_sec) << 16) | AIT_KEY(&a->cfg_attr)) -
64: ((AIT_KEY(&b->cfg_sec) << 16) | AIT_KEY(&b->cfg_attr));
65:
66: if (ret < 0)
67: return -1;
68: else if (ret > 0)
69: return 1;
70:
71: return ret;
72: }
73:
74: RB_GENERATE(tagRC, tagCfg, cfg_node, cfg_tree_cmp);
75:
76: #pragma GCC visibility pop
77:
78:
79: // cfg_GetErrno() Get error code of last operation
80: inline int
81: cfg_GetErrno()
82: {
83: return cfg_Errno;
84: }
85:
86: // cfg_GetError() Get error text of last operation
87: inline const char *
88: cfg_GetError()
89: {
90: return cfg_Error;
91: }
92:
93: // cfg_SetErr() Set error to variables for internal use!!!
94: inline void
95: cfg_SetErr(int eno, char *estr, ...)
96: {
97: va_list lst;
98:
99: cfg_Errno = eno;
100: memset(cfg_Error, 0, sizeof cfg_Error);
101: va_start(lst, estr);
102: vsnprintf(cfg_Error, sizeof cfg_Error, estr, lst);
103: va_end(lst);
104: }
105:
106:
107: /*
108: * cfgInitConfig() - Init config root
109: *
110: * @cfg = Config root
111: * return: -1 error or 0 ok
112: */
113: int
114: cfgInitConfig(cfg_root_t * __restrict cfg)
115: {
116: if (!cfg)
117: return -1;
118:
119: pthread_mutex_init(&cfg->rc_mtx, NULL);
120:
121: SLIST_INIT(cfg);
122: RB_INIT(cfg);
123: return 0;
124: }
125:
126: /*
127: * cfgLoadConfig() - Load config from file
128: *
129: * @cfgName = Config filename
130: * @cfg = Config root
131: * return: -1 error or 0 ok
132: */
133: int
134: cfgLoadConfig(const char *cfgName, cfg_root_t * __restrict cfg)
135: {
136: FILE *f;
137: int ret;
138:
139: if (!cfgName || !cfg) {
140: cfg_SetErr(EINVAL, "Invalid parameter(s)");
141: return -1;
142: } else
143: cfgInitConfig(cfg);
144:
145: f = fopen(cfgName, "r");
146: if (!f) {
147: LOGERR;
148: return -1;
149: }
150:
151: ret = cfgReadConfig(f, cfg);
152:
153: fclose(f);
154: return ret;
155: }
156:
157: /*
158: * cfgClearConfig() - Clear config and free resources
159: *
160: * @cfg = Config root
161: * return: none
162: */
163: void
164: cfgClearConfig(cfg_root_t * __restrict cfg)
165: {
166: struct tagCfg *av;
167:
168: if (!cfg)
169: return;
170:
171: CFG_RC_LOCK(cfg);
172: while ((av = SLIST_FIRST(cfg))) {
173: SLIST_REMOVE_HEAD(cfg, cfg_next);
174:
175: AIT_FREE_VAL(&av->cfg_val);
176: AIT_FREE_VAL(&av->cfg_attr);
177: AIT_FREE_VAL(&av->cfg_sec);
178: io_free(av);
179: }
180: cfg->rbh_root = NULL;
181: CFG_RC_UNLOCK(cfg);
182: }
183:
184: /*
185: * cfgUnloadConfig() - Unload config from memory and destroy resources
186: *
187: * @cfg = Config root
188: * return: none
189: */
190: void
191: cfgUnloadConfig(cfg_root_t * __restrict cfg)
192: {
193: if (!cfg)
194: return;
195:
196: cfgClearConfig(cfg);
197: pthread_mutex_destroy(&cfg->rc_mtx);
198: }
199:
200: /*
201: * cfgCreateConfig() - Create config file from memory
202: *
203: * @csConfigName = New config filename
204: * @cfg = Config root
205: * @whitespace = Additional whitespace characters to file
206: * return: -1 error or 0 ok
207: */
208: int
209: cfgCreateConfig(const char *csConfigName, cfg_root_t * __restrict cfg, int whitespace)
210: {
211: FILE *f;
212: int ret;
213:
214: if (!csConfigName || !cfg)
215: return -1;
216:
217: f = fopen(csConfigName, "w");
218: if (!f) {
219: LOGERR;
220: return -1;
221: }
222:
223: ret = cfgWriteConfig(f, cfg, whitespace);
224:
225: fclose(f);
226: return ret;
227: }
228:
229: /*
230: * cfgInitPasswd() - Init password root
231: *
232: * @pwd = Password root
233: * return: -1 error or 0 ok
234: */
235: int
236: cfgInitPasswd(pwd_root_t * __restrict pwd)
237: {
238: if (!pwd)
239: return -1;
240:
241: pthread_mutex_init(&pwd->pwd_mtx, NULL);
242:
243: SLIST_INIT(pwd);
244: RB_INIT(pwd);
245: return 0;
246: }
247:
248: /*
249: * cfgLoadPasswd() - Load passwords from file
250: *
251: * @pwdName = Passwords filename
252: * @pwd = Password root
253: * return: -1 error or 0 ok
254: */
255: int
256: cfgLoadPasswd(const char *pwdName, pwd_root_t * __restrict pwd)
257: {
258: FILE *f;
259: int ret;
260:
261: if (!pwdName || !pwd) {
262: cfg_SetErr(EINVAL, "Invalid parameter(s)");
263: return -1;
264: } else
265: cfgInitPasswd(pwd);
266:
267: f = fopen(pwdName, "r");
268: if (!f) {
269: LOGERR;
270: return -1;
271: }
272:
273: ret = cfgReadPasswd(f, pwd);
274:
275: fclose(f);
276: return ret;
277: }
278:
279: /*
280: * cfgClearPasswd() - Clear passwords and free resources
281: *
282: * @cfg = Password root
283: * return: none
284: */
285: void
286: cfgClearPasswd(pwd_root_t * __restrict pwd)
287: {
288: struct tagUser *p;
289:
290: if (!pwd)
291: return;
292:
293: PWD_LOCK(pwd);
294: while ((p = SLIST_FIRST(pwd))) {
295: SLIST_REMOVE_HEAD(pwd, usr_next);
296:
297: AIT_FREE_VAL(&p->usr_name);
298: AIT_FREE_VAL(&p->usr_pass);
299: AIT_FREE_VAL(&p->usr_uid);
300: AIT_FREE_VAL(&p->usr_gid);
301: AIT_FREE_VAL(&p->usr_class);
302: AIT_FREE_VAL(&p->usr_change);
303: AIT_FREE_VAL(&p->usr_expire);
304: AIT_FREE_VAL(&p->usr_realm);
305: AIT_FREE_VAL(&p->usr_home);
306: AIT_FREE_VAL(&p->usr_shell);
307: io_free(p);
308: }
309: pwd->rbh_root = NULL;
310: PWD_UNLOCK(pwd);
311: }
312:
313: /*
314: * cfgUnloadPasswd() - Unload passwords from memory and destroy resources
315: *
316: * @pwd = Password root
317: * return: none
318: */
319: void
320: cfgUnloadPasswd(pwd_root_t * __restrict pwd)
321: {
322: if (!pwd)
323: return;
324:
325: cfgClearPasswd(pwd);
326: pthread_mutex_destroy(&pwd->pwd_mtx);
327: }
328:
329: /*
330: * cfgCreatePasswd() - Create password file from memory
331: *
332: * @pwdName = New password filename
333: * @pwd = Password root
334: * return: -1 error or 0 ok
335: */
336: int
337: cfgCreatePasswd(const char *pwdName, pwd_root_t * __restrict pwd)
338: {
339: FILE *f;
340: int ret;
341:
342: if (!pwdName || !pwd)
343: return -1;
344:
345: f = fopen(pwdName, "w");
346: if (!f) {
347: LOGERR;
348: return -1;
349: }
350:
351: ret = cfgWritePasswd(f, pwd);
352:
353: fclose(f);
354: return ret;
355: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>