diff -dNru cyrus-sasl-2.1.22/saslauthd/Makefile.in cyrus-sasl-2.1.22.fjo/saslauthd/Makefile.in --- cyrus-sasl-2.1.22/saslauthd/Makefile.in Thu May 18 21:30:21 2006 +++ cyrus-sasl-2.1.22.fjo/saslauthd/Makefile.in Tue Feb 13 13:41:22 2007 @@ -139,6 +139,7 @@ mechanisms.h auth_dce.c auth_dce.h auth_getpwent.c \ auth_getpwent.h auth_krb5.c auth_krb5.h auth_krb4.c \ auth_krb4.h auth_pam.c auth_pam.h auth_rimap.c auth_httpform.c \ + auth_pgsql.c \ auth_rimap.h auth_shadow.c auth_shadow.h auth_sia.c auth_httpform.h \ auth_sia.h auth_sasldb.c auth_sasldb.h lak.c lak.h \ auth_ldap.c auth_ldap.h cache.c cache.h cfile.c cfile.h \ @@ -173,6 +174,7 @@ am_saslauthd_OBJECTS = mechanisms.$(OBJEXT) auth_dce.$(OBJEXT) \ auth_getpwent.$(OBJEXT) auth_krb5.$(OBJEXT) auth_krb4.$(OBJEXT) \ + auth_pgsql.$(OBJEXT) \ auth_pam.$(OBJEXT) auth_rimap.$(OBJEXT) auth_httpform.$(OBJEXT) \ auth_shadow.$(OBJEXT) auth_sia.$(OBJEXT) auth_sasldb.$(OBJEXT) \ lak.$(OBJEXT) auth_ldap.$(OBJEXT) cache.$(OBJEXT) \ diff -dNru cyrus-sasl-2.1.22/saslauthd/auth_pgsql.c cyrus-sasl-2.1.22.fjo/saslauthd/auth_pgsql.c --- cyrus-sasl-2.1.22/saslauthd/auth_pgsql.c Thu Jan 1 01:00:00 1970 +++ cyrus-sasl-2.1.22.fjo/saslauthd/auth_pgsql.c Tue Feb 13 13:42:55 2007 @@ -0,0 +1,111 @@ +#include +#include +#include +#include "cfile.h" +#include "auth_pgsql.h" + +#define MAX_RETRIES 1 +#define RETURN_OK return strdup("OK") +#define RETURN_NO return strdup("NO") +#define VALID(x) if (!x) { syslog(LOG_WARNING, "%s is NULL", #x); RETURN_NO; } + +static PGconn *pgconn; + +int auth_pgsql_init () { + static cfile config; + static char complaint[1024]; + char *connstring = ""; + + if (access(SASLAUTHD_CONF_FILE_DEFAULT, F_OK) == 0) { + config = cfile_read(SASLAUTHD_CONF_FILE_DEFAULT, complaint, + sizeof(complaint)); + if (!config) { + syslog(LOG_ERR, "%s: %s", SASLAUTHD_CONF_FILE_DEFAULT, complaint); + return -1; + } + + connstring = cfile_getstring(config, "pgconn_opts", connstring); + } + + pgconn = PQconnectdb(connstring); + if (PQstatus(pgconn) == CONNECTION_OK) return 0; + + syslog(LOG_WARNING, "PQconnectdb(): %s", PQerrorMessage(pgconn)); + return 1; +} + +static int my_reconnect () { + PQreset(pgconn); + if (PQstatus(pgconn) == CONNECTION_OK) return 0; + syslog(LOG_WARNING, "PQreset(): %s", PQerrorMessage(pgconn)); + return -1; +} + +char *auth_pgsql (const char *login, const char *password, + const char *service, const char *realm) { + PGresult *pgresult; + int l1, l2, l3, l4, i; + char *query, *c; + + VALID(login) + VALID(password) + VALID(service) + VALID(realm) + + if (PQstatus(pgconn) != CONNECTION_OK) if (my_reconnect()) RETURN_NO; + + l1 = strlen(login); + l2 = strlen(password); + l3 = strlen(service); + l4 = strlen(realm); + + query = malloc(2 * (l1 + l2 + l3 + l4) + 32); + if (!query) { + syslog(LOG_WARNING, "no memory!"); + RETURN_NO; + } + + strcpy(query, "SELECT sasl_login('"); + c = query + 19; + c += PQescapeString(c, login, l1) + 3; + strcat(query, "','"); + c += PQescapeString(c, password, l2) + 3; + strcat(query, "','"); + c += PQescapeString(c, service, l3) + 3; + strcat(query, "','"); + PQescapeString(c, realm, l4); + strcat(query, "')"); + + for (i = 0; i <= MAX_RETRIES; ++i) { + pgresult = PQexec(pgconn, query); + if (PQresultStatus(pgresult) == PGRES_TUPLES_OK) break; + if (i < MAX_RETRIES) i = (my_reconnect()) ? (MAX_RETRIES) : (0); + else syslog(LOG_WARNING, "PQexec(): ", PQerrorMessage(pgconn)); + PQclear(pgresult); + } + free(query); + if (i > 1) RETURN_NO; + + i = PQntuples(pgresult); + if (i != 1) { + syslog(LOG_WARNING, "query returns %i rows", i); + PQclear(pgresult); + RETURN_NO; + } + + i = PQnfields(pgresult); + if (i != 1) { + syslog(LOG_WARNING, "query returns %i fields", i); + PQclear(pgresult); + RETURN_NO; + } + + c = PQgetvalue(pgresult, 0, 0); + if (strcmp(c, "OK")) { + PQclear(pgresult); + RETURN_NO; + } + + PQclear(pgresult); + RETURN_OK; +} diff -dNru cyrus-sasl-2.1.22/saslauthd/auth_pgsql.h cyrus-sasl-2.1.22.fjo/saslauthd/auth_pgsql.h --- cyrus-sasl-2.1.22/saslauthd/auth_pgsql.h Thu Jan 1 01:00:00 1970 +++ cyrus-sasl-2.1.22.fjo/saslauthd/auth_pgsql.h Tue Feb 13 13:42:55 2007 @@ -0,0 +1,2 @@ +int auth_pgsql_init (); +char *auth_pgsql (const char *, const char *, const char *, const char *); diff -dNru cyrus-sasl-2.1.22/saslauthd/mechanisms.c cyrus-sasl-2.1.22.fjo/saslauthd/mechanisms.c --- cyrus-sasl-2.1.22/saslauthd/mechanisms.c Mon Mar 13 21:17:09 2006 +++ cyrus-sasl-2.1.22.fjo/saslauthd/mechanisms.c Tue Feb 13 13:42:41 2007 @@ -61,6 +61,7 @@ #include "auth_httpform.h" #endif /* END PUBLIC DEPENDENCIES */ +#include "auth_pgsql.h" authmech_t mechanisms[] = { @@ -93,6 +94,7 @@ #ifdef AUTH_HTTPFORM { "httpform", auth_httpform_init, auth_httpform }, #endif /* AUTH_LDAP */ + { "pgsql", auth_pgsql_init, auth_pgsql }, { 0, 0, 0 } };