Patch: back-passwd needs pwent mutex (ITS#1794)

================
Written by Hallvard B. Furuseth and placed into the public domain.
This software is not subject to any license of the University of Oslo.
			================

back-passwd uses getpwent() and setpwfile(), which use static data.
It needs a mutex to make sure these operations can complete without
interference from another back-passwd call.  Here is a patch.

Hallvard B. Furuseth <h.b.furuseth@usit.uio.no>, May 2002.
This commit is contained in:
Kurt Zeilenga 2002-05-09 02:26:05 +00:00
parent 15e6a98bba
commit 445b7982d7
3 changed files with 46 additions and 12 deletions

View File

@ -5,6 +5,7 @@
LDAP_BEGIN_DECL LDAP_BEGIN_DECL
extern BI_init passwd_back_initialize; extern BI_init passwd_back_initialize;
extern BI_destroy passwd_back_destroy;
extern BI_op_search passwd_back_search; extern BI_op_search passwd_back_search;

View File

@ -8,7 +8,9 @@
#include <ac/socket.h> #include <ac/socket.h>
#include "slap.h" #include "slap.h"
#include "external.h" #include "back-passwd.h"
ldap_pvt_thread_mutex_t passwd_mutex;
#ifdef SLAPD_PASSWD_DYNAMIC #ifdef SLAPD_PASSWD_DYNAMIC
@ -30,10 +32,12 @@ passwd_back_initialize(
BackendInfo *bi BackendInfo *bi
) )
{ {
ldap_pvt_thread_mutex_init( &passwd_mutex );
bi->bi_open = 0; bi->bi_open = 0;
bi->bi_config = 0; bi->bi_config = 0;
bi->bi_close = 0; bi->bi_close = 0;
bi->bi_destroy = 0; bi->bi_destroy = passwd_back_destroy;
bi->bi_db_init = 0; bi->bi_db_init = 0;
bi->bi_db_config = passwd_back_db_config; bi->bi_db_config = passwd_back_db_config;
@ -62,3 +66,12 @@ passwd_back_initialize(
return 0; return 0;
} }
int
passwd_back_destroy(
BackendInfo *bi
)
{
ldap_pvt_thread_mutex_destroy( &passwd_mutex );
return 0;
}

View File

@ -13,9 +13,11 @@
#include <pwd.h> #include <pwd.h>
#include "slap.h" #include "slap.h"
#include "external.h" #include "back-passwd.h"
#include <ldap_pvt.h> #include <ldap_pvt.h>
stativ void pw_start( Backend *be );
static Entry *pw2entry( static Entry *pw2entry(
Backend *be, Backend *be,
struct passwd *pw, struct passwd *pw,
@ -59,14 +61,6 @@ passwd_back_search(
slimit = (slimit > be->be_sizelimit || slimit < 1) ? be->be_sizelimit slimit = (slimit > be->be_sizelimit || slimit < 1) ? be->be_sizelimit
: slimit; : slimit;
endpwent();
#ifdef HAVE_SETPWFILE
if ( be->be_private != NULL ) {
(void) setpwfile( (char *) be->be_private );
}
#endif /* HAVE_SETPWFILE */
/* Handle a query for the base of this backend */ /* Handle a query for the base of this backend */
if ( be_issuffix( be, nbase ) ) { if ( be_issuffix( be, nbase ) ) {
struct berval vals[2]; struct berval vals[2];
@ -130,10 +124,13 @@ passwd_back_search(
if ( scope != LDAP_SCOPE_BASE ) { if ( scope != LDAP_SCOPE_BASE ) {
/* check all our "children" */ /* check all our "children" */
ldap_pvt_thread_mutex_lock( &passwd_mutex );
pw_start( be );
for ( pw = getpwent(); pw != NULL; pw = getpwent() ) { for ( pw = getpwent(); pw != NULL; pw = getpwent() ) {
/* check for abandon */ /* check for abandon */
if ( op->o_abandon ) { if ( op->o_abandon ) {
endpwent(); endpwent();
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
return( -1 ); return( -1 );
} }
@ -142,12 +139,14 @@ passwd_back_search(
send_ldap_result( conn, op, LDAP_TIMELIMIT_EXCEEDED, send_ldap_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
NULL, NULL, NULL, NULL ); NULL, NULL, NULL, NULL );
endpwent(); endpwent();
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
return( 0 ); return( 0 );
} }
if ( !(e = pw2entry( be, pw, &text )) ) { if ( !(e = pw2entry( be, pw, &text )) ) {
err = LDAP_OPERATIONS_ERROR; err = LDAP_OPERATIONS_ERROR;
endpwent(); endpwent();
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
goto done; goto done;
} }
@ -157,6 +156,7 @@ passwd_back_search(
send_ldap_result( conn, op, LDAP_SIZELIMIT_EXCEEDED, send_ldap_result( conn, op, LDAP_SIZELIMIT_EXCEEDED,
NULL, NULL, NULL, NULL ); NULL, NULL, NULL, NULL );
endpwent(); endpwent();
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
return( 0 ); return( 0 );
} }
@ -168,6 +168,7 @@ passwd_back_search(
entry_free( e ); entry_free( e );
} }
endpwent(); endpwent();
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
} }
} else { } else {
@ -201,13 +202,18 @@ passwd_back_search(
goto done; goto done;
} }
ldap_pvt_thread_mutex_lock( &passwd_mutex );
pw_start( be );
if ( (pw = getpwnam( rdn[0][0]->la_value.bv_val )) == NULL ) { if ( (pw = getpwnam( rdn[0][0]->la_value.bv_val )) == NULL ) {
matched = parent.bv_val; matched = parent.bv_val;
err = LDAP_NO_SUCH_OBJECT; err = LDAP_NO_SUCH_OBJECT;
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
goto done; goto done;
} }
if ( !(e = pw2entry( be, pw, &text )) ) { e = pw2entry( be, pw, &text );
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
if ( !e ) {
err = LDAP_OPERATIONS_ERROR; err = LDAP_OPERATIONS_ERROR;
goto done; goto done;
} }
@ -231,6 +237,20 @@ done:
return( 0 ); return( 0 );
} }
static void
pw_start(
Backend *be
)
{
endpwent();
#ifdef HAVE_SETPWFILE
if ( be->be_private != NULL ) {
(void) setpwfile( (char *) be->be_private );
}
#endif /* HAVE_SETPWFILE */
}
static Entry * static Entry *
pw2entry( Backend *be, struct passwd *pw, const char **text ) pw2entry( Backend *be, struct passwd *pw, const char **text )
{ {