On Wed, Feb 06, 2008 at 04:36:36PM -0500, Need Coffee wrote:
> Sorry -- I realized this after posting.  I am using authdaemond for pop/imap,
> and also for Postfix SMTP-AUTH via Cyrus SASL.  The above was in the Postfix
> log.

So Cyrus SASL can talk to authdaemond - interesting, that's new to me.

Hmm, a quick look at cyrus-sasl-2.1.22 source code shows that it's broken.

Here's the bit of borked code in lib/checkpw.c:

    s = socket(AF_UNIX, SOCK_STREAM, 0);
...
    /* Use nonblocking unix socket connect(2). */
    if (authdaemon_blocking(s, 0)) {
        sasl_seterror(conn, 0, "cannot set nonblocking bit: %m", errno);
        goto fail;
    }

    r = connect(s, (struct sockaddr *) &srvaddr, sizeof(srvaddr));
    if (r == -1) {
        sasl_seterror(conn, 0, "cannot connect to Courier authdaemond: %m", 
errno);
        goto fail;
    }

    if (authdaemon_blocking(s, 1)) {
        sasl_seterror(conn, 0, "cannot clear nonblocking bit: %m", errno);
        goto fail;
    }

The correct way to do handle non-blocking connect is shown in MrSam's code
at courier-authlib/authdaemonlib.c. If you want the full details, buy a copy
of "Unix Network Programming" by the late Richard Stevens (pub. Addison
Wesley).

But in summary: if you set non-blocking mode on a socket and then call
connect(), it *may* return with success immediately, or it *may* return -1
with errno set to EINPROGRESS. Both are normal and expected behaviour. In
the latter case you have to wait for the connection to complete by calling
select() and then a getsockopt() call to find the connection result.

So what's happening is, when your system is very lightly loaded, since you
are connecting to a local socket, often it completes immediately. When it
gets busier, it doesn't complete immediately but it would complete a few
milliseconds later. However the above code doesn't accommodate this, and
instead treats EINPROGRESS as meaning the connection failed (which it most
likely didn't). Increasing the number of authdaemond processes won't make
the slightest bit of difference, because they have not even received the
incoming connection by the time courier-sasl has decided to abort.

However in the above code I don't know why they're bothering to set
non-blocking mode before the connect, and clear it after the connect. They
don't do this in pwcheck_verify_password(), nor in
saslauthd_verify_password()

You may be able to fix the problem simply by removing those two
if (authdaemon(blocking(s, x)) { ... } blocks.

Anyway, I suggest you take this problem up on a cyrus-sasl mailing list.
http://asg.web.cmu.edu/sasl/#mailinglists

HTH,

Brian.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Courier-imap mailing list
Courier-imap@lists.sourceforge.net
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-imap

Reply via email to