{
        int rc;
 
+       /* map SASL errors to LDAP API errors returned by:
+        *      sasl_client_new()
+        *              SASL_OK, SASL_NOMECH, SASL_NOMEM
+        *      sasl_client_start()
+        *              SASL_OK, SASL_NOMECH, SASL_NOMEM, SASL_INTERACT
+        *      sasl_client_step()
+        *              SASL_OK, SASL_INTERACT, SASL_BADPROT, SASL_BADSERV
+        */
+
        switch (saslerr) {
                case SASL_CONTINUE:
                        rc = LDAP_MORE_RESULTS_TO_RETURN;
                case SASL_OK:
                        rc = LDAP_SUCCESS;
                        break;
-               case SASL_FAIL:
-                       rc = LDAP_LOCAL_ERROR;
-                       break;
                case SASL_NOMEM:
                        rc = LDAP_NO_MEMORY;
                        break;
                case SASL_NOMECH:
                        rc = LDAP_AUTH_UNKNOWN;
                        break;
+               case SASL_BADPROT:
+                       rc = LDAP_DECODING_ERROR;
+                       break;
+               case SASL_BADSERV:
+                       rc = LDAP_AUTH_UNKNOWN;
+                       break;
+
+               /* other codes */
                case SASL_BADAUTH:
                        rc = LDAP_AUTH_UNKNOWN;
                        break;
                case SASL_NOAUTHZ:
                        rc = LDAP_PARAM_ERROR;
                        break;
+               case SASL_FAIL:
+                       rc = LDAP_LOCAL_ERROR;
+                       break;
                case SASL_TOOWEAK:
                case SASL_ENCRYPT:
                        rc = LDAP_AUTH_UNKNOWN;
 
 
        {LDAP_X_NO_OPERATION,                   N_("No Operation (X)")},
 
+       {LDAP_CUP_RESOURCES_EXHAUSTED,  N_("LCUP Resources Exhausted")},
+       {LDAP_CUP_SECURITY_VIOLATION,   N_("LCUP Security Violation")},
+       {LDAP_CUP_INVALID_DATA,                 N_("LCUP Invalid Data")},
+       {LDAP_CUP_UNSUPPORTED_SCHEME,   N_("LCUP Unsupported Scheme")},
+       {LDAP_CUP_RELOAD_REQUIRED,              N_("LCUP Reload Required")},
+
+
        /* API ResultCodes */
        {LDAP_SERVER_DOWN,                              N_("Can't contact LDAP server")},
        {LDAP_LOCAL_ERROR,                              N_("Local error")},
        {LDAP_CLIENT_LOOP,                              N_("Client Loop")},
        {LDAP_REFERRAL_LIMIT_EXCEEDED,  N_("Referral Limit Exceeded")},
 
-       {LDAP_CUP_RESOURCES_EXHAUSTED,  N_("LCUP Resources Exhausted")},
-       {LDAP_CUP_SECURITY_VIOLATION,   N_("LCUP Security Violation")},
-       {LDAP_CUP_INVALID_DATA,                 N_("LCUP Invalid Data")},
-       {LDAP_CUP_UNSUPPORTED_SCHEME,   N_("LCUP Unsupported Scheme")},
-       {LDAP_CUP_RELOAD_REQUIRED,              N_("LCUP Reload Required")},
-
        {0, NULL}
 };
 
 
 {
        int rc;
 
+       /* map SASL errors to LDAP resultCode returned by:
+        *      sasl_server_new()
+        *              SASL_OK, SASL_NOMEM
+        *      sasl_server_step()
+        *              SASL_OK, SASL_CONTINUE, SASL_TRANS, SASL_BADPARAM, SASL_BADPROT,
+        *      ...
+        *      sasl_server_start()
+        *      + SASL_NOMECH
+        *      sasl_setprop()
+        *              SASL_OK, SASL_BADPARAM
+        */
+
        switch (saslerr) {
                case SASL_OK:
                        rc = LDAP_SUCCESS;
                        rc = LDAP_SASL_BIND_IN_PROGRESS;
                        break;
                case SASL_FAIL:
-                       rc = LDAP_OTHER;
-                       break;
                case SASL_NOMEM:
                        rc = LDAP_OTHER;
                        break;
                        rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
                        break;
                case SASL_BADAUTH:
+               case SASL_NOUSER:
+               case SASL_TRANS:
+               case SASL_EXPIRED:
                        rc = LDAP_INVALID_CREDENTIALS;
                        break;
                case SASL_NOAUTHZ:
                case SASL_ENCRYPT:
                        rc = LDAP_INAPPROPRIATE_AUTH;
                        break;
+               case SASL_UNAVAIL:
+               case SASL_TRYAGAIN:
+                       rc = LDAP_UNAVAILABLE;
+                       break;
+               case SASL_DISABLED:
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+                       break;
                default:
                        rc = LDAP_OTHER;
                        break;