diff -uNr cyrus-sasl2.orig/files/patch-lib::checkpw.c-crypt cyrus-sasl2/files/patch-lib::checkpw.c-crypt --- cyrus-sasl2.orig/files/patch-lib::checkpw.c-crypt Thu Jan 1 01:00:00 1970 +++ cyrus-sasl2/files/patch-lib::checkpw.c-crypt Fri Sep 12 04:14:29 2003 @@ -0,0 +1,189 @@ +--- ./lib/checkpw.c.orig Wed Mar 19 18:25:27 2003 ++++ ./lib/checkpw.c Fri Sep 12 04:04:05 2003 +@@ -93,6 +93,11 @@ + # include + # endif + ++/* cleartext password formats */ ++#define PASSWORD_FORMAT_CLEARTEXT 1 ++#define PASSWORD_FORMAT_CRYPT 2 ++#define PASSWORD_FORMAT_CRYPTTRAD 3 ++ + extern int errno; + #endif + +@@ -128,6 +133,32 @@ + return SASL_OK; + } + ++/* weeds out crypt(3) password's salt */ ++int get_salt (char *dest, char *src, int format) { ++ /* how many characters is salt long? */ ++ int num; ++ ++ if (format == PASSWORD_FORMAT_CRYPT) { ++ if (src[1] == '1') ++ num = 12; // md5 crypt ++ else if (src[1] == '2') ++ num = 16; // blowfish crypt ++ else ++ num = 2; // traditional crypt ++ } ++ else if (format == PASSWORD_FORMAT_CRYPTTRAD) { ++ num = 2; ++ } ++ ++ /* weed it out ! */ ++ strncpy(dest, src, num); ++ ++ /* terminate string */ ++ dest[num] = '\0'; ++ ++ return 1; ++} ++ + /* erase & dispose of a sasl_secret_t + */ + static int auxprop_verify_password(sasl_conn_t *conn, +@@ -145,7 +176,39 @@ + "*cmusaslsecretPLAIN", + NULL }; + struct propval auxprop_values[3]; +- ++ ++ /* for password format check */ ++ sasl_getopt_t *getopt; ++ void *context; ++ const char *p = NULL; ++ char pass_format_str[11]; ++ /* ++ * MD5: 12 char salt ++ * BLOWFISH: 16 char salt ++ */ ++ char salt[17]; ++ int password_format; ++ ++ ++ /* check for password format */ ++ if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) { ++ getopt(context, NULL, "password_format", &p, NULL); ++ } ++ if (p) { ++ strncpy(pass_format_str, p, 9); ++ ++ if (strncmp(pass_format_str, "crypt", 11) == 0) ++ password_format = PASSWORD_FORMAT_CRYPT; ++ else if (strncmp(pass_format_str, "crypt_trad", 11) == 0) ++ password_format = PASSWORD_FORMAT_CRYPTTRAD; ++ else ++ password_format = PASSWORD_FORMAT_CLEARTEXT; ++ ++ } else { ++ password_format = PASSWORD_FORMAT_CLEARTEXT; ++ } ++ ++ + if (!conn || !userstr) + return SASL_BADPARAM; + +@@ -184,37 +247,71 @@ + + /* At the point this has been called, the username has been canonified + * and we've done the auxprop lookup. This should be easy. */ +- if(auxprop_values[0].name +- && auxprop_values[0].values +- && auxprop_values[0].values[0] +- && !strcmp(auxprop_values[0].values[0], passwd)) { +- /* We have a plaintext version and it matched! */ +- return SASL_OK; +- } else if(auxprop_values[1].name +- && auxprop_values[1].values +- && auxprop_values[1].values[0]) { +- const char *db_secret = auxprop_values[1].values[0]; +- sasl_secret_t *construct; +- +- ret = _sasl_make_plain_secret(db_secret, passwd, +- strlen(passwd), +- &construct); +- if (ret != SASL_OK) { +- goto done; +- } + +- if (!memcmp(db_secret, construct->data, construct->len)) { +- /* password verified! */ +- ret = SASL_OK; +- } else { +- /* passwords do not match */ +- ret = SASL_BADAUTH; +- } +- +- sasl_FREE(construct); +- } else { ++ /* check password, but with specified password format */ ++ if (password_format == PASSWORD_FORMAT_CRYPT) { ++ get_salt(salt, auxprop_values[0].values[0], PASSWORD_FORMAT_CRYPT); ++ ++ /* compare passwords */ ++ if (auxprop_values[0].name && ++ auxprop_values[0].values && ++ auxprop_values[0].values[0] && ++ strcmp(crypt(passwd, salt), auxprop_values[0].values[0]) == 0 ++ ) { ++ return SASL_OK; ++ } ++ } ++ else if (password_format == PASSWORD_FORMAT_CRYPTTRAD) { ++ get_salt(salt, auxprop_values[0].values[0], PASSWORD_FORMAT_CRYPTTRAD); ++ ++ /* compare passwords */ ++ if (auxprop_values[0].name && ++ auxprop_values[0].values && ++ auxprop_values[0].values[0] && ++ strcmp(crypt(passwd, salt), auxprop_values[0].values[0]) == 0 ++ ) { ++ return SASL_OK; ++ } ++ } ++ else if (password_format == PASSWORD_FORMAT_CLEARTEXT) { ++ ++ /* compare passwords */ ++ if (auxprop_values[0].name && ++ auxprop_values[0].values && ++ auxprop_values[0].values[0] && ++ strcmp(auxprop_values[0].values[0], passwd) == 0 ++ ) { ++ return SASL_OK; ++ } ++ } ++ /* original SASL checks continue here */ ++ else if (auxprop_values[1].name && ++ auxprop_values[1].values && ++ auxprop_values[1].values[0]) { ++ ++ const char *db_secret = auxprop_values[1].values[0]; ++ sasl_secret_t *construct; ++ ++ ret = _sasl_make_plain_secret(db_secret, passwd, ++ strlen(passwd), &construct); ++ ++ if (ret != SASL_OK) { ++ goto done; ++ } ++ ++ if (!memcmp(db_secret, construct->data, construct->len)) { ++ /* password verified! */ ++ ret = SASL_OK; ++ } else { ++ /* passwords do not match */ ++ ret = SASL_BADAUTH; ++ } ++ ++ sasl_FREE(construct); ++ } ++ else { + /* passwords do not match */ +- ret = SASL_BADAUTH; ++ ret = SASL_BADAUTH; + } + + done: diff -uNr cyrus-sasl2.orig/files/patch-plugins::mysql.c-logfailures cyrus-sasl2/files/patch-plugins::mysql.c-logfailures --- cyrus-sasl2.orig/files/patch-plugins::mysql.c-logfailures Thu Jan 1 01:00:00 1970 +++ cyrus-sasl2/files/patch-plugins::mysql.c-logfailures Fri Sep 12 04:14:29 2003 @@ -0,0 +1,14 @@ +--- plugins/mysql.c.orig Tue Jul 1 14:52:12 2003 ++++ plugins/mysql.c Fri Sep 12 03:20:54 2003 +@@ -337,6 +337,11 @@ + settings->mysql_passwd, + NULL, 0, NULL, 0); + if (sock) break; ++ ++ sparams->utils->log(NULL, SASL_LOG_ERR, ++ "mysql plugin couldnt connect to host %s:" ++ "error %d, %s\n", cur_host, mysql_errno(&mysql), ++ mysql_error(&mysql)); + + cur_host = db_host; + } diff -uNr cyrus-sasl2.orig/files/patch-plugins::mysql.c-ssl cyrus-sasl2/files/patch-plugins::mysql.c-ssl --- cyrus-sasl2.orig/files/patch-plugins::mysql.c-ssl Thu Jan 1 01:00:00 1970 +++ cyrus-sasl2/files/patch-plugins::mysql.c-ssl Fri Sep 12 04:14:29 2003 @@ -0,0 +1,64 @@ +--- ./plugins/mysql.c.orig Tue Jul 1 14:52:12 2003 ++++ ./plugins/mysql.c Fri Sep 12 04:10:04 2003 +@@ -16,6 +16,7 @@ + ** mysql_database: + ** mysql_statement: