Changes in / [166a571:991c75f]


Ignore:
Files:
4 added
19 edited

Legend:

Unmodified
Added
Removed
  • .travis.yml

    r166a571 r991c75f  
    33
    44script:
    5  - ./configure
     5 - ./configure --pam=1 --ldap=1
    66 - make check
    77 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us -d
     
    2929    - libpurple-dev
    3030    - check
     31    - libpam0g-dev
     32    - libldap2-dev
    3133  coverity_scan:
    3234    project:
     
    3436      description: "An IRC to other chat networks gateway"
    3537    notification_email: dx@dxzone.com.ar
    36     build_command_prepend: ./configure --otr=1 --debug=1
     38    build_command_prepend: ./configure --otr=1 --debug=1 --pam=1 --ldap=1
    3739    build_command: make
    3840    branch_pattern: coverity_scan
  • Makefile

    r166a571 r991c75f  
    1010
    1111# Program variables
    12 objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_cap.o irc_channel.o irc_commands.o irc_send.o irc_user.o irc_util.o nick.o $(OTR_BI) query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o conf.o log.o
     12objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_cap.o irc_channel.o irc_commands.o irc_send.o irc_user.o irc_util.o nick.o $(OTR_BI) query.o root_commands.o set.o storage.o $(STORAGE_OBJS) auth.o $(AUTH_OBJS) unix.o conf.o log.o
    1313headers = $(wildcard $(_SRCDIR_)*.h $(_SRCDIR_)lib/*.h $(_SRCDIR_)protocols/*.h)
    1414subdirs = lib protocols
  • bitlbee.conf

    r166a571 r991c75f  
    5252# AuthMode = Open
    5353
     54## AuthBackend
     55##
     56## By default, the authentication data for a user is stored in the storage
     57## backend. If you want to authenticate against another authentication system
     58## (e.g. ldap), you can specify that here.
     59##
     60## Beware that this disables password changes and causes passwords for the
     61## accounts people create to be stored in plain text instead of encrypted with
     62## their bitlbee password.
     63##
     64## Currently available backends:
     65##
     66## - storage (internal storage)
     67## - pam (Linux PAM authentication)
     68## - ldap (LDAP server configured in the openldap settings)
     69#
     70# AuthBackend = storage
     71#
     72
    5473## AuthPassword
    5574##
     
    6988## or
    7089# OperPassword = md5:I0mnZbn1t4R731zzRdDN2/pK7lRX
     90
     91## AllowAccountAdd
     92##
     93## Whether to allow registered and identified users to add new accounts using
     94## 'account add'
     95##
     96# AllowAccountAdd 1
    7197
    7298## HostName
  • bitlbee.h

    r166a571 r991c75f  
    133133#include "irc.h"
    134134#include "storage.h"
     135#include "auth.h"
    135136#include "set.h"
    136137#include "nogaim.h"
     
    154155        conf_t *conf;
    155156        GList *storage; /* The first backend in the list will be used for saving */
     157        GList *auth;    /* Authentication backends */
    156158        char *helpfile;
    157159        int restart;
  • conf.c

    r166a571 r991c75f  
    5555        conf->runmode = RUNMODE_INETD;
    5656        conf->authmode = AUTHMODE_OPEN;
     57        conf->auth_backend = NULL;
    5758        conf->auth_pass = NULL;
    5859        conf->oper_pass = NULL;
     60        conf->allow_account_add = 1;
    5961        conf->configdir = g_strdup(CONFIG);
    6062        conf->plugindir = g_strdup(PLUGINDIR);
     
    240242                                        conf->authmode = AUTHMODE_OPEN;
    241243                                }
     244                        } else if (g_strcasecmp(ini->key, "authbackend") == 0) {
     245                                if (g_strcasecmp(ini->value, "storage") == 0) {
     246                                        conf->auth_backend = NULL;
     247                                } else if (g_strcasecmp(ini->value, "pam") == 0 ||
     248                                         g_strcasecmp(ini->value, "ldap") == 0) {
     249                                        g_free(conf->auth_backend);
     250                                        conf->auth_backend = g_strdup(ini->value);
     251                                } else {
     252                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
     253                                        return 0;
     254                                }
    242255                        } else if (g_strcasecmp(ini->key, "authpassword") == 0) {
    243256                                g_free(conf->auth_pass);
     
    246259                                g_free(conf->oper_pass);
    247260                                conf->oper_pass = g_strdup(ini->value);
     261                        } else if (g_strcasecmp(ini->key, "allowaccountadd") == 0) {
     262                                if (!is_bool(ini->value)) {
     263                                        fprintf(stderr, "Invalid %s value: %s\n", ini->key, ini->value);
     264                                        return 0;
     265                                }
     266                                conf->allow_account_add = bool2int(ini->value);
    248267                        } else if (g_strcasecmp(ini->key, "hostname") == 0) {
    249268                                g_free(conf->hostname);
  • conf.h

    r166a571 r991c75f  
    3737        runmode_t runmode;
    3838        authmode_t authmode;
     39        char *auth_backend;
    3940        char *auth_pass;
    4041        char *oper_pass;
     42        int allow_account_add;
    4143        char *hostname;
    4244        char *configdir;
  • configure

    r166a571 r991c75f  
    5252ssl=auto
    5353
     54pam=0
     55ldap=0
     56
    5457pie=1
    5558
     
    133136--purple=0/1    Disable/enable libpurple support        $purple
    134137                (automatically disables other protocol modules)
     138
     139--pam=0/1       Disable/enable PAM authentication       $pam
     140--ldap=0/1      Disable/enable LDAP authentication      $ldap
    135141
    136142--doc=0/1       Disable/enable help.txt generation      $doc
     
    628634done
    629635echo "STORAGE_OBJS="$STORAGE_OBJS >> Makefile.settings
     636
     637authobjs=
     638authlibs=
     639if [ "$pam" = 0 ]; then
     640        echo '#undef WITH_PAM' >> config.h
     641else
     642        if ! echo '#include <security/pam_appl.h>' | $CC -E - >/dev/null 2>/dev/null; then
     643                echo 'Cannot find libpam development libraries, aborting. (Install libpam0g-dev?)'
     644                exit 1
     645        fi
     646        echo '#define WITH_PAM' >> config.h
     647        authobjs=$authobjs'auth_pam.o '
     648        authlibs=$authlibs'-lpam '
     649fi
     650if [ "$ldap" = 0 ]; then
     651        echo '#undef WITH_LDAP' >> config.h
     652else
     653        if ! echo '#include <ldap.h>' | $CC -E - >/dev/null 2>/dev/null; then
     654                echo 'Cannot find libldap development libraries, aborting. (Install libldap2-dev?)'
     655                exit 1
     656        fi
     657        echo '#define WITH_LDAP' >> config.h
     658        authobjs=$authobjs'auth_ldap.o '
     659        authlibs=$authlibs'-lldap '
     660fi
     661echo AUTH_OBJS=$authobjs >> Makefile.settings
     662echo EFLAGS+=$authlibs >> Makefile.settings
    630663
    631664if [ "$strip" = 0 ]; then
  • irc.h

    r166a571 r991c75f  
    9292                           logging in, this may contain a password we should
    9393                           send to identify after USER/NICK are received. */
     94        char *auth_backend;
    9495
    9596        char umode[8];
  • irc_cap.c

    r166a571 r991c75f  
    177177
    178178        } else if (g_strcasecmp(cmd[1], "END") == 0) {
     179                if (!(irc->status & USTATUS_CAP_PENDING)) {
     180                        return;
     181                }
    179182                irc->status &= ~USTATUS_CAP_PENDING;
    180183
  • irc_commands.c

    r166a571 r991c75f  
    9797        /* just check the password here to be able to reply with useful numerics
    9898         * the actual identification will be handled later */
    99         status = storage_check_pass(user, pass);
     99        status = auth_check_pass(irc, user, pass);
    100100
    101101        if (status == STORAGE_OK) {
  • protocols/account.c

    r166a571 r991c75f  
    6767
    6868        s = set_add(&a->set, "password", NULL, set_eval_account, a);
    69         s->flags |= SET_NOSAVE | SET_NULL_OK | SET_PASSWORD;
     69        s->flags |= SET_NOSAVE | SET_NULL_OK | SET_PASSWORD | ACC_SET_LOCKABLE;
    7070
    7171        s = set_add(&a->set, "tag", NULL, set_eval_account, a);
     
    7373
    7474        s = set_add(&a->set, "username", NULL, set_eval_account, a);
    75         s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
     75        s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY | ACC_SET_LOCKABLE;
    7676        set_setstr(&a->set, "username", user);
    7777
  • protocols/account.h

    r166a571 r991c75f  
    6363        ACC_SET_OFFLINE_ONLY = 0x02,    /* Allow changes only if the acct is offline. */
    6464        ACC_SET_ONLINE_ONLY = 0x04,     /* Allow changes only if the acct is online. */
     65        ACC_SET_LOCKABLE = 0x08         /* Setting cannot be changed if the account is locked down */
    6566} account_set_flag_t;
    6667
     
    7071        ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */
    7172        ACC_FLAG_LOCAL = 0x08,          /* Contact list is local. */
     73        ACC_FLAG_LOCKED = 0x10,         /* Account is locked (cannot be deleted, certain settings can't changed) */
    7274} account_flag_t;
    7375
  • root_commands.c

    r166a571 r991c75f  
    143143        }
    144144
    145         if (load) {
     145        status = auth_check_pass(irc, irc->user->nick, password);
     146        if (load && (status == STORAGE_OK)) {
    146147                status = storage_load(irc, password);
    147         } else {
    148                 status = storage_check_pass(irc->user->nick, password);
    149148        }
    150149
     
    159158                irc_rootmsg(irc, "Password accepted%s",
    160159                            load ? ", settings and accounts loaded" : "");
    161                 irc_setpass(irc, password);
    162160                irc->status |= USTATUS_IDENTIFIED;
    163161                irc_umode_set(irc, "+R", 1);
     
    268266        storage_status_t status;
    269267
    270         status = storage_remove(irc->user->nick, cmd[1]);
     268        status = auth_check_pass(irc, irc->user->nick, cmd[1]);
     269        if (status == STORAGE_OK) {
     270                status = storage_remove(irc->user->nick);
     271        }
     272
    271273        switch (status) {
    272274        case STORAGE_NO_SUCH_USER:
     
    340342                int st;
    341343
     344                if (s && s->flags & SET_LOCKED) {
     345                        irc_rootmsg(irc, "This setting can not be changed");
     346                        return 0;
     347                }
    342348                if (s && checkflags && checkflags(irc, s) == 0) {
    343349                        return 0;
     
    388394                irc_rootmsg(irc, "This setting can only be changed when the account is %s-line", "on");
    389395                return 0;
     396        } else if (a->flags & ACC_FLAG_LOCKED && s && s->flags & ACC_SET_LOCKABLE) {
     397                irc_rootmsg(irc, "This setting can not be changed for locked accounts");
     398                return 0;
    390399        }
    391400
     
    409418
    410419                MIN_ARGS(3);
     420
     421                if (!global.conf->allow_account_add) {
     422                        irc_rootmsg(irc, "This server does not allow adding new accounts");
     423                        return;
     424                }
    411425
    412426                if (cmd[4] == NULL) {
     
    547561
    548562        if (len >= 1 && g_strncasecmp(cmd[2], "del", len) == 0) {
    549                 if (a->ic) {
     563                if (a->flags & ACC_FLAG_LOCKED) {
     564                        irc_rootmsg(irc, "Account is locked, can't delete");
     565                }
     566                else if (a->ic) {
    550567                        irc_rootmsg(irc, "Account is still logged in, can't delete");
    551568                } else {
  • set.h

    r166a571 r991c75f  
    4949        SET_PASSWORD = 0x0400, /* Value shows up in settings list as "********". */
    5050        SET_HIDDEN_DEFAULT = 0x0800, /* Hide unless changed from default. */
     51        SET_LOCKED = 0x1000    /* Setting is locked, don't allow changing it */
    5152} set_flags_t;
    5253
  • storage.c

    r166a571 r991c75f  
    8787}
    8888
    89 storage_status_t storage_check_pass(const char *nick, const char *password)
     89storage_status_t storage_check_pass(irc_t *irc, const char *nick, const char *password)
    9090{
    9191        GList *gl;
     
    9797                storage_status_t status;
    9898
    99                 status = st->check_pass(nick, password);
     99                status = st->check_pass(irc, nick, password);
    100100                if (status != STORAGE_NO_SUCH_USER) {
    101101                        return status;
     
    171171}
    172172
    173 storage_status_t storage_remove(const char *nick, const char *password)
     173storage_status_t storage_remove(const char *nick)
    174174{
    175175        GList *gl;
     
    185185                storage_status_t status;
    186186
    187                 status = st->remove(nick, password);
     187                status = st->remove(nick);
    188188                ok |= status == STORAGE_OK;
    189189                if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK) {
  • storage.h

    r166a571 r991c75f  
    3131        STORAGE_NO_SUCH_USER,
    3232        STORAGE_INVALID_PASSWORD,
     33        STORAGE_CHECK_BACKEND,
    3334        STORAGE_ALREADY_EXISTS,
    3435        STORAGE_OTHER_ERROR /* Error that isn't caused by user input, such as
     
    4344        void (*init)(void);
    4445
    45         storage_status_t (*check_pass)(const char *nick, const char *password);
     46        storage_status_t (*check_pass)(irc_t *irc, const char *nick, const char *password);
    4647
    4748        storage_status_t (*load)(irc_t *irc, const char *password);
    4849        storage_status_t (*save)(irc_t *irc, int overwrite);
    49         storage_status_t (*remove)(const char *nick, const char *password);
     50        storage_status_t (*remove)(const char *nick);
    5051
    5152        /* May be NULL if not supported by backend */
     
    5354} storage_t;
    5455
    55 storage_status_t storage_check_pass(const char *nick, const char *password);
     56storage_status_t storage_check_pass(irc_t *irc, const char *nick, const char *password);
    5657
    5758storage_status_t storage_load(irc_t * irc, const char *password);
    5859storage_status_t storage_save(irc_t *irc, char *password, int overwrite);
    59 storage_status_t storage_remove(const char *nick, const char *password);
     60storage_status_t storage_remove(const char *nick);
    6061
    6162void register_storage_backend(storage_t *);
  • storage_xml.c

    r166a571 r991c75f  
    3434
    3535typedef enum {
    36         XML_PASS_CHECK_ONLY = -1,
    37         XML_PASS_UNKNOWN = 0,
    38         XML_PASS_WRONG,
    39         XML_PASS_OK
    40 } xml_pass_st;
     36        XML_PASS_CHECK = 0,
     37        XML_LOAD
     38} xml_action;
    4139
    4240/* To make it easier later when extending the format: */
     
    6563{
    6664        struct xt_node *c;
     65        struct set *s;
    6766
    6867        for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) {
    6968                char *name = xt_find_attr(c, "name");
     69                char *locked = xt_find_attr(c, "locked");
    7070
    7171                if (!name) {
     
    8080                }
    8181                set_setstr(head, name, c->text);
     82                if (locked && !g_strcasecmp(locked, "true")) {
     83                        s = set_find(head, name);
     84                        if (s) {
     85                                s->flags |= SET_LOCKED;
     86                        }
     87                }
    8288        }
    8389}
     
    8692{
    8793        struct xml_parsedata *xd = data;
    88         char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag;
     94        char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag, *locked;
    8995        char *pass_b64 = NULL;
    9096        unsigned char *pass_cr = NULL;
     
    99105        autoconnect = xt_find_attr(node, "autoconnect");
    100106        tag = xt_find_attr(node, "tag");
     107        locked = xt_find_attr(node, "locked");
    101108
    102109        protocol = xt_find_attr(node, "protocol");
     
    112119        if (!handle || !pass_b64 || !protocol || !prpl) {
    113120                return XT_ABORT;
    114         } else if ((pass_len = base64_decode(pass_b64, (unsigned char **) &pass_cr)) &&
    115                    arc_decode(pass_cr, pass_len, &password, xd->given_pass) >= 0) {
    116                 acc = account_add(xd->irc->b, prpl, handle, password);
    117                 if (server) {
    118                         set_setstr(&acc->set, "server", server);
    119                 }
    120                 if (autoconnect) {
    121                         set_setstr(&acc->set, "auto_connect", autoconnect);
    122                 }
    123                 if (tag) {
    124                         set_setstr(&acc->set, "tag", tag);
    125                 }
    126                 if (local) {
    127                         acc->flags |= ACC_FLAG_LOCAL;
    128                 }
     121        }
     122
     123        pass_len = base64_decode(pass_b64, (unsigned char **) &pass_cr);
     124        if (xd->irc->auth_backend) {
     125                password = g_strdup((char *)pass_cr);
    129126        } else {
    130                 g_free(pass_cr);
    131                 g_free(password);
    132                 return XT_ABORT;
     127                pass_len = arc_decode(pass_cr, pass_len, &password, xd->given_pass);
     128                if (pass_len < 0) {
     129                        g_free(pass_cr);
     130                        g_free(password);
     131                        return XT_ABORT;
     132                }
     133        }
     134
     135        acc = account_add(xd->irc->b, prpl, handle, password);
     136        if (server) {
     137                set_setstr(&acc->set, "server", server);
     138        }
     139        if (autoconnect) {
     140                set_setstr(&acc->set, "auto_connect", autoconnect);
     141        }
     142        if (tag) {
     143                set_setstr(&acc->set, "tag", tag);
     144        }
     145        if (local) {
     146                acc->flags |= ACC_FLAG_LOCAL;
     147        }
     148        if (locked && !g_strcasecmp(locked, "true")) {
     149                acc->flags |= ACC_FLAG_LOCKED;
    133150        }
    134151
     
    186203};
    187204
    188 static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_pass_st action)
     205static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_action action)
    189206{
    190207        struct xml_parsedata xd[1];
     
    228245        }
    229246
    230         {
     247        if (action == XML_PASS_CHECK) {
    231248                char *nick = xt_find_attr(node, "nick");
    232249                char *pass = xt_find_attr(node, "password");
    233 
    234                 if (!nick || !pass) {
     250                char *backend = xt_find_attr(node, "auth_backend");
     251
     252                if (!nick || !(pass || backend)) {
    235253                        goto error;
     254                }
     255
     256                if (backend) {
     257                        g_free(xd->irc->auth_backend);
     258                        xd->irc->auth_backend = g_strdup(backend);
     259                        ret = STORAGE_CHECK_BACKEND;
    236260                } else if ((st = md5_verify_password(xd->given_pass, pass)) != 0) {
    237261                        ret = STORAGE_INVALID_PASSWORD;
    238                         goto error;
    239                 }
    240         }
    241 
    242         if (action == XML_PASS_CHECK_ONLY) {
    243                 ret = STORAGE_OK;
    244                 goto error;
    245         }
    246 
    247         /* DO NOT call xt_handle() before verifying the password! */
     262                } else {
     263                        ret = STORAGE_OK;
     264                }
     265                goto error;
     266        }
     267
    248268        if (xt_handle(xp, NULL, 1) == XT_HANDLED) {
    249269                ret = STORAGE_OK;
     
    260280static storage_status_t xml_load(irc_t *irc, const char *password)
    261281{
    262         return xml_load_real(irc, irc->user->nick, password, XML_PASS_UNKNOWN);
    263 }
    264 
    265 static storage_status_t xml_check_pass(const char *my_nick, const char *password)
    266 {
    267         return xml_load_real(NULL, my_nick, password, XML_PASS_CHECK_ONLY);
     282        return xml_load_real(irc, irc->user->nick, password, XML_LOAD);
     283}
     284
     285static storage_status_t xml_check_pass(irc_t *irc, const char *my_nick, const char *password)
     286{
     287        return xml_load_real(irc, my_nick, password, XML_PASS_CHECK);
    268288}
    269289
     
    280300        struct xt_node *root, *cur;
    281301
    282         /* Generate a salted md5sum of the password. Use 5 bytes for the salt
    283            (to prevent dictionary lookups of passwords) to end up with a 21-
    284            byte password hash, more convenient for base64 encoding. */
    285         random_bytes(pass_md5 + 16, 5);
    286         md5_init(&md5_state);
    287         md5_append(&md5_state, (md5_byte_t *) irc->password, strlen(irc->password));
    288         md5_append(&md5_state, pass_md5 + 16, 5);   /* Add the salt. */
    289         md5_finish(&md5_state, pass_md5);
    290         /* Save the hash in base64-encoded form. */
    291         pass_buf = base64_encode(pass_md5, 21);
    292 
    293302        root = cur = xt_new_node("user", NULL, NULL);
     303        if (irc->auth_backend) {
     304                xt_add_attr(cur, "auth_backend", irc->auth_backend);
     305        } else {
     306                /* Generate a salted md5sum of the password. Use 5 bytes for the salt
     307                   (to prevent dictionary lookups of passwords) to end up with a 21-
     308                   byte password hash, more convenient for base64 encoding. */
     309                random_bytes(pass_md5 + 16, 5);
     310                md5_init(&md5_state);
     311                md5_append(&md5_state, (md5_byte_t *) irc->password, strlen(irc->password));
     312                md5_append(&md5_state, pass_md5 + 16, 5);   /* Add the salt. */
     313                md5_finish(&md5_state, pass_md5);
     314                /* Save the hash in base64-encoded form. */
     315                pass_buf = base64_encode(pass_md5, 21);
     316                xt_add_attr(cur, "password", pass_buf);
     317                g_free(pass_buf);
     318        }
     319
    294320        xt_add_attr(cur, "nick", irc->user->nick);
    295         xt_add_attr(cur, "password", pass_buf);
    296321        xt_add_attr(cur, "version", XML_FORMAT_VERSION);
    297 
    298         g_free(pass_buf);
    299322
    300323        xml_generate_settings(cur, &irc->b->set);
     
    307330                int pass_len;
    308331
    309                 pass_len = arc_encode(acc->pass, strlen(acc->pass), (unsigned char **) &pass_cr, irc->password, 12);
    310                 pass_b64 = base64_encode(pass_cr, pass_len);
    311                 g_free(pass_cr);
     332                if(irc->auth_backend) {
     333                        /* If we don't "own" the password, it may change without us
     334                         * knowing, so we cannot encrypt the data, as we then may not be
     335                         * able to decrypt it */
     336                        pass_b64 = base64_encode((unsigned char *)acc->pass, strlen(acc->pass));
     337                } else {
     338                        pass_len = arc_encode(acc->pass, strlen(acc->pass), (unsigned char **) &pass_cr, irc->password, 12);
     339                        pass_b64 = base64_encode(pass_cr, pass_len);
     340                        g_free(pass_cr);
     341                }
    312342
    313343                cur = xt_new_node("account", NULL, NULL);
     
    320350                        xt_add_attr(cur, "server", acc->server);
    321351                }
     352                if (acc->flags & ACC_FLAG_LOCKED) {
     353                        xt_add_attr(cur, "locked", "true");
     354                }
    322355
    323356                g_free(pass_b64);
     
    364397                        xt_add_child(cur, xset = xt_new_node("setting", set->value, NULL));
    365398                        xt_add_attr(xset, "name", set->key);
     399                        if (set->flags & SET_LOCKED) {
     400                                xt_add_attr(xset, "locked", "true");
     401                        }
    366402                }
    367403        }
     
    422458
    423459
    424 static storage_status_t xml_remove(const char *nick, const char *password)
     460static storage_status_t xml_remove(const char *nick)
    425461{
    426462        char s[512], *lc;
    427         storage_status_t status;
    428 
    429         status = xml_check_pass(nick, password);
    430         if (status != STORAGE_OK) {
    431                 return status;
    432         }
    433463
    434464        lc = g_strdup(nick);
  • tests/Makefile

    r166a571 r991c75f  
    1515distclean: clean
    1616
    17 main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o
     17main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o auth.o auth_pam.o auth_ldap.o
    1818
    1919test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_set.o check_jabber_sasl.o check_jabber_util.o
  • unix.c

    r166a571 r991c75f  
    104104        }
    105105
     106        global.auth = auth_init(global.conf->auth_backend);
     107        if (global.conf->auth_backend && global.auth == NULL) {
     108                log_message(LOGLVL_ERROR, "Unable to load authentication backend '%s'", global.conf->auth_backend);
     109                return(1);
     110        }
     111
    106112        if (global.conf->runmode == RUNMODE_INETD) {
    107113                log_link(LOGLVL_ERROR, LOGOUTPUT_IRC);
Note: See TracChangeset for help on using the changeset viewer.