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