--- cyrus-sasl-2.1.17/saslauthd/auth_pam.c 2003-05-31 19:00:24.000000000 +0200 +++ cyrus-sasl-2.1.17a/saslauthd/auth_pam.c 2004-02-18 06:25:21.000000000 +0100 @@ -178,7 +178,7 @@ auth_pam ( const char *login, /* I: plaintext authenticator */ const char *password, /* I: plaintext password */ const char *service, /* I: service name */ - const char *realm __attribute__((unused)) + const char *realm /* END PARAMETERS */ ) { @@ -187,19 +187,50 @@ auth_pam ( struct pam_conv my_conv; /* pam conversion data */ pam_handle_t *pamh; /* pointer to PAM handle */ int rc; /* return code holder */ + + /* Patched to revert auth pam behavior to 2.1.15, where login + * includes the associated domain. + * There's probably a _reason_ to cut off domains from logins, + * but this PAM module does not seem to use realms at all, and + * is actually breaking lots of virtual mailhosting setups. + * + * Alex Unleashed - + */ + char *new_login; /* new login */ + int must_free = 0; /* free the mallocs! */ /* END VARIABLES */ - my_appdata.login = login; + /* Make sure realm is added to login */ + if (realm && (strchr(login, '@') == NULL)) { + /* allocate space for login plus realm plus '@' plus '\0' */ + new_login = (char *) malloc((strlen(login) + strlen(realm) + 2) * sizeof(char)); + if (new_login == NULL) { + syslog(LOG_DEBUG, "DEBUG: auth_pam: out of memory"); + RETURN("NO PAM not enough memory"); + } + must_free = 1; + strcpy(new_login, login); + strcat(new_login, "@"); + strcat(new_login, realm); + } + else + new_login = login; + + my_appdata.login = new_login; my_appdata.password = password; my_appdata.pamh = NULL; my_conv.conv = saslauthd_pam_conv; my_conv.appdata_ptr = &my_appdata; - rc = pam_start(service, login, &my_conv, &pamh); + rc = pam_start(service, new_login, &my_conv, &pamh); if (rc != PAM_SUCCESS) { syslog(LOG_DEBUG, "DEBUG: auth_pam: pam_start failed: %s", pam_strerror(pamh, rc)); + if (must_free) { + my_appdata.login = login; + free(new_login); + } RETURN("NO PAM start error"); } @@ -210,6 +241,10 @@ auth_pam ( syslog(LOG_DEBUG, "DEBUG: auth_pam: pam_authenticate failed: %s", pam_strerror(pamh, rc)); pam_end(pamh, rc); + if (must_free) { + my_appdata.login = login; + free(new_login); + } RETURN("NO PAM auth error"); } @@ -218,10 +253,18 @@ auth_pam ( syslog(LOG_DEBUG, "DEBUG: auth_pam: pam_acct_mgmt failed: %s", pam_strerror(pamh, rc)); pam_end(pamh, rc); + if (must_free) { + my_appdata.login = login; + free(new_login); + } RETURN("NO PAM acct error"); } pam_end(pamh, PAM_SUCCESS); + if (must_free) { + my_appdata.login = login; + free(new_login); + } RETURN("OK"); }