Hi,

unfortunately, Christian's patch (using PQconnectdb instead of
PQsetdbLogin) does not work / suffice for libpq4.

Without a running nscd, PQconnectdb attempts to setup the SSL
environment and searches for $HOME/.postgresql/server.crt (or similar),
calling getpwuid to retrieve the home-directory. This obviously causes
another entrance into libnss-pgsql which results in a hang while waiting
for the (already owned) lock.

While running nscd, the second nss call (getpwuid) can be resolved via
/etc/passwd (as long as nscd runs as root / a local user) and therefore
avoids the dead-lock.

The attached patch replaces all pthread_mutex_lock() calls with
pthread_mutex_trylock(), aborting any recursive locking attempts with
NSS_STATUS_UNAVAIL. Not very pretty, but appears to work fine. (Might
need more testing though.)

Fabian

ii  libnss-pgsql1       1.3.1
ii  libc6               2.3.6.ds1-10
ii  libpq4              8.1.6-1
diff -urN libnss-pgsql-1.3.1/src/interface.c libnss-pgsql-1.3.1.fixed/src/interface.c
--- libnss-pgsql-1.3.1/src/interface.c	2006-04-16 17:04:46.000000000 +0200
+++ libnss-pgsql-1.3.1.fixed/src/interface.c	2007-01-15 22:29:26.000000000 +0100
@@ -23,7 +23,9 @@
 {
 	 enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
   	 if(!backend_isopen()) {
 		 backend_open();
   	 }
@@ -38,7 +40,9 @@
 enum nss_status
 _nss_pgsql_endpwent(void)
 {
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return NSS_STATUS_UNAVAIL;
+	 }
 	 backend_close();
 	 pthread_mutex_unlock(&lock);
 
@@ -53,7 +57,9 @@
 {
 	 enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
 
 	 // Make sure the database is opened in case no one has called setpwent()
 	 if(!backend_isopen())
@@ -76,7 +82,10 @@
 {
 	 enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
+
 	 if(backend_open()) {
 		 retval = backend_getpwnam(pwnam, result, buffer, buflen, errnop);
 		 backend_close();
@@ -95,7 +104,10 @@
 {
 	enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
+
 	 if(backend_open()) {
 		 retval = backend_getpwuid(uid, result, buffer, buflen, errnop);
 		 backend_close();
@@ -113,7 +125,9 @@
 {
 	enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
   	 if(!backend_isopen()) {
 		 backend_open();
   	 }
@@ -129,7 +143,9 @@
 enum nss_status
 _nss_pgsql_endgrent(void)
 {
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return NSS_STATUS_UNAVAIL;
+	 }
 	 backend_close();
 	 pthread_mutex_unlock(&lock);
 
@@ -144,7 +160,9 @@
 {
 	enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
 
 	 // Make sure the database is opened in case no one has called setpwent()
 	 if(!backend_isopen())
@@ -167,7 +185,9 @@
 {
 	enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
 	 if(backend_open()) {
 		 retval = backend_getgrnam(grnam, result, buffer, buflen, errnop);
 		 backend_close();
@@ -186,7 +206,9 @@
 {
 	enum nss_status retval = NSS_STATUS_UNAVAIL;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
 	if(backend_open()) {
 		retval = backend_getgrgid(gid, result, buffer, buflen, errnop);
 		backend_close();
@@ -208,7 +230,9 @@
 	enum nss_status retval = NSS_STATUS_UNAVAIL;
 	size_t numgroups;
 
-	 pthread_mutex_lock(&lock);
+	 if (pthread_mutex_trylock(&lock) != 0) {
+	 	return retval;
+	 }
 	 if(backend_open()) {
 		 numgroups = backend_initgroups_dyn(user, group, start, size, groupsp,
 														limit, errnop);

Reply via email to