#include <pwd.h>
#include "slap.h"
-#include "external.h"
+#include "back-passwd.h"
#include <ldap_pvt.h>
+static void pw_start( Backend *be );
+
static Entry *pw2entry(
Backend *be,
struct passwd *pw,
slimit = (slimit > be->be_sizelimit || slimit < 1) ? be->be_sizelimit
: 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 */
if ( be_issuffix( be, nbase ) ) {
struct berval vals[2];
if ( scope != LDAP_SCOPE_BASE ) {
/* check all our "children" */
+ ldap_pvt_thread_mutex_lock( &passwd_mutex );
+ pw_start( be );
for ( pw = getpwent(); pw != NULL; pw = getpwent() ) {
/* check for abandon */
if ( op->o_abandon ) {
endpwent();
+ ldap_pvt_thread_mutex_unlock( &passwd_mutex );
return( -1 );
}
send_ldap_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
NULL, NULL, NULL, NULL );
endpwent();
+ ldap_pvt_thread_mutex_unlock( &passwd_mutex );
return( 0 );
}
if ( !(e = pw2entry( be, pw, &text )) ) {
- err = LDAP_OPERATIONS_ERROR;
+ err = LDAP_OTHER;
endpwent();
+ ldap_pvt_thread_mutex_unlock( &passwd_mutex );
goto done;
}
send_ldap_result( conn, op, LDAP_SIZELIMIT_EXCEEDED,
NULL, NULL, NULL, NULL );
endpwent();
+ ldap_pvt_thread_mutex_unlock( &passwd_mutex );
return( 0 );
}
entry_free( e );
}
endpwent();
+ ldap_pvt_thread_mutex_unlock( &passwd_mutex );
}
} else {
if ( ldap_bv2rdn( base, &rdn, (char **)&text,
LDAP_DN_FORMAT_LDAP ))
{
- err = LDAP_OPERATIONS_ERROR;
+ err = LDAP_OTHER;
goto done;
}
+ ldap_pvt_thread_mutex_lock( &passwd_mutex );
+ pw_start( be );
if ( (pw = getpwnam( rdn[0][0]->la_value.bv_val )) == NULL ) {
matched = parent.bv_val;
err = LDAP_NO_SUCH_OBJECT;
+ ldap_pvt_thread_mutex_unlock( &passwd_mutex );
goto done;
}
- if ( !(e = pw2entry( be, pw, &text )) ) {
- err = LDAP_OPERATIONS_ERROR;
+ e = pw2entry( be, pw, &text );
+ ldap_pvt_thread_mutex_unlock( &passwd_mutex );
+ if ( !e ) {
+ err = LDAP_OTHER;
goto done;
}
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 *
pw2entry( Backend *be, struct passwd *pw, const char **text )
{
s = strchr(vals[0].bv_val, '&');
if (s) {
- char buf[256];
- int i = s - vals[0].bv_val;
- strncpy(buf, vals[0].bv_val, i);
- s = buf+i;
- strcpy(s, pw->pw_name);
- *s = TOUPPER((unsigned char)*s);
- strcat(s, vals[0].bv_val+i+1);
- vals[0].bv_val = buf;
+ char buf[1024];
+
+ if( vals[0].bv_len + pwlen < sizeof(buf) ) {
+ int i = s - vals[0].bv_val;
+ strncpy(buf, vals[0].bv_val, i);
+ s = buf+i;
+ strcpy(s, pw->pw_name);
+ *s = TOUPPER((unsigned char)*s);
+ strcat(s, vals[0].bv_val+i+1);
+ vals[0].bv_val = buf;
+ }
}
vals[0].bv_len = strlen(vals[0].bv_val);
- if ( strcmp( vals[0].bv_val, pw->pw_name ))
+
+ if ( vals[0].bv_len && strcasecmp( vals[0].bv_val, pw->pw_name )) {
attr_merge( e, ad_cn, vals );
+ }
+
if ( (s=strrchr(vals[0].bv_val, ' '))) {
vals[0].bv_val = s + 1;
vals[0].bv_len = strlen(vals[0].bv_val);