Example #1
0
END_TEST

START_TEST(process_err_halt_queue) {
    smf_list_append(settings->modules, smf_module_create_callback("mod1", mod1));
    smf_list_append(settings->modules, smf_module_create_callback("mod2", mod2));
    smf_list_append(settings->modules, smf_module_create_callback("mod3", mod3));
    fail_unless(smf_list_size(settings->modules) == 3);
    
    mod2_data.rc = 1; // != 0 is that counts
    processing_error_data.rc = 0; // halt the queue, can be continued
        
    fail_unless(smf_modules_process(queue, session, settings) == -1);
    fail_unless(mod1_data.count == 1);
    fail_unless(mod2_data.count == 1);
    fail_unless(mod3_data.count == 0);
    fail_unless(error_data.count == 0);
    fail_unless(processing_error_data.count == 1);
    fail_unless(nexthop_error_data.count == 0);
    
    // queue can be continued
    mod2_data.rc = 0;
    
    fail_unless(smf_modules_process(queue, session, settings) == 0);
    fail_unless(mod1_data.count == 1); // Now skipped
    fail_unless(mod2_data.count == 2); // Repeated, but now successful
    fail_unless(mod3_data.count == 1); // Now executed
    fail_unless(error_data.count == 0);
    fail_unless(processing_error_data.count == 1);
    fail_unless(nexthop_error_data.count == 0);
}
Example #2
0
END_TEST

START_TEST(process_err_stop_queue) {
    smf_list_append(settings->modules, smf_module_create_callback("mod1", mod1));
    smf_list_append(settings->modules, smf_module_create_callback("mod2", mod2));
    smf_list_append(settings->modules, smf_module_create_callback("mod3", mod3));
    fail_unless(smf_list_size(settings->modules) == 3);
    
    mod2_data.rc = 1; // != 0 is that counts
    processing_error_data.rc = 1; // stop the queue
    
    fail_unless(smf_modules_process(queue, session, settings) == 1);
    fail_unless(mod1_data.count == 1);
    fail_unless(mod2_data.count == 1);
    fail_unless(mod3_data.count == 0);
    fail_unless(error_data.count == 0);
    fail_unless(processing_error_data.count == 1);
    fail_unless(nexthop_error_data.count == 0);
    
    // processing the module-queue again will invoke all modules
    mod2_data.rc = 0;
    processing_error_data.rc = 0;
    
    fail_unless(smf_modules_process(queue, session, settings) == 0);
    fail_unless(mod1_data.count == 2);
    fail_unless(mod2_data.count == 2);
    fail_unless(mod3_data.count == 1);
    fail_unless(error_data.count == 0);
    fail_unless(processing_error_data.count == 1);
    fail_unless(nexthop_error_data.count == 0);
}
Example #3
0
END_TEST

START_TEST(process_success) {
    smf_list_append(settings->modules, smf_module_create_callback("mod1", mod1));
    smf_list_append(settings->modules, smf_module_create_callback("mod2", mod2));
    smf_list_append(settings->modules, smf_module_create_callback("mod3", mod3));
    fail_unless(smf_list_size(settings->modules) == 3);
    
    
    fail_unless(smf_modules_process(queue, session, settings) == 0);
    fail_unless(mod1_data.count == 1);
    fail_unless(mod2_data.count == 1);
    fail_unless(mod3_data.count == 1);
    fail_unless(error_data.count == 0);
    fail_unless(processing_error_data.count == 0);
    fail_unless(nexthop_error_data.count == 0);
}
Example #4
0
END_TEST

START_TEST(create_skeleton) {
    SMFMessage_T *m;
    SMFEmailAddress_T *addr;
    SMFList_T *l;

    fail_unless((m = smf_message_create_skeleton("sender", "recipient", "subject")) != NULL);
    fail_unless((addr = smf_message_get_sender(m)) != NULL);
    ck_assert_str_eq(smf_email_address_get_email(addr), "sender");
    fail_unless((l = smf_message_get_recipients(m)) != NULL);
    ck_assert_int_eq(smf_list_size(l), 1);
    fail_unless((addr = smf_list_head(l)->data) != NULL);
    ck_assert_str_eq(smf_email_address_get_email(addr), "recipient");
    ck_assert_str_eq(smf_message_get_subject(m), "subject");
    smf_message_free(m);
}
Example #5
0
END_TEST

START_TEST(process_err_nexthop_err) {
    smf_settings_set_nexthop(settings, "something_that_not_exists");
        
    smf_list_append(settings->modules, smf_module_create_callback("mod1", mod1));
    smf_list_append(settings->modules, smf_module_create_callback("mod2", mod2));
    smf_list_append(settings->modules, smf_module_create_callback("mod3", mod3));
    fail_unless(smf_list_size(settings->modules) == 3);
        
    mod2_data.rc = 1; // != 0 is that counts
    processing_error_data.rc = 2; // stop the queue, invoke nexthop
     
    fail_unless(smf_modules_process(queue, session, settings) == -1);
    fail_unless(mod1_data.count == 1);
    fail_unless(mod2_data.count == 1);
    fail_unless(mod3_data.count == 0);
    fail_unless(error_data.count == 0);
    fail_unless(processing_error_data.count == 1);
    fail_unless(nexthop_error_data.count == 1);
}
Example #6
0
END_TEST

START_TEST(add_recipient) {
    SMFList_T *l;
    SMFListElem_T *e;

    fail_unless(smf_message_add_recipient(msg, "*****@*****.**", SMF_EMAIL_ADDRESS_TYPE_TO) == 0);
    fail_unless(smf_message_add_recipient(msg, "*****@*****.**", SMF_EMAIL_ADDRESS_TYPE_CC) == 0);
    fail_unless(smf_message_add_recipient(msg, "*****@*****.**", SMF_EMAIL_ADDRESS_TYPE_BCC) == 0);
    
    fail_unless((l = smf_message_get_recipients(msg)) != NULL);
    ck_assert_int_eq(smf_list_size(l), 3);
    e = smf_list_head(l);
    ck_assert_str_eq(smf_email_address_get_email((SMFEmailAddress_T*)e->data), "*****@*****.**");
    ck_assert_int_eq(smf_email_address_get_type((SMFEmailAddress_T*)e->data), SMF_EMAIL_ADDRESS_TYPE_TO);
    e = smf_list_next(e);
    ck_assert_str_eq(smf_email_address_get_email((SMFEmailAddress_T*)e->data), "*****@*****.**");
    ck_assert_int_eq(smf_email_address_get_type((SMFEmailAddress_T*)e->data), SMF_EMAIL_ADDRESS_TYPE_CC);
    e = smf_list_next(e);
    ck_assert_str_eq(smf_email_address_get_email((SMFEmailAddress_T*)e->data), "*****@*****.**");
    ck_assert_int_eq(smf_email_address_get_type((SMFEmailAddress_T*)e->data), SMF_EMAIL_ADDRESS_TYPE_BCC);
}
Example #7
0
int main (int argc, char const *argv[]) {
    SMFList_T *l;
    char *out;
    char *data;
    char *pop;
    SMFListElem_T *e;

    printf("Start SMFList_T tests...\n");

    printf("* testing smf_list_new()...\t\t\t\t");
    if (smf_list_new(&l,list_destroy)!=0) {
        printf("failed\n");           
        return -1;
    }
    printf("passed\n");

    printf("* testing smf_list_append()...\t\t\t\t");
    if (smf_list_append(l,TEST_STRING1)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");
    
    printf("* testing smf_list_data()...\t\t\t\t");
    out = (char *)smf_list_data(smf_list_head(l));
    if (strcmp(TEST_STRING1,out)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");
    
    printf("* testing smf_list_size()...\t\t\t\t");
    if (smf_list_size(l)!=1) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");
    
    printf("* testing smf_list_head()...\t\t\t\t");
    e = smf_list_head(l);
    if (smf_list_is_head(e)!=1) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");

    printf("* testing smf_list_insert_next()...\t\t\t");
    if (smf_list_insert_next(l,e,TEST_STRING2)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");
    
    printf("* testing smf_list_tail()...\t\t\t\t");
    e = smf_list_tail(l);
    if (smf_list_is_tail(e)!=1) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");

    printf("* testing smf_list_data()...\t\t\t\t");
    out = (char *)smf_list_data(e);
    if (strcmp(TEST_STRING2,out)!=0) { 
        printf("failed\n");
        return -1;
    } 
    printf("passed\n");
    
    printf("* testing smf_list_insert_prev()...\t\t\t");    
    if (smf_list_insert_prev(l,e,TEST_STRING3)!=0) {
        printf("failed\n");
        return -1;
    }

    out = (char *)smf_list_data(smf_list_prev(e));
    if (strcmp(TEST_STRING3,out)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");


    printf("* testing smf_list_prepend()...\t\t\t\t");
    if (smf_list_prepend(l,TEST_STRING4)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");

    printf("* testing smf_list_map()...\t\t\t\t");
    smf_list_map(l,list_char_printer,NULL);
    printf("passed\n");

    printf("* testing smf_list_remove()...\t\t\t\t");
    e = smf_list_head(l);
    if (smf_list_remove(l,e,(void *)&data)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");

    printf("* testing smf_list_pop_head()...\t\t\t");
    pop = smf_list_pop_head(l);
    assert(pop);
    if (strcmp(pop,TEST_STRING1)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");
    
    printf("* testing smf_list_pop_tail()...\t\t\t");
    pop = smf_list_pop_tail(l);
    assert(pop);
    if (strcmp(pop,TEST_STRING2)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");

    printf("* testing smf_list_free()...\t\t\t\t");
    if (smf_list_free(l)!=0) {
        printf("failed\n");
        return -1;
    }
    printf("passed\n");

    return 0;
}
Example #8
0
int smf_settings_parse_config(SMFSettings_T **settings, char *alternate_file) {
    FILE *in = NULL;
    char line[MAX_LINE+1];
    char section[MAX_LINE+1];
    char key[MAX_LINE+1];
    char val[MAX_LINE+1];
    SMFList_T *list = NULL;
    SMFListElem_T *elem = NULL;
    char *s = NULL;
    int last=0;
    int len=0;
    int lineno=0;
    int errs=0;
    char *clean_section = NULL;
    char *clean_key = NULL;
    char *clean_val = NULL;
    char *tmp = NULL;
    SMFModule_T *mod = NULL;

    assert(*settings);

    /* fallback to default config path,
     * if config file is not defined as
     * command argument */
    if (alternate_file != NULL) {
        (*settings)->config_file = strdup(alternate_file);
    } else {
        (*settings)->config_file = strdup("/etc/spmfilter.conf");
    }

    if ((in=fopen((*settings)->config_file, "r")) == NULL) {
        TRACE(TRACE_ERR,"Error loading config: %s (%d)",strerror(errno), errno);
        perror("spmfilter: failed to load config file");
        return -1;
    }

    memset(line, 0, MAX_LINE);
    memset(section, 0, MAX_LINE);
    memset(key, 0, MAX_LINE);
    memset(val, 0, MAX_LINE);

    while (fgets(line+last, MAX_LINE-last, in) != NULL) {
        lineno++ ;
        len = (int)strlen(line)-1;
        if (len==0)
            continue;
        
        if (len > MAX_LINE) {
            TRACE(TRACE_ERR,"input line too long in %s (%d)\n", (*settings)->config_file, lineno);
            fclose(in);
            return -1;
        }

        /* Detect multi-line */
        if (line[len]=='\\') {
            /* Multi-line value */
            last=len;
            continue;
        } else {
            last=0;
        }
        switch (_parse_line(line, section, key, val)) {
            case LINE_EMPTY:
            case LINE_COMMENT:
                break;

            case LINE_SECTION:
                clean_section = smf_core_strstrip(section);
                break;

            case LINE_VALUE:
                clean_key = smf_core_strstrip(key);
                clean_val = smf_core_strstrip(val);

                if ((strcmp(clean_section,"global")==0)
                        ||(strcmp(clean_section,"smtpd")==0)
                        ||(strcmp(clean_section,"sql")==0)
                        ||(strcmp(clean_section,"ldap")==0)) {
                    _set_config_value(settings,clean_section,clean_key,clean_val);
                } else {
                    asprintf(&tmp,"%s:%s",clean_section,clean_key);
                    if (smf_dict_set((*settings)->groups,tmp,clean_val)!=0) {
                        errs++;
                        TRACE(TRACE_ERR,"failed to set config value: %s:%s=>%s");
                    }
                    free(tmp);
                }
                break;

            case LINE_ERROR:
                TRACE(TRACE_ERR, "syntax error in %s (%d): %s",
                    (*settings)->config_file,
                    lineno,line);
                errs++;
                break;

            default:
                break;
        }
        memset(line, 0, MAX_LINE);

        last=0;
        if (errs<0) {
            TRACE(TRACE_ERR, "memory allocation failure");
            break ;
        }
    }

    if (fclose(in)!=0)
        TRACE(TRACE_ERR,"failed to close config file: %s (%d)",strerror(errno), errno);

    // check defaults
    if ((*settings)->queue_dir == NULL) {
        (*settings)->queue_dir = strdup("/var/spool/spmfilter");
        TRACE(TRACE_DEBUG,"config value queue_dir not set, using default");
    }

    if ((*settings)->engine == NULL) {
        TRACE(TRACE_ERR,"config value engine not set");
        return -1;
    }

    if ((*settings)->backend_connection == NULL) 
        (*settings)->backend_connection = strdup("failover");

    if ((*settings)->backend != NULL) {
        /** sql checks **/
        if (strcmp((*settings)->backend,"sql")==0) {
            if ((*settings)->sql_driver==NULL) {
                TRACE(TRACE_ERR, "no database driver set");
                return -1;
            }
            if ((*settings)->sql_name==NULL) {
                TRACE(TRACE_ERR, "config value sql name not set");
                return -1;
            }

            if ((strcmp((*settings)->sql_driver,"mysql")==0)||(strcmp((*settings)->sql_driver,"pgsql")==0)) {
                if (smf_list_size((*settings)->sql_host)==0){
                    TRACE(TRACE_ERR, "no sql host set");
                    return -1;
                }
            }

            if (strcmp((*settings)->sql_driver,"mysql")==0) {
                if ((*settings)->sql_port == 0)
                    (*settings)->sql_port = 3306;
            }

            if (strcmp((*settings)->sql_driver,"pgsql")==0) {
                if ((*settings)->sql_port == 0)
                    (*settings)->sql_port = 5432;
            }        
        }

        /** ldap checks **/
        if (strcmp((*settings)->backend,"ldap")==0) {
            if ((*settings)->ldap_port == 0)
                (*settings)->ldap_port = 389;

            if ((*settings)->ldap_base == NULL) {
                TRACE(TRACE_ERR, "no ldap search base set");
                return -1;
            }

            if ((*settings)->ldap_scope != NULL) {
                if ((strcmp((*settings)->ldap_scope,"base")!=0)
                        && (strcmp((*settings)->ldap_scope,"onlevel")!=0)
                        && (strcmp((*settings)->ldap_scope,"subtree")!=0)) {
                    TRACE(TRACE_ERR, "invalid ldap search scope");
                    return -1;
                }
            } else
                (*settings)->ldap_scope = strdup("subtree");
        }
    }

    TRACE(TRACE_DEBUG, "settings->queue_dir: [%s]", (*settings)->queue_dir);
    TRACE(TRACE_DEBUG, "settings->engine: [%s]", (*settings)->engine);
    elem = smf_list_head((*settings)->modules);
    while(elem != NULL) {
        mod = (SMFModule_T *)smf_list_data(elem);
        TRACE(TRACE_DEBUG, "settings->modules: [%s]", mod->name);
        elem = elem->next;
    }
    TRACE(TRACE_DEBUG, "settings->module_fail [%d]",(*settings)->module_fail);
    TRACE(TRACE_DEBUG, "settings->nexthop: [%s]", (*settings)->nexthop);
    TRACE(TRACE_DEBUG, "settings->backend: [%s]", (*settings)->backend);
    TRACE(TRACE_DEBUG, "settings->backend_connection: [%s]", (*settings)->backend_connection);
    TRACE(TRACE_DEBUG, "settings->add_header: [%d]", (*settings)->add_header);
    TRACE(TRACE_DEBUG, "settings->max_size: [%d]", (*settings)->max_size);
    TRACE(TRACE_DEBUG, "settings->tls: [%d]", (*settings)->tls);
    TRACE(TRACE_DEBUG, "settings->lib_dir: [%s]", (*settings)->lib_dir);
    TRACE(TRACE_DEBUG, "settings->pid_file: [%s]", (*settings)->pid_file);
    TRACE(TRACE_DEBUG, "settings->bind_ip: [%s]", (*settings)->bind_ip);
    TRACE(TRACE_DEBUG, "settings->bind_port: [%d]", (*settings)->bind_port);
    TRACE(TRACE_DEBUG, "settings->listen_backlog: [%d]", (*settings)->listen_backlog);
    TRACE(TRACE_DEBUG, "settings->foreground: [%d]", (*settings)->foreground);
    TRACE(TRACE_DEBUG, "settings->user: [%s]", (*settings)->user);
    TRACE(TRACE_DEBUG, "settings->group: [%s]", (*settings)->group);
    TRACE(TRACE_DEBUG, "settings->max_childs: [%d]", (*settings)->max_childs);
    TRACE(TRACE_DEBUG, "settings->spare_childs: [%d]", (*settings)->spare_childs);
    TRACE(TRACE_DEBUG, "settings->lookup_persistent: [%d]", (*settings)->lookup_persistent);
    TRACE(TRACE_DEBUG, "settings->syslog_facility: [%d]", (*settings)->syslog_facility);

    TRACE(TRACE_DEBUG, "settings->sql_driver: [%s]", (*settings)->sql_driver);
    TRACE(TRACE_DEBUG, "settings->sql_name: [%s]", (*settings)->sql_name);
    elem = smf_list_head((*settings)->sql_host);
    while(elem != NULL) {
        s = (char *)smf_list_data(elem);
        TRACE(TRACE_DEBUG, "settings->sql_host: [%s]", s);
        elem = elem->next;
    }
    TRACE(TRACE_DEBUG, "settings->sql_user: [%s]", (*settings)->sql_user);
    TRACE(TRACE_DEBUG, "settings->sql_pass: [%s]", (*settings)->sql_pass);
    TRACE(TRACE_DEBUG, "settings->sql_user_query: [%s]", (*settings)->sql_user_query);
    TRACE(TRACE_DEBUG, "settings->encoding: [%s]", (*settings)->sql_encoding);
    TRACE(TRACE_DEBUG, "settings->max_connections: [%d]", (*settings)->sql_max_connections);
    TRACE(TRACE_DEBUG, "settings->port: [%d]", (*settings)->sql_port);

    TRACE(TRACE_DEBUG, "settings->ldap_uri: [%s]", (*settings)->ldap_uri);
    elem = smf_list_head((*settings)->ldap_host);
    while(elem != NULL) {
        s = (char *)smf_list_data(elem);
        TRACE(TRACE_DEBUG, "settings->ldap_host: [%s]", s);
        elem = elem->next;
    }
    TRACE(TRACE_DEBUG, "settings->ldap_port: [%d]", (*settings)->ldap_port);
    TRACE(TRACE_DEBUG, "settings->ldap_binddn: [%s]", (*settings)->ldap_binddn);
    TRACE(TRACE_DEBUG, "settings->ldap_bindpw: [%s]", (*settings)->ldap_bindpw);
    TRACE(TRACE_DEBUG, "settings->ldap_base: [%s]", (*settings)->ldap_base);
    TRACE(TRACE_DEBUG, "settings->ldap_user_query: [%s]", (*settings)->ldap_user_query);
    TRACE(TRACE_DEBUG, "settings->ldap_scope: [%s]", (*settings)->ldap_scope);
    TRACE(TRACE_DEBUG, "settings->ldap_referrals: [%d]", (*settings)->ldap_referrals);

    /** smtpd checks **/
    if ((*settings)->nexthop_fail_msg == NULL)
        (*settings)->nexthop_fail_msg = strdup("Requested action aborted: local error in processing");

    TRACE(TRACE_DEBUG, "settings->nexthop_fail_code: [%d]", (*settings)->nexthop_fail_code);
    TRACE(TRACE_DEBUG, "settings->nexthop_fail_msg: [%s]", (*settings)->nexthop_fail_msg);
    TRACE(TRACE_DEBUG, "settings->smtpd_timeout: [%d]\n", (*settings)->smtpd_timeout);

    list = smf_dict_get_keys((*settings)->smtp_codes);
    elem = smf_list_head(list);
    while(elem != NULL) {
        s = (char *)smf_list_data(elem);
        TRACE(TRACE_DEBUG, "settings->smtp_codes: append %s=%s",s,smf_dict_get((*settings)->smtp_codes,s));
        elem = elem->next;
    }
    smf_list_free(list);
    return 0;
}
Example #9
0
void _set_config_value(SMFSettings_T **settings, char *section, char *key, char *val) {
    char **sl = NULL;
    char **p = NULL;
    char *s = NULL;
    char *tmp = NULL;
    int i;

    if (val==NULL || strlen(val) == 0)
        return;

    /** global section **/
    if (strcmp(section,"global")==0) {
        /** [global]debug **/
        if (strcmp(key,"debug")==0) {
            (*settings)->debug = _get_boolean(val);
            configure_debug((*settings)->debug);
        /** [global]queue_dir **/
        } else if (strcmp(key,"queue_dir")==0) {
            if ((*settings)->queue_dir!=NULL)
                free((*settings)->queue_dir);

            (*settings)->queue_dir = strdup(val);
        /** [global]modules **/
        } else if (strcmp(key, "modules")==0) {
            if (smf_list_size((*settings)->modules) > 0) {
                if (smf_list_free((*settings)->modules)!=0)
                    TRACE(TRACE_ERR,"failed to free modules list");
                else 
                    if (smf_list_new(&((*settings)->modules),_mod_list_destroy)!=0)
                        TRACE(TRACE_ERR,"failed to create modules list");
            }
            sl = _get_list(val);
            p = sl;
            while(*p != NULL) {
                s = smf_core_strstrip(*p);
                smf_settings_add_module((*settings),s);
                free(s);
                p++;
            }
            free(sl);
        /** [global]engine **/
        } else if (strcmp(key,"engine")==0) {
            if ((*settings)->engine!=NULL) 
                free((*settings)->engine);

            (*settings)->engine = strdup(val);
        /** [global]module_fail **/
        } else if (strcmp(key,"module_fail")==0) {
            i = _get_integer(val);

            /** check allowed values... */
            if (i==1 || i==2 || i==3)
                (*settings)->module_fail = i;
        /** [global]nexthop **/
        } else if (strcmp(key,"nexthop")==0) {
            if ((*settings)->nexthop!=NULL)
                free((*settings)->nexthop);
        
            (*settings)->nexthop = strdup(val);
        /** [global]backend **/
        } else if (strcmp(key,"backend")==0) {
            if ((*settings)->backend!=NULL)
                free((*settings)->backend);

            if ((strcmp(val,"sql")==0)||(strcmp(val,"ldap")==0))
                (*settings)->backend = strdup(val);
        /** [global]backend_connection **/
        } else if (strcmp(key,"backend_connection")==0) {
            if ((*settings)->backend_connection!=NULL) 
                free((*settings)->backend_connection);

            if ((strcmp(val,"balance")==0)||(strcmp(val,"failover")==0)) 
                (*settings)->backend_connection = strdup(val);
        /** [global]add_header **/
        } else if (strcmp(key,"add_header")==0) {
            (*settings)->add_header = _get_boolean(val);
        /** [global]max_size **/
        } else if (strcmp(key,"max_size")==0) {
            (*settings)->max_size = _get_integer(val);
        /** [global]tls_enable **/
        } else if (strcmp(key,"tls_enable")==0) {
            i = _get_integer(val);
            /** check allowed values... */
            if (i==0 || i==1 || i==2)
                (*settings)->tls = i;
        /** [global]lib_dir **/
        } else if (strcmp(key,"lib_dir")==0) {
            if ((*settings)->lib_dir!=NULL)
                free((*settings)->lib_dir);
        
            (*settings)->lib_dir = strdup(val);
        /** [global]pid_file **/
        } else if (strcmp(key,"pid_file")==0) {
            if ((*settings)->pid_file!=NULL)
                free((*settings)->pid_file);

            (*settings)->pid_file = strdup(val);
        /** [global]bind_ip **/
        } else if (strcmp(key,"bind_ip")==0) {
            if ((*settings)->bind_ip!=NULL)
                free((*settings)->bind_ip);

            (*settings)->bind_ip = strdup(val);
        /** [global]bind_port **/
        } else if (strcmp(key,"bind_port")==0) {
            (*settings)->bind_port = _get_integer(val);
        /** [global]listen_backlog **/
        } else if (strcmp(key,"listen_backlog")==0) {
            (*settings)->listen_backlog = _get_integer(val);
        /** [global]foreground **/
        } else if (strcmp(key,"foreground")==0) {
            int fg = _get_boolean(val);
            (*settings)->foreground = fg;
            configure_trace_destination(fg ? TRACE_DEST_STDERR : TRACE_DEST_SYSLOG);
        /** [global]user **/
        } else if (strcmp(key,"user")==0) {
            if ((*settings)->user!=NULL)
                free((*settings)->user);

            (*settings)->user = strdup(val);
        /** [global]group **/
        } else if (strcmp(key,"group")==0) {
            if ((*settings)->group!=NULL)
                free((*settings)->group);

            (*settings)->group = strdup(val);
        /** [global]max_childs **/
        } else if (strcmp(key,"max_childs")==0) {
            (*settings)->max_childs = _get_integer(val);
        /** [global]spare_childs **/
        } else if (strcmp(key,"spare_childs")==0) {
            (*settings)->spare_childs = _get_integer(val);
        /** [global]lookup_persistent **/
        } else if (strcmp(key,"lookup_persistent")==0) {
            (*settings)->lookup_persistent = _get_boolean(val);
        } else if (strcmp(key,"syslog_facility")==0) {
            smf_settings_set_syslog_facility((*settings), val);
        }
    /** sql section **/
    } else if (strcmp(section,"sql")==0) {
        /** [sql]driver **/
        if (strcmp(key,"driver")==0) {
            if ((*settings)->sql_driver != NULL)
                free((*settings)->sql_driver);

            if ((strcmp(val,"mysql")==0)||(strcmp(val,"pgsql")==0)||(strcmp(val,"sqlite")==0))
                (*settings)->sql_driver = strdup(val);
        /** [sql]name **/
        } else if (strcmp(key, "name")==0) {
            if ((*settings)->sql_name != NULL)
                free((*settings)->sql_name);

            (*settings)->sql_name = strdup(val);
        /** [sql]host **/
        } else if (strcmp(key, "host")==0) {
            if (smf_list_size((*settings)->sql_host) > 0) {
                if (smf_list_free((*settings)->sql_host)!=0)
                    TRACE(TRACE_ERR,"failed to free host list");
                else 
                    if (smf_list_new(&((*settings)->sql_host),smf_internal_string_list_destroy)!=0)
                        TRACE(TRACE_ERR,"failed to create host list");
            }
            sl = _get_list(val);
            p = sl;
            while(*p != NULL) {
                s = smf_core_strstrip(*p);
                smf_list_append((*settings)->sql_host, s);
                p++;
            }
            free(sl); 
        /** [sql]user **/
        } else if (strcmp(key, "user")==0) {
            if ((*settings)->sql_user != NULL)
                free((*settings)->sql_user);

            (*settings)->sql_user = strdup(val);
        /** [sql]pass **/
        } else if (strcmp(key, "pass")==0) {
            if ((*settings)->sql_pass != NULL)
                free((*settings)->sql_pass);

            (*settings)->sql_pass = strdup(val);
        /** [sql]user_query **/
        } else if (strcmp(key, "user_query")==0) {
            if ((*settings)->sql_user_query != NULL)
                free((*settings)->sql_user_query);

            (*settings)->sql_user_query = strdup(val);
        /** [sql]encoding **/
        } else if (strcmp(key, "encoding")==0) {
            if ((*settings)->sql_encoding != NULL)
                free((*settings)->sql_encoding);

            (*settings)->sql_encoding = strdup(val);
        /** [sql]max_connections **/
        } else if (strcmp(key,"max_connections")==0) {
            (*settings)->sql_max_connections = _get_integer(val);
        /** [sql]port **/
        } else if (strcmp(key,"port")==0) {
            (*settings)->sql_port = _get_integer(val);
        }
    /** ldap section **/
    } else if (strcmp(section,"ldap")==0) {
        /** [ldap]uri **/
        if (strcmp(key, "uri")==0) {
            if ((*settings)->ldap_uri != NULL)
                free((*settings)->ldap_uri);

            (*settings)->ldap_uri = strdup(val);
        /** [ldap]host **/
        } else if (strcmp(key, "host")==0) {
            if (smf_list_size((*settings)->ldap_host) > 0) {
                if (smf_list_free((*settings)->ldap_host)!=0)
                    TRACE(TRACE_ERR,"failed to free host list");
                else 
                    if (smf_list_new(&((*settings)->ldap_host),smf_internal_string_list_destroy)!=0)
                        TRACE(TRACE_ERR,"failed to create host list");
            }
            sl = _get_list(val);
            p = sl;
            while(*p != NULL) {
                s = smf_core_strstrip(*p);
                smf_list_append((*settings)->ldap_host, s);
                p++;
            }
            free(sl);
        /** [ldap]port **/
        } else if (strcmp(key,"port")==0) {
            (*settings)->ldap_port = _get_integer(val);
        /** [ldap]binddn **/
        } else if (strcmp(key, "binddn")==0) {
            if ((*settings)->ldap_binddn != NULL)
                free((*settings)->ldap_binddn);

            (*settings)->ldap_binddn = strdup(val);
        /** [ldap]bindpw **/
        } else if (strcmp(key, "bindpw")==0) {
            if ((*settings)->ldap_bindpw != NULL)
                free((*settings)->ldap_bindpw);

            (*settings)->ldap_bindpw = strdup(val);
        /** [ldap]base **/
        } else if (strcmp(key, "base")==0) {
            if ((*settings)->ldap_base != NULL)
                free((*settings)->ldap_base);

            (*settings)->ldap_base = strdup(val);
        /** [ldap]user_query **/
        } else if (strcmp(key, "user_query")==0) {
            if ((*settings)->ldap_user_query != NULL)
                free((*settings)->ldap_user_query);

            (*settings)->ldap_user_query = strdup(val);
        /** [ldap]scope **/
        } else if (strcmp(key, "scope")==0) {
            if ((*settings)->ldap_scope != NULL)
                free((*settings)->ldap_scope);

            (*settings)->ldap_scope = strdup(val);
        /** [ldap]referrals **/
        } else if (strcmp(key,"referrals")==0) {
            (*settings)->ldap_referrals = _get_boolean(val);
        }
    /** smtpd section **/
    } else if (strcmp(section,"smtpd")==0) {
        /** [smtpd]nexthop_fail_msg **/
        if (strcmp(key, "nexthop_fail_msg")==0) {
            if ((*settings)->nexthop_fail_msg != NULL)
                free((*settings)->nexthop_fail_msg);

            (*settings)->nexthop_fail_msg = strdup(val);
        /** [smtpd]nexthop_fail_code **/
        } else if (strcmp(key, "nexthop_fail_code")==0) {
            (*settings)->nexthop_fail_code = _get_integer(val);
        } else if (strcmp(key, "smtpd_timeout")==0) {
            (*settings)->smtpd_timeout = _get_integer(val);
        /** smtp code **/
        } else {
            i = _get_integer(key);
            if (i >= 250 && i < 600) {
                smf_dict_set((*settings)->smtp_codes,key,val);
            }
        }
    /** custom sections */
    } else {
        asprintf(&tmp,"%s:%s",section,key);
        smf_dict_set((*settings)->groups,tmp,val);
    }

}