+
+int auth_sasl_ex(const char *method,
+ const char *initresponse,
+ const char *externalauth,
+ char *(*callback_func)(const char *, void *),
+ void *callback_arg,
+ char **authtype_ptr, /* Returned - AUTHTYPE */
+ char **authdata_ptr)
+{
+ char *uid;
+ int n;
+
+ if (strcmp(method, "EXTERNAL"))
+ return auth_sasl(method, initresponse, callback_func,
+ callback_arg,
+ authtype_ptr,
+ authdata_ptr);
+
+ if (initresponse && *initresponse)
+ return AUTHSASL_ERROR;
+
+ if (!externalauth || !*externalauth)
+ return AUTHSASL_ERROR;
+
+ if (!initresponse)
+ {
+ uid=callback_func("", callback_arg);
+
+ if (*uid == '*')
+ {
+ free(uid);
+ return (AUTHSASL_ABORTED);
+ }
+
+ n=authsasl_frombase64(uid);
+
+ if (n < 0)
+ {
+ free(uid);
+ return AUTHSASL_ABORTED;
+ }
+ uid[n]=0;
+
+ if (uid[0])
+ {
+ free(uid);
+ return AUTHSASL_ABORTED;
+ }
+ free(uid);
+ }
+
+ if ((*authtype_ptr=strdup("EXTERNAL")) == NULL)
+ return AUTHSASL_ABORTED;
+
+ if ((*authdata_ptr=strdup(externalauth)) == NULL)
+ {
+ free(authtype_ptr);
+ return AUTHSASL_ABORTED;
+ }
+
+ return 0;
+}