Still seems wrong: Caller passes len=500, generic_sb_sasl_write() returns 0 or -1 with LDAP_PVT_SASL_PARTIAL_WRITE, caller collects 300 more bytes and passes len=800, then generic_sb_sasl_write() ignores not 500 but 800 bytes and tells caller that they were all written.
Either make p->flags a ber_slen_t with the number of incoming bytes to ignore, or after p->ops->encode() = success, write() = <partial write or non-fatal error> return len-1 with with LDAP_PVT_SASL_PARTIAL_WRITE.