Skip to content

CUSTOM_EMAIL_QUERY_FUNCTION return value required since 1.4.8 — breaks custom auth plugins #430

@cnbhl

Description

@cnbhl

Summary

Since piler 1.4.8, checkLoginAgainstIMAP() in auth.php uses the return value of CUSTOM_EMAIL_QUERY_FUNCTION as the email array. Previously (≤ 1.4.4), the return value was ignored and the function was expected to modify the session directly.

This is a breaking change that causes a fatal error for any custom auth plugin that doesn't return an array — including the widely used mailpiler-mailcow-integration by @patschi.

This is very likely the same root cause as #330 (LDAP users seeing no mails after upgrade to 1.4.8).

The change in auth.php

In model/user/auth.php, checkLoginAgainstIMAP():

// Line 388: initial email array
$emails = array($username);

// Line 408-410: CUSTOM_EMAIL_QUERY_FUNCTION now OVERWRITES $emails
if(CUSTOM_EMAIL_QUERY_FUNCTION && function_exists(CUSTOM_EMAIL_QUERY_FUNCTION)) {
    $emails = call_user_func(CUSTOM_EMAIL_QUERY_FUNCTION, $username);
}

// Line 412-415: $emails is used directly — crashes if null
$extra_emails = $this->model_user_user->get_email_addresses_from_groups($emails);
$emails = array_merge($emails, $extra_emails);
$data = $this->fix_user_data($username, $emails[0], $emails, 0);

In older versions (≤ 1.4.4), the return value of call_user_func() was not assigned to $emails, so custom functions only needed to modify the session.

Error

When the custom function returns void (null), PHP 8.x throws a fatal error:

count(): Argument #1 ($value) must be of type Countable|array, null given
in /var/piler/www/system/misc.php on line 624

Result: After IMAP login, the user sees a blank page (HTTP 500). Admin and auditor accounts (which don't use IMAP auth) continue to work normally.

Affected plugins

Workaround

Custom auth functions must now return the email array (including the username as first element):

// Add at the end of your custom email query function:
return array_merge([$username], $emails);

Suggested fix

A defensive check in auth.php would prevent breakage for existing plugins:

if(CUSTOM_EMAIL_QUERY_FUNCTION && function_exists(CUSTOM_EMAIL_QUERY_FUNCTION)) {
    $result = call_user_func(CUSTOM_EMAIL_QUERY_FUNCTION, $username);
    if(is_array($result) && count($result) > 0) {
        $emails = $result;
    }
}

This way, if the custom function returns null/void (old-style plugins that only modify the session), $emails keeps its original value array($username) and login still works.

Environment

  • Piler: 1.4.8 (Docker image simatec/piler:1.4.8)
  • PHP: 8.3
  • OS: Debian 12

Additional note

The auth-mailcow.php from patschi/mailpiler-mailcow-integration also has a second minor bug: in mailcow_get_mailbox_realname(), the empty-check condition is inverted ($mailbox !== '' instead of $mailbox === ''), causing the function to always return null. This is a separate issue in that project, but it surfaced during the same debugging session.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions