1 /* spmfilter - mail filtering framework
2 * Copyright (C) 2009-2012 Axel Steiner and SpaceNet AG
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
8 *
9 * This program 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 GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #define THIS_MODULE "settings"
19 #define _GNU_SOURCE
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <strings.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <sys/stat.h>
29 #include <syslog.h>
30
31 #include "smf_trace.h"
32 #include "smf_settings.h"
33 #include "smf_settings_private.h"
34 #include "smf_list.h"
35 #include "smf_dict.h"
36 #include "smf_core.h"
37 #include "smf_internal.h"
38 #include "smf_modules.h"
39
40 #define MAX_LINE 200
41
42 /**
43 * This enum stores the status for each parsed line (internal use only).
44 */
45 typedef enum _line_status {
46 LINE_UNPROCESSED,
47 LINE_ERROR,
48 LINE_EMPTY,
49 LINE_COMMENT,
50 LINE_SECTION,
51 LINE_VALUE
52 } line_status ;
53
_mod_list_destroy(void * data)54 void _mod_list_destroy(void *data) {
55 SMFModule_T *mod = (SMFModule_T *)data;
56 smf_module_destroy(mod);
57 }
58
_get_boolean(char * val)59 int _get_boolean(char *val) {
60 int ret = 0;
61
62 if (val[0]=='y' || val[0]=='Y' || val[0]=='1' || val[0]=='t' || val[0]=='T') {
63 ret = 1 ;
64 }
65
66 return ret;
67 }
68
_get_integer(char * val)69 int _get_integer(char *val) {
70 return (int)strtol(val, NULL, 0);
71 }
72
_get_list(char * val)73 char **_get_list(char *val) {
74 char **sl = NULL;
75
76 if (strchr(val,';') != NULL) {
77 sl = smf_core_strsplit(val, ";", NULL);
78 } else {
79 sl = smf_core_strsplit(val, ",", NULL);
80 }
81
82 return sl;
83 }
84
_parse_line(char * input_line,char * section,char * key,char * value)85 static line_status _parse_line(
86 char *input_line,
87 char *section,
88 char *key,
89 char *value) {
90
91 line_status sta;
92 char *line;
93 int len;
94
95 line = smf_core_strstrip(input_line);
96 len = (int)strlen(line);
97
98 sta = LINE_UNPROCESSED ;
99 if (len<1) {
100 /* Empty line */
101 sta = LINE_EMPTY ;
102 } else if (line[0]=='#' || line[0]==';') {
103 /* Comment line */
104 sta = LINE_COMMENT ;
105 } else if (line[0]=='[' && line[len-1]==']') {
106 /* Section name */
107 sscanf(line, "[%[^]]", section);
108 sta = LINE_SECTION ;
109 } else if (sscanf(line, "%[^=] = \"%[^\"]\"", key, value)==2
110 || sscanf(line, "%[^=] = '%[^\']'", key, value)==2
111 || sscanf(line, "%[^=] = %[^#]", key, value)==2) {
112 /* sscanf cannot handle '' or "" as empty values
113 * this is done here
114 */
115 if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
116 value[0]=0;
117 }
118 sta = LINE_VALUE ;
119 } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2
120 || sscanf(line, "%[^=] %[=]", key, value)==2) {
121 /*
122 * Special cases:
123 * key=
124 * key=;
125 * key=#
126 */
127 value[0]=0;
128 sta = LINE_VALUE ;
129 } else {
130 /* Generate syntax error */
131 sta = LINE_ERROR ;
132 }
133
134 return sta ;
135 }
136
_set_config_value(SMFSettings_T ** settings,char * section,char * key,char * val)137 void _set_config_value(SMFSettings_T **settings, char *section, char *key, char *val) {
138 char **sl = NULL;
139 char **p = NULL;
140 char *s = NULL;
141 char *tmp = NULL;
142 int i;
143
144 if (val==NULL || strlen(val) == 0)
145 return;
146
147 /** global section **/
148 if (strcmp(section,"global")==0) {
149 /** [global]debug **/
150 if (strcmp(key,"debug")==0) {
151 (*settings)->debug = _get_boolean(val);
152 configure_debug((*settings)->debug);
153 /** [global]queue_dir **/
154 } else if (strcmp(key,"queue_dir")==0) {
155 if ((*settings)->queue_dir!=NULL)
156 free((*settings)->queue_dir);
157
158 (*settings)->queue_dir = strdup(val);
159 /** [global]modules **/
160 } else if (strcmp(key, "modules")==0) {
161 if (smf_list_size((*settings)->modules) > 0) {
162 if (smf_list_free((*settings)->modules)!=0)
163 TRACE(TRACE_ERR,"failed to free modules list");
164 else
165 if (smf_list_new(&((*settings)->modules),_mod_list_destroy)!=0)
166 TRACE(TRACE_ERR,"failed to create modules list");
167 }
168 sl = _get_list(val);
169 p = sl;
170 while(*p != NULL) {
171 s = smf_core_strstrip(*p);
172 smf_settings_add_module((*settings),s);
173 free(s);
174 p++;
175 }
176 free(sl);
177 /** [global]engine **/
178 } else if (strcmp(key,"engine")==0) {
179 if ((*settings)->engine!=NULL)
180 free((*settings)->engine);
181
182 (*settings)->engine = strdup(val);
183 /** [global]module_fail **/
184 } else if (strcmp(key,"module_fail")==0) {
185 i = _get_integer(val);
186
187 /** check allowed values... */
188 if (i==1 || i==2 || i==3)
189 (*settings)->module_fail = i;
190 /** [global]nexthop **/
191 } else if (strcmp(key,"nexthop")==0) {
192 if ((*settings)->nexthop!=NULL)
193 free((*settings)->nexthop);
194
195 (*settings)->nexthop = strdup(val);
196 /** [global]backend **/
197 } else if (strcmp(key,"backend")==0) {
198 if ((*settings)->backend!=NULL)
199 free((*settings)->backend);
200
201 if ((strcmp(val,"sql")==0)||(strcmp(val,"ldap")==0))
202 (*settings)->backend = strdup(val);
203 /** [global]backend_connection **/
204 } else if (strcmp(key,"backend_connection")==0) {
205 if ((*settings)->backend_connection!=NULL)
206 free((*settings)->backend_connection);
207
208 if ((strcmp(val,"balance")==0)||(strcmp(val,"failover")==0))
209 (*settings)->backend_connection = strdup(val);
210 /** [global]add_header **/
211 } else if (strcmp(key,"add_header")==0) {
212 (*settings)->add_header = _get_boolean(val);
213 /** [global]max_size **/
214 } else if (strcmp(key,"max_size")==0) {
215 (*settings)->max_size = _get_integer(val);
216 /** [global]tls_enable **/
217 } else if (strcmp(key,"tls_enable")==0) {
218 i = _get_integer(val);
219 /** check allowed values... */
220 if (i==0 || i==1 || i==2)
221 (*settings)->tls = i;
222 /** [global]lib_dir **/
223 } else if (strcmp(key,"lib_dir")==0) {
224 if ((*settings)->lib_dir!=NULL)
225 free((*settings)->lib_dir);
226
227 (*settings)->lib_dir = strdup(val);
228 /** [global]pid_file **/
229 } else if (strcmp(key,"pid_file")==0) {
230 if ((*settings)->pid_file!=NULL)
231 free((*settings)->pid_file);
232
233 (*settings)->pid_file = strdup(val);
234 /** [global]bind_ip **/
235 } else if (strcmp(key,"bind_ip")==0) {
236 if ((*settings)->bind_ip!=NULL)
237 free((*settings)->bind_ip);
238
239 (*settings)->bind_ip = strdup(val);
240 /** [global]bind_port **/
241 } else if (strcmp(key,"bind_port")==0) {
242 (*settings)->bind_port = _get_integer(val);
243 /** [global]listen_backlog **/
244 } else if (strcmp(key,"listen_backlog")==0) {
245 (*settings)->listen_backlog = _get_integer(val);
246 /** [global]foreground **/
247 } else if (strcmp(key,"foreground")==0) {
248 int fg = _get_boolean(val);
249 (*settings)->foreground = fg;
250 configure_trace_destination(fg ? TRACE_DEST_STDERR : TRACE_DEST_SYSLOG);
251 /** [global]user **/
252 } else if (strcmp(key,"user")==0) {
253 if ((*settings)->user!=NULL)
254 free((*settings)->user);
255
256 (*settings)->user = strdup(val);
257 /** [global]group **/
258 } else if (strcmp(key,"group")==0) {
259 if ((*settings)->group!=NULL)
260 free((*settings)->group);
261
262 (*settings)->group = strdup(val);
263 /** [global]max_childs **/
264 } else if (strcmp(key,"max_childs")==0) {
265 (*settings)->max_childs = _get_integer(val);
266 /** [global]spare_childs **/
267 } else if (strcmp(key,"spare_childs")==0) {
268 (*settings)->spare_childs = _get_integer(val);
269 /** [global]lookup_persistent **/
270 } else if (strcmp(key,"lookup_persistent")==0) {
271 (*settings)->lookup_persistent = _get_boolean(val);
272 } else if (strcmp(key,"syslog_facility")==0) {
273 smf_settings_set_syslog_facility((*settings), val);
274 }
275 /** sql section **/
276 } else if (strcmp(section,"sql")==0) {
277 /** [sql]driver **/
278 if (strcmp(key,"driver")==0) {
279 if ((*settings)->sql_driver != NULL)
280 free((*settings)->sql_driver);
281
282 if ((strcmp(val,"mysql")==0)||(strcmp(val,"postgresql")==0)||(strcmp(val,"sqlite")==0))
283 (*settings)->sql_driver = strdup(val);
284 /** [sql]name **/
285 } else if (strcmp(key, "name")==0) {
286 if ((*settings)->sql_name != NULL)
287 free((*settings)->sql_name);
288
289 (*settings)->sql_name = strdup(val);
290 /** [sql]host **/
291 } else if (strcmp(key, "host")==0) {
292 if (smf_list_size((*settings)->sql_host) > 0) {
293 if (smf_list_free((*settings)->sql_host)!=0)
294 TRACE(TRACE_ERR,"failed to free host list");
295 else
296 if (smf_list_new(&((*settings)->sql_host),smf_internal_string_list_destroy)!=0)
297 TRACE(TRACE_ERR,"failed to create host list");
298 }
299 sl = _get_list(val);
300 p = sl;
301 while(*p != NULL) {
302 s = smf_core_strstrip(*p);
303 smf_list_append((*settings)->sql_host, s);
304 p++;
305 }
306 free(sl);
307 /** [sql]user **/
308 } else if (strcmp(key, "user")==0) {
309 if ((*settings)->sql_user != NULL)
310 free((*settings)->sql_user);
311
312 (*settings)->sql_user = strdup(val);
313 /** [sql]pass **/
314 } else if (strcmp(key, "pass")==0) {
315 if ((*settings)->sql_pass != NULL)
316 free((*settings)->sql_pass);
317
318 (*settings)->sql_pass = strdup(val);
319 /** [sql]user_query **/
320 } else if (strcmp(key, "user_query")==0) {
321 if ((*settings)->sql_user_query != NULL)
322 free((*settings)->sql_user_query);
323
324 (*settings)->sql_user_query = strdup(val);
325 /** [sql]encoding **/
326 } else if (strcmp(key, "encoding")==0) {
327 if ((*settings)->sql_encoding != NULL)
328 free((*settings)->sql_encoding);
329
330 (*settings)->sql_encoding = strdup(val);
331 /** [sql]max_connections **/
332 } else if (strcmp(key,"max_connections")==0) {
333 (*settings)->sql_max_connections = _get_integer(val);
334 /** [sql]port **/
335 } else if (strcmp(key,"port")==0) {
336 (*settings)->sql_port = _get_integer(val);
337 }
338 /** ldap section **/
339 } else if (strcmp(section,"ldap")==0) {
340 /** [ldap]uri **/
341 if (strcmp(key, "uri")==0) {
342 if ((*settings)->ldap_uri != NULL)
343 free((*settings)->ldap_uri);
344
345 (*settings)->ldap_uri = strdup(val);
346 /** [ldap]host **/
347 } else if (strcmp(key, "host")==0) {
348 if (smf_list_size((*settings)->ldap_host) > 0) {
349 if (smf_list_free((*settings)->ldap_host)!=0)
350 TRACE(TRACE_ERR,"failed to free host list");
351 else
352 if (smf_list_new(&((*settings)->ldap_host),smf_internal_string_list_destroy)!=0)
353 TRACE(TRACE_ERR,"failed to create host list");
354 }
355 sl = _get_list(val);
356 p = sl;
357 while(*p != NULL) {
358 s = smf_core_strstrip(*p);
359 smf_list_append((*settings)->ldap_host, s);
360 p++;
361 }
362 free(sl);
363 /** [ldap]port **/
364 } else if (strcmp(key,"port")==0) {
365 (*settings)->ldap_port = _get_integer(val);
366 /** [ldap]binddn **/
367 } else if (strcmp(key, "binddn")==0) {
368 if ((*settings)->ldap_binddn != NULL)
369 free((*settings)->ldap_binddn);
370
371 (*settings)->ldap_binddn = strdup(val);
372 /** [ldap]bindpw **/
373 } else if (strcmp(key, "bindpw")==0) {
374 if ((*settings)->ldap_bindpw != NULL)
375 free((*settings)->ldap_bindpw);
376
377 (*settings)->ldap_bindpw = strdup(val);
378 /** [ldap]base **/
379 } else if (strcmp(key, "base")==0) {
380 if ((*settings)->ldap_base != NULL)
381 free((*settings)->ldap_base);
382
383 (*settings)->ldap_base = strdup(val);
384 /** [ldap]user_query **/
385 } else if (strcmp(key, "user_query")==0) {
386 if ((*settings)->ldap_user_query != NULL)
387 free((*settings)->ldap_user_query);
388
389 (*settings)->ldap_user_query = strdup(val);
390 /** [ldap]result_attributes **/
391 } else if (strcmp(key, "result_attributes")==0) {
392 if (smf_list_size((*settings)->ldap_result_attributes) > 0) {
393 if (smf_list_free((*settings)->ldap_result_attributes)!=0)
394 TRACE(TRACE_ERR,"failed to free result attribute list");
395 else
396 if (smf_list_new(&((*settings)->ldap_result_attributes),smf_internal_string_list_destroy)!=0)
397 TRACE(TRACE_ERR,"failed to create result attribute list");
398 }
399 sl = _get_list(val);
400 p = sl;
401 while(*p != NULL) {
402 s = smf_core_strstrip(*p);
403 smf_list_append((*settings)->ldap_result_attributes, s);
404 p++;
405 }
406 free(sl);
407
408 /** [ldap]scope **/
409 } else if (strcmp(key, "scope")==0) {
410 if ((*settings)->ldap_scope != NULL)
411 free((*settings)->ldap_scope);
412
413 (*settings)->ldap_scope = strdup(val);
414 /** [ldap]referrals **/
415 } else if (strcmp(key,"referrals")==0) {
416 (*settings)->ldap_referrals = _get_boolean(val);
417 }
418 /** smtpd section **/
419 } else if (strcmp(section,"smtpd")==0) {
420 /** [smtpd]nexthop_fail_msg **/
421 if (strcmp(key, "nexthop_fail_msg")==0) {
422 if ((*settings)->nexthop_fail_msg != NULL)
423 free((*settings)->nexthop_fail_msg);
424
425 (*settings)->nexthop_fail_msg = strdup(val);
426 /** [smtpd]nexthop_fail_code **/
427 } else if (strcmp(key, "nexthop_fail_code")==0) {
428 (*settings)->nexthop_fail_code = _get_integer(val);
429 } else if (strcmp(key, "smtpd_timeout")==0) {
430 (*settings)->smtpd_timeout = _get_integer(val);
431 /** smtp code **/
432 } else {
433 i = _get_integer(key);
434 if (i >= 250 && i < 600) {
435 smf_dict_set((*settings)->smtp_codes,key,val);
436 }
437 }
438 /** custom sections */
439 } else {
440 asprintf(&tmp,"%s:%s",section,key);
441 smf_dict_set((*settings)->groups,tmp,val);
442 }
443
444 }
445
smf_settings_new(void)446 SMFSettings_T *smf_settings_new(void) {
447 SMFSettings_T *settings = NULL;
448
449 if (!(settings = (SMFSettings_T *)calloc(1, sizeof(SMFSettings_T))))
450 return NULL;
451
452 settings->debug = 0;
453 settings->config_file = NULL;
454 settings->queue_dir = NULL;
455 settings->engine = NULL;
456 if (smf_list_new(&settings->modules, _mod_list_destroy) != 0) {
457 TRACE(TRACE_ERR,"failed to allocate space for settings->modules");
458 free(settings);
459 return NULL;
460 }
461 settings->nexthop = NULL;
462 settings->nexthop_fail_msg = NULL;
463 settings->backend = NULL;
464 settings->backend_connection = NULL;
465 settings->lib_dir = NULL;
466 settings->pid_file = NULL;
467 settings->bind_ip = NULL;
468 settings->bind_port = 10025;
469 settings->listen_backlog = 511;
470 settings->foreground = 0;
471 settings->user = NULL;
472 settings->group = NULL;
473 settings->max_childs = 10;
474 settings->spare_childs = 2;
475 settings->lookup_persistent = 0;
476 settings->syslog_facility = LOG_MAIL;
477
478 settings->smtp_codes = smf_dict_new();
479 settings->smtpd_timeout = 300;
480
481 settings->sql_driver = NULL;
482 settings->sql_name = NULL;
483 if (smf_list_new(&settings->sql_host, smf_internal_string_list_destroy) != 0) {
484 TRACE(TRACE_ERR,"failed to allocate space for settings->sql_host");
485 smf_list_free(settings->modules);
486 free(settings);
487 return NULL;
488 }
489 settings->sql_user = NULL;
490 settings->sql_pass = NULL;
491 settings->sql_user_query = NULL;
492 settings->sql_encoding = NULL;
493 settings->ldap_uri = NULL;
494 if (smf_list_new(&settings->ldap_host, smf_internal_string_list_destroy) != 0) {
495 TRACE(TRACE_ERR,"failed to allocate space for settings->ldap_host");
496 smf_list_free(settings->modules);
497 smf_list_free(settings->sql_host);
498 free(settings);
499 return NULL;
500 }
501 settings->ldap_binddn = NULL;
502 settings->ldap_bindpw = NULL;
503 settings->ldap_base = NULL;
504 settings->ldap_scope = NULL;
505 settings->ldap_referrals = 0;
506 settings->ldap_user_query = NULL;
507 if (smf_list_new(&settings->ldap_result_attributes, smf_internal_string_list_destroy) != 0) {
508 TRACE(TRACE_ERR, "failed to allocate space for settings->ldap_result_attributes");
509 smf_list_free(settings->modules);
510 smf_list_free(settings->sql_host);
511 smf_list_free(settings->ldap_host);
512 free(settings);
513 return NULL;
514 }
515 settings->module_fail = 3;
516 settings->nexthop_fail_code = 451;
517 settings->add_header = 1;
518 settings->max_size = 0;
519 settings->tls = 0;
520 settings->sql_max_connections = 3;
521 settings->sql_port = 0;
522 settings->ldap_port = 0;
523
524 settings->lookup_connection = NULL;
525
526 settings->groups = smf_dict_new();
527
528 return settings;
529 }
530
smf_settings_free(SMFSettings_T * settings)531 void smf_settings_free(SMFSettings_T *settings) {
532 assert(settings);
533
534 if (smf_list_free(settings->modules) != 0)
535 TRACE(TRACE_ERR,"failed to free settings->modules");
536
537 if (settings->config_file != NULL) free(settings->config_file);
538 if (settings->queue_dir != NULL) free(settings->queue_dir);
539 if (settings->engine != NULL) free(settings->engine);
540 if (settings->nexthop != NULL) free(settings->nexthop);
541 if (settings->nexthop_fail_msg != NULL) free(settings->nexthop_fail_msg);
542 if (settings->backend != NULL) free(settings->backend);
543 if (settings->backend_connection != NULL) free(settings->backend_connection);
544 if (settings->lib_dir != NULL) free(settings->lib_dir);
545 if (settings->pid_file != NULL) free(settings->pid_file);
546 if (settings->bind_ip != NULL) free(settings->bind_ip);
547 if (settings->user != NULL) free(settings->user);
548 if (settings->group != NULL) free(settings->group);
549
550 smf_dict_free(settings->smtp_codes);
551 if (settings->sql_driver) free(settings->sql_driver);
552 if (settings->sql_name) free(settings->sql_name);
553 if (smf_list_free(settings->sql_host) != 0)
554 TRACE(TRACE_ERR,"failed to free settings->sql_host");
555 if (settings->sql_user != NULL) free(settings->sql_user);
556 if (settings->sql_pass != NULL) free(settings->sql_pass);
557 if (settings->sql_user_query != NULL) free(settings->sql_user_query);
558 if (settings->sql_encoding != NULL) free(settings->sql_encoding);
559 if (settings->ldap_uri != NULL) free(settings->ldap_uri);
560 if (smf_list_free(settings->ldap_host) != 0)
561 TRACE(TRACE_ERR,"failed to free settings->ldap_host");
562 if (settings->ldap_binddn != NULL) free(settings->ldap_binddn);
563 if (settings->ldap_bindpw != NULL) free(settings->ldap_bindpw);
564 if (settings->ldap_base != NULL) free(settings->ldap_base);
565 if (settings->ldap_scope != NULL) free(settings->ldap_scope);
566 if (settings->ldap_user_query != NULL) free(settings->ldap_user_query);
567 if (smf_list_free(settings->ldap_result_attributes) != 0)
568 TRACE(TRACE_ERR,"failed to free settings->ldap_result_attributes");
569
570 smf_dict_free(settings->groups);
571
572 free(settings);
573 }
574
smf_settings_parse_config(SMFSettings_T ** settings,char * alternate_file)575 int smf_settings_parse_config(SMFSettings_T **settings, char *alternate_file) {
576 FILE *in = NULL;
577 char line[MAX_LINE+1];
578 char section[MAX_LINE+1];
579 char key[MAX_LINE+1];
580 char val[MAX_LINE+1];
581 SMFList_T *list = NULL;
582 SMFListElem_T *elem = NULL;
583 char *s = NULL;
584 int last=0;
585 int len=0;
586 int lineno=0;
587 int errs=0;
588 char *clean_section = NULL;
589 char *clean_key = NULL;
590 char *clean_val = NULL;
591 char *tmp = NULL;
592 SMFModule_T *mod = NULL;
593
594 assert(*settings);
595
596 /* fallback to default config path,
597 * if config file is not defined as
598 * command argument */
599 if (alternate_file != NULL) {
600 (*settings)->config_file = strdup(alternate_file);
601 } else {
602 (*settings)->config_file = strdup("/etc/spmfilter.conf");
603 }
604
605 if ((in=fopen((*settings)->config_file, "r")) == NULL) {
606 TRACE(TRACE_ERR,"Error loading config: %s (%d)",strerror(errno), errno);
607 perror("spmfilter: failed to load config file");
608 return -1;
609 }
610
611 memset(line, 0, MAX_LINE);
612 memset(section, 0, MAX_LINE);
613 memset(key, 0, MAX_LINE);
614 memset(val, 0, MAX_LINE);
615
616 while (fgets(line+last, MAX_LINE-last, in) != NULL) {
617 lineno++ ;
618 len = (int)strlen(line)-1;
619 if (len==0)
620 continue;
621
622 if (len > MAX_LINE) {
623 TRACE(TRACE_ERR,"input line too long in %s (%d)\n", (*settings)->config_file, lineno);
624 fclose(in);
625 return -1;
626 }
627
628 /* Detect multi-line */
629 if (line[len]=='\\') {
630 /* Multi-line value */
631 last=len;
632 continue;
633 } else {
634 last=0;
635 }
636 switch (_parse_line(line, section, key, val)) {
637 case LINE_EMPTY:
638 case LINE_COMMENT:
639 break;
640
641 case LINE_SECTION:
642 clean_section = smf_core_strstrip(section);
643 break;
644
645 case LINE_VALUE:
646 clean_key = smf_core_strstrip(key);
647 clean_val = smf_core_strstrip(val);
648
649 if ((strcmp(clean_section,"global")==0)
650 ||(strcmp(clean_section,"smtpd")==0)
651 ||(strcmp(clean_section,"sql")==0)
652 ||(strcmp(clean_section,"ldap")==0)) {
653 _set_config_value(settings,clean_section,clean_key,clean_val);
654 } else {
655 asprintf(&tmp,"%s:%s",clean_section,clean_key);
656 if (smf_dict_set((*settings)->groups,tmp,clean_val)!=0) {
657 errs++;
658 TRACE(TRACE_ERR,"failed to set config value: %s:%s=>%s");
659 }
660 free(tmp);
661 }
662 break;
663
664 case LINE_ERROR:
665 TRACE(TRACE_ERR, "syntax error in %s (%d): %s",
666 (*settings)->config_file,
667 lineno,line);
668 errs++;
669 break;
670
671 default:
672 break;
673 }
674 memset(line, 0, MAX_LINE);
675
676 last=0;
677 if (errs<0) {
678 TRACE(TRACE_ERR, "memory allocation failure");
679 break ;
680 }
681 }
682
683 if (fclose(in)!=0)
684 TRACE(TRACE_ERR,"failed to close config file: %s (%d)",strerror(errno), errno);
685
686 // check defaults
687 if ((*settings)->queue_dir == NULL) {
688 (*settings)->queue_dir = strdup("/var/spool/spmfilter");
689 TRACE(TRACE_DEBUG,"config value queue_dir not set, using default");
690 }
691
692 if ((*settings)->engine == NULL) {
693 TRACE(TRACE_ERR,"config value engine not set");
694 return -1;
695 }
696
697 if ((*settings)->backend_connection == NULL)
698 (*settings)->backend_connection = strdup("failover");
699
700 if ((*settings)->backend != NULL) {
701 /** sql checks **/
702 if (strcmp((*settings)->backend,"sql")==0) {
703 if ((*settings)->sql_driver==NULL) {
704 TRACE(TRACE_ERR, "no database driver set");
705 return -1;
706 }
707 if ((*settings)->sql_name==NULL) {
708 TRACE(TRACE_ERR, "config value sql name not set");
709 return -1;
710 }
711
712 if ((strcmp((*settings)->sql_driver,"mysql")==0)||(strcmp((*settings)->sql_driver,"postgresql")==0)) {
713 if (smf_list_size((*settings)->sql_host)==0){
714 TRACE(TRACE_ERR, "no sql host set");
715 return -1;
716 }
717 }
718
719 if (strcmp((*settings)->sql_driver,"mysql")==0) {
720 if ((*settings)->sql_port == 0)
721 (*settings)->sql_port = 3306;
722 }
723
724 if (strcmp((*settings)->sql_driver,"postgresql")==0) {
725 if ((*settings)->sql_port == 0)
726 (*settings)->sql_port = 5432;
727 }
728 }
729
730 /** ldap checks **/
731 if (strcmp((*settings)->backend,"ldap")==0) {
732 if ((*settings)->ldap_port == 0)
733 (*settings)->ldap_port = 389;
734
735 if ((*settings)->ldap_base == NULL) {
736 TRACE(TRACE_ERR, "no ldap search base set");
737 return -1;
738 }
739
740 if ((*settings)->ldap_scope != NULL) {
741 if ((strcmp((*settings)->ldap_scope,"base")!=0)
742 && (strcmp((*settings)->ldap_scope,"onlevel")!=0)
743 && (strcmp((*settings)->ldap_scope,"subtree")!=0)) {
744 TRACE(TRACE_ERR, "invalid ldap search scope");
745 return -1;
746 }
747 } else
748 (*settings)->ldap_scope = strdup("subtree");
749 }
750 }
751
752 TRACE(TRACE_DEBUG, "settings->queue_dir: [%s]", (*settings)->queue_dir);
753 TRACE(TRACE_DEBUG, "settings->engine: [%s]", (*settings)->engine);
754 elem = smf_list_head((*settings)->modules);
755 while(elem != NULL) {
756 mod = (SMFModule_T *)smf_list_data(elem);
757 TRACE(TRACE_DEBUG, "settings->modules: [%s]", mod->name);
758 elem = elem->next;
759 }
760 TRACE(TRACE_DEBUG, "settings->module_fail [%d]",(*settings)->module_fail);
761 TRACE(TRACE_DEBUG, "settings->nexthop: [%s]", (*settings)->nexthop);
762 TRACE(TRACE_DEBUG, "settings->backend: [%s]", (*settings)->backend);
763 TRACE(TRACE_DEBUG, "settings->backend_connection: [%s]", (*settings)->backend_connection);
764 TRACE(TRACE_DEBUG, "settings->add_header: [%d]", (*settings)->add_header);
765 TRACE(TRACE_DEBUG, "settings->max_size: [%d]", (*settings)->max_size);
766 TRACE(TRACE_DEBUG, "settings->tls: [%d]", (*settings)->tls);
767 TRACE(TRACE_DEBUG, "settings->lib_dir: [%s]", (*settings)->lib_dir);
768 TRACE(TRACE_DEBUG, "settings->pid_file: [%s]", (*settings)->pid_file);
769 TRACE(TRACE_DEBUG, "settings->bind_ip: [%s]", (*settings)->bind_ip);
770 TRACE(TRACE_DEBUG, "settings->bind_port: [%d]", (*settings)->bind_port);
771 TRACE(TRACE_DEBUG, "settings->listen_backlog: [%d]", (*settings)->listen_backlog);
772 TRACE(TRACE_DEBUG, "settings->foreground: [%d]", (*settings)->foreground);
773 TRACE(TRACE_DEBUG, "settings->user: [%s]", (*settings)->user);
774 TRACE(TRACE_DEBUG, "settings->group: [%s]", (*settings)->group);
775 TRACE(TRACE_DEBUG, "settings->max_childs: [%d]", (*settings)->max_childs);
776 TRACE(TRACE_DEBUG, "settings->spare_childs: [%d]", (*settings)->spare_childs);
777 TRACE(TRACE_DEBUG, "settings->lookup_persistent: [%d]", (*settings)->lookup_persistent);
778 TRACE(TRACE_DEBUG, "settings->syslog_facility: [%d]", (*settings)->syslog_facility);
779
780 TRACE(TRACE_DEBUG, "settings->sql_driver: [%s]", (*settings)->sql_driver);
781 TRACE(TRACE_DEBUG, "settings->sql_name: [%s]", (*settings)->sql_name);
782 elem = smf_list_head((*settings)->sql_host);
783 while(elem != NULL) {
784 s = (char *)smf_list_data(elem);
785 TRACE(TRACE_DEBUG, "settings->sql_host: [%s]", s);
786 elem = elem->next;
787 }
788 TRACE(TRACE_DEBUG, "settings->sql_user: [%s]", (*settings)->sql_user);
789 TRACE(TRACE_DEBUG, "settings->sql_pass: [%s]", (*settings)->sql_pass);
790 TRACE(TRACE_DEBUG, "settings->sql_user_query: [%s]", (*settings)->sql_user_query);
791 TRACE(TRACE_DEBUG, "settings->encoding: [%s]", (*settings)->sql_encoding);
792 TRACE(TRACE_DEBUG, "settings->max_connections: [%d]", (*settings)->sql_max_connections);
793 TRACE(TRACE_DEBUG, "settings->port: [%d]", (*settings)->sql_port);
794
795 TRACE(TRACE_DEBUG, "settings->ldap_uri: [%s]", (*settings)->ldap_uri);
796 elem = smf_list_head((*settings)->ldap_host);
797 while(elem != NULL) {
798 s = (char *)smf_list_data(elem);
799 TRACE(TRACE_DEBUG, "settings->ldap_host: [%s]", s);
800 elem = elem->next;
801 }
802 TRACE(TRACE_DEBUG, "settings->ldap_port: [%d]", (*settings)->ldap_port);
803 TRACE(TRACE_DEBUG, "settings->ldap_binddn: [%s]", (*settings)->ldap_binddn);
804 TRACE(TRACE_DEBUG, "settings->ldap_bindpw: [%s]", (*settings)->ldap_bindpw);
805 TRACE(TRACE_DEBUG, "settings->ldap_base: [%s]", (*settings)->ldap_base);
806 TRACE(TRACE_DEBUG, "settings->ldap_user_query: [%s]", (*settings)->ldap_user_query);
807 elem = smf_list_head((*settings)->ldap_result_attributes);
808 while(elem != NULL) {
809 s = (char *)smf_list_data(elem);
810 TRACE(TRACE_DEBUG, "settings->ldap_result_attributes: [%s]", s);
811 elem = elem->next;
812 }
813 TRACE(TRACE_DEBUG, "settings->ldap_scope: [%s]", (*settings)->ldap_scope);
814 TRACE(TRACE_DEBUG, "settings->ldap_referrals: [%d]", (*settings)->ldap_referrals);
815
816 /** smtpd checks **/
817 if ((*settings)->nexthop_fail_msg == NULL)
818 (*settings)->nexthop_fail_msg = strdup("Requested action aborted: local error in processing");
819
820 TRACE(TRACE_DEBUG, "settings->nexthop_fail_code: [%d]", (*settings)->nexthop_fail_code);
821 TRACE(TRACE_DEBUG, "settings->nexthop_fail_msg: [%s]", (*settings)->nexthop_fail_msg);
822 TRACE(TRACE_DEBUG, "settings->smtpd_timeout: [%d]\n", (*settings)->smtpd_timeout);
823
824 list = smf_dict_get_keys((*settings)->smtp_codes);
825 elem = smf_list_head(list);
826 while(elem != NULL) {
827 s = (char *)smf_list_data(elem);
828 TRACE(TRACE_DEBUG, "settings->smtp_codes: append %s=%s",s,smf_dict_get((*settings)->smtp_codes,s));
829 elem = elem->next;
830 }
831 smf_list_free(list);
832 return 0;
833 }
834
smf_settings_set_debug(SMFSettings_T * settings,int debug)835 int smf_settings_set_debug(SMFSettings_T *settings, int debug) {
836 assert(settings);
837
838 if ((debug != 0) && (debug != 1)) {
839 TRACE(TRACE_ERR,"debug setting must be either 0 or 1");
840 return -1;
841 }
842 configure_debug(debug);
843 settings->debug = debug;
844
845 return 0;
846 }
847
smf_settings_get_debug(SMFSettings_T * settings)848 int smf_settings_get_debug(SMFSettings_T *settings) {
849 assert(settings);
850 return settings->debug;
851 }
852
smf_settings_set_config_file(SMFSettings_T * settings,char * cf)853 int smf_settings_set_config_file(SMFSettings_T *settings, char *cf) {
854 struct stat sb;
855 assert(settings);
856 assert(cf);
857
858 if (stat(cf,&sb) != 0) {
859 TRACE(TRACE_ERR,"file [%s] does not exist: %s (%d)",cf,strerror(errno), errno);
860 return -1;
861 }
862
863 if (settings->config_file != NULL) free(settings->config_file);
864 settings->config_file = strdup(cf);
865
866 return 0;
867 }
868
smf_settings_get_config_file(SMFSettings_T * settings)869 char *smf_settings_get_config_file(SMFSettings_T *settings) {
870 assert(settings);
871 return settings->config_file;
872 }
873
smf_settings_set_queue_dir(SMFSettings_T * settings,char * qd)874 int smf_settings_set_queue_dir(SMFSettings_T *settings, char *qd) {
875 struct stat sb;
876 assert(settings);
877 assert(qd);
878
879 if (stat(qd,&sb) != 0) {
880 TRACE(TRACE_ERR,"directory [%s] does not exist: %s (%d)",qd,strerror(errno), errno);
881 return -1;
882 }
883
884 if(!S_ISDIR(sb.st_mode)) {
885 TRACE(TRACE_ERR,"[%s] is not a directory",qd);
886 return -2;
887 }
888
889 if (access(qd,W_OK) != 0) {
890 TRACE(TRACE_ERR,"directory [%s] is not writeable: %s (%d)",qd, strerror(errno), errno);
891 return -1;
892 }
893
894 if (settings->queue_dir != NULL)
895 free(settings->queue_dir);
896
897 settings->queue_dir = strdup(qd);
898
899 return 0;
900 }
901
smf_settings_get_queue_dir(SMFSettings_T * settings)902 char *smf_settings_get_queue_dir(SMFSettings_T *settings) {
903 assert(settings);
904 return settings->queue_dir;
905 }
906
smf_settings_set_engine(SMFSettings_T * settings,char * engine)907 void smf_settings_set_engine(SMFSettings_T *settings, char *engine) {
908 assert(settings);
909 assert(engine);
910
911 if (settings->engine != NULL) free(settings->engine);
912 settings->engine = strdup(engine);
913 }
914
smf_settings_get_engine(SMFSettings_T * settings)915 char *smf_settings_get_engine(SMFSettings_T *settings) {
916 assert(settings);
917 return settings->engine;
918 }
919
smf_settings_add_module(SMFSettings_T * settings,char * module)920 int smf_settings_add_module(SMFSettings_T *settings, char *module) {
921 SMFModule_T *m;
922
923 assert(settings);
924 assert(module);
925
926 if ((m = smf_module_create(module)) == NULL)
927 return -1;
928
929 return smf_list_append(settings->modules, m);
930 }
931
smf_settings_get_modules(SMFSettings_T * settings)932 SMFList_T *smf_settings_get_modules(SMFSettings_T *settings) {
933 assert(settings);
934 return settings->modules;
935 }
936
smf_settings_set_nexthop(SMFSettings_T * settings,char * nexthop)937 void smf_settings_set_nexthop(SMFSettings_T *settings, char *nexthop) {
938 assert(settings);
939 assert(nexthop);
940
941 if (settings->nexthop != NULL) free(settings->nexthop);
942
943 settings->nexthop = strdup(nexthop);
944 }
945
smf_settings_get_nexthop(SMFSettings_T * settings)946 char *smf_settings_get_nexthop(SMFSettings_T *settings) {
947 assert(settings);
948 return settings->nexthop;
949 }
950
smf_settings_set_module_fail(SMFSettings_T * settings,int i)951 void smf_settings_set_module_fail(SMFSettings_T *settings, int i) {
952 assert(settings);
953 settings->module_fail = i;
954 }
955
smf_settings_get_module_fail(SMFSettings_T * settings)956 int smf_settings_get_module_fail(SMFSettings_T *settings) {
957 assert(settings);
958 return settings->module_fail;
959 }
960
smf_settings_set_nexthop_fail_code(SMFSettings_T * settings,int i)961 void smf_settings_set_nexthop_fail_code(SMFSettings_T *settings, int i) {
962 assert(settings);
963 settings->nexthop_fail_code = i;
964 }
965
smf_settings_get_nexthop_fail_code(SMFSettings_T * settings)966 int smf_settings_get_nexthop_fail_code(SMFSettings_T *settings) {
967 assert(settings);
968 return settings->nexthop_fail_code;
969 }
970
smf_settings_set_nexthop_fail_msg(SMFSettings_T * settings,char * msg)971 void smf_settings_set_nexthop_fail_msg(SMFSettings_T *settings, char *msg) {
972 assert(settings);
973 assert(msg);
974
975 if (settings->nexthop_fail_msg != NULL) free(settings->nexthop_fail_msg);
976
977 settings->nexthop_fail_msg = strdup(msg);
978 }
979
smf_settings_get_nexthop_fail_msg(SMFSettings_T * settings)980 char *smf_settings_get_nexthop_fail_msg(SMFSettings_T *settings) {
981 assert(settings);
982 return settings->nexthop_fail_msg;
983 }
984
smf_settings_set_backend(SMFSettings_T * settings,char * backend)985 void smf_settings_set_backend(SMFSettings_T *settings, char *backend) {
986 assert(settings);
987 assert(backend);
988
989 if (settings->backend != NULL) free(settings->backend);
990
991 settings->backend = strdup(backend);
992 }
993
smf_settings_get_backend(SMFSettings_T * settings)994 char *smf_settings_get_backend(SMFSettings_T *settings) {
995 assert(settings);
996 return settings->backend;
997 }
998
smf_settings_set_backend_connection(SMFSettings_T * settings,char * conn)999 void smf_settings_set_backend_connection(SMFSettings_T *settings, char *conn) {
1000 assert(settings);
1001 assert(conn);
1002
1003 if (settings->backend_connection != NULL) free(settings->backend_connection);
1004
1005 settings->backend_connection = strdup(conn);
1006 }
1007
smf_settings_get_backend_connection(SMFSettings_T * settings)1008 char *smf_settings_get_backend_connection(SMFSettings_T *settings) {
1009 assert(settings);
1010 return settings->backend_connection;
1011 }
1012
smf_settings_set_add_header(SMFSettings_T * settings,int i)1013 void smf_settings_set_add_header(SMFSettings_T *settings, int i) {
1014 assert(settings);
1015 settings->add_header = i;
1016 }
1017
smf_settings_get_add_header(SMFSettings_T * settings)1018 int smf_settings_get_add_header(SMFSettings_T *settings) {
1019 assert(settings);
1020 return settings->add_header;
1021 }
1022
smf_settings_set_max_size(SMFSettings_T * settings,unsigned long size)1023 void smf_settings_set_max_size(SMFSettings_T *settings, unsigned long size) {
1024 assert(settings);
1025 settings->max_size = size;
1026 }
1027
smf_settings_get_max_size(SMFSettings_T * settings)1028 unsigned long smf_settings_get_max_size(SMFSettings_T *settings) {
1029 assert(settings);
1030 return settings->max_size;
1031 }
1032
smf_settings_set_tls(SMFSettings_T * settings,SMFTlsOption_T t)1033 void smf_settings_set_tls(SMFSettings_T *settings, SMFTlsOption_T t) {
1034 assert(settings);
1035 settings->tls = t;
1036 }
1037
smf_settings_get_tls(SMFSettings_T * settings)1038 SMFTlsOption_T smf_settings_get_tls(SMFSettings_T *settings) {
1039 assert(settings);
1040 return settings->tls;
1041 }
1042
smf_settings_set_lib_dir(SMFSettings_T * settings,char * lib_dir)1043 void smf_settings_set_lib_dir(SMFSettings_T *settings, char *lib_dir) {
1044 assert(settings);
1045 assert(lib_dir);
1046
1047 if (settings->lib_dir != NULL) free(settings->lib_dir);
1048
1049 settings->lib_dir = strdup(lib_dir);
1050 }
1051
smf_settings_get_lib_dir(SMFSettings_T * settings)1052 char *smf_settings_get_lib_dir(SMFSettings_T *settings) {
1053 assert(settings);
1054 return settings->lib_dir;
1055 }
1056
smf_settings_set_pid_file(SMFSettings_T * settings,char * pid_file)1057 void smf_settings_set_pid_file(SMFSettings_T *settings, char *pid_file) {
1058 assert(settings);
1059 assert(pid_file);
1060
1061 if (settings->pid_file != NULL) free(settings->pid_file);
1062
1063 settings->pid_file = strdup(pid_file);
1064 }
1065
smf_settings_get_pid_file(SMFSettings_T * settings)1066 char *smf_settings_get_pid_file(SMFSettings_T *settings) {
1067 assert(settings);
1068 return settings->pid_file;
1069 }
1070
smf_settings_set_bind_ip(SMFSettings_T * settings,char * ip)1071 void smf_settings_set_bind_ip(SMFSettings_T *settings, char *ip) {
1072 assert(settings);
1073 assert(ip);
1074
1075 if (settings->bind_ip != NULL) free(settings->bind_ip);
1076
1077 settings->bind_ip = strdup(ip);
1078 }
1079
smf_settings_get_bind_ip(SMFSettings_T * settings)1080 char *smf_settings_get_bind_ip(SMFSettings_T *settings) {
1081 assert(settings);
1082 return settings->bind_ip;
1083 }
1084
smf_settings_set_bind_port(SMFSettings_T * settings,int port)1085 void smf_settings_set_bind_port(SMFSettings_T *settings, int port) {
1086 assert(settings);
1087 settings->bind_port = port;
1088 }
1089
smf_settings_get_bind_port(SMFSettings_T * settings)1090 int smf_settings_get_bind_port(SMFSettings_T *settings) {
1091 assert(settings);
1092 return settings->bind_port;
1093 }
1094
smf_settings_set_listen_backlog(SMFSettings_T * settings,int backlog)1095 void smf_settings_set_listen_backlog(SMFSettings_T *settings, int backlog) {
1096 assert(settings);
1097 settings->listen_backlog = backlog;
1098 }
1099
smf_settings_get_listen_backlog(SMFSettings_T * settings)1100 int smf_settings_get_listen_backlog(SMFSettings_T *settings) {
1101 assert(settings);
1102 return settings->listen_backlog;
1103 }
1104
smf_settings_set_foreground(SMFSettings_T * settings,int foreground)1105 void smf_settings_set_foreground(SMFSettings_T *settings, int foreground) {
1106 assert(settings);
1107 settings->foreground = foreground;
1108 }
1109
smf_settings_get_foreground(SMFSettings_T * settings)1110 int smf_settings_get_foreground(SMFSettings_T *settings) {
1111 assert(settings);
1112 return settings->foreground;
1113 }
1114
smf_settings_set_user(SMFSettings_T * settings,char * user)1115 void smf_settings_set_user(SMFSettings_T *settings, char *user) {
1116 assert(settings);
1117 assert(user);
1118
1119 if (settings->user != NULL) free(settings->user);
1120
1121 settings->user = strdup(user);
1122 }
1123
smf_settings_get_user(SMFSettings_T * settings)1124 char *smf_settings_get_user(SMFSettings_T *settings) {
1125 assert(settings);
1126 return settings->user;
1127 }
1128
smf_settings_set_group(SMFSettings_T * settings,char * group)1129 void smf_settings_set_group(SMFSettings_T *settings, char *group) {
1130 assert(settings);
1131 assert(group);
1132
1133 if (settings->group != NULL) free(settings->group);
1134
1135 settings->group = strdup(group);
1136 }
1137
smf_settings_get_group(SMFSettings_T * settings)1138 char *smf_settings_get_group(SMFSettings_T *settings) {
1139 assert(settings);
1140 return settings->group;
1141 }
1142
smf_settings_set_max_childs(SMFSettings_T * settings,int max_childs)1143 void smf_settings_set_max_childs(SMFSettings_T *settings, int max_childs) {
1144 assert(settings);
1145 settings->max_childs = max_childs;
1146 }
1147
smf_settings_get_max_childs(SMFSettings_T * settings)1148 int smf_settings_get_max_childs(SMFSettings_T *settings) {
1149 assert(settings);
1150 return settings->max_childs;
1151 }
1152
smf_settings_set_spare_childs(SMFSettings_T * settings,int spare_childs)1153 void smf_settings_set_spare_childs(SMFSettings_T *settings, int spare_childs) {
1154 assert(settings);
1155 settings->spare_childs = spare_childs;
1156 }
1157
smf_settings_get_spare_childs(SMFSettings_T * settings)1158 int smf_settings_get_spare_childs(SMFSettings_T *settings) {
1159 assert(settings);
1160 return settings->spare_childs;
1161 }
1162
smf_settings_set_syslog_facility(SMFSettings_T * settings,char * facility)1163 void smf_settings_set_syslog_facility(SMFSettings_T *settings, char *facility) {
1164 if (strcasecmp(facility,"auth")==0)
1165 settings->syslog_facility = LOG_AUTH;
1166 else if (strcasecmp(facility,"authpriv")==0)
1167 settings->syslog_facility = LOG_AUTHPRIV;
1168 else if (strcasecmp(facility,"cron")==0)
1169 settings->syslog_facility = LOG_CRON;
1170 else if (strcasecmp(facility,"daemon")==0)
1171 settings->syslog_facility = LOG_DAEMON;
1172 else if (strcasecmp(facility, "ftp")==0)
1173 settings->syslog_facility = LOG_FTP;
1174 else if (strcasecmp(facility, "kern")==0)
1175 settings->syslog_facility = LOG_KERN;
1176 else if (strcasecmp(facility, "local0")==0)
1177 settings->syslog_facility = LOG_LOCAL0;
1178 else if (strcasecmp(facility, "local1")==0)
1179 settings->syslog_facility = LOG_LOCAL1;
1180 else if (strcasecmp(facility, "local2")==0)
1181 settings->syslog_facility = LOG_LOCAL2;
1182 else if (strcasecmp(facility, "local3")==0)
1183 settings->syslog_facility = LOG_LOCAL3;
1184 else if (strcasecmp(facility, "local4")==0)
1185 settings->syslog_facility = LOG_LOCAL4;
1186 else if (strcasecmp(facility, "local5")==0)
1187 settings->syslog_facility = LOG_LOCAL5;
1188 else if (strcasecmp(facility, "local6")==0)
1189 settings->syslog_facility = LOG_LOCAL6;
1190 else if (strcasecmp(facility, "local7")==0)
1191 settings->syslog_facility = LOG_LOCAL7;
1192 else if (strcasecmp(facility, "lpr")==0)
1193 settings->syslog_facility = LOG_LPR;
1194 else if (strcasecmp(facility, "mail")==0)
1195 settings->syslog_facility = LOG_MAIL;
1196 else if (strcasecmp(facility, "news")==0)
1197 settings->syslog_facility = LOG_NEWS;
1198 else if (strcasecmp(facility, "user")==0)
1199 settings->syslog_facility = LOG_USER;
1200 else if (strcasecmp(facility, "uucp")==0)
1201 settings->syslog_facility = LOG_UUCP;
1202 }
1203
smf_settings_get_syslog_facility(SMFSettings_T * settings)1204 int smf_settings_get_syslog_facility(SMFSettings_T *settings) {
1205 assert(settings);
1206 return settings->syslog_facility;
1207 }
1208
smf_settings_set_smtp_code(SMFSettings_T * settings,int code,char * msg)1209 int smf_settings_set_smtp_code(SMFSettings_T *settings, int code, char *msg) {
1210 char *strcode = NULL;
1211 int res;
1212
1213 assert(settings);
1214 assert(msg);
1215
1216 asprintf(&strcode,"%d",code);
1217
1218 res = smf_dict_set(settings->smtp_codes,strcode,msg);
1219 free(strcode);
1220 return res;
1221 }
1222
smf_settings_get_smtp_code(SMFSettings_T * settings,int code)1223 char *smf_settings_get_smtp_code(SMFSettings_T *settings, int code) {
1224 char *strcode = NULL;
1225 char *p = NULL;
1226
1227 assert(settings);
1228
1229 asprintf(&strcode,"%d",code);
1230 p = smf_dict_get(settings->smtp_codes,strcode);
1231 free(strcode);
1232
1233 return p;
1234 }
1235
smf_settings_set_smtpd_timeout(SMFSettings_T * settings,int timeout)1236 void smf_settings_set_smtpd_timeout(SMFSettings_T *settings, int timeout) {
1237 assert(settings);
1238 settings->smtpd_timeout = timeout;
1239 }
1240
smf_settings_get_smtpd_timeout(SMFSettings_T * settings)1241 int smf_settings_get_smtpd_timeout(SMFSettings_T *settings) {
1242 assert(settings);
1243 return settings->smtpd_timeout;
1244 }
1245
smf_settings_set_sql_driver(SMFSettings_T * settings,char * driver)1246 void smf_settings_set_sql_driver(SMFSettings_T *settings, char *driver) {
1247 assert(settings);
1248 assert(driver);
1249
1250 if (settings->sql_driver != NULL) free(settings->sql_driver);
1251
1252 settings->sql_driver = strdup(driver);
1253 }
1254
smf_settings_get_sql_driver(SMFSettings_T * settings)1255 char *smf_settings_get_sql_driver(SMFSettings_T *settings) {
1256 assert(settings);
1257 return settings->sql_driver;
1258 }
1259
smf_settings_set_sql_name(SMFSettings_T * settings,char * name)1260 void smf_settings_set_sql_name(SMFSettings_T *settings, char *name) {
1261 assert(settings);
1262 assert(name);
1263
1264 if (settings->sql_name != NULL) free(settings->sql_name);
1265
1266 settings->sql_name = strdup(name);
1267 }
1268
smf_settings_get_sql_name(SMFSettings_T * settings)1269 char *smf_settings_get_sql_name(SMFSettings_T *settings) {
1270 assert(settings);
1271 return settings->sql_name;
1272 }
1273
smf_settings_add_sql_host(SMFSettings_T * settings,char * host)1274 int smf_settings_add_sql_host(SMFSettings_T *settings, char *host) {
1275 assert(settings);
1276 assert(host);
1277
1278 return smf_list_append(settings->sql_host,(void *)host);
1279 }
1280
smf_settings_get_sql_hosts(SMFSettings_T * settings)1281 SMFList_T *smf_settings_get_sql_hosts(SMFSettings_T *settings) {
1282 assert(settings);
1283 return settings->sql_host;
1284 }
1285
smf_settings_set_sql_port(SMFSettings_T * settings,int port)1286 void smf_settings_set_sql_port(SMFSettings_T *settings, int port) {
1287 assert(settings);
1288 settings->sql_port = port;
1289 }
1290
smf_settings_get_sql_port(SMFSettings_T * settings)1291 int smf_settings_get_sql_port(SMFSettings_T *settings) {
1292 assert(settings);
1293 return settings->sql_port;
1294 }
1295
smf_settings_set_sql_user(SMFSettings_T * settings,char * user)1296 void smf_settings_set_sql_user(SMFSettings_T *settings, char *user) {
1297 assert(settings);
1298 assert(user);
1299
1300 if (settings->sql_user != NULL) free(settings->sql_user);
1301
1302 settings->sql_user = strdup(user);
1303 }
1304
smf_settings_get_sql_user(SMFSettings_T * settings)1305 char *smf_settings_get_sql_user(SMFSettings_T *settings) {
1306 assert(settings);
1307 return settings->sql_user;
1308 }
1309
smf_settings_set_sql_pass(SMFSettings_T * settings,char * pass)1310 void smf_settings_set_sql_pass(SMFSettings_T *settings, char *pass) {
1311 assert(settings);
1312 assert(pass);
1313
1314 if (settings->sql_pass != NULL) free(settings->sql_pass);
1315
1316 settings->sql_pass = strdup(pass);
1317 }
1318
smf_settings_get_sql_pass(SMFSettings_T * settings)1319 char *smf_settings_get_sql_pass(SMFSettings_T *settings) {
1320 assert(settings);
1321 return settings->sql_pass;
1322 }
1323
smf_settings_set_sql_user_query(SMFSettings_T * settings,char * query)1324 void smf_settings_set_sql_user_query(SMFSettings_T *settings, char *query) {
1325 assert(settings);
1326 assert(query);
1327
1328 if (settings->sql_user_query != NULL) free(settings->sql_user_query);
1329
1330 settings->sql_user_query = strdup(query);
1331 }
1332
smf_settings_get_sql_user_query(SMFSettings_T * settings)1333 char *smf_settings_get_sql_user_query(SMFSettings_T *settings) {
1334 assert(settings);
1335 return settings->sql_user_query;
1336 }
1337
smf_settings_set_sql_encoding(SMFSettings_T * settings,char * encoding)1338 void smf_settings_set_sql_encoding(SMFSettings_T *settings, char *encoding) {
1339 assert(settings);
1340 assert(encoding);
1341
1342 if (settings->sql_encoding != NULL) free(settings->sql_encoding);
1343
1344 settings->sql_encoding = strdup(encoding);
1345 }
1346
smf_settings_get_sql_encoding(SMFSettings_T * settings)1347 char *smf_settings_get_sql_encoding(SMFSettings_T *settings) {
1348 assert(settings);
1349 return settings->sql_encoding;
1350 }
1351
smf_settings_set_sql_max_connections(SMFSettings_T * settings,int i)1352 void smf_settings_set_sql_max_connections(SMFSettings_T *settings, int i) {
1353 assert(settings);
1354 settings->sql_max_connections = i;
1355 }
1356
smf_settings_get_sql_max_connections(SMFSettings_T * settings)1357 int smf_settings_get_sql_max_connections(SMFSettings_T *settings) {
1358 assert(settings);
1359 return settings->sql_max_connections;
1360 }
1361
smf_settings_set_ldap_uri(SMFSettings_T * settings,char * uri)1362 void smf_settings_set_ldap_uri(SMFSettings_T *settings, char *uri) {
1363 assert(settings);
1364 assert(uri);
1365
1366 if (settings->ldap_uri != NULL) free(settings->ldap_uri);
1367
1368 settings->ldap_uri = strdup(uri);
1369 }
1370
smf_settings_get_ldap_uri(SMFSettings_T * settings)1371 char *smf_settings_get_ldap_uri(SMFSettings_T *settings) {
1372 assert(settings);
1373 return settings->ldap_uri;
1374 }
1375
smf_settings_add_ldap_host(SMFSettings_T * settings,char * host)1376 int smf_settings_add_ldap_host(SMFSettings_T *settings, char *host) {
1377 assert(settings);
1378 assert(host);
1379
1380 return smf_list_append(settings->ldap_host, (void *)host);
1381 }
1382
smf_settings_get_ldap_hosts(SMFSettings_T * settings)1383 SMFList_T *smf_settings_get_ldap_hosts(SMFSettings_T *settings) {
1384 assert(settings);
1385 return settings->ldap_host;
1386 }
1387
smf_settings_set_ldap_port(SMFSettings_T * settings,int port)1388 void smf_settings_set_ldap_port(SMFSettings_T *settings, int port) {
1389 assert(settings);
1390 settings->ldap_port = port;
1391 }
1392
smf_settings_get_ldap_port(SMFSettings_T * settings)1393 int smf_settings_get_ldap_port(SMFSettings_T *settings) {
1394 assert(settings);
1395 return settings->ldap_port;
1396 }
1397
smf_settings_set_ldap_binddn(SMFSettings_T * settings,char * binddn)1398 void smf_settings_set_ldap_binddn(SMFSettings_T *settings, char *binddn) {
1399 assert(settings);
1400 assert(binddn);
1401
1402 if (settings->ldap_binddn != NULL) free(settings->ldap_binddn);
1403
1404 settings->ldap_binddn = strdup(binddn);
1405 }
1406
smf_settings_get_ldap_binddn(SMFSettings_T * settings)1407 char *smf_settings_get_ldap_binddn(SMFSettings_T *settings) {
1408 assert(settings);
1409 return settings->ldap_binddn;
1410 }
1411
smf_settings_set_ldap_bindpw(SMFSettings_T * settings,char * bindpw)1412 void smf_settings_set_ldap_bindpw(SMFSettings_T *settings, char *bindpw) {
1413 assert(settings);
1414 assert(bindpw);
1415
1416 if (settings->ldap_bindpw != NULL) free(settings->ldap_bindpw);
1417
1418 settings->ldap_bindpw = strdup(bindpw);
1419 }
1420
smf_settings_get_ldap_bindpw(SMFSettings_T * settings)1421 char *smf_settings_get_ldap_bindpw(SMFSettings_T *settings) {
1422 assert(settings);
1423 return settings->ldap_bindpw;
1424 }
1425
smf_settings_set_ldap_base(SMFSettings_T * settings,char * base)1426 void smf_settings_set_ldap_base(SMFSettings_T *settings, char *base) {
1427 assert(settings);
1428 assert(base);
1429
1430 if (settings->ldap_base != NULL) free(settings->ldap_base);
1431
1432 settings->ldap_base = strdup(base);
1433 }
1434
smf_settings_get_ldap_base(SMFSettings_T * settings)1435 char *smf_settings_get_ldap_base(SMFSettings_T *settings) {
1436 assert(settings);
1437 return settings->ldap_base;
1438 }
1439
smf_settings_set_ldap_referrals(SMFSettings_T * settings,int i)1440 void smf_settings_set_ldap_referrals(SMFSettings_T *settings, int i) {
1441 assert(settings);
1442 settings->ldap_referrals = i;
1443 }
1444
smf_settings_get_ldap_referrals(SMFSettings_T * settings)1445 int smf_settings_get_ldap_referrals(SMFSettings_T *settings) {
1446 assert(settings);
1447 return settings->ldap_referrals;
1448 }
1449
smf_settings_set_ldap_scope(SMFSettings_T * settings,char * scope)1450 void smf_settings_set_ldap_scope(SMFSettings_T *settings, char *scope) {
1451 assert(settings);
1452 assert(scope);
1453
1454 if (settings->ldap_scope != NULL) free(settings->ldap_scope);
1455
1456 settings->ldap_scope = strdup(scope);
1457 }
1458
smf_settings_get_ldap_scope(SMFSettings_T * settings)1459 char *smf_settings_get_ldap_scope(SMFSettings_T *settings) {
1460 assert(settings);
1461 return settings->ldap_scope;
1462 }
1463
smf_settings_set_ldap_user_query(SMFSettings_T * settings,char * query)1464 void smf_settings_set_ldap_user_query(SMFSettings_T *settings, char *query) {
1465 assert(settings);
1466 assert(query);
1467
1468 if (settings->ldap_user_query != NULL) free(settings->ldap_user_query);
1469
1470 settings->ldap_user_query = strdup(query);
1471 }
1472
smf_settings_get_ldap_user_query(SMFSettings_T * settings)1473 char *smf_settings_get_ldap_user_query(SMFSettings_T *settings) {
1474 assert(settings);
1475 return settings->ldap_user_query;
1476 }
1477
smf_settings_add_ldap_result_attribute(SMFSettings_T * settings,char * attribute)1478 int smf_settings_add_ldap_result_attribute(SMFSettings_T *settings, char *attribute) {
1479 assert(settings);
1480 assert(attribute);
1481
1482 return smf_list_append(settings->ldap_result_attributes, (void *)attribute);
1483 }
1484
smf_settings_get_ldap_result_attributes(SMFSettings_T * settings)1485 SMFList_T *smf_settings_get_ldap_result_attributes(SMFSettings_T *settings) {
1486 assert(settings);
1487 return settings->ldap_result_attributes;
1488 }
1489
smf_settings_set_lookup_persistent(SMFSettings_T * settings,int persistent)1490 void smf_settings_set_lookup_persistent(SMFSettings_T *settings, int persistent) {
1491 assert(settings);
1492 settings->lookup_persistent = persistent;
1493 }
1494
smf_settings_get_lookup_persistent(SMFSettings_T * settings)1495 int smf_settings_get_lookup_persistent(SMFSettings_T *settings) {
1496 assert(settings);
1497 return settings->lookup_persistent;
1498 }
1499
smf_settings_group_get(SMFSettings_T * settings,char * group_name,char * key)1500 char *smf_settings_group_get(SMFSettings_T *settings, char *group_name, char *key) {
1501 char *tmp = NULL;
1502 char *s = NULL;
1503
1504 assert(settings);
1505 assert(group_name);
1506 assert(key);
1507
1508 asprintf(&tmp,"%s:%s",group_name,key);
1509 s = smf_dict_get(settings->groups,tmp);
1510 free(tmp);
1511
1512 return s;
1513 }
1514
smf_settings_group_get_integer(SMFSettings_T * settings,char * group_name,char * key)1515 int smf_settings_group_get_integer(SMFSettings_T *settings, char *group_name, char *key) {
1516 char *tmp = NULL;
1517 char *s = NULL;
1518
1519 assert(settings);
1520 assert(group_name);
1521 assert(key);
1522
1523 asprintf(&tmp,"%s:%s",group_name,key);
1524 s = smf_dict_get(settings->groups,tmp);
1525 free(tmp);
1526
1527 return _get_integer(s);
1528 }
1529
smf_settings_group_get_boolean(SMFSettings_T * settings,char * group_name,char * key)1530 int smf_settings_group_get_boolean(SMFSettings_T *settings, char *group_name, char *key) {
1531 char *tmp = NULL;
1532 char *s = NULL;
1533
1534 assert(settings);
1535 assert(group_name);
1536 assert(key);
1537
1538 asprintf(&tmp,"%s:%s",group_name,key);
1539 s = smf_dict_get(settings->groups,tmp);
1540 free(tmp);
1541
1542 if (s!=NULL)
1543 return _get_boolean(s);
1544
1545 return 0;
1546 }
1547
smf_settings_group_get_list(SMFSettings_T * settings,char * group_name,char * key)1548 SMFList_T *smf_settings_group_get_list(SMFSettings_T *settings, char *group_name, char *key) {
1549 char *tmp = NULL;
1550 char *s = NULL;
1551 char **sl = NULL;
1552 char **p = NULL;
1553 SMFList_T *list = NULL;
1554
1555 assert(settings);
1556 assert(group_name);
1557 assert(key);
1558
1559 if (smf_list_new(&list,smf_internal_string_list_destroy)!=0)
1560 return NULL;
1561
1562 asprintf(&tmp,"%s:%s",group_name,key);
1563 s = smf_dict_get(settings->groups,tmp);
1564 free(tmp);
1565
1566 sl = smf_core_strsplit(s, ";", NULL);
1567 p = sl;
1568 while(*p != NULL) {
1569 tmp = smf_core_strstrip(*p);
1570 smf_list_append(list, tmp);
1571 p++;
1572 }
1573 free(sl);
1574
1575 return list;
1576 }
1577
1578