Changes in / [166a571:991c75f]
- Files:
-
- 4 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
.travis.yml
r166a571 r991c75f 3 3 4 4 script: 5 - ./configure 5 - ./configure --pam=1 --ldap=1 6 6 - make check 7 7 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us -d … … 29 29 - libpurple-dev 30 30 - check 31 - libpam0g-dev 32 - libldap2-dev 31 33 coverity_scan: 32 34 project: … … 34 36 description: "An IRC to other chat networks gateway" 35 37 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 37 39 build_command: make 38 40 branch_pattern: coverity_scan -
Makefile
r166a571 r991c75f 10 10 11 11 # 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.o12 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) auth.o $(AUTH_OBJS) unix.o conf.o log.o 13 13 headers = $(wildcard $(_SRCDIR_)*.h $(_SRCDIR_)lib/*.h $(_SRCDIR_)protocols/*.h) 14 14 subdirs = lib protocols -
bitlbee.conf
r166a571 r991c75f 52 52 # AuthMode = Open 53 53 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 54 73 ## AuthPassword 55 74 ## … … 69 88 ## or 70 89 # 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 71 97 72 98 ## HostName -
bitlbee.h
r166a571 r991c75f 133 133 #include "irc.h" 134 134 #include "storage.h" 135 #include "auth.h" 135 136 #include "set.h" 136 137 #include "nogaim.h" … … 154 155 conf_t *conf; 155 156 GList *storage; /* The first backend in the list will be used for saving */ 157 GList *auth; /* Authentication backends */ 156 158 char *helpfile; 157 159 int restart; -
conf.c
r166a571 r991c75f 55 55 conf->runmode = RUNMODE_INETD; 56 56 conf->authmode = AUTHMODE_OPEN; 57 conf->auth_backend = NULL; 57 58 conf->auth_pass = NULL; 58 59 conf->oper_pass = NULL; 60 conf->allow_account_add = 1; 59 61 conf->configdir = g_strdup(CONFIG); 60 62 conf->plugindir = g_strdup(PLUGINDIR); … … 240 242 conf->authmode = AUTHMODE_OPEN; 241 243 } 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 } 242 255 } else if (g_strcasecmp(ini->key, "authpassword") == 0) { 243 256 g_free(conf->auth_pass); … … 246 259 g_free(conf->oper_pass); 247 260 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); 248 267 } else if (g_strcasecmp(ini->key, "hostname") == 0) { 249 268 g_free(conf->hostname); -
conf.h
r166a571 r991c75f 37 37 runmode_t runmode; 38 38 authmode_t authmode; 39 char *auth_backend; 39 40 char *auth_pass; 40 41 char *oper_pass; 42 int allow_account_add; 41 43 char *hostname; 42 44 char *configdir; -
configure
r166a571 r991c75f 52 52 ssl=auto 53 53 54 pam=0 55 ldap=0 56 54 57 pie=1 55 58 … … 133 136 --purple=0/1 Disable/enable libpurple support $purple 134 137 (automatically disables other protocol modules) 138 139 --pam=0/1 Disable/enable PAM authentication $pam 140 --ldap=0/1 Disable/enable LDAP authentication $ldap 135 141 136 142 --doc=0/1 Disable/enable help.txt generation $doc … … 628 634 done 629 635 echo "STORAGE_OBJS="$STORAGE_OBJS >> Makefile.settings 636 637 authobjs= 638 authlibs= 639 if [ "$pam" = 0 ]; then 640 echo '#undef WITH_PAM' >> config.h 641 else 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 ' 649 fi 650 if [ "$ldap" = 0 ]; then 651 echo '#undef WITH_LDAP' >> config.h 652 else 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 ' 660 fi 661 echo AUTH_OBJS=$authobjs >> Makefile.settings 662 echo EFLAGS+=$authlibs >> Makefile.settings 630 663 631 664 if [ "$strip" = 0 ]; then -
irc.h
r166a571 r991c75f 92 92 logging in, this may contain a password we should 93 93 send to identify after USER/NICK are received. */ 94 char *auth_backend; 94 95 95 96 char umode[8]; -
irc_cap.c
r166a571 r991c75f 177 177 178 178 } else if (g_strcasecmp(cmd[1], "END") == 0) { 179 if (!(irc->status & USTATUS_CAP_PENDING)) { 180 return; 181 } 179 182 irc->status &= ~USTATUS_CAP_PENDING; 180 183 -
irc_commands.c
r166a571 r991c75f 97 97 /* just check the password here to be able to reply with useful numerics 98 98 * the actual identification will be handled later */ 99 status = storage_check_pass(user, pass);99 status = auth_check_pass(irc, user, pass); 100 100 101 101 if (status == STORAGE_OK) { -
protocols/account.c
r166a571 r991c75f 67 67 68 68 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; 70 70 71 71 s = set_add(&a->set, "tag", NULL, set_eval_account, a); … … 73 73 74 74 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; 76 76 set_setstr(&a->set, "username", user); 77 77 -
protocols/account.h
r166a571 r991c75f 63 63 ACC_SET_OFFLINE_ONLY = 0x02, /* Allow changes only if the acct is offline. */ 64 64 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 */ 65 66 } account_set_flag_t; 66 67 … … 70 71 ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */ 71 72 ACC_FLAG_LOCAL = 0x08, /* Contact list is local. */ 73 ACC_FLAG_LOCKED = 0x10, /* Account is locked (cannot be deleted, certain settings can't changed) */ 72 74 } account_flag_t; 73 75 -
root_commands.c
r166a571 r991c75f 143 143 } 144 144 145 if (load) { 145 status = auth_check_pass(irc, irc->user->nick, password); 146 if (load && (status == STORAGE_OK)) { 146 147 status = storage_load(irc, password); 147 } else {148 status = storage_check_pass(irc->user->nick, password);149 148 } 150 149 … … 159 158 irc_rootmsg(irc, "Password accepted%s", 160 159 load ? ", settings and accounts loaded" : ""); 161 irc_setpass(irc, password);162 160 irc->status |= USTATUS_IDENTIFIED; 163 161 irc_umode_set(irc, "+R", 1); … … 268 266 storage_status_t status; 269 267 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 271 273 switch (status) { 272 274 case STORAGE_NO_SUCH_USER: … … 340 342 int st; 341 343 344 if (s && s->flags & SET_LOCKED) { 345 irc_rootmsg(irc, "This setting can not be changed"); 346 return 0; 347 } 342 348 if (s && checkflags && checkflags(irc, s) == 0) { 343 349 return 0; … … 388 394 irc_rootmsg(irc, "This setting can only be changed when the account is %s-line", "on"); 389 395 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; 390 399 } 391 400 … … 409 418 410 419 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 } 411 425 412 426 if (cmd[4] == NULL) { … … 547 561 548 562 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) { 550 567 irc_rootmsg(irc, "Account is still logged in, can't delete"); 551 568 } else { -
set.h
r166a571 r991c75f 49 49 SET_PASSWORD = 0x0400, /* Value shows up in settings list as "********". */ 50 50 SET_HIDDEN_DEFAULT = 0x0800, /* Hide unless changed from default. */ 51 SET_LOCKED = 0x1000 /* Setting is locked, don't allow changing it */ 51 52 } set_flags_t; 52 53 -
storage.c
r166a571 r991c75f 87 87 } 88 88 89 storage_status_t storage_check_pass( const char *nick, const char *password)89 storage_status_t storage_check_pass(irc_t *irc, const char *nick, const char *password) 90 90 { 91 91 GList *gl; … … 97 97 storage_status_t status; 98 98 99 status = st->check_pass( nick, password);99 status = st->check_pass(irc, nick, password); 100 100 if (status != STORAGE_NO_SUCH_USER) { 101 101 return status; … … 171 171 } 172 172 173 storage_status_t storage_remove(const char *nick , const char *password)173 storage_status_t storage_remove(const char *nick) 174 174 { 175 175 GList *gl; … … 185 185 storage_status_t status; 186 186 187 status = st->remove(nick , password);187 status = st->remove(nick); 188 188 ok |= status == STORAGE_OK; 189 189 if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK) { -
storage.h
r166a571 r991c75f 31 31 STORAGE_NO_SUCH_USER, 32 32 STORAGE_INVALID_PASSWORD, 33 STORAGE_CHECK_BACKEND, 33 34 STORAGE_ALREADY_EXISTS, 34 35 STORAGE_OTHER_ERROR /* Error that isn't caused by user input, such as … … 43 44 void (*init)(void); 44 45 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); 46 47 47 48 storage_status_t (*load)(irc_t *irc, const char *password); 48 49 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); 50 51 51 52 /* May be NULL if not supported by backend */ … … 53 54 } storage_t; 54 55 55 storage_status_t storage_check_pass( const char *nick, const char *password);56 storage_status_t storage_check_pass(irc_t *irc, const char *nick, const char *password); 56 57 57 58 storage_status_t storage_load(irc_t * irc, const char *password); 58 59 storage_status_t storage_save(irc_t *irc, char *password, int overwrite); 59 storage_status_t storage_remove(const char *nick , const char *password);60 storage_status_t storage_remove(const char *nick); 60 61 61 62 void register_storage_backend(storage_t *); -
storage_xml.c
r166a571 r991c75f 34 34 35 35 typedef 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; 41 39 42 40 /* To make it easier later when extending the format: */ … … 65 63 { 66 64 struct xt_node *c; 65 struct set *s; 67 66 68 67 for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) { 69 68 char *name = xt_find_attr(c, "name"); 69 char *locked = xt_find_attr(c, "locked"); 70 70 71 71 if (!name) { … … 80 80 } 81 81 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 } 82 88 } 83 89 } … … 86 92 { 87 93 struct xml_parsedata *xd = data; 88 char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag ;94 char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag, *locked; 89 95 char *pass_b64 = NULL; 90 96 unsigned char *pass_cr = NULL; … … 99 105 autoconnect = xt_find_attr(node, "autoconnect"); 100 106 tag = xt_find_attr(node, "tag"); 107 locked = xt_find_attr(node, "locked"); 101 108 102 109 protocol = xt_find_attr(node, "protocol"); … … 112 119 if (!handle || !pass_b64 || !protocol || !prpl) { 113 120 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); 129 126 } 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; 133 150 } 134 151 … … 186 203 }; 187 204 188 static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_ pass_staction)205 static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_action action) 189 206 { 190 207 struct xml_parsedata xd[1]; … … 228 245 } 229 246 230 {247 if (action == XML_PASS_CHECK) { 231 248 char *nick = xt_find_attr(node, "nick"); 232 249 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)) { 235 253 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; 236 260 } else if ((st = md5_verify_password(xd->given_pass, pass)) != 0) { 237 261 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 248 268 if (xt_handle(xp, NULL, 1) == XT_HANDLED) { 249 269 ret = STORAGE_OK; … … 260 280 static storage_status_t xml_load(irc_t *irc, const char *password) 261 281 { 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 285 static 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); 268 288 } 269 289 … … 280 300 struct xt_node *root, *cur; 281 301 282 /* Generate a salted md5sum of the password. Use 5 bytes for the salt283 (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 293 302 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 294 320 xt_add_attr(cur, "nick", irc->user->nick); 295 xt_add_attr(cur, "password", pass_buf);296 321 xt_add_attr(cur, "version", XML_FORMAT_VERSION); 297 298 g_free(pass_buf);299 322 300 323 xml_generate_settings(cur, &irc->b->set); … … 307 330 int pass_len; 308 331 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 } 312 342 313 343 cur = xt_new_node("account", NULL, NULL); … … 320 350 xt_add_attr(cur, "server", acc->server); 321 351 } 352 if (acc->flags & ACC_FLAG_LOCKED) { 353 xt_add_attr(cur, "locked", "true"); 354 } 322 355 323 356 g_free(pass_b64); … … 364 397 xt_add_child(cur, xset = xt_new_node("setting", set->value, NULL)); 365 398 xt_add_attr(xset, "name", set->key); 399 if (set->flags & SET_LOCKED) { 400 xt_add_attr(xset, "locked", "true"); 401 } 366 402 } 367 403 } … … 422 458 423 459 424 static storage_status_t xml_remove(const char *nick , const char *password)460 static storage_status_t xml_remove(const char *nick) 425 461 { 426 462 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 }433 463 434 464 lc = g_strdup(nick); -
tests/Makefile
r166a571 r991c75f 15 15 distclean: clean 16 16 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 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 auth.o auth_pam.o auth_ldap.o 18 18 19 19 test_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 104 104 } 105 105 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 106 112 if (global.conf->runmode == RUNMODE_INETD) { 107 113 log_link(LOGLVL_ERROR, LOGOUTPUT_IRC);
Note: See TracChangeset
for help on using the changeset viewer.