Index: debian/control =================================================================== --- debian/control (Revision 26197) +++ debian/control (Arbeitskopie) @@ -2,7 +2,7 @@ Section: univention Maintainer: Univention GmbH Standards-Version: 3.5.5 -Build-Depends: debhelper (>>7), ucslint, libssl-dev, libldap2-dev, libdb4.8-dev, python2.6-dev, libunivention-debug-dev (>= 0.8), libunivention-config-dev, libunivention-policy-dev, univention-config-dev, libunivention-policy-dev +Build-Depends: debhelper (>>7), ucslint, libssl-dev, libldap2-dev, libdb3-dev, python2.6-dev, libunivention-debug-dev (>= 0.8), libunivention-config-dev, libunivention-policy-dev, univention-config-dev, libunivention-policy-dev Package: univention-directory-listener Architecture: any Index: debian/rules =================================================================== --- debian/rules (Revision 26197) +++ debian/rules (Arbeitskopie) @@ -50,7 +50,7 @@ dh_installinit -a --no-start -r -u"defaults 50" override_dh_auto_build: - cd src; $(MAKE) clean; $(MAKE) DB_CFLAGS="-I/usr/include/db -DWITH_DB48" DB_LDADD="-ldb-4.8"; cd - + cd src; $(MAKE) clean; $(MAKE) DB_CFLAGS="-I/usr/include/db3 -DWITH_DB3" DB_LDADD="-ldb3"; cd - dh_auto_build override_dh_auto_test: Index: src/notifier.c =================================================================== --- src/notifier.c (Revision 26197) +++ src/notifier.c (Arbeitskopie) @@ -100,15 +100,28 @@ int notifier_listen(univention_ldap_parameters_t *lp, univention_krb5_parameters_t *kp, int write_transaction_file, - univention_ldap_parameters_t *lp_local, CacheMasterEntry master_entry) + univention_ldap_parameters_t *lp_local) { + NotifierID id; + +#ifndef WITH_DB42 + /* we should only get here, if the cache has previously been + initialized; thus, *some* ID should've been stored in the + cache */ + cache_get_int("notifier_id", &id, -1); + if ((long)id == -1) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "failed to get last transaction ID from cache; possibly, it hasn't been initialized yet"); + return 1; + } +#endif + for (;;) { NotifierEntry entry; int msgid; time_t timeout = DELAY_LDAP_CLOSE; int rv; - if ((msgid = notifier_get_dn(NULL, master_entry.id+1)) < 1) + if ((msgid = notifier_get_dn(NULL, id+1)) < 1) break; /* wait for data; on timeouts, do maintainance stuff @@ -122,7 +135,7 @@ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "failed to get alive answer"); return 1; } - notifier_resend_get_dn(NULL, msgid, master_entry.id+1); + notifier_resend_get_dn(NULL, msgid, id+1); } else { if (lp->ld != NULL) { ldap_unbind_ext(lp->ld, NULL, NULL); @@ -151,8 +164,8 @@ } univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "notifier returned = id: %ld\tdn: %s\tcmd: %c", entry.id, entry.dn, entry.command); - if (entry.id != master_entry.id+1) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "notifier returned transaction id %ld (%ld expected)", entry.id, master_entry.id+1); + if (entry.id != id+1) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "notifier returned transaction id %ld (%ld expected)", entry.id, id+1); notifier_entry_free(&entry); return 1; } @@ -191,8 +204,10 @@ break; } - master_entry.id = entry.id; - + id = entry.id; +#ifndef WITH_DB42 + cache_set_int("notifier_id", id); +#endif notifier_entry_free(&entry); } Index: src/notifier.h =================================================================== --- src/notifier.h (Revision 26197) +++ src/notifier.h (Arbeitskopie) @@ -39,12 +39,10 @@ #else typedef void univention_krb5_parameters_t; #endif -#include "cache.h" int notifier_listen (univention_ldap_parameters_t *lp, univention_krb5_parameters_t *kp, int write_transaction_file, - univention_ldap_parameters_t *lp_local, - CacheMasterEntry master_entry); + univention_ldap_parameters_t *lp_local); #endif /* _NOTIFIER_H_ */ Index: src/cache_entry.c =================================================================== --- src/cache_entry.c (Revision 26197) +++ src/cache_entry.c (Arbeitskopie) @@ -2,7 +2,7 @@ * Univention Directory Listener * entries in the cache * - * Copyright 2004-2011 Univention GmbH + * Copyright 2004-2010 Univention GmbH * * http://www.univention.de/ * @@ -78,7 +78,7 @@ { CacheEntryAttribute **attribute; char **module; - unsigned char **value; + char **value; fprintf(fp, "dn: %s\n", dn); for (attribute=entry->attributes; attribute != NULL && *attribute != NULL; attribute++) { Index: src/change.c =================================================================== --- src/change.c (Revision 26197) +++ src/change.c (Arbeitskopie) @@ -295,7 +295,11 @@ /* Make sure schema is up-to-date */ int change_update_schema(univention_ldap_parameters_t *lp) { +#ifdef WITH_DB42 CacheMasterEntry master_entry; +#else + NotifierID id = 0; +#endif NotifierID new_id = 0; LDAPMessage *res, *cur; @@ -316,17 +320,25 @@ timeout.tv_sec = 300; timeout.tv_usec = 0; +#ifdef WITH_DB42 if ((rv=cache_get_master_entry(&master_entry)) == DB_NOTFOUND) { master_entry.id = 0; master_entry.schema_id = 0; } else if (rv != 0) return rv; +#else + cache_get_schema_id("notifier_schema_id", &id, 0); +#endif if ((notifier_get_schema_id_s(NULL, &new_id)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "failed to get schema DN"); return LDAP_OTHER; } +#ifdef WITH_DB42 if (new_id > master_entry.schema_id) { +#else + if (new_id > id) { +#endif if ((rv=ldap_search_ext_s(lp->ld, "cn=Subschema", LDAP_SCOPE_BASE, "(objectClass=*)", attrs, 0, NULL /*serverctrls*/, NULL /*clientctrls*/, &timeout, 0 /*sizelimit*/, &res)) == LDAP_SUCCESS) { if ((cur=ldap_first_entry(lp->ld, res)) == NULL) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "got no entry for schema"); @@ -339,6 +351,10 @@ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "could not receive schema (%s)", ldap_err2string(rv)); } +#ifndef WITH_DB42 + if (rv == 0) + cache_set_schema_id("notifier_schema_id", new_id); +#endif } return rv; Index: src/Makefile =================================================================== --- src/Makefile (Revision 26197) +++ src/Makefile (Arbeitskopie) @@ -30,8 +30,8 @@ # . # CC=gcc -DB_LDADD=-ldb-4.8 -DB_CFLAGS=-I/usr/include/db -DWITH_DB48 +DB_LDADD=-ldb3 +DB_CFLAGS=-I/usr/include/db3 -DWITH_DB3 DB_OBJS=cache.o cache_entry.o cache_lowlevel.o base64.o CFLAGS=-g -Wall -D_FILE_OFFSET_BITS=64 $(DB_CFLAGS) Index: src/cache.c =================================================================== --- src/cache.c (Revision 26197) +++ src/cache.c (Arbeitskopie) @@ -88,13 +88,17 @@ DB *dbp; DBC *dbc_cur = NULL; +#ifdef WITH_DB42 DB_ENV *dbenvp; +#endif static FILE *lock_fp=NULL; +#ifdef WITH_DB42 static void cache_panic_call(DB_ENV *dbenvp, int errval) { exit(1); } +#endif char* _convert_to_lower(char *dn) { @@ -112,7 +116,7 @@ return lower_dn; } -static void cache_error_message(const DB_ENV *dbenvp, const char *errpfx, const char *msg) +static void cache_error_message(const char *errpfx, char *msg) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "database error: %s", msg); @@ -142,6 +146,7 @@ } lockf(fileno(lock_fp), F_LOCK, 0); +#ifdef WITH_DB42 if ((rv = db_env_create(&dbenvp, 0)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "creating database environment failed"); @@ -171,6 +176,21 @@ // FIXME: free dbp return rv; } +#else + if ((rv = db_create(&dbp, NULL, 0)) != 0) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "creating database handle failed"); + return rv; + } + if ((rv = dbp->open(dbp, file, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "opening database failed"); + dbp->err(dbp, rv, "open"); + // FIXME: free dbp + return rv; + } + dbp->set_errcall(dbp, cache_error_message); +#endif return 0; } @@ -229,6 +249,7 @@ return fclose(fp); } +#ifdef WITH_DB42 int cache_get_master_entry(CacheMasterEntry *master_entry) { DBT key, data; @@ -277,9 +298,11 @@ data.data=(void*)master_entry; data.size=sizeof(CacheMasterEntry); +#ifdef WITH_DB42 if (dbtxnp == NULL) flags = DB_AUTO_COMMIT; else +#endif flags = 0; if ((rv=dbp->put(dbp, dbtxnp, &key, &data, flags)) != 0) { @@ -295,9 +318,11 @@ return 0; } +#endif DB_TXN* cache_new_transaction(NotifierID id, char *dn) { +#ifdef WITH_DB42 DB_TXN *dbtxnp; CacheMasterEntry master_entry; NotifierID *old_id; @@ -315,30 +340,32 @@ else old_id = &master_entry.id; - if (*old_id > id) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "New ID (%ld) is lower than old ID (%ld): %s", id, *old_id, dn); + if (*old_id >= id) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "New ID (%ld) is not greater than old" + " ID (%ld): %s", id, *old_id, dn); dbtxnp->abort(dbtxnp); return NULL; - } else if ( *old_id < id ) { + } else *old_id = id; - - if (cache_update_master_entry(&master_entry, dbtxnp) != 0) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "cache_new_transaction: cache_update_master_entry failed"); - dbtxnp->abort(dbtxnp); - return NULL; - } + if (cache_update_master_entry(&master_entry, dbtxnp) != 0) { + dbtxnp->abort(dbtxnp); + return NULL; } } return dbtxnp; +#else + return NULL; +#endif } /* XXX: The NotifierID is passed for future use. Once the journal is implemented, entries other than the most recent one can be returned. At the moment, the id parameters for cache_update_entry, and - cache_delete_entry do nothing (at least if WITH_DB48 is undefined) */ + cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */ inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry) { DBT key, data; @@ -357,12 +384,16 @@ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %d bytes", data.size); signals_block(); +#ifdef WITH_DB42 dbtxnp = cache_new_transaction(id, dn); if (dbtxnp == NULL) { signals_unblock(); free(data.data); return 1; } +#else + dbtxnp = NULL; +#endif key.data=dn; key.size=strlen(dn)+1; @@ -372,12 +403,16 @@ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "storing entry in database failed: %s", dn); dbp->err(dbp, rv, "put"); +#ifdef WITH_DB42 dbtxnp->abort(dbtxnp); +#endif free(data.data); return rv; } +#ifdef WITH_DB42 dbtxnp->commit(dbtxnp, 0); +#endif if ( !INIT_ONLY ) { dbp->sync(dbp, 0); } @@ -411,11 +446,15 @@ key.size=strlen(dn)+1; signals_block(); +#ifdef WITH_DB42 dbtxnp = cache_new_transaction(id, dn); if (dbtxnp == NULL) { signals_unblock(); return 1; } +#else + dbtxnp = NULL; +#endif if ((rv=dbp->del(dbp, dbtxnp, &key, 0)) != 0 && rv != DB_NOTFOUND) { signals_unblock(); @@ -424,7 +463,9 @@ dbp->err(dbp, rv, "del"); } +#ifdef WITH_DB42 dbtxnp->commit(dbtxnp, 0); +#endif if ( !INIT_ONLY ) { dbp->sync(dbp, 0); } @@ -622,10 +663,12 @@ if ((rv = dbp->close(dbp, 0)) != 0) { dbp->err(dbp, rv, "close"); } +#ifdef WITH_DB42 if ((rv = dbenvp->close(dbenvp, 0)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "closing database environment failed"); } +#endif if (lock_fp != NULL) { int rc=lockf(fileno(lock_fp), F_ULOCK, 0); if (rc == 0) { Index: src/dump.c =================================================================== --- src/dump.c (Revision 26197) +++ src/dump.c (Arbeitskopie) @@ -63,7 +63,7 @@ int main(int argc, char* argv[]) { - int debugging = 0, broken_only = 0; + int debugging = 0, broken_only = 0, id_only = 0; char *output_file = NULL; FILE *fp; int rv; @@ -94,6 +94,11 @@ case 'r': broken_only=1; break; +#ifdef WITH_DB42 + case 'i': + id_only=1; + break; +#endif default: usage(); exit(1); @@ -127,7 +132,21 @@ if (cache_init() != 0) exit(1); +#ifdef WITH_DB42 + if (id_only) { + + CacheMasterEntry master_entry; + cache_get_master_entry(&master_entry); + + printf("%ld %ld\n", master_entry.id, master_entry.schema_id); + } else { + + cache_print_entries("uid=b95152,cn=users,dc=olb,dc=de"); + + exit(0); +#endif + for (rv=cache_first_entry(&cur, &dn, &entry); rv != DB_NOTFOUND; rv=cache_next_entry(&cur, &dn, &entry)) { if ((rv == 0 && !broken_only) || (rv == -1 && broken_only)) { @@ -139,6 +158,10 @@ } cache_free_cursor(cur); +#ifdef WITH_DB42 + } +#endif + cache_close(); return 0; Index: src/cache.h =================================================================== --- src/cache.h (Revision 26197) +++ src/cache.h (Arbeitskopie) @@ -40,16 +40,19 @@ #include -int cache_init (void); - -typedef struct _CacheMasterEntry { +#ifdef WITH_DB42 +struct _CacheMasterEntry { NotifierID id; NotifierID schema_id; } CacheMasterEntry; +#endif -int cache_get_master_entry (CacheMasterEntry *master_entry); -int cache_update_master_entry (CacheMasterEntry *master_entry, DB_TXN *dptxnp); - +int cache_init (void); +#ifdef WITH_DB42 +int cache_get_master_entry (CacheMasterEntry *master_entry); +int cache_update_master_entry (CacheMasterEntry *master_entry, + DB_TXN *dptxnp); +#endif int cache_update_entry (NotifierID id, char *dn, CacheEntry *entry); Index: src/main.c =================================================================== --- src/main.c (Revision 26197) +++ src/main.c (Arbeitskopie) @@ -178,6 +178,29 @@ static void convert_cookie(void) { +#ifndef WITH_DB42 + char *f; + struct stat stbuf; + + asprintf(&f, "%s/notifier_id", cache_dir); + if (stat(f, &stbuf) != 0) { + free(f); + asprintf(&f, "%s/cookie", cache_dir); + FILE *fp = fopen(f, "r"); + if (fp != NULL) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "converting cookie file"); + char buf[1024]; + int i; + fgets(buf, 1024, fp); + fgets(buf, 1024, fp); + i = atoi(buf); + if (i > 0) + cache_set_int("notifier_id", i); + fclose(fp); + } + } + free(f); +#else char *filename; FILE *fp; CacheMasterEntry master_entry; @@ -214,9 +237,11 @@ fclose(fp); } else master_entry.schema_id = 0; + free(filename); if ((rv=cache_update_master_entry(&master_entry, NULL)) != 0) exit(1); /* XXX */ +#endif } void purge_cache(const char *cache_dir) @@ -306,7 +331,11 @@ write_transaction_file = 0; int rv; NotifierID id = -1; +#ifndef WITH_DB42 + NotifierID old_id = -1; +#else CacheMasterEntry master_entry; +#endif struct stat stbuf; if (stat("/var/lib/univention-directory-listener/bad_cache", &stbuf) == 0) { @@ -538,6 +567,7 @@ signals_unblock(); /* if no ID is set, assume the database has just been initialized */ +#ifdef WITH_DB42 if ((rv=cache_get_master_entry(&master_entry)) == DB_NOTFOUND) { master_entry.id = id; if ((rv=cache_update_master_entry(&master_entry, NULL)) != 0) @@ -545,9 +575,15 @@ } else if (rv != 0) exit(1); +#else + cache_get_int("notifier_id", &old_id, -1); + if ((long)old_id == -1) { + cache_set_int("notifier_id", id); + } +#endif if (!initialize_only) { - rv=notifier_listen(lp, kp, write_transaction_file, lp_local, master_entry); + rv=notifier_listen(lp, kp, write_transaction_file, lp_local); } if (rv != 0)