AUTH_SASL(3)
π AUTH_SASL(3) β SASL implementation π
okay bestie, gather round, because this is the AUTH_SASL(3) page and it's literally the moment where your app learns how to do SASL. no cap. this whole thing was written by S. Varshavchik, an absolute legend, and we're about to go through it together, top to bottom, every last flag and return code, because β¨ details β¨ are the whole vibe.
πΈ NAME πΈ
auth_sasl, auth_sasl_ex β SASL implementation
so yeah, you've got two functions here, not one. one of them is the main character, and the other one is the main character's slightly more sophisticated sibling who went to the EXTERNAL of it all. iykyk.
π SYNOPSIS π
#include <courierauthsasl.h>
int rc=auth_sasl(const char *method, const char *initialresponse,
char *(*conversation_func)(const char *, void *)),
void *callback_arg, char **authtype_ret,
char **authdata_ret);
int rc=auth_sasl_ex(const char *method, const char *initialresponse,
const char *externalauth,
char *(*conversation_func)(const char *, void *)),
void *callback_arg, char **authtype_ret,
char **authdata_ret);
okay so first things first, you gotta #include <courierauthsasl.h>. that's the vibe check you have to pass before anything else works. π
then you pick your function, and honestly? auth_sasl_ex is just auth_sasl with one extra argument in the middle, so don't let it intimidate you. look at those signatures, babes, they're literally the same shape otherwise. π¦
β¨ DESCRIPTION β¨
auth_sasl is a generic SASL server implementation. that's the headline. remember it, because it's doing a LOT of heavy lifting for you behind the scenes. π«Ά
method is the requested SASL method β aka, the client walks up and says "hey, i'd like to authenticate using this" and you hand that request straight to method. at this time, auth_sasl knows how to handle the following SASL methods:
LOGINPLAINCRAM-MD5CRAM-SHA1
that's the roster. those are the four icons it currently serves. no more, no less, periodt. π
initialresponse is a base64-encoded initial response provided in the client's SASL request. and listen, this is important: initialresponse must be NULL if an initial response was not included in the client's SASL request. don't be out here passing garbage when the client gave you nothing. NULL it is. π
conversation_func is the application-implemented SASL conversation callback function β yes, you write this one, bestie, it's your homework. here's how the whole back-and-forth goes:
conversation_funcreceives a base64-encoded SASL prompt, plus thecallback_argargument that you passed toauth_sasl.conversation_funcmust return a buffer containing the base64-encoded reply from the client.auth_saslwillfree(3)this buffer when it's done with it. so do not free it yourself, okay? let the function handle its own business. πconversation_funcshould returnNULLto abort the SASL conversation. that's your escape hatch, the "nope, we're done here" button.
auth_sasl_ex is a version of auth_sasl that recognizes the EXTERNAL SASL method. so it's the glow-up edition. π it takes an extra parameter, externalauth, and this one should be set to indicate a login that was authenticated via some other means β such as, perhaps, an SSL certificate β or NULL if no externally-authenticated identity was established.
now for the plot twist, and this is the part where auth_sasl_ex behaves exactly like its sibling:
- If
methodis notEXTERNAL,auth_sasl_exis identical toauth_sasl, andexternalauthis ignored. like, literally just vibing in the corner, doing nothing. - Otherwise, if
methodisEXTERNALandexternalauthis notNULL,auth_sasl_exreturnsAUTHSASL_OK, and sets*authtype_retand*authdata_retaccordingly.
and why do we care about those two? because of this: the subsequent invocation of auth_generic() returns authentication information for the login ID specified by externalauth. so it all chains together, a whole relay race of auth. πββοΈπ¨
π₯ RETURNS π₯
If the SASL conversation successfully completes, auth_sasl or auth_sasl_ex initializes *authtype_ret and *authdata_ret. they'll be set to malloc(3)-ed buffers that can be directly passed as arguments to auth_generic_meta(3)[1].
and girly, listen to me: it is the application's responsibility to free(3) these buffers when it's done with them. the library is NOT going to clean up after you. that's your mess, you own it. π§Ήβ¨
auth_sasl or auth_sasl_ex returns AUTHSASL_OK when the SASL conversation successfully completes, and *authtype_ret and *authdata_ret are successfully assembled. any other return indicates an error condition. and right now, two error conditions are defined:
AUTHSASL_ABORTEDβ the SASL conversation was aborted by the client. they hung up on you mid-conversation, iconic of them, but also rude. πAUTHSASL_ERRORβ general error (insufficient memory, or some other reason). checkerrnofor any clues. yeah, that's the "idk what happened bestie, go readerrno" error. π΅οΈββοΈ
β οΈ real talk: anything that isn't AUTHSASL_OK means something went wrong. don't be out here treating random return values as success. that's not the move.
π SEE ALSO π
authlib(3)[2], auth_generic_meta(3)[1].
go read these next, they're the supporting cast and they absolutely understood the assignment.
π NOTES π
auth_generic_meta(3)https://www.courier-mta.org/authlib/auth_generic.htmlauthlib(3)https://www.courier-mta.org/authlib/authlib.html
and that's the whole page, bestie!! you made it to the end, which is honestly main character energy. π
this was brought to you by S. Varshavchik, dated 06/18/2026 β so go forth, implement your conversation_func, free your buffers, and slay those SASL conversations. AUTHSASL_OK or it didn't happen. π
β¨ bye!!
π¦ where this page comes from
- ubuntu stonking: courier-authlib-dev 0.73.1-2ubuntu1 Β· GPL-3+~with-OpenSSL-exception
- Copyright 2004-2008 S. Varshavchik. See COPYING for -->
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms