From b5d5ca8314f9203ad92c846e37b18588c525c59b Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 8 Jun 2005 23:50:16 +0000 Subject: [PATCH] Sync with HEAD (ready for 2.3 "release"?) --- contrib/slapd-modules/smbk5pwd/smbk5pwd.c | 15 ++ libraries/libldap_r/thr_stub.c | 16 ++ servers/slapd/acl.c | 10 + servers/slapd/add.c | 2 + .../slapd/back-monitor/proto-back-monitor.h | 52 ---- servers/slapd/ctxcsn.c | 6 + servers/slapd/modify.c | 50 ++-- servers/slapd/modrdn.c | 2 + servers/slapd/overlays/auditlog.c | 236 ++++++++++++++++++ servers/slapd/overlays/lastmod.c | 38 +-- servers/slapd/overlays/pcache.c | 1 + servers/slapd/overlays/ppolicy.c | 45 ++-- servers/slapd/overlays/refint.c | 4 + servers/slapd/overlays/syncprov.c | 1 + servers/slapd/passwd.c | 1 + servers/slapd/proto-slap.h | 4 + servers/slapd/sasl.c | 1 + servers/slapd/schema.c | 19 +- servers/slapd/slap.h | 9 +- servers/slapd/slapadd.c | 8 +- servers/slapd/slapi/slapi_ops.c | 4 + servers/slapd/slapi/slapi_utils.c | 3 + servers/slapd/syncrepl.c | 5 + 23 files changed, 390 insertions(+), 142 deletions(-) create mode 100644 servers/slapd/overlays/auditlog.c diff --git a/contrib/slapd-modules/smbk5pwd/smbk5pwd.c b/contrib/slapd-modules/smbk5pwd/smbk5pwd.c index 1387916697..1f0c57eb72 100644 --- a/contrib/slapd-modules/smbk5pwd/smbk5pwd.c +++ b/contrib/slapd-modules/smbk5pwd/smbk5pwd.c @@ -373,6 +373,9 @@ static int smbk5pwd_exop_passwd( ml->sml_desc = ad_krb5Key; ml->sml_op = LDAP_MOD_REPLACE; +#ifdef SLAP_MOD_INTERNAL + ml->sml_flags = SLAP_MOD_INTERNAL; +#endif ml->sml_values = keys; ml->sml_nvalues = NULL; @@ -382,6 +385,9 @@ static int smbk5pwd_exop_passwd( ml->sml_desc = ad_krb5KeyVersionNumber; ml->sml_op = LDAP_MOD_REPLACE; +#ifdef SLAP_MOD_INTERNAL + ml->sml_flags = SLAP_MOD_INTERNAL; +#endif ml->sml_values = ch_malloc( 2 * sizeof(struct berval)); ml->sml_values[0].bv_val = ch_malloc( 64 ); ml->sml_values[0].bv_len = sprintf(ml->sml_values[0].bv_val, @@ -430,6 +436,9 @@ static int smbk5pwd_exop_passwd( ml->sml_desc = ad_sambaNTPassword; ml->sml_op = LDAP_MOD_REPLACE; +#ifdef SLAP_MOD_INTERNAL + ml->sml_flags = SLAP_MOD_INTERNAL; +#endif ml->sml_values = keys; ml->sml_nvalues = NULL; @@ -454,6 +463,9 @@ static int smbk5pwd_exop_passwd( ml->sml_desc = ad_sambaLMPassword; ml->sml_op = LDAP_MOD_REPLACE; +#ifdef SLAP_MOD_INTERNAL + ml->sml_flags = SLAP_MOD_INTERNAL; +#endif ml->sml_values = keys; ml->sml_nvalues = NULL; @@ -472,6 +484,9 @@ static int smbk5pwd_exop_passwd( ml->sml_desc = ad_sambaPwdLastSet; ml->sml_op = LDAP_MOD_REPLACE; +#ifdef SLAP_MOD_INTERNAL + ml->sml_flags = SLAP_MOD_INTERNAL; +#endif ml->sml_values = keys; ml->sml_nvalues = NULL; } diff --git a/libraries/libldap_r/thr_stub.c b/libraries/libldap_r/thr_stub.c index 0f9bae6f19..ee65e67790 100644 --- a/libraries/libldap_r/thr_stub.c +++ b/libraries/libldap_r/thr_stub.c @@ -195,6 +195,22 @@ int ldap_pvt_thread_pool_setkey ( return(0); } +void ldap_pvt_thread_pool_purgekey( void *key ) +{ +} + +int ldap_pvt_thread_pool_pause ( + ldap_pvt_thread_pool_t *tpool ) +{ + return(0); +} + +int ldap_pvt_thread_pool_resume ( + ldap_pvt_thread_pool_t *tpool ) +{ + return(0); +} + void *ldap_pvt_thread_pool_context( ) { return(NULL); diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index e71d14fcca..0276f35075 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -2259,6 +2259,16 @@ acl_check_modlist( } for ( ; mlist != NULL; mlist = mlist->sml_next ) { + /* + * Internal mods are ignored by ACL_WRITE checking + */ + if ( mlist->sml_flags & SLAP_MOD_INTERNAL ) { + Debug( LDAP_DEBUG_ACL, "acl: internal mod %s:" + " modify access granted\n", + mlist->sml_desc->ad_cname.bv_val, 0, 0 ); + continue; + } + /* * no-user-modification operational attributes are ignored * by ACL_WRITE checking as any found here are not provided diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 39480b5c93..537129fdd4 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -120,6 +120,7 @@ do_add( Operation *op, SlapReply *rs ) mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = LDAP_MOD_ADD; + mod->sml_flags = 0; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; @@ -612,6 +613,7 @@ slap_entry2mods( mod = (Modifications *) malloc( sizeof( Modifications )); mod->sml_op = LDAP_MOD_REPLACE; + mod->sml_flags = 0; mod->sml_type = a_new_desc->ad_cname; diff --git a/servers/slapd/back-monitor/proto-back-monitor.h b/servers/slapd/back-monitor/proto-back-monitor.h index 0df5ebb1cd..d73bf61d6b 100644 --- a/servers/slapd/back-monitor/proto-back-monitor.h +++ b/servers/slapd/back-monitor/proto-back-monitor.h @@ -268,58 +268,6 @@ monitor_subsys_rww_update LDAP_P(( SlapReply *rs, Entry *e )); -/* NOTE: this macro assumes that bv has been allocated - * by ber_* malloc functions or is { 0L, NULL } */ -#if defined(HAVE_BIGNUM) -#define UI2BV(bv,ui) \ - do { \ - char *val; \ - ber_len_t len; \ - val = BN_bn2dec(ui); \ - if (val) { \ - len = strlen(val); \ - if ( len > (bv)->bv_len ) { \ - (bv)->bv_val = ber_memrealloc( (bv)->bv_val, len + 1 ); \ - } \ - AC_MEMCPY((bv)->bv_val, val, len + 1); \ - (bv)->bv_len = len; \ - OPENSSL_free(val); \ - } else { \ - ber_memfree( (bv)->bv_val ); \ - BER_BVZERO( (bv) ); \ - } \ - } while ( 0 ) -#elif defined(HAVE_GMP) -/* NOTE: according to the documentation, the result - * of mpz_sizeinbase() can exceed the length of the - * string representation of the number by 1 - */ -#define UI2BV(bv,ui) \ - do { \ - ber_len_t len = mpz_sizeinbase( (ui), 10 ); \ - if ( len > (bv)->bv_len ) { \ - (bv)->bv_val = ber_memrealloc( (bv)->bv_val, len + 1 ); \ - } \ - (void)mpz_get_str( (bv)->bv_val, 10, (ui) ); \ - if ( (bv)->bv_val[ len - 1 ] == '\0' ) { \ - len--; \ - } \ - (bv)->bv_len = len; \ - } while ( 0 ) -#else /* ! HAVE_BIGNUM && ! HAVE_GMP */ -#define UI2BV(bv,ui) \ - do { \ - char buf[] = "+9223372036854775807L"; \ - ber_len_t len; \ - snprintf( buf, sizeof( buf ), "%lu", (ui) ); \ - len = strlen( buf ); \ - if ( len > (bv)->bv_len ) { \ - (bv)->bv_val = ber_memrealloc( (bv)->bv_val, len + 1 ); \ - } \ - AC_MEMCPY( (bv)->bv_val, buf, len + 1 ); \ - } while ( 0 ) -#endif /* ! HAVE_GMP */ - /* * former external.h */ diff --git a/servers/slapd/ctxcsn.c b/servers/slapd/ctxcsn.c index defcac2e89..408ee66838 100644 --- a/servers/slapd/ctxcsn.c +++ b/servers/slapd/ctxcsn.c @@ -183,7 +183,13 @@ slap_get_csn( { if ( csn == NULL ) return LDAP_OTHER; +#ifndef HAVE_GMTIME_R + ldap_pvt_thread_mutex_lock( &gmtime_mutex ); +#endif csn->bv_len = lutil_csnstr( csnbuf, len, 0, 0 ); +#ifndef HAVE_GMTIME_R + ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); +#endif csn->bv_val = csnbuf; if ( manage_ctxcsn ) diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 77b0d5013a..17ac17c4a3 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -104,6 +104,7 @@ do_modify( mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = mop; + mod->sml_flags = 0; mod->sml_type = tmp.sml_type; mod->sml_values = tmp.sml_values; mod->sml_nvalues = NULL; @@ -831,6 +832,28 @@ int slap_mods_check( return LDAP_SUCCESS; } +/* Enter with bv->bv_len = sizeof buffer, returns with + * actual length of string + */ +void slap_timestamp( time_t *tm, struct berval *bv ) +{ + struct tm *ltm; +#ifdef HAVE_GMTIME_R + struct tm ltm_buf; + + ltm = gmtime_r( tm, <m_buf ); +#else + ldap_pvt_thread_mutex_lock( &gmtime_mutex ); + ltm = gmtime( &tm ); +#endif + + bv->bv_len = lutil_gentime( bv->bv_val, bv->bv_len, ltm ); + +#ifndef HAVE_GMTIME_R + ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); +#endif +} + int slap_mods_opattrs( Operation *op, Modifications *mods, @@ -852,28 +875,14 @@ int slap_mods_opattrs( assert( *modtail == NULL ); if ( SLAP_LASTMOD( op->o_bd )) { - struct tm *ltm; -#ifdef HAVE_GMTIME_R - struct tm ltm_buf; -#endif time_t now = slap_get_time(); -#ifdef HAVE_GMTIME_R - ltm = gmtime_r( &now, <m_buf ); -#else - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - ltm = gmtime( &now ); -#endif /* HAVE_GMTIME_R */ - lutil_gentime( timebuf, sizeof(timebuf), ltm ); - slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, manage_ctxcsn ); -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); -#endif - timestamp.bv_val = timebuf; - timestamp.bv_len = strlen(timebuf); + timestamp.bv_len = sizeof(timebuf); + + slap_timestamp( &now, ×tamp ); if( op->o_dn.bv_len == 0 ) { BER_BVSTR( &name, SLAPD_ANONYMOUS ); @@ -894,6 +903,7 @@ int slap_mods_opattrs( mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; + mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_structuralObjectClass; mod->sml_values = @@ -920,6 +930,7 @@ int slap_mods_opattrs( mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; + mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_entryUUID; mod->sml_values = @@ -942,6 +953,7 @@ int slap_mods_opattrs( mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; + mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_creatorsName; mod->sml_values = @@ -961,6 +973,7 @@ int slap_mods_opattrs( mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; + mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_createTimestamp; mod->sml_values = @@ -978,6 +991,7 @@ int slap_mods_opattrs( if ( SLAP_LASTMOD( op->o_bd )) { mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; + mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_entryCSN; mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); @@ -991,6 +1005,7 @@ int slap_mods_opattrs( mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; + mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_modifiersName; mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); @@ -1009,6 +1024,7 @@ int slap_mods_opattrs( mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; + mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_modifyTimestamp; mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index b0f8d3e028..c2ceab26bb 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -480,6 +480,7 @@ slap_modrdn2mods( mod_tmp->sml_nvalues = NULL; } mod_tmp->sml_op = SLAP_MOD_SOFTADD; + mod_tmp->sml_flags = SLAP_MOD_INTERNAL; mod_tmp->sml_next = mod; mod = mod_tmp; } @@ -534,6 +535,7 @@ slap_modrdn2mods( mod_tmp->sml_nvalues = NULL; } mod_tmp->sml_op = LDAP_MOD_DELETE; + mod_tmp->sml_flags = SLAP_MOD_INTERNAL; mod_tmp->sml_next = mod; mod = mod_tmp; } diff --git a/servers/slapd/overlays/auditlog.c b/servers/slapd/overlays/auditlog.c new file mode 100644 index 0000000000..41da39cbc8 --- /dev/null +++ b/servers/slapd/overlays/auditlog.c @@ -0,0 +1,236 @@ +/* auditlog.c - log modifications for audit/history purposes */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 2005 The OpenLDAP Foundation. + * Portions copyright 2004-2005 Symas Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Symas Corp. for inclusion in + * OpenLDAP Software. This work was sponsored by Hewlett-Packard. + */ + +#include "portable.h" + +#ifdef SLAPD_OVER_AUDITLOG + +#include + +#include +#include + +#include "slap.h" +#include "ldif.h" + +typedef struct auditlog_data { + ldap_pvt_thread_mutex_t ad_mutex; + char *ad_logfile; +} auditlog_data; + +int fprint_ldif(FILE *f, char *name, char *val, ber_len_t len) { + char *s; + if((s = ldif_put(LDIF_PUT_VALUE, name, val, len)) == NULL) + return(-1); + fputs(s, f); + ber_memfree(s); + return(0); +} + +int auditlog_response(Operation *op, SlapReply *rs) { + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + auditlog_data *ad = on->on_bi.bi_private; + FILE *f; + Attribute *a; + Modifications *m; + struct berval *b; + char *what, *subop, *suffix, *who = NULL; + long stamp = slap_get_time(); + int i; + + if ( rs->sr_err != LDAP_SUCCESS ) return SLAP_CB_CONTINUE; + + if ( !op->o_bd || !ad->ad_logfile ) return SLAP_CB_CONTINUE; + +/* +** add or modify: use modifiersName if present +** +*/ + switch(op->o_tag) { + case LDAP_REQ_MODRDN: what = "modrdn"; break; + case LDAP_REQ_DELETE: what = "delete"; break; + case LDAP_REQ_ADD: + what = "add"; + for(a = op->ora_e->e_attrs; a; a = a->a_next) + if( a->a_desc == slap_schema.si_ad_modifiersName ) { + who = a->a_vals[0].bv_val; + break; + } + break; + case LDAP_REQ_MODIFY: + what = "modify"; + for(m = op->orm_modlist; m; m = m->sml_next) + if( m->sml_desc == slap_schema.si_ad_modifiersName ) { + who = m->sml_values[0].bv_val; + break; + } + break; + default: + return SLAP_CB_CONTINUE; + } + + suffix = op->o_bd->be_suffix[0].bv_len ? op->o_bd->be_suffix[0].bv_val : + "global"; + +/* +** note: this means requestor's dn when modifiersName is null +*/ + if ( !who ) + who = op->o_dn.bv_val; + + ldap_pvt_thread_mutex_lock(&ad->ad_mutex); + if((f = fopen(ad->ad_logfile, "a")) == NULL) { + ldap_pvt_thread_mutex_unlock(&ad->ad_mutex); + return SLAP_CB_CONTINUE; + } + + fprintf(f, "# %s %ld %s%s%s\ndn: %s\nchangetype: %s\n", + what, stamp, suffix, who ? " " : "", who ? who : "", + op->o_req_dn.bv_val, what); + + switch(op->o_tag) { + case LDAP_REQ_ADD: + for(a = op->ora_e->e_attrs; a; a = a->a_next) + if(b = a->a_vals) + for(i = 0; b[i].bv_val; i++) + fprint_ldif(f, a->a_desc->ad_cname.bv_val, b[i].bv_val, b[i].bv_len); + break; + + case LDAP_REQ_MODIFY: + for(m = op->orm_modlist; m; m = m->sml_next) { + switch(m->sml_op & LDAP_MOD_OP) { + case LDAP_MOD_ADD: what = "add"; break; + case LDAP_MOD_REPLACE: what = "replace"; break; + case LDAP_MOD_DELETE: what = "delete"; break; + case LDAP_MOD_INCREMENT: what = "increment"; break; + default: + fprintf(f, "# MOD_TYPE_UNKNOWN:%02x\n", m->sml_op & LDAP_MOD_OP); + continue; + } + fprintf(f, "%s: %s\n", what, m->sml_desc->ad_cname.bv_val); + if(b = m->sml_values) for(i = 0; b[i].bv_val; i++) + fprint_ldif(f, m->sml_desc->ad_cname.bv_val, b[i].bv_val, b[i].bv_len); + fprintf(f, "-\n"); + } + break; + + case LDAP_REQ_MODRDN: + fprintf(f, "newrdn: %s\ndeleteoldrdn: %s\n", + op->orr_newrdn.bv_val, op->orr_deleteoldrdn ? "1" : "0"); + if(op->orr_newSup) fprintf(f, "newsuperior: %s\n", op->orr_newSup->bv_val); + break; + + case LDAP_REQ_DELETE: + /* nothing else needed */ + break; + } + + fprintf(f, "# end %s %ld\n\n", what, stamp); + + fclose(f); + ldap_pvt_thread_mutex_unlock(&ad->ad_mutex); + return SLAP_CB_CONTINUE; +} + +static slap_overinst auditlog; + +static int +auditlog_db_init( + BackendDB *be +) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + auditlog_data *ad = ch_malloc(sizeof(auditlog_data)); + + on->on_bi.bi_private = ad; + ldap_pvt_thread_mutex_init( &ad->ad_mutex ); + return 0; +} + +static int +auditlog_db_close( + BackendDB *be +) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + auditlog_data *ad = on->on_bi.bi_private; + + free( ad->ad_logfile ); + ad->ad_logfile = NULL; +} + +static int +auditlog_db_destroy( + BackendDB *be +) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + auditlog_data *ad = on->on_bi.bi_private; + + ldap_pvt_thread_mutex_destroy( &ad->ad_mutex ); + free( ad ); +} + +static int +auditlog_config( + BackendDB *be, + const char *fname, + int lineno, + int argc, + char **argv +) +{ + slap_overinst *on = (slap_overinst *) be->bd_info; + auditlog_data *ad = on->on_bi.bi_private; + + /* history log file */ + if ( strcasecmp( argv[0], "auditlog" ) == 0 ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing filename in \"auditlog \" line\n", + fname, lineno, 0 ); + return( 1 ); + } + ad->ad_logfile = ch_strdup( argv[1] ); + return 0; + } + return SLAP_CONF_UNKNOWN; +} + +int auditlog_init() { + + auditlog.on_bi.bi_type = "auditlog"; + auditlog.on_bi.bi_db_init = auditlog_db_init; + auditlog.on_bi.bi_db_config = auditlog_config; + auditlog.on_bi.bi_db_close = auditlog_db_close; + auditlog.on_bi.bi_db_destroy = auditlog_db_destroy; + auditlog.on_response = auditlog_response; + + return overlay_register(&auditlog); +} + +#if SLAPD_OVER_AUDITLOG == SLAPD_MOD_DYNAMIC && defined(PIC) +int init_module( int argc, char *argv[]) { + return auditlog_init(); +} +#endif + +#endif /* SLAPD_OVER_AUDITLOG */ diff --git a/servers/slapd/overlays/lastmod.c b/servers/slapd/overlays/lastmod.c index a645f7d8b4..8a9996708f 100644 --- a/servers/slapd/overlays/lastmod.c +++ b/servers/slapd/overlays/lastmod.c @@ -378,11 +378,8 @@ best_guess( Operation *op, } if ( bv_modifyTimestamp ) { - struct tm *tm; -#ifdef HAVE_GMTIME_R - struct tm tm_buf; -#endif char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + struct berval timestamp; time_t currtime; /* best guess */ @@ -392,18 +389,11 @@ best_guess( Operation *op, /* maybe we better use the time the operation was initiated */ currtime = op->o_time; -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - tm = gmtime( &currtime ); -#else /* HAVE_GMTIME_R */ - tm = gmtime_r( &currtime, &tm_buf ); -#endif /* HAVE_GMTIME_R */ - lutil_gentime( tmbuf, sizeof( tmbuf ), tm ); -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); -#endif + timestamp.bv_val = tmbuf; + timestamp.bv_len = sizeof(tmbuf); + slap_timestamp( &currtime, ×tamp ); - ber_str2bv( tmbuf, 0, 1, bv_modifyTimestamp ); + ber_dupbv( bv_modifyTimestamp, ×tamp ); ber_dupbv( bv_nmodifyTimestamp, bv_modifyTimestamp ); } @@ -904,14 +894,11 @@ lastmod_db_open( slap_overinst *on = (slap_overinst *) be->bd_info; lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private; char buf[ 8192 ]; - struct tm *tms; -#ifdef HAVE_GMTIME_R - struct tm tm_buf; -#endif static char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; struct berval entryCSN; + struct berval timestamp; if ( !SLAP_LASTMOD( be ) ) { fprintf( stderr, "set \"lastmod on\" to make this overlay effective\n" ); @@ -921,16 +908,9 @@ lastmod_db_open( /* * Start */ -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - tms = gmtime( &starttime ); -#else /* HAVE_GMTIME_R */ - tms = gmtime_r( &starttime, &tm_buf ); -#endif /* HAVE_GMTIME_R */ - lutil_gentime( tmbuf, sizeof(tmbuf), tms ); -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); -#endif + timestamp.bv_val = tmbuf; + timestamp.bv_len = sizeof(tmbuf); + slap_timestamp( &starttime, ×tamp ); slap_get_csn( NULL, csnbuf, sizeof(csnbuf), &entryCSN, 0 ); diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index 0e1349a181..a8d8a2c6b8 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -854,6 +854,7 @@ remove_query_data ( vals[1].bv_val = NULL; vals[1].bv_len = 0; mod.sml_op = LDAP_MOD_DELETE; + mod.sml_flags = 0; mod.sml_desc = ad_queryid; mod.sml_type = ad_queryid->ad_cname; mod.sml_values = vals; diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index 2937ae3cf9..9941f865dc 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -238,6 +238,7 @@ account_locked( Operation *op, Entry *e, m = ch_calloc( sizeof(Modifications), 1 ); m->sml_op = LDAP_MOD_DELETE; + m->sml_flags = 0; m->sml_type = ad_pwdAccountLockedTime->ad_cname; m->sml_desc = ad_pwdAccountLockedTime; m->sml_next = *mod; @@ -682,10 +683,10 @@ ppolicy_bind_resp( Operation *op, SlapReply *rs ) int pwExpired = 0; int ngut = -1, warn = -1, age, rc, i; Attribute *a; - struct tm *tm; time_t now, then, pwtime = (time_t)-1; const char *txt; char nowstr[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + struct berval timestamp; BackendInfo *bi = op->o_bd->bd_info; Entry *e; @@ -703,21 +704,21 @@ ppolicy_bind_resp( Operation *op, SlapReply *rs ) } now = slap_get_time(); /* stored for later consideration */ - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - tm = gmtime(&now); - lutil_gentime( nowstr, sizeof(nowstr), tm ); - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); + timestamp.bv_val = nowstr; + timestamp.bv_len = sizeof(nowstr); + slap_timestamp( &now, ×tamp ); if ( rs->sr_err == LDAP_INVALID_CREDENTIALS ) { int i = 0, fc = 0; m = ch_calloc( sizeof(Modifications), 1 ); m->sml_op = LDAP_MOD_ADD; + m->sml_flags = 0; m->sml_type = ad_pwdFailureTime->ad_cname; m->sml_desc = ad_pwdFailureTime; m->sml_values = ch_calloc( sizeof(struct berval), 2 ); - ber_str2bv( nowstr, 0, 1, &m->sml_values[0] ); + ber_dupbv( &m->sml_values[0], ×tamp ); m->sml_next = mod; mod = m; @@ -759,10 +760,11 @@ ppolicy_bind_resp( Operation *op, SlapReply *rs ) */ m = ch_calloc( sizeof(Modifications), 1 ); m->sml_op = LDAP_MOD_REPLACE; + m->sml_flags = 0; m->sml_type = ad_pwdAccountLockedTime->ad_cname; m->sml_desc = ad_pwdAccountLockedTime; m->sml_values = ch_calloc( sizeof(struct berval), 2 ); - ber_str2bv( nowstr, 0, 1, &m->sml_values[0] ); + ber_dupbv( &m->sml_values[0], ×tamp ); m->sml_next = mod; mod = m; } @@ -774,6 +776,7 @@ ppolicy_bind_resp( Operation *op, SlapReply *rs ) if ( attr_find( e->e_attrs, ad_pwdFailureTime )) { m = ch_calloc( sizeof(Modifications), 1 ); m->sml_op = LDAP_MOD_DELETE; + m->sml_flags = 0; m->sml_type = ad_pwdFailureTime->ad_cname; m->sml_desc = ad_pwdFailureTime; m->sml_next = mod; @@ -859,10 +862,11 @@ grace: */ m = ch_calloc( sizeof(Modifications), 1 ); m->sml_op = LDAP_MOD_ADD; + m->sml_flags = 0; m->sml_type = ad_pwdGraceUseTime->ad_cname; m->sml_desc = ad_pwdGraceUseTime; m->sml_values = ch_calloc( sizeof(struct berval), 2 ); - ber_str2bv( nowstr, 0, 1, &m->sml_values[0] ); + ber_dupbv( &m->sml_values[0], ×tamp ); m->sml_next = mod; mod = m; @@ -1124,16 +1128,11 @@ ppolicy_add( if (( pp.pwdMaxAge || pp.pwdMinAge ) && !be_shadow_update( op )) { struct berval timestamp; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; - struct tm *ltm; time_t now = slap_get_time(); - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - ltm = gmtime( &now ); - lutil_gentime( timebuf, sizeof(timebuf), ltm ); - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); - timestamp.bv_val = timebuf; - timestamp.bv_len = strlen(timebuf); + timestamp.bv_len = sizeof(timebuf); + slap_timestamp( &now, ×tamp ); attr_merge_one( op->ora_e, ad_pwdChangedTime, ×tamp, NULL ); } @@ -1299,6 +1298,7 @@ ppolicy_modify( Operation *op, SlapReply *rs ) if (pp.pwdSafeModify && oldpw.bv_val ) { ml = (Modifications *) ch_malloc( sizeof( Modifications ) ); ml->sml_op = LDAP_MOD_DELETE; + ml->sml_flags = SLAP_MOD_INTERNAL; ml->sml_desc = pp.ad; ml->sml_type = pp.ad->ad_cname; ml->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); @@ -1437,7 +1437,6 @@ do_modify: if ((pwmod) && (!be_shadow_update( op ))) { struct berval timestamp; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; - struct tm *ltm; time_t now = slap_get_time(); Attribute *ga; @@ -1446,13 +1445,10 @@ do_modify: * up to date. */ - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - ltm = gmtime( &now ); - lutil_gentime( timebuf, sizeof(timebuf), ltm ); - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); - timestamp.bv_val = timebuf; - timestamp.bv_len = strlen(timebuf); + timestamp.bv_len = sizeof(timebuf); + slap_timestamp( &now, ×tamp ); + mods = (Modifications *) ch_malloc( sizeof( Modifications ) ); mods->sml_type.bv_val = NULL; mods->sml_desc = ad_pwdChangedTime; @@ -1467,6 +1463,7 @@ do_modify: mods->sml_op = LDAP_MOD_DELETE; mods->sml_values = NULL; } + mods->sml_flags = SLAP_MOD_INTERNAL; mods->sml_nvalues = NULL; mods->sml_next = NULL; modtail->sml_next = mods; @@ -1475,6 +1472,7 @@ do_modify: if (attr_find(e->e_attrs, ad_pwdGraceUseTime )) { mods = (Modifications *) ch_malloc( sizeof( Modifications ) ); mods->sml_op = LDAP_MOD_DELETE; + mods->sml_flags = SLAP_MOD_INTERNAL; mods->sml_type.bv_val = NULL; mods->sml_desc = ad_pwdGraceUseTime; mods->sml_values = NULL; @@ -1488,6 +1486,7 @@ do_modify: if ((zapReset) && (attr_find(e->e_attrs, ad_pwdReset ))) { mods = (Modifications *) ch_malloc( sizeof( Modifications ) ); mods->sml_op = LDAP_MOD_DELETE; + mods->sml_flags = SLAP_MOD_INTERNAL; mods->sml_type.bv_val = NULL; mods->sml_desc = ad_pwdReset; mods->sml_values = NULL; @@ -1517,6 +1516,7 @@ do_modify: */ mods = (Modifications *) ch_malloc( sizeof( Modifications ) ); mods->sml_op = LDAP_MOD_DELETE; + mods->sml_flags = SLAP_MOD_INTERNAL; mods->sml_type.bv_val = NULL; mods->sml_desc = ad_pwdHistory; mods->sml_nvalues = NULL; @@ -1549,6 +1549,7 @@ do_modify: if ((pa = attr_find( e->e_attrs, pp.ad )) != NULL) { mods = (Modifications *) ch_malloc( sizeof( Modifications ) ); mods->sml_op = LDAP_MOD_ADD; + mods->sml_flags = SLAP_MOD_INTERNAL; mods->sml_type.bv_val = NULL; mods->sml_desc = ad_pwdHistory; mods->sml_nvalues = NULL; diff --git a/servers/slapd/overlays/refint.c b/servers/slapd/overlays/refint.c index 991b82b28f..a233fec070 100644 --- a/servers/slapd/overlays/refint.c +++ b/servers/slapd/overlays/refint.c @@ -291,6 +291,7 @@ refint_delete_cb( mp->sml_values[1].bv_val = mp->sml_nvalues[1].bv_val = NULL; mp->sml_op = LDAP_MOD_ADD; + mp->sml_flags = 0; ber_dupbv(&mp->sml_values[0], &dd->nothing); ber_dupbv(&mp->sml_nvalues[0], &dd->nnothing); mp->sml_next = ma; @@ -305,6 +306,7 @@ refint_delete_cb( mp->sml_values[1].bv_len = mp->sml_nvalues[1].bv_len = 0; mp->sml_values[1].bv_val = mp->sml_nvalues[1].bv_val = NULL; mp->sml_op = LDAP_MOD_DELETE; + mp->sml_flags = 0; ber_dupbv(&mp->sml_values[0], &dd->dn); ber_dupbv(&mp->sml_nvalues[0], &mp->sml_values[0]); mp->sml_next = ma; @@ -389,6 +391,7 @@ refint_modrdn_cb( } mp = ch_malloc(sizeof(Modifications)); mp->sml_op = LDAP_MOD_ADD; + mp->sml_flags = 0; mp->sml_desc = ia->attr; /* XXX */ mp->sml_type = ia->attr->ad_cname; mp->sml_values = ch_malloc(2 * sizeof(BerValue)); @@ -401,6 +404,7 @@ refint_modrdn_cb( ip->mm = mp; mp = ch_malloc(sizeof(Modifications)); mp->sml_op = LDAP_MOD_DELETE; + mp->sml_flags = 0; mp->sml_desc = ia->attr; /* XXX */ mp->sml_type = ia->attr->ad_cname; mp->sml_values = ch_malloc(2 * sizeof(BerValue)); diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 5c51f03c2d..74d428c4bc 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -1151,6 +1151,7 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on ) mod.sml_nvalues = NULL; mod.sml_desc = slap_schema.si_ad_contextCSN; mod.sml_op = LDAP_MOD_REPLACE; + mod.sml_flags = 0; mod.sml_next = NULL; cb.sc_response = slap_null_cb; diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index 270b1148b2..0917bd2273 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -213,6 +213,7 @@ int passwd_extop( ml->sml_nvalues = NULL; ml->sml_desc = slap_schema.si_ad_userPassword; ml->sml_op = LDAP_MOD_REPLACE; + ml->sml_flags = 0; ml->sml_next = qpw->rs_mods; qpw->rs_mods = ml; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index f5ed80742f..cb453fe715 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -897,6 +897,10 @@ LDAP_SLAPD_F( int ) slap_mods_check( const char **text, char *textbuf, size_t textlen, void *ctx ); +LDAP_SLAPD_F( void ) slap_timestamp( + time_t *tm, + struct berval *bv ); + LDAP_SLAPD_F( int ) slap_mods_opattrs( Operation *op, Modifications *mods, diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 87fce497a5..10b17ca62f 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -369,6 +369,7 @@ slap_auxprop_store( for (i=0; pr[i].name; i++) { mod = (Modifications *)ch_malloc( sizeof(Modifications) ); mod->sml_op = LDAP_MOD_REPLACE; + mod->sml_flags = 0; ber_str2bv( pr[i].name, 0, 0, &mod->sml_type ); mod->sml_values = (struct berval *)ch_malloc( (pr[i].nvalues + 1) * sizeof(struct berval)); diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index bd1601ce0d..c2f0970ff9 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -117,10 +117,6 @@ schema_info( Entry **entry, const char **text ) } { - struct tm *ltm; -#ifdef HAVE_GMTIME_R - struct tm ltm_buf; -#endif char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; /* @@ -134,19 +130,10 @@ schema_info( Entry **entry, const char **text ) * AND modified at server startup time ... */ -#ifdef HAVE_GMTIME_R - ltm = gmtime_r( &starttime, <m_buf ); -#else - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - ltm = gmtime( &starttime ); -#endif /* HAVE_GMTIME_R */ - lutil_gentime( timebuf, sizeof(timebuf), ltm ); -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); -#endif - vals[0].bv_val = timebuf; - vals[0].bv_len = strlen( timebuf ); + vals[0].bv_len = sizeof( timebuf ); + + slap_timestamp( &starttime, vals ); if( attr_merge_one( e, ad_createTimestamp, vals, NULL ) ) { /* Out of memory, do something about it */ diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index b4e7e187a3..4b761747ec 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1145,7 +1145,13 @@ typedef struct slap_entry { * A list of LDAPMods */ typedef struct slap_mod { - int sm_op; + short sm_op; + short sm_flags; +/* Set for internal mods, will bypass ACL checks. Only needed when + * running as non-root user, for user modifiable attributes. + */ +#define SLAP_MOD_INTERNAL 0x01 + AttributeDescription *sm_desc; struct berval sm_type; BerVarray sm_values; @@ -1155,6 +1161,7 @@ typedef struct slap_mod { typedef struct slap_mod_list { Modification sml_mod; #define sml_op sml_mod.sm_op +#define sml_flags sml_mod.sm_flags #define sml_desc sml_mod.sm_desc #define sml_type sml_mod.sm_type #define sml_values sml_mod.sm_values diff --git a/servers/slapd/slapadd.c b/servers/slapd/slapadd.c index ac66a3f008..fec476894d 100644 --- a/servers/slapd/slapadd.c +++ b/servers/slapd/slapadd.c @@ -196,7 +196,6 @@ slapadd( int argc, char **argv ) } if ( SLAP_LASTMOD(be) ) { - struct tm *ltm; time_t now = slap_get_time(); char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; struct berval vals[ 2 ]; @@ -213,14 +212,13 @@ slapadd( int argc, char **argv ) nvals[1].bv_len = 0; nvals[1].bv_val = NULL; - ltm = gmtime(&now); - lutil_gentime( timebuf, sizeof(timebuf), ltm ); - csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), 0, 0 ); csn.bv_val = csnbuf; timestamp.bv_val = timebuf; - timestamp.bv_len = strlen(timebuf); + timestamp.bv_len = sizeof(timebuf); + + slap_timestamp( &now, ×tamp ); if ( BER_BVISEMPTY( &be->be_rootndn ) ) { BER_BVSTR( &name, SLAPD_ANONYMOUS ); diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c index 5a95c62fc3..5e85fe80b8 100644 --- a/servers/slapd/slapi/slapi_ops.c +++ b/servers/slapd/slapi/slapi_ops.c @@ -406,6 +406,7 @@ slapi_int_ldapmod_to_entry( mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = LDAP_MOD_ADD; + mod->sml_flags = 0; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; @@ -431,6 +432,7 @@ slapi_int_ldapmod_to_entry( mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = LDAP_MOD_ADD; + mod->sml_flags = 0; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; @@ -965,6 +967,7 @@ slapi_modify_internal( mod = (Modifications *)ch_malloc( sizeof(Modifications) ); mod->sml_op = pMod->mod_op & LDAP_MOD_OP; + mod->sml_flags = 0; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; @@ -982,6 +985,7 @@ slapi_modify_internal( mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = pMod->mod_op & LDAP_MOD_OP; + mod->sml_flags = 0; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; diff --git a/servers/slapd/slapi/slapi_utils.c b/servers/slapd/slapi/slapi_utils.c index 1adeb85086..ca7e8c45da 100644 --- a/servers/slapd/slapi/slapi_utils.c +++ b/servers/slapd/slapi/slapi_utils.c @@ -604,6 +604,7 @@ slapi_entry_add_values( Slapi_Entry *e, const char *type, struct berval **vals ) char textbuf[SLAP_TEXT_BUFLEN]; mod.sm_op = LDAP_MOD_ADD; + mod.sm_flags = 0; mod.sm_desc = NULL; mod.sm_type.bv_val = (char *)type; mod.sm_type.bv_len = strlen( type ); @@ -676,6 +677,7 @@ slapi_entry_delete_values( Slapi_Entry *e, const char *type, struct berval **val char textbuf[SLAP_TEXT_BUFLEN]; mod.sm_op = LDAP_MOD_DELETE; + mod.sm_flags = 0; mod.sm_desc = NULL; mod.sm_type.bv_val = (char *)type; mod.sm_type.bv_len = strlen( type ); @@ -3524,6 +3526,7 @@ Modifications *slapi_int_ldapmods2modifications (LDAPMod **mods) mod = (Modifications *) ch_malloc( sizeof(Modifications) ); mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES); + mod->sml_flags = 0; mod->sml_type.bv_val = (*modp)->mod_type; mod->sml_type.bv_len = strlen( mod->sml_type.bv_val ); mod->sml_desc = NULL; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index ff49fc7df9..118e7771b5 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -1094,6 +1094,7 @@ syncrepl_message_to_entry( mod = (Modifications *) ch_malloc( sizeof( Modifications )); mod->sml_op = LDAP_MOD_REPLACE; + mod->sml_flags = 0; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; @@ -1470,6 +1471,7 @@ retry_add:; for ( i = 0; i < dni.attrs; i++ ) { mod = ch_malloc( sizeof( Modifications ) ); mod->sml_op = LDAP_MOD_DELETE; + mod->sml_flags = 0; mod->sml_desc = dni.ads[i]; mod->sml_type = mod->sml_desc->ad_cname; mod->sml_values = NULL; @@ -1496,6 +1498,7 @@ retry_add:; mod = (Modifications *)ch_calloc(1, sizeof(Modifications)); mod->sml_op = LDAP_MOD_REPLACE; + mod->sml_flags = 0; mod->sml_desc = slap_schema.si_ad_entryUUID; mod->sml_type = mod->sml_desc->ad_cname; ber_dupbv( &uuid_bv, &syncUUID_strrep ); @@ -1676,6 +1679,7 @@ syncrepl_del_nonpresent( if ( rs_delete.sr_err == LDAP_NOT_ALLOWED_ON_NONLEAF ) { Modifications mod1, mod2; mod1.sml_op = LDAP_MOD_REPLACE; + mod1.sml_flags = 0; mod1.sml_desc = slap_schema.si_ad_objectClass; mod1.sml_type = mod1.sml_desc->ad_cname; mod1.sml_values = &gcbva[0]; @@ -1683,6 +1687,7 @@ syncrepl_del_nonpresent( mod1.sml_next = &mod2; mod2.sml_op = LDAP_MOD_REPLACE; + mod2.sml_flags = 0; mod2.sml_desc = slap_schema.si_ad_structuralObjectClass; mod2.sml_type = mod2.sml_desc->ad_cname; mod2.sml_values = &gcbva[1]; -- 2.39.5