From 5554601bf5dcf12fa2a7545c41c24fb94ee8cb1d Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sun, 25 Oct 1998 16:53:57 +0000 Subject: [PATCH] Fix Y2K/localtime bug --- servers/slapd/add.c | 31 +++++++++++++++------ servers/slapd/bind.c | 10 +++++-- servers/slapd/daemon.c | 5 ++-- servers/slapd/entry.c | 3 +- servers/slapd/modify.c | 56 ++++++++++++++++++++++--------------- servers/slapd/monitor.c | 50 +++++++++++++++++++++++++++------ servers/slapd/result.c | 57 +++++++++++++++++++++++++++++++------- servers/slapd/str2filter.c | 2 +- 8 files changed, 157 insertions(+), 57 deletions(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 027e40a8e4..e42ccbd32c 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -117,21 +117,25 @@ do_add( conn, op ) */ if ( be->be_add != NULL ) { /* do the update here */ - if ( be->be_updatedn == NULL || strcasecmp( be->be_updatedn, - op->o_dn ) == 0 ) { - if ( (be->be_lastmod == ON || be->be_lastmod == 0 && - global_lastmod == ON) && be->be_updatedn == NULL ) { + if ( be->be_updatedn == NULL || + strcasecmp( be->be_updatedn, op->o_dn ) == 0 ) { + + if ( (be->be_lastmod == ON || (be->be_lastmod == UNDEFINED && + global_lastmod == ON)) && be->be_updatedn == NULL ) { + add_created_attrs( op, e ); } if ( (*be->be_add)( be, conn, op, e ) == 0 ) { replog( be, LDAP_REQ_ADD, e->e_dn, e, 0 ); } + } else { entry_free( e ); send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL, default_referral ); } } else { + Debug( LDAP_DEBUG_ARGS, " do_add: HHH\n", 0, 0, 0 ); entry_free( e ); send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented" ); @@ -141,7 +145,7 @@ do_add( conn, op ) static void add_created_attrs( Operation *op, Entry *e ) { - char buf[20]; + char buf[22]; struct berval bv; struct berval *bvals[2]; Attribute **a, **next; @@ -155,8 +159,10 @@ add_created_attrs( Operation *op, Entry *e ) /* remove any attempts by the user to add these attrs */ for ( a = &e->e_attrs; *a != NULL; a = next ) { - if ( strcasecmp( (*a)->a_type, "createtimestamp" ) == 0 - || strcasecmp( (*a)->a_type, "creatorsname" ) == 0 ) { + if ( strcasecmp( (*a)->a_type, "modifiersname" ) == 0 || + strcasecmp( (*a)->a_type, "modifytimestamp" ) == 0 || + strcasecmp( (*a)->a_type, "creatorsname" ) == 0 || + strcasecmp( (*a)->a_type, "createtimestamp" ) == 0 ) { tmp = *a; *a = (*a)->a_next; attr_free( tmp ); @@ -176,8 +182,15 @@ add_created_attrs( Operation *op, Entry *e ) attr_merge( e, "creatorsname", bvals ); pthread_mutex_lock( ¤ttime_mutex ); - ltm = localtime( ¤ttime ); - strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); + +#ifndef LDAP_LOCALTIME + ltm = gmtime( ¤ttime ); + strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm ); +#else + ltm = localtime( ¤ttime ); + strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); +#endif + pthread_mutex_unlock( ¤ttime_mutex ); bv.bv_val = buf; diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index 562ce5b54a..fbffeebc9f 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -143,10 +143,14 @@ do_bind( free( cred.bv_val ); } if ( cred.bv_len == 0 ) { - send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL ); + send_ldap_result( conn, op, LDAP_SUCCESS, + NULL, NULL ); + } else if ( default_referral && *default_referral ) { + send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, + NULL, default_referral ); } else { - send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL, - default_referral ); + send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS, + NULL, default_referral ); } return; } diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index f8e1816aec..509ed6a275 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -195,6 +195,9 @@ slapd_daemon( FD_ZERO( &readfds ); FD_SET( tcps, &readfds ); + zero.tv_sec = 0; + zero.tv_usec = 0; + pthread_mutex_lock( &active_threads_mutex ); Debug( LDAP_DEBUG_CONNS, "listening for connections on %d, activity on:", @@ -215,8 +218,6 @@ slapd_daemon( Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 ); pthread_mutex_unlock( &new_conn_mutex ); - zero.tv_sec = 0; - zero.tv_usec = 0; Debug( LDAP_DEBUG_CONNS, "before select active_threads %d\n", active_threads, 0, 0 ); #if defined(PTHREAD_PREEMPTIVE) || defined(NO_THREADS) diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index d5ee966b57..f7aae37662 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -43,7 +43,8 @@ str2entry( char *s ) * or newline. */ - Debug( LDAP_DEBUG_TRACE, "=> str2entry\n", s, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "=> str2entry\n", + s ? s : "NULL", 0, 0 ); e = (Entry *) ch_calloc( 1, sizeof(Entry) ); diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 6575fe36ad..2629291563 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -155,14 +155,14 @@ do_modify( */ if ( be->be_modify != NULL ) { /* do the update here */ - if ( be->be_updatedn == NULL || strcasecmp( be->be_updatedn, - op->o_dn ) == 0 ) { - if ( (be->be_lastmod == ON || be->be_lastmod == 0 && - global_lastmod == ON) && be->be_updatedn == NULL ) { + if ( be->be_updatedn == NULL || + strcasecmp( be->be_updatedn, op->o_dn ) == 0 ) { + + if ( (be->be_lastmod == ON || ( be->be_lastmod == UNDEFINED && + global_lastmod == ON ) ) && be->be_updatedn == NULL ) { add_lastmods( op, &mods ); } - if ( (*be->be_modify)( be, conn, op, odn, mods ) - == 0 ) { + if ( (*be->be_modify)( be, conn, op, odn, mods ) == 0 ) { replog( be, LDAP_REQ_MODIFY, dn, mods, 0 ); } @@ -200,7 +200,7 @@ modlist_free( static void add_lastmods( Operation *op, LDAPMod **mods ) { - char buf[20]; + char buf[22]; struct berval bv; struct berval *bvals[2]; LDAPMod **m; @@ -214,17 +214,25 @@ add_lastmods( Operation *op, LDAPMod **mods ) /* remove any attempts by the user to modify these attrs */ for ( m = mods; *m != NULL; m = &(*m)->mod_next ) { - if ( strcasecmp( (*m)->mod_type, "modifytimestamp" ) == 0 - || strcasecmp( (*m)->mod_type, "modifiersname" ) == 0 ) { - tmp = *m; - *m = (*m)->mod_next; - free( tmp->mod_type ); - if ( tmp->mod_bvalues != NULL ) { - ber_bvecfree( tmp->mod_bvalues ); - } - free( tmp ); - } - } + if ( strcasecmp( (*m)->mod_type, "modifytimestamp" ) == 0 || + strcasecmp( (*m)->mod_type, "modifiersname" ) == 0 || + strcasecmp( (*m)->mod_type, "createtimestamp" ) == 0 || + strcasecmp( (*m)->mod_type, "creatorsname" ) == 0 ) { + + Debug( LDAP_DEBUG_TRACE, + "add_lastmods: found lastmod attr: %s\n", + (*m)->mod_type, 0, 0 ); + tmp = *m; + *m = (*m)->mod_next; + free( tmp->mod_type ); + if ( tmp->mod_bvalues != NULL ) { + ber_bvecfree( tmp->mod_bvalues ); + } + free( tmp ); + if (!*m) + break; + } + } if ( op->o_dn == NULL || op->o_dn[0] == '\0' ) { bv.bv_val = "NULLDN"; @@ -243,16 +251,20 @@ add_lastmods( Operation *op, LDAPMod **mods ) *mods = tmp; pthread_mutex_lock( ¤ttime_mutex ); - ltm = localtime( ¤ttime ); - strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); +#ifndef LDAP_LOCALTIME + ltm = gmtime( ¤ttime ); + strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm ); +#else + ltm = localtime( ¤ttime ); + strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); +#endif pthread_mutex_unlock( ¤ttime_mutex ); bv.bv_val = buf; bv.bv_len = strlen( bv.bv_val ); tmp = (LDAPMod *) ch_calloc( 1, sizeof(LDAPMod) ); tmp->mod_type = strdup( "modifytimestamp" ); tmp->mod_op = LDAP_MOD_REPLACE; - tmp->mod_bvalues = (struct berval **) ch_calloc( 1, - 2 * sizeof(struct berval *) ); + tmp->mod_bvalues = (struct berval **) ch_calloc( 1, 2 * sizeof(struct berval *) ); tmp->mod_bvalues[0] = ber_bvdup( &bv ); tmp->mod_next = *mods; *mods = tmp; diff --git a/servers/slapd/monitor.c b/servers/slapd/monitor.c index 7dbabc9377..0aa56575e7 100644 --- a/servers/slapd/monitor.c +++ b/servers/slapd/monitor.c @@ -10,8 +10,16 @@ * is provided ``as is'' without express or implied warranty. */ +/* Revision history + * + * 5-Jun-96 jeff.hodges@stanford.edu + * Added locking of new_conn_mutex when traversing the c[] array. + * Added locking of currenttime_mutex to protect call(s) to localtime(). + */ + #include #include +#include #include #include #include "slap.h" @@ -32,18 +40,16 @@ extern time_t currenttime; extern time_t starttime; extern int num_conns; +extern pthread_mutex_t new_conn_mutex; +extern pthread_mutex_t currenttime_mutex; extern char Versionstr[]; -/* - * no mutex protection in here - take our chances! - */ - void monitor_info( Connection *conn, Operation *op ) { Entry *e; - char buf[BUFSIZ], buf2[20]; + char buf[BUFSIZ], buf2[22]; struct berval val; struct berval *vals[2]; int i, nconns, nwritewaiters, nreadwaiters; @@ -73,6 +79,8 @@ monitor_info( Connection *conn, Operation *op ) nconns = 0; nwritewaiters = 0; nreadwaiters = 0; + + pthread_mutex_lock( &new_conn_mutex ); for ( i = 0; i < dtblsize; i++ ) { if ( c[i].c_sb.sb_sd != -1 ) { nconns++; @@ -82,8 +90,16 @@ monitor_info( Connection *conn, Operation *op ) if ( c[i].c_gettingber ) { nreadwaiters++; } + pthread_mutex_lock( ¤ttime_mutex ); +#ifndef LDAP_LOCALTIME + ltm = gmtime( &c[i].c_starttime ); + strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm ); +#else ltm = localtime( &c[i].c_starttime ); strftime( buf2, sizeof(buf2), "%y%m%d%H%M%SZ", ltm ); +#endif + pthread_mutex_unlock( ¤ttime_mutex ); + pthread_mutex_lock( &c[i].c_dnmutex ); sprintf( buf, "%d : %s : %ld : %ld : %s : %s%s", i, buf2, c[i].c_opsinitiated, c[i].c_opscompleted, @@ -96,6 +112,8 @@ monitor_info( Connection *conn, Operation *op ) attr_merge( e, "connection", vals ); } } + pthread_mutex_unlock( &new_conn_mutex ); + sprintf( buf, "%d", nconns ); val.bv_val = buf; val.bv_len = strlen( buf ); @@ -141,14 +159,28 @@ monitor_info( Connection *conn, Operation *op ) val.bv_len = strlen( buf ); attr_merge( e, "bytessent", vals ); - ltm = localtime( ¤ttime ); - strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); + pthread_mutex_lock( ¤ttime_mutex ); +#ifndef LDAP_LOCALTIME + ltm = gmtime( ¤ttime ); + strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm ); +#else + ltm = localtime( ¤ttime ); + strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); +#endif + pthread_mutex_unlock( ¤ttime_mutex ); val.bv_val = buf; val.bv_len = strlen( buf ); attr_merge( e, "currenttime", vals ); - ltm = localtime( &starttime ); - strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); + pthread_mutex_lock( ¤ttime_mutex ); +#ifndef LDAP_LOCALTIME + ltm = gmtime( &starttime ); + strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm ); +#else + ltm = localtime( &starttime ); + strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm ); +#endif + pthread_mutex_unlock( ¤ttime_mutex ); val.bv_val = buf; val.bv_len = strlen( buf ); attr_merge( e, "starttime", vals ); diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 0ef82a7b3e..9feec1cded 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -40,6 +40,9 @@ send_ldap_result2( int rc, sd; unsigned long tag, bytes; + if ( err == LDAP_PARTIAL_RESULTS && (text == NULL || *text == '\0') ) + err = LDAP_NO_SUCH_OBJECT; + Debug( LDAP_DEBUG_TRACE, "send_ldap_result %d:%s:%s\n", err, matched ? matched : "", text ? text : "" ); @@ -121,7 +124,13 @@ send_ldap_result2( pthread_mutex_lock( &active_threads_mutex ); active_threads--; conn->c_writewaiter = 1; + +#ifdef linux + pthread_kill( listener_tid, SIGSTKFLT ); +#else /* !linux */ pthread_kill( listener_tid, SIGUSR1 ); +#endif /* !linux */ + pthread_cond_wait( &conn->c_wcv, &active_threads_mutex ); pthread_mutex_unlock( &active_threads_mutex ); @@ -192,6 +201,7 @@ send_search_entry( Attribute *a; int i, rc, bytes, sd; struct acl *acl; + char *edn; Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 ); @@ -202,15 +212,19 @@ send_search_entry( return( 1 ); } + edn = dn_normalize_case( strdup( e->e_dn ) ); + #ifdef COMPAT30 if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER )) - == NULLBER ) { + == NULLBER ) #else - if ( (ber = der_alloc()) == NULLBER ) { + if ( (ber = der_alloc()) == NULLBER ) #endif + { Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, - "ber_alloc" ); + "ber_alloc" ); + free(edn); return( 1 ); } @@ -220,26 +234,44 @@ send_search_entry( LDAP_RES_SEARCH_ENTRY, e->e_dn ); } else #endif + { rc = ber_printf( ber, "{it{s{", op->o_msgid, - LDAP_RES_SEARCH_ENTRY, e->e_dn ); + LDAP_RES_SEARCH_ENTRY, e->e_dn ); + } if ( rc == -1 ) { Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); ber_free( ber, 1 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf dn" ); + free(edn); return( 1 ); } for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + regmatch_t matches[MAXREMATCHES]; + if ( attrs != NULL && ! charray_inlist( attrs, a->a_type ) ) { continue; } - acl = acl_get_applicable( be, op, e, a->a_type ); + /* the lastmod attributes are ignored by ACL checking */ + if ( strcasecmp( a->a_type, "modifiersname" ) == 0 || + strcasecmp( a->a_type, "modifytimestamp" ) == 0 || + strcasecmp( a->a_type, "creatorsname" ) == 0 || + strcasecmp( a->a_type, "createtimestamp" ) == 0 ) + { + Debug( LDAP_DEBUG_ACL, "LASTMOD attribute: %s access DEFAULT\n", + a->a_type, 0, 0 ); + acl = NULL; + } else { + acl = acl_get_applicable( be, op, e, a->a_type, edn, + MAXREMATCHES, matches ); + } - if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, - ACL_READ ) ) { + if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, ACL_READ, + edn, matches ) ) + { continue; } @@ -248,14 +280,15 @@ send_search_entry( ber_free( ber, 1 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf type" ); + free(edn); return( 1 ); } if ( ! attrsonly ) { for ( i = 0; a->a_vals[i] != NULL; i++ ) { - if ( a->a_syntax & SYNTAX_DN && - ! acl_access_allowed( acl, be, conn, e, - a->a_vals[i], op, ACL_READ ) ) + if ( a->a_syntax & SYNTAX_DN && + ! acl_access_allowed( acl, be, conn, e, a->a_vals[i], op, + ACL_READ, edn, matches) ) { continue; } @@ -270,6 +303,7 @@ send_search_entry( send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf value" ); + free(edn); return( 1 ); } } @@ -280,10 +314,13 @@ send_search_entry( ber_free( ber, 1 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf type end" ); + free(edn); return( 1 ); } } + free(edn); + #ifdef COMPAT30 if ( conn->c_version == 30 ) { rc = ber_printf( ber, "}}}}" ); diff --git a/servers/slapd/str2filter.c b/servers/slapd/str2filter.c index aca9674fd8..cf95d922e8 100644 --- a/servers/slapd/str2filter.c +++ b/servers/slapd/str2filter.c @@ -14,7 +14,7 @@ static int str2subvals(); Filter * str2filter( char *str ) { - Filter *f; + Filter *f = NULL; char *end; Debug( LDAP_DEBUG_FILTER, "str2filter \"%s\"\n", str, 0, 0 ); -- 2.47.2