View | Details | Raw Unified | Return to bug 23367 | Differences between
and this patch

Collapse All | Expand All

(-)debian/control (-2 / +3 lines)
 Lines 7-13    Link Here 
7
 ucslint-univention,
7
 ucslint-univention,
8
 libssl-dev,
8
 libssl-dev,
9
 libldap2-dev,
9
 libldap2-dev,
10
 libdb3-dev,
10
 liblmdb-dev,
11
 python-all-dev,
11
 python-all-dev,
12
 libunivention-debug-dev (>= 0.8),
12
 libunivention-debug-dev (>= 0.8),
13
 libunivention-config-dev,
13
 libunivention-config-dev,
 Lines 26-32    Link Here 
26
 univention-runit,
26
 univention-runit,
27
 python2.7-univention,
27
 python2.7-univention,
28
 python2.7-univention-debug,
28
 python2.7-univention-debug,
29
 python-univention-lib (>= 1.0.25-1)
29
 python-univention-lib (>= 1.0.25-1),
30
 lmdb-utils
30
Conflicts: univention-ldap-listener (<< 2.2.2)
31
Conflicts: univention-ldap-listener (<< 2.2.2)
31
Description: UCS - Directory Listener
32
Description: UCS - Directory Listener
32
 UCS Directory Listener is a client for the UCS
33
 UCS Directory Listener is a client for the UCS
(-)debian/rules (-1 / +1 lines)
 Lines 37-43    Link Here 
37
37
38
override_dh_auto_build:
38
override_dh_auto_build:
39
	$(MAKE) -C src clean
39
	$(MAKE) -C src clean
40
	$(MAKE) -C src DB_CFLAGS="-I/usr/include/db3 -DWITH_DB3" DB_LDADD="-ldb3"
40
	$(MAKE) -C src DB_LDADD="-llmdb"
41
	dh_auto_build
41
	dh_auto_build
42
42
43
override_dh_auto_install:
43
override_dh_auto_install:
(-)debian/univention-directory-listener.postinst (+8 lines)
 Lines 45-50    Link Here 
45
	chown listener /var/lib/univention-ldap/listener/listener*
45
	chown listener /var/lib/univention-ldap/listener/listener*
46
fi
46
fi
47
47
48
if [ ! -e /var/lib/univention-directory-listener/cache ]; then
49
	mkdir /var/lib/univention-directory-listener/cache
50
	if [ -f /var/lib/univention-directory-listener/cache.db ]; then
51
		db_dump /var/lib/univention-directory-listener/cache.db | \
52
			mdb_load /var/lib/univention-directory-listener/cache
53
	fi
54
fi
55
48
#DEBHELPER#
56
#DEBHELPER#
49
57
50
univention-config-registry set listener/debug/level?2 \
58
univention-config-registry set listener/debug/level?2 \
(-)src/Makefile (-4 / +3 lines)
 Lines 30-40    Link Here 
30
# <http://www.gnu.org/licenses/>.
30
# <http://www.gnu.org/licenses/>.
31
#
31
#
32
CC=gcc
32
CC=gcc
33
DB_LDADD=-ldb3
33
DB_LDADD=-llmdb
34
DB_CFLAGS=-I/usr/include/db3 -DWITH_DB3
35
DB_OBJS=cache.o cache_entry.o cache_lowlevel.o base64.o filter.o
34
DB_OBJS=cache.o cache_entry.o cache_lowlevel.o base64.o filter.o
36
35
37
CFLAGS=-g -Wall -Werror -D_FILE_OFFSET_BITS=64 $(DB_CFLAGS)
36
CFLAGS=-g -Wall -Werror -D_FILE_OFFSET_BITS=64
38
LDADD=-g -luniventiondebug -licuuc
37
LDADD=-g -luniventiondebug -licuuc
39
LISTENER_LDADD=$(LDADD) -luniventionpolicy -lldap -lpython2.7 $(DB_LDADD)
38
LISTENER_LDADD=$(LDADD) -luniventionpolicy -lldap -lpython2.7 $(DB_LDADD)
40
LISTENER_OBJS=main.o notifier.o transfile.o handlers.o change.o network.o signals.o select_server.o utils.o $(DB_OBJS)
39
LISTENER_OBJS=main.o notifier.o transfile.o handlers.o change.o network.o signals.o select_server.o utils.o $(DB_OBJS)
 Lines 62-65    Link Here 
62
61
63
.PHONY: clean
62
.PHONY: clean
64
clean:
63
clean:
65
	$(RM) *.o listener dump demo verify *.db3 *.db42
64
	$(RM) *.o listener dump demo verify
(-)src/cache.c (-200 / +211 lines)
 Lines 67-73    Link Here 
67
#include <sys/types.h>
67
#include <sys/types.h>
68
#include <sys/file.h>
68
#include <sys/file.h>
69
#include <sys/stat.h>
69
#include <sys/stat.h>
70
#include <db.h>
70
#include <lmdb.h>
71
#include <stdbool.h>
71
#include <stdbool.h>
72
#include <assert.h>
72
#include <assert.h>
73
73
 Lines 91-100    Link Here 
91
91
92
CacheMasterEntry cache_master_entry;
92
CacheMasterEntry cache_master_entry;
93
93
94
DB *dbp;
94
MDB_env *env;
95
#ifdef WITH_DB42
95
MDB_dbi dbi;
96
DB_ENV *dbenvp;
97
#endif
98
static FILE *lock_fp=NULL;
96
static FILE *lock_fp=NULL;
99
97
100
static struct filter cache_filter;
98
static struct filter cache_filter;
 Lines 110-126    Link Here 
110
	}
108
	}
111
}
109
}
112
110
113
#ifdef WITH_DB42
111
static void cache_error_message(int rv, char *msg)
114
static void cache_panic_call(DB_ENV *dbenvp, int errval)
115
{
112
{
116
	exit(1);
117
}
118
#endif
119
120
static void cache_error_message(const char *errpfx, char *msg)
121
{
122
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
113
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
123
			"database error: %s", msg);
114
			"database error: %s: %s (%d)\n",
115
			msg, mdb_strerror(rv), rv);
124
}
116
}
125
117
126
int cache_lock(void)
118
int cache_lock(void)
 Lines 130-136    Link Here 
130
122
131
	assert(!lock_fp);
123
	assert(!lock_fp);
132
124
133
	rv = snprintf(lock_file, PATH_MAX, "%s/cache.db.lock", cache_dir);
125
	rv = snprintf(lock_file, PATH_MAX, "%s/cache.lock", cache_dir);
134
	if (rv < 0 || rv >= PATH_MAX)
126
	if (rv < 0 || rv >= PATH_MAX)
135
		abort();
127
		abort();
136
128
 Lines 156-219    Link Here 
156
{
148
{
157
	int rv;
149
	int rv;
158
	char file[PATH_MAX];
150
	char file[PATH_MAX];
151
	MDB_txn *txn;
159
152
160
	snprintf(file, PATH_MAX, "%s/cache.db", cache_dir);
153
	snprintf(file, PATH_MAX, "%s/cache", cache_dir);
161
154
162
#ifdef WITH_DB42
155
	if ((rv = mdb_env_create(&env)) != 0) {
163
	if ((rv = db_env_create(&dbenvp, 0)) != 0) {
164
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
156
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
165
				"creating database environment failed");
157
				"creating environment handle failed");
158
		cache_error_message(rv, "mdb_env_create");
166
		return rv;
159
		return rv;
167
	}
160
	}
168
	dbenvp->set_errcall(dbenvp, cache_error_message);
161
	if ((rv = mdb_env_open(env, cache_dir, MDB_NORDAHEAD, 0600)) != 0) {
169
	dbenvp->set_paniccall(dbenvp, cache_panic_call);
170
	if ((rv = dbenvp->open(dbenvp, cache_dir, DB_CREATE | DB_INIT_MPOOL |
171
				/*DB_INIT_LOCK | */DB_INIT_LOG | DB_INIT_TXN |
172
				DB_RECOVER, 0600)) != 0) {
173
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
162
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
174
				"opening database environment failed");
163
				"opening database failed");
175
		dbenvp->err(dbenvp, rv, "%s", "environment");
164
		cache_error_message(rv, "mdb_env_open");
176
		return rv;
165
		return rv;
177
	}
166
	}
178
	if ((rv = db_create(&dbp, dbenvp, 0)) != 0) {
167
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
179
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
168
		cache_error_message(rv, "mdb_txn_begin");
180
				"creating database handle failed");
169
		mdb_env_close(env);
181
		return rv;
170
		return rv;
182
	}
171
	}
183
	if ((rv = dbp->open(dbp, NULL, "cache.db", NULL, DB_BTREE,
172
	if ((rv = mdb_open(txn, NULL, 0, &dbi)) != 0) {
184
				DB_CREATE | DB_CHKSUM | DB_AUTO_COMMIT,
173
		cache_error_message(rv, "mdb_open");
185
				0600)) != 0) {
174
		mdb_txn_abort(txn);
186
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
175
		mdb_env_close(env);
187
				"opening database failed");
188
		dbp->err(dbp, rv, "open");
189
		// FIXME: free dbp
190
		return rv;
176
		return rv;
191
	}
177
	}
192
#else
178
	if ((rv = mdb_txn_commit(txn)) != 0) {
193
	if ((rv = db_create(&dbp, NULL, 0)) != 0) {
179
		cache_error_message(rv, "mdb_txn_commit");
194
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
180
		mdb_dbi_close(env, dbi);
195
				"creating database handle failed");
181
		mdb_env_close(env);
196
		return rv;
182
		return rv;
197
	}
183
	}
198
	if ((rv = dbp->open(dbp, file, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) {
184
199
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
200
				"opening database failed");
201
		dbp->err(dbp, rv, "open");
202
		// FIXME: free dbp
203
		return rv;
204
	}
205
	dbp->set_errcall(dbp, cache_error_message);
206
#endif
207
	setup_cache_filter();
185
	setup_cache_filter();
208
	return 0;
186
	return 0;
209
}
187
}
210
188
211
void cache_sync(void) {
212
	if (!INIT_ONLY && dbp) {
213
		dbp->sync(dbp, 0);
214
	}
215
}
216
217
int cache_set_schema_id(const NotifierID value)
189
int cache_set_schema_id(const NotifierID value)
218
{
190
{
219
	int rv, fd, len;
191
	int rv, fd, len;
 Lines 297-379    Link Here 
297
269
298
int cache_get_master_entry(CacheMasterEntry *master_entry)
270
int cache_get_master_entry(CacheMasterEntry *master_entry)
299
{
271
{
300
	DBT key, data;
272
	MDB_txn *txn;
273
	MDB_cursor *cursor;
274
	MDB_val key, data;
301
	int rv;
275
	int rv;
302
276
303
	memset(&key, 0, sizeof(DBT));
277
	memset(&key, 0, sizeof(MDB_val));
304
	memset(&data, 0, sizeof(DBT));
278
	memset(&data, 0, sizeof(MDB_val));
305
279
306
	key.data=MASTER_KEY;
280
	key.mv_data=MASTER_KEY;
307
	key.size=MASTER_KEY_SIZE;
281
	key.mv_size=MASTER_KEY_SIZE;
308
	data.flags = DB_DBT_REALLOC;
309
282
310
	if ((rv=dbp->get(dbp, NULL, &key, &data, 0)) == DB_NOTFOUND)
283
	if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) {
284
		cache_error_message(rv, "mdb_txn_begin");
311
		return rv;
285
		return rv;
286
	}
287
	if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) {
288
		cache_error_message(rv, "mdb_cursor_open");
289
		mdb_txn_abort(txn);
290
		return rv;
291
	}
292
	if ((rv = mdb_cursor_get(cursor, &key, &data, MDB_SET_KEY)) == MDB_NOTFOUND) {
293
		mdb_cursor_close(cursor);
294
		mdb_txn_abort(txn);
295
		return rv;
296
	}
312
	else if (rv != 0) {
297
	else if (rv != 0) {
313
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
298
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
314
				"reading master entry from database failed");
299
				"reading master entry from database failed");
315
		dbp->err(dbp, rv, "get");
300
		cache_error_message(rv, "mdb_get");
301
		mdb_cursor_close(cursor);
302
		mdb_txn_abort(txn);
316
		return rv;
303
		return rv;
317
	}
304
	}
305
	mdb_cursor_close(cursor);
306
	mdb_txn_abort(txn);
318
307
319
	if (data.size != sizeof(CacheMasterEntry)) {
308
	if (data.mv_size != sizeof(CacheMasterEntry)) {
320
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
309
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
321
				"master entry has unexpected length");
310
				"master entry has unexpected length");
322
		return 1;
311
		return 1;
323
	}
312
	}
324
313
325
	memcpy(master_entry, data.data, sizeof(CacheMasterEntry));
314
	memcpy(master_entry, data.mv_data, sizeof(CacheMasterEntry));
326
	free(data.data);
327
315
328
	return 0;
316
	return 0;
329
}
317
}
330
318
331
int cache_update_master_entry(CacheMasterEntry *master_entry, DB_TXN *dbtxnp)
319
/* The dbtxnp argument is only used when WITH_DB42 is defined - useless? */
320
int cache_update_master_entry(CacheMasterEntry *master_entry, MDB_txn *dbtxnp)
332
{
321
{
333
	DBT key, data;
322
	MDB_txn *txn = dbtxnp;
323
	MDB_val key, data;
334
	int rv;
324
	int rv;
335
	int flags;
325
	int flags;
336
326
337
	memset(&key, 0, sizeof(DBT));
327
	memset(&key, 0, sizeof(MDB_val));
338
	memset(&data, 0, sizeof(DBT));
328
	memset(&data, 0, sizeof(MDB_val));
339
329
340
	key.data=MASTER_KEY;
330
	key.mv_data=MASTER_KEY;
341
	key.size=MASTER_KEY_SIZE;
331
	key.mv_size=MASTER_KEY_SIZE;
342
332
343
	data.data=(void*)master_entry;
333
	data.mv_data=(void*)master_entry;
344
	data.size=sizeof(CacheMasterEntry);
334
	data.mv_size=sizeof(CacheMasterEntry);
345
335
346
#ifdef WITH_DB42
336
	flags = 0;
347
	if (dbtxnp == NULL)
348
		flags = DB_AUTO_COMMIT;
349
	else
350
#endif
351
		flags = 0;
352
337
353
	if ((rv=dbp->put(dbp, dbtxnp, &key, &data, flags)) != 0) {
338
	if (!dbtxnp && (rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
339
		cache_error_message(rv, "mdb_txn_begin");
340
		return rv;
341
	}
342
	if ((rv = mdb_put(txn, dbi, &key, &data, flags)) != 0) {
354
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
343
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
355
				"storing master entry in database failed");
344
				"storing master entry in database failed");
356
		dbp->err(dbp, rv, "put");
345
		cache_error_message(rv, "mdb_put");
346
		mdb_txn_abort(txn);
357
		return rv;
347
		return rv;
358
	}
348
	}
349
	if (!dbtxnp && (rv = mdb_txn_commit(txn)) != 0) {
350
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
351
				"storing master entry in database failed");
352
		cache_error_message(rv, "mdb_txn_commit");
353
		return rv;
354
	}
359
355
360
	cache_sync();
361
362
	return 0;
356
	return 0;
363
}
357
}
364
358
365
DB_TXN* cache_new_transaction(NotifierID id, char *dn)
359
MDB_txn *cache_new_transaction(NotifierID id, char *dn)
366
{
360
{
367
#ifdef WITH_DB42
361
#ifdef WITH_DB42
368
	DB_TXN			*dbtxnp;
362
	int rv;
363
	MDB_txn			*txn;
369
	CacheMasterEntry	 master_entry;
364
	CacheMasterEntry	 master_entry;
370
	NotifierID		*old_id;
365
	NotifierID		*old_id;
371
366
372
	dbenvp->txn_begin(dbenvp, NULL, &dbtxnp, 0);
367
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
368
		cache_error_message(rv, "mdb_txn_begin");
369
		return NULL;
370
	}
373
371
374
	if (id != 0) {
372
	if (id != 0) {
375
		if (cache_get_master_entry(&master_entry) != 0) {
373
		if (cache_get_master_entry(&master_entry) != 0) {
376
			dbtxnp->abort(dbtxnp);
374
			mdb_txn_abort(txn);
377
			return NULL;
375
			return NULL;
378
		}
376
		}
379
377
 Lines 386-403    Link Here 
386
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
384
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
387
					"New ID (%ld) is not greater than old"
385
					"New ID (%ld) is not greater than old"
388
					" ID (%ld): %s", id, *old_id, dn);
386
					" ID (%ld): %s", id, *old_id, dn);
389
			dbtxnp->abort(dbtxnp);
387
			mdb_txn_abort(txn);
390
			return NULL;
388
			return NULL;
391
		} else
389
		} else
392
			*old_id = id;
390
			*old_id = id;
393
391
394
		if (cache_update_master_entry(&master_entry, dbtxnp) != 0) {
392
		if (cache_update_master_entry(&master_entry, txn) != 0) {
395
			dbtxnp->abort(dbtxnp);
393
			mdb_txn_abort(txn);
396
			return NULL;
394
			return NULL;
397
		}
395
		}
398
	}
396
	}
399
397
400
	return dbtxnp;
398
	return txn;
401
#else
399
#else
402
	return NULL;
400
	return NULL;
403
#endif
401
#endif
 Lines 410-423    Link Here 
410
   cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */
408
   cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */
411
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry)
409
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry)
412
{
410
{
413
	DBT key, data;
411
	MDB_txn *txn;
414
	DB_TXN *dbtxnp;
412
	MDB_val key, data;
415
	int rv = 0;
413
	int rv = 0;
416
414
417
	memset(&key, 0, sizeof(DBT));
415
	memset(&key, 0, sizeof(MDB_val));
418
	memset(&data, 0, sizeof(DBT));
416
	memset(&data, 0, sizeof(MDB_val));
419
417
420
	if ((rv=unparse_entry(&data.data, &data.size, entry)) != 0) {
418
	if ((rv=unparse_entry(&data.mv_data, &data.mv_size, entry)) != 0) {
421
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
419
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
422
				"unparsing entry failed");
420
				"unparsing entry failed");
423
		return rv;
421
		return rv;
 Lines 426-465    Link Here 
426
424
427
	signals_block();
425
	signals_block();
428
#ifdef WITH_DB42
426
#ifdef WITH_DB42
429
	dbtxnp = cache_new_transaction(id, dn);
427
	txn = cache_new_transaction(id, dn);
430
	if (dbtxnp == NULL) {
428
	if (txn == NULL) {
431
		signals_unblock();
429
		signals_unblock();
432
		free(data.data);
433
		return 1;
430
		return 1;
434
	}
431
	}
435
#else
432
#else
436
	dbtxnp = NULL;
433
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
434
		cache_error_message(rv, "mdb_txn_begin");
435
		signals_unblock();
436
		return rv;
437
	}
437
#endif
438
#endif
438
439
439
	key.data=dn;
440
	key.mv_data=dn;
440
	key.size=strlen(dn)+1;
441
	key.mv_size=strlen(dn)+1;
441
442
442
	if ((rv=dbp->put(dbp, dbtxnp, &key, &data, 0)) != 0) {
443
	if ((rv = mdb_put(txn, dbi, &key, &data, 0)) != 0) {
443
		signals_unblock();
444
		signals_unblock();
444
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
445
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
445
				"storing entry in database failed: %s", dn);
446
				"storing entry in database failed: %s", dn);
446
		dbp->err(dbp, rv, "put");
447
		cache_error_message(rv, "mdb_put");
447
#ifdef WITH_DB42
448
		mdb_txn_abort(txn);
448
		dbtxnp->abort(dbtxnp);
449
#endif
450
		free(data.data);
451
		return rv;
449
		return rv;
452
	}
450
	}
453
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %d bytes for %s", data.size, dn);
451
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %zu bytes for %s", data.mv_size, dn);
454
452
455
453
456
#ifdef WITH_DB42
454
	if ((rv = mdb_txn_commit(txn)) != 0) {
457
	dbtxnp->commit(dbtxnp, 0);
455
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
458
#endif
456
				"storing master entry in database failed");
459
	cache_sync();
457
		cache_error_message(rv, "mdb_txn_commit");
458
		return rv;
459
	}
460
460
	signals_unblock();
461
	signals_unblock();
461
462
462
	free(data.data);
463
	return rv;
463
	return rv;
464
}
464
}
465
465
 Lines 482-518    Link Here 
482
482
483
int cache_delete_entry(NotifierID id, char *dn)
483
int cache_delete_entry(NotifierID id, char *dn)
484
{
484
{
485
	DB_TXN	*dbtxnp;
485
	MDB_txn *txn;
486
	DBT	 key;
486
	MDB_val	 key;
487
	int	 rv;
487
	int	 rv;
488
488
489
	memset(&key, 0, sizeof(DBT));
489
	memset(&key, 0, sizeof(MDB_val));
490
490
491
	key.data=dn;
491
	key.mv_data=dn;
492
	key.size=strlen(dn)+1;
492
	key.mv_size=strlen(dn)+1;
493
493
494
	signals_block();
494
	signals_block();
495
#ifdef WITH_DB42
495
#ifdef WITH_DB42
496
	dbtxnp = cache_new_transaction(id, dn);
496
	txn = cache_new_transaction(id, dn);
497
	if (dbtxnp == NULL) {
497
	if (txn == NULL) {
498
		signals_unblock();
498
		signals_unblock();
499
		return 1;
499
		return 1;
500
	}
500
	}
501
#else
501
#else
502
	dbtxnp = NULL;
502
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
503
		cache_error_message(rv, "mdb_txn_begin");
504
		return rv;
505
	}
503
#endif
506
#endif
504
507
505
	if ((rv=dbp->del(dbp, dbtxnp, &key, 0)) != 0 && rv != DB_NOTFOUND) {
508
	if ((rv = mdb_del(txn, dbi, &key, 0)) != 0 && rv != MDB_NOTFOUND) {
506
		signals_unblock();
509
		signals_unblock();
507
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
510
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
508
				"removing from database failed: %s", dn);
511
				"removing from database failed: %s", dn);
509
		dbp->err(dbp, rv, "del");
512
		cache_error_message(rv, "mdb_del");
513
		mdb_txn_abort(txn);
514
		return rv;
510
	}
515
	}
511
516
512
#ifdef WITH_DB42
517
	if ((rv = mdb_txn_commit(txn)) != 0) {
513
	dbtxnp->commit(dbtxnp, 0);
518
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
514
#endif
519
				"storing master entry in database failed");
515
	cache_sync();
520
		cache_error_message(rv, "mdb_txn_commit");
521
		return rv;
522
	}
516
	signals_unblock();
523
	signals_unblock();
517
524
518
	return rv;
525
	return rv;
 Lines 551-593    Link Here 
551
558
552
int cache_get_entry(char *dn, CacheEntry *entry)
559
int cache_get_entry(char *dn, CacheEntry *entry)
553
{
560
{
554
	DBT key, data;
561
	MDB_txn *txn;
562
	MDB_val key, data;
555
	int rv = 0;
563
	int rv = 0;
556
564
557
	memset(&key, 0, sizeof(DBT));
565
	memset(&key, 0, sizeof(MDB_val));
558
	memset(&data, 0, sizeof(DBT));
566
	memset(&data, 0, sizeof(MDB_val));
559
	memset(entry, 0, sizeof(CacheEntry));
567
	memset(entry, 0, sizeof(CacheEntry));
560
568
561
	key.data=dn;
569
	key.mv_data=dn;
562
	key.size=strlen(dn)+1;
570
	key.mv_size=strlen(dn)+1;
563
	data.flags = DB_DBT_REALLOC;
564
571
572
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
573
		cache_error_message(rv, "mdb_txn_begin");
574
		return rv;
575
	}
565
	signals_block();
576
	signals_block();
566
	rv=dbp->get(dbp, NULL, &key, &data, 0);
577
	rv = mdb_get(txn, dbi, &key, &data);
567
	signals_unblock();
578
	signals_unblock();
579
	mdb_txn_abort(txn);
568
580
569
	if (rv != 0 && rv != DB_NOTFOUND) {
581
	if (rv != 0 && rv != MDB_NOTFOUND) {
570
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
582
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
571
				"reading %s from database failed", dn);
583
				"reading %s from database failed", dn);
572
		dbp->err(dbp, rv, "get");
584
		cache_error_message(rv, "mdb_get");
573
		return rv;
585
		return rv;
574
	} else if (rv == DB_NOTFOUND) {
586
	} else if (rv == MDB_NOTFOUND) {
575
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "no cache entry found for %s",
587
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "no cache entry found for %s",
576
				dn);
588
				dn);
577
		return rv;
589
		return rv;
578
	}
590
	}
579
591
580
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes for %s",
592
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes for %s",
581
			data.size, dn);
593
			data.mv_size, dn);
582
594
583
	if ((rv=parse_entry(data.data, data.size, entry)) != 0) {
595
	if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) {
584
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
596
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
585
				"parsing entry failed");
597
				"parsing entry failed");
586
		free(data.data);
587
		exit(1);
598
		exit(1);
588
	}
599
	}
589
600
590
	free(data.data);
591
	return rv;
601
	return rv;
592
}
602
}
593
603
 Lines 604-610    Link Here 
604
	}
614
	}
605
615
606
	rv = cache_get_entry(lower_dn, entry);
616
	rv = cache_get_entry(lower_dn, entry);
607
	if (rv == DB_NOTFOUND && mixedcase ) {
617
	if (rv == MDB_NOTFOUND && mixedcase ) {
608
		// try again with original dn
618
		// try again with original dn
609
		rv = cache_get_entry(dn, entry);
619
		rv = cache_get_entry(dn, entry);
610
	}
620
	}
 Lines 613-720    Link Here 
613
	return rv;
623
	return rv;
614
}
624
}
615
625
616
int cache_first_entry(DBC **cur, char **dn, CacheEntry *entry)
626
int cache_first_entry(MDB_cursor *cursor, char **dn, CacheEntry *entry)
617
{
627
{
628
	MDB_txn *txn;
618
	int rv;
629
	int rv;
619
630
620
	if ((rv=dbp->cursor(dbp, NULL, cur, 0)) != 0) {
631
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
621
		dbp->err(dbp, rv, "cursor");
632
		cache_error_message(rv, "mdb_txn_begin");
622
		return rv;
633
		return rv;
623
	}
634
	}
635
	if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) {
636
		cache_error_message(rv, "mdb_cursor_open");
637
		mdb_txn_abort(txn);
638
		return rv;
639
	}
624
640
625
	return cache_next_entry(cur, dn, entry);
641
	return cache_next_entry(cursor, dn, entry);
626
}
642
}
627
643
628
int cache_print_entries(char *dn)
644
int cache_print_entries(char *dn)
629
{
645
{
630
	DBT key, data;
646
	MDB_txn *txn;
631
	DBC *cur;
647
	MDB_val key, data;
632
	memset(&key, 0, sizeof(DBT));
648
	MDB_cursor *cursor;
633
	memset(&data, 0, sizeof(DBT));
649
	int rv = 0;
634
	key.data = strdup(dn);
635
	key.size = strlen(dn)+1;
636
	key.flags = DB_DBT_REALLOC;
637
	data.flags = DB_DBT_REALLOC;
638
650
639
	dbp->cursor(dbp, NULL, &cur, 0);
651
	memset(&key, 0, sizeof(MDB_val));
640
	cur->c_get(cur, &key, &data, DB_FIRST);
652
	memset(&data, 0, sizeof(MDB_val));
653
	key.mv_data = strdup(dn);
654
	key.mv_size = strlen(dn)+1;
655
656
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
657
		cache_error_message(rv, "mdb_txn_begin");
658
		return rv;
659
	}
660
	if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) {
661
		cache_error_message(rv, "mdb_cursor_open");
662
		mdb_txn_abort(txn);
663
		return rv;
664
	}
665
	rv = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
641
	do {
666
	do {
642
		printf("%s\n", (char*)key.data);
667
		if (rv != 0) {
643
	} while (cur->c_get(cur, &key, &data, DB_NEXT) == 0);
668
			cache_error_message(rv, "mdb_cursor_get");
669
			mdb_txn_abort(txn);
670
			return rv;
671
		}
672
		printf("%s\n", (char*)key.mv_data);
673
	} while ((rv = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)));
644
674
645
	cur->c_close(cur);
675
	mdb_cursor_close(cursor);
646
	free(key.data);
676
	mdb_txn_abort(txn);
647
	free(data.data);
648
	return 0;
677
	return 0;
649
}
678
}
650
679
651
int cache_next_entry(DBC **cur, char **dn, CacheEntry *entry)
680
int cache_next_entry(MDB_cursor *cursor, char **dn, CacheEntry *entry)
652
{
681
{
653
	DBT key, data;
682
	MDB_val key, data;
654
	int rv;
683
	int rv;
655
684
656
	memset(&key, 0, sizeof(DBT));
685
	memset(&key, 0, sizeof(MDB_val));
657
	key.flags = DB_DBT_REALLOC;
686
	memset(&data, 0, sizeof(MDB_val));
658
	memset(&data, 0, sizeof(DBT));
659
	data.flags = DB_DBT_REALLOC;
660
687
661
	if ((rv=(*cur)->c_get(*cur, &key, &data, DB_NEXT)) == DB_NOTFOUND) {
688
	if ((rv=mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == MDB_NOTFOUND) {
662
		return rv;
689
		return rv;
663
	} else if (rv != 0) {
690
	} else if (rv != 0) {
664
		dbp->err(dbp, rv, "c_get");
691
		cache_error_message(rv, "mdb_cursor_get");
665
		return rv;
692
		return rv;
666
	}
693
	}
667
694
668
	/* skip master entry */
695
	/* skip master entry */
669
	if (strcmp(key.data, MASTER_KEY) == 0) {
696
	if (strcmp(key.mv_data, MASTER_KEY) == 0) {
670
		free(key.data);
697
		return cache_next_entry(cursor, dn, entry);
671
		free(data.data);
672
		return cache_next_entry(cur, dn, entry);
673
	}
698
	}
674
699
675
	if (*dn)
700
	if (*dn)
676
		free(*dn);
701
		free(*dn);
677
	*dn = strdup(key.data);
702
	*dn = strdup(key.mv_data);
678
703
679
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes", data.size);
704
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes", data.mv_size);
680
705
681
	if ((rv=parse_entry(data.data, data.size, entry)) != 0) {
706
	if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) {
682
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
707
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
683
				"parsing entry failed: %s", *dn);
708
				"parsing entry failed: %s", *dn);
684
		printf("%d\n", data.size);
709
		printf("%zu\n", data.mv_size);
685
		free(key.data);
686
		free(data.data);
687
		return rv;
710
		return rv;
688
	}
711
	}
689
712
690
	free(key.data);
691
	free(data.data);
692
693
	return 0;
713
	return 0;
694
}
714
}
695
715
696
int cache_free_cursor(DBC *cur)
716
void cache_free_cursor(MDB_cursor *cursor)
697
{
717
{
698
	return cur->c_close(cur);
718
	mdb_cursor_close(cursor);
719
	mdb_txn_commit(mdb_cursor_txn(cursor));
699
}
720
}
700
721
701
int cache_close(void)
722
void cache_close(void)
702
{
723
{
703
	int rv;
724
	mdb_close(env, dbi);
725
	mdb_env_close(env);
704
726
705
	if (dbp && (rv = dbp->close(dbp, 0)) != 0) {
706
		dbp->err(dbp, rv, "close");
707
	}
708
	dbp = NULL;
709
#ifdef WITH_DB42
710
	if ((rv = dbenvp->close(dbenvp, 0)) != 0) {
711
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
712
				"closing database environment failed");
713
	}
714
#endif
715
	if (lock_fp != NULL) {
727
	if (lock_fp != NULL) {
716
		fclose(lock_fp);
728
		fclose(lock_fp);
717
		lock_fp = NULL;
729
		lock_fp = NULL;
718
	}
730
	}
719
	return rv;
720
}
731
}
(-)src/cache.h (-6 / +6 lines)
 Lines 33-39    Link Here 
33
#ifndef _CACHE_H_
33
#ifndef _CACHE_H_
34
#define _CACHE_H_
34
#define _CACHE_H_
35
35
36
#include <db.h>
36
#include <lmdb.h>
37
37
38
#include "network.h"
38
#include "network.h"
39
#include "cache_entry.h"
39
#include "cache_entry.h"
 Lines 53-59    Link Here 
53
void	cache_sync(void);
53
void	cache_sync(void);
54
int	cache_get_master_entry			(CacheMasterEntry	 *master_entry);
54
int	cache_get_master_entry			(CacheMasterEntry	 *master_entry);
55
int	cache_update_master_entry		(CacheMasterEntry	 *master_entry,
55
int	cache_update_master_entry		(CacheMasterEntry	 *master_entry,
56
						 DB_TXN			 *dptxnp);
56
						 MDB_txn		 *dptxnp);
57
int	cache_update_entry			(NotifierID		  id,
57
int	cache_update_entry			(NotifierID		  id,
58
						 char			 *dn,
58
						 char			 *dn,
59
						 CacheEntry		 *entry);
59
						 CacheEntry		 *entry);
 Lines 73-86    Link Here 
73
int	cache_get_entry_lower_upper(
73
int	cache_get_entry_lower_upper(
74
						 char			 *dn,
74
						 char			 *dn,
75
						 CacheEntry		 *entry);
75
						 CacheEntry		 *entry);
76
int	cache_first_entry			(DBC			**cur,
76
int	cache_first_entry			(MDB_cursor		*cur,
77
						 char			**dn,
77
						 char			**dn,
78
						 CacheEntry		 *entry);
78
						 CacheEntry		 *entry);
79
int	cache_next_entry			(DBC			**cur,
79
int	cache_next_entry			(MDB_cursor		*cur,
80
						 char			**dn,
80
						 char			**dn,
81
						 CacheEntry		 *entry);
81
						 CacheEntry		 *entry);
82
int	cache_free_cursor			(DBC			 *cur);
82
void	cache_free_cursor			(MDB_cursor		 *cur);
83
int	cache_close				(void);
83
void	cache_close				(void);
84
84
85
/* deprecated with DB42*/
85
/* deprecated with DB42*/
86
int	cache_set_int				(char		 *key,
86
int	cache_set_int				(char		 *key,
(-)src/cache_lowlevel.c (-24 / +24 lines)
 Lines 46-57    Link Here 
46
46
47
struct cache_entry_header {
47
struct cache_entry_header {
48
	u_int16_t type;
48
	u_int16_t type;
49
	u_int32_t key_size;
49
	size_t key_size;
50
	u_int32_t data_size;
50
	size_t data_size;
51
};
51
};
52
52
53
53
54
void hex_dump(int level, void *data, u_int32_t start, u_int32_t size)
54
void hex_dump(int level, void *data, size_t start, size_t size)
55
{
55
{
56
	int i;
56
	int i;
57
	int pos;
57
	int pos;
 Lines 68-74    Link Here 
68
		snprintf(str+pos    , 80-pos    , "%c", isprint(((char*)data+start)[i]) ? ((char*)data+start)[i] : '?');
68
		snprintf(str+pos    , 80-pos    , "%c", isprint(((char*)data+start)[i]) ? ((char*)data+start)[i] : '?');
69
		pos+=1;
69
		pos+=1;
70
		if ((i+1) % per_line == 0) {
70
		if ((i+1) % per_line == 0) {
71
			univention_debug(UV_DEBUG_LISTENER, level, "%s| %s (%08d)", hex, str, start+i-per_line);
71
			univention_debug(UV_DEBUG_LISTENER, level, "%s| %s (%08zu)", hex, str, start+i-per_line);
72
			//fprintf(stderr, "%s| %s (%08d)\n", hex, str, start+i-per_line);
72
			//fprintf(stderr, "%s| %s (%08d)\n", hex, str, start+i-per_line);
73
			memset(hex, 0, 80);
73
			memset(hex, 0, 80);
74
			memset(str, 0, 80);
74
			memset(str, 0, 80);
 Lines 80-101    Link Here 
80
}
80
}
81
81
82
/* assumption: enough memory as been allocated for us */
82
/* assumption: enough memory as been allocated for us */
83
static int append_buffer(void **data, u_int32_t *size, u_int32_t *pos, void* blob_data, u_int32_t blob_size)
83
static int append_buffer(void **data, size_t *size, size_t *pos, void* blob_data, size_t blob_size)
84
{
84
{
85
	if (blob_size > 0) {
85
	if (blob_size > 0) {
86
		memcpy((void*)(((char*)*data)+*pos), blob_data, blob_size);
86
		memcpy((void*)(((char*)*data)+*pos), blob_data, blob_size);
87
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "position was=%d is=%d", *pos, *pos+blob_size);
87
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "position was=%zu is=%zu", *pos, *pos+blob_size);
88
		*pos += blob_size;
88
		*pos += blob_size;
89
	}
89
	}
90
	return 0;
90
	return 0;
91
}
91
}
92
92
93
static int write_header(void **data, u_int32_t *size, u_int32_t *pos, u_int16_t type, void* key_data, u_int32_t key_size, void* data_data, u_int32_t data_size)
93
static int write_header(void **data, size_t *size, size_t *pos, u_int16_t type, void* key_data, size_t key_size, void* data_data, size_t data_size)
94
{
94
{
95
	struct cache_entry_header h;
95
	struct cache_entry_header h;
96
	u_int32_t need_memory;
96
	size_t need_memory;
97
97
98
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "write_header key_size=%d data_size=%d", key_size, data_size);
98
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "write_header key_size=%zu data_size=%zu", key_size, data_size);
99
99
100
	need_memory = sizeof(struct cache_entry_header)+key_size+data_size;
100
	need_memory = sizeof(struct cache_entry_header)+key_size+data_size;
101
	if (*size < *pos+need_memory) {
101
	if (*size < *pos+need_memory) {
 Lines 118-124    Link Here 
118
	return 0;
118
	return 0;
119
}
119
}
120
120
121
int unparse_entry(void **data, u_int32_t *size, CacheEntry *entry)
121
int unparse_entry(void **data, size_t *size, CacheEntry *entry)
122
{
122
{
123
	CacheEntryAttribute **attribute;
123
	CacheEntryAttribute **attribute;
124
	char **value;
124
	char **value;
 Lines 125-131    Link Here 
125
	char **module;
125
	char **module;
126
	int *length;
126
	int *length;
127
	int i;
127
	int i;
128
	u_int32_t pos=0;
128
	size_t pos=0;
129
129
130
	for (attribute=entry->attributes; attribute != NULL && *attribute != NULL; attribute++) {
130
	for (attribute=entry->attributes; attribute != NULL && *attribute != NULL; attribute++) {
131
		for (value=(*attribute)->values, i=0, length=(*attribute)->length; *value != NULL; value++, i++) {
131
		for (value=(*attribute)->values, i=0, length=(*attribute)->length; *value != NULL; value++, i++) {
 Lines 146-160    Link Here 
146
	return 0;
146
	return 0;
147
}
147
}
148
148
149
static int read_header(void *data, u_int32_t size, u_int32_t *pos, void **key_data, u_int32_t *key_size, void **data_data, u_int32_t *data_size)
149
static int read_header(void *data, size_t size, size_t *pos, void **key_data, size_t *key_size, void **data_data, size_t *data_size)
150
{
150
{
151
	struct cache_entry_header *h;
151
	struct cache_entry_header *h;
152
152
153
	if (*pos == size) {
153
	if (*pos == size) {
154
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "end of buffer pos=size=%d", *pos);
154
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "end of buffer pos=size=%zu", *pos);
155
		return 0;
155
		return 0;
156
	} else if (*pos+sizeof(struct cache_entry_header) > size) {
156
	} else if (*pos+sizeof(struct cache_entry_header) > size) {
157
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%d size=%d", *pos, size);
157
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%zu size=%zu", *pos, size);
158
		return -1;
158
		return -1;
159
	}
159
	}
160
160
 Lines 161-167    Link Here 
161
	h = (struct cache_entry_header*)((char*)data+*pos);
161
	h = (struct cache_entry_header*)((char*)data+*pos);
162
162
163
	if ((h->type != 1 && h->type != 2) || h->key_size == 0) {
163
	if ((h->type != 1 && h->type != 2) || h->key_size == 0) {
164
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%d type=%d key_size=%d data_size=%d", *pos, h->type, h->key_size, h->data_size);
164
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%zu type=%d key_size=%zu data_size=%zu", *pos, h->type, h->key_size, h->data_size);
165
		*key_size = 0;
165
		*key_size = 0;
166
		*key_data = NULL;
166
		*key_data = NULL;
167
		*data_size = 0;
167
		*data_size = 0;
 Lines 170-176    Link Here 
170
	}
170
	}
171
	*pos += sizeof(struct cache_entry_header);
171
	*pos += sizeof(struct cache_entry_header);
172
	if (*pos+h->key_size+h->data_size > size) {
172
	if (*pos+h->key_size+h->data_size > size) {
173
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%d size=%d", *pos, size);
173
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%zu size=%zu", *pos, size);
174
		return -1;
174
		return -1;
175
	}
175
	}
176
176
 Lines 186-202    Link Here 
186
		*data_size = 0;
186
		*data_size = 0;
187
		*data_data = NULL;
187
		*data_data = NULL;
188
	}
188
	}
189
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%d type=%d key_size=%d data_size=%d key_data=[%s] data_data=[%s]", *pos, h->type, h->key_size, h->data_size, (char*)*key_data, (char*)*data_data);
189
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%zu type=%d key_size=%zu data_size=%zu key_data=[%s] data_data=[%s]", *pos, h->type, h->key_size, h->data_size, (char*)*key_data, (char*)*data_data);
190
190
191
	return h->type;
191
	return h->type;
192
}
192
}
193
193
194
int parse_entry(void *data, u_int32_t size, CacheEntry *entry)
194
int parse_entry(void *data, size_t size, CacheEntry *entry)
195
{
195
{
196
	u_int16_t type;
196
	u_int16_t type;
197
	void *key_data, *data_data;
197
	void *key_data, *data_data;
198
	u_int32_t key_size, data_size;
198
	size_t key_size, data_size;
199
	u_int32_t pos=0;
199
	size_t pos=0;
200
200
201
	entry->attributes=NULL;
201
	entry->attributes=NULL;
202
	entry->attribute_count=0;
202
	entry->attribute_count=0;
 Lines 265-279    Link Here 
265
		} else {
265
		} else {
266
			char filename[PATH_MAX];
266
			char filename[PATH_MAX];
267
			FILE *file;
267
			FILE *file;
268
			u_int32_t len;
268
			size_t len;
269
			int rv;
269
			int rv;
270
270
271
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "bad data block at position %d:", pos);
271
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "bad data block at position %zu:", pos);
272
			len = pos < 1000 ? pos : 1000;
272
			len = pos < 1000 ? pos : 1000;
273
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "last %d bytes of previous entry:", len);
273
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "last %zu bytes of previous entry:", len);
274
			hex_dump(UV_DEBUG_ERROR, data, pos < 1000 ? 0 : pos-1000, len);
274
			hex_dump(UV_DEBUG_ERROR, data, pos < 1000 ? 0 : pos-1000, len);
275
			len = pos + 1000 > size ? size-pos : 1000;
275
			len = pos + 1000 > size ? size-pos : 1000;
276
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "first %d bytes of current entry:", len);
276
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "first %zu bytes of current entry:", len);
277
			hex_dump(UV_DEBUG_ERROR, data, pos, len);
277
			hex_dump(UV_DEBUG_ERROR, data, pos, len);
278
278
279
			rv = snprintf(filename, PATH_MAX, "%s/bad_cache", cache_dir);
279
			rv = snprintf(filename, PATH_MAX, "%s/bad_cache", cache_dir);
(-)src/cache_lowlevel.h (-3 / +3 lines)
 Lines 36-46    Link Here 
36
#include "cache.h"
36
#include "cache.h"
37
37
38
int	unparse_entry	(void		**data,
38
int	unparse_entry	(void		**data,
39
			 u_int32_t	 *size,
39
			 size_t		 *size,
40
			 CacheEntry	 *entry);
40
			 CacheEntry	 *entry);
41
int	parse_entry	(void		 *data,
41
int	parse_entry	(void		 *data,
42
			 u_int32_t	  size,
42
			 size_t		  size,
43
			 CacheEntry	 *entry);
43
			 CacheEntry	 *entry);
44
void hex_dump(int level, void *data, u_int32_t start, u_int32_t size);
44
void hex_dump(int level, void *data, size_t start, size_t size);
45
45
46
#endif /* _CACHE_LOWLEVEL_ */
46
#endif /* _CACHE_LOWLEVEL_ */
(-)src/change.c (-10 / +9 lines)
 Lines 40-46    Link Here 
40
#include <stdlib.h>
40
#include <stdlib.h>
41
#include <stdbool.h>
41
#include <stdbool.h>
42
#include <string.h>
42
#include <string.h>
43
#include <db.h>
43
#include <lmdb.h>
44
44
45
#include <univention/debug.h>
45
#include <univention/debug.h>
46
#include <univention/config.h>
46
#include <univention/config.h>
 Lines 74-80    Link Here 
74
	struct filter **f;
74
	struct filter **f;
75
	int rv;
75
	int rv;
76
	CacheEntry cache_entry, old_cache_entry;
76
	CacheEntry cache_entry, old_cache_entry;
77
	DBC *dbc_cur;
77
	MDB_cursor *dbc_cur = NULL;
78
	char *dn = NULL;
78
	char *dn = NULL;
79
	int i;
79
	int i;
80
	bool abort_init = false;
80
	bool abort_init = false;
 Lines 93-100    Link Here 
93
	/* remove old entries for module */
93
	/* remove old entries for module */
94
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO,
94
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO,
95
			"remove old entries for module %s", handler->name);
95
			"remove old entries for module %s", handler->name);
96
	for (rv=cache_first_entry(&dbc_cur, &dn, &cache_entry); rv != DB_NOTFOUND;
96
	for (rv=cache_first_entry(dbc_cur, &dn, &cache_entry); rv != MDB_NOTFOUND;
97
			rv=cache_next_entry(&dbc_cur, &dn, &cache_entry)) {
97
			rv=cache_next_entry(dbc_cur, &dn, &cache_entry)) {
98
		if (rv == -1) continue;
98
		if (rv == -1) continue;
99
		if (rv < 0) break;
99
		if (rv < 0) break;
100
100
 Lines 112-118    Link Here 
112
	/* initialize schema; if it's not in cache yet (it really should be), it'll
112
	/* initialize schema; if it's not in cache yet (it really should be), it'll
113
	   be initialized on the regular schema check after ldapsearches */
113
	   be initialized on the regular schema check after ldapsearches */
114
	if ((rv = cache_get_entry_lower_upper("cn=Subschema", &cache_entry)) != 0 &&
114
	if ((rv = cache_get_entry_lower_upper("cn=Subschema", &cache_entry)) != 0 &&
115
			rv != DB_NOTFOUND) {
115
			rv != MDB_NOTFOUND) {
116
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN,
116
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN,
117
				"error while reading from database");
117
				"error while reading from database");
118
		return LDAP_OTHER;
118
		return LDAP_OTHER;
 Lines 183-189    Link Here 
183
		for (i=0; i<dn_count; i++) {
183
		for (i=0; i<dn_count; i++) {
184
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "DN: %s", dns[i].dn);
184
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "DN: %s", dns[i].dn);
185
185
186
			if ((rv = cache_get_entry_lower_upper(dns[i].dn, &cache_entry)) == DB_NOTFOUND) { /* XXX */
186
			if ((rv = cache_get_entry_lower_upper(dns[i].dn, &cache_entry)) == MDB_NOTFOUND) { /* XXX */
187
				LDAPMessage *res2, *first;
187
				LDAPMessage *res2, *first;
188
				int attrsonly0 = 0;
188
				int attrsonly0 = 0;
189
				rv = LDAP_RETRY(lp, ldap_search_ext_s(lp->ld, dns[i].dn, LDAP_SCOPE_BASE, "(objectClass=*)", attrs, attrsonly0, serverctrls, clientctrls, &timeout, sizelimit0, &res2));
189
				rv = LDAP_RETRY(lp, ldap_search_ext_s(lp->ld, dns[i].dn, LDAP_SCOPE_BASE, "(objectClass=*)", attrs, attrsonly0, serverctrls, clientctrls, &timeout, sizelimit0, &res2));
 Lines 243-249    Link Here 
243
		}
243
		}
244
	}
244
	}
245
	INIT_ONLY = old_init_only;
245
	INIT_ONLY = old_init_only;
246
	cache_sync();
247
246
248
	return 0;
247
	return 0;
249
}
248
}
 Lines 264-270    Link Here 
264
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while converting LDAP entry to cache entry");
263
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while converting LDAP entry to cache entry");
265
		goto result;
264
		goto result;
266
	}
265
	}
267
	if ((rv = cache_get_entry_lower_upper(dn, &old_cache_entry)) != 0 && rv != DB_NOTFOUND) {
266
	if ((rv = cache_get_entry_lower_upper(dn, &old_cache_entry)) != 0 && rv != MDB_NOTFOUND) {
268
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while reading from database");
267
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while reading from database");
269
		rv = LDAP_OTHER;
268
		rv = LDAP_OTHER;
270
	} else {
269
	} else {
 Lines 290-296    Link Here 
290
	CacheEntry entry;
289
	CacheEntry entry;
291
	int rv;
290
	int rv;
292
291
293
	if ((rv = cache_get_entry_lower_upper(dn, &entry)) == DB_NOTFOUND) {
292
	if ((rv = cache_get_entry_lower_upper(dn, &entry)) == MDB_NOTFOUND) {
294
		signals_block();
293
		signals_block();
295
		/* run handlers anyway */
294
		/* run handlers anyway */
296
		if (handlers_delete(dn, &entry, command) == 0) {
295
		if (handlers_delete(dn, &entry, command) == 0) {
 Lines 703-709    Link Here 
703
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "updating '%s' command %c", trans->cur.notify.dn, trans->cur.notify.command);
702
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "updating '%s' command %c", trans->cur.notify.dn, trans->cur.notify.command);
704
703
705
	rv = cache_get_entry_lower_upper(trans->cur.notify.dn, &trans->cur.cache);
704
	rv = cache_get_entry_lower_upper(trans->cur.notify.dn, &trans->cur.cache);
706
	if (rv != 0 && rv != DB_NOTFOUND) {
705
	if (rv != 0 && rv != MDB_NOTFOUND) {
707
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error reading database for %s", trans->cur.notify.dn);
706
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error reading database for %s", trans->cur.notify.dn);
708
		return LDAP_OTHER;
707
		return LDAP_OTHER;
709
	}
708
	}
(-)src/dump.c (-3 / +3 lines)
 Lines 67-73    Link Here 
67
	char *output_file = NULL;
67
	char *output_file = NULL;
68
	FILE *fp;
68
	FILE *fp;
69
	int rv;
69
	int rv;
70
	DBC *cur;
70
	MDB_cursor *cur = NULL;
71
	char *dn = NULL;
71
	char *dn = NULL;
72
	CacheEntry entry;
72
	CacheEntry entry;
73
73
 Lines 136-143    Link Here 
136
		printf("%ld %ld\n", cache_master_entry.id, cache_master_entry.schema_id);
136
		printf("%ld %ld\n", cache_master_entry.id, cache_master_entry.schema_id);
137
	} else {
137
	} else {
138
138
139
	for (rv=cache_first_entry(&cur, &dn, &entry); rv != DB_NOTFOUND;
139
	for (rv=cache_first_entry(cur, &dn, &entry); rv != MDB_NOTFOUND;
140
			rv=cache_next_entry(&cur, &dn, &entry)) {
140
			rv=cache_next_entry(cur, &dn, &entry)) {
141
		if ((rv == 0 && !broken_only) || (rv == -1 && broken_only)) {
141
		if ((rv == 0 && !broken_only) || (rv == -1 && broken_only)) {
142
			cache_dump_entry(dn, &entry, fp);
142
			cache_dump_entry(dn, &entry, fp);
143
			fprintf(fp, "\n");
143
			fprintf(fp, "\n");
(-)src/main.c (-1 / +1 lines)
 Lines 594-600    Link Here 
594
594
595
	/* if no ID is set, assume the database has just been initialized */
595
	/* if no ID is set, assume the database has just been initialized */
596
	rv = cache_get_master_entry(&cache_master_entry);
596
	rv = cache_get_master_entry(&cache_master_entry);
597
	if (rv == DB_NOTFOUND) {
597
	if (rv == MDB_NOTFOUND) {
598
		cache_get_int("notifier_id", &cache_master_entry.id, -1);
598
		cache_get_int("notifier_id", &cache_master_entry.id, -1);
599
		if (cache_master_entry.id == -1) {
599
		if (cache_master_entry.id == -1) {
600
			rv = notifier_get_id_s(NULL, &cache_master_entry.id);
600
			rv = notifier_get_id_s(NULL, &cache_master_entry.id);
(-)src/verify.c (-4 / +4 lines)
 Lines 140-146    Link Here 
140
	char		*bindpw = NULL;
140
	char		*bindpw = NULL;
141
	char		*basedn = NULL;
141
	char		*basedn = NULL;
142
	int		 rv;
142
	int		 rv;
143
	DBC		*cur;
143
	MDB_cursor	*cur = NULL;
144
	char		*dn;
144
	char		*dn;
145
	CacheEntry	 entry;
145
	CacheEntry	 entry;
146
	LDAP		*ld;
146
	LDAP		*ld;
 Lines 227-234    Link Here 
227
	if (cache_init() != 0)
227
	if (cache_init() != 0)
228
		exit(1);
228
		exit(1);
229
229
230
	for (rv=cache_first_entry(&cur, &dn, &entry); rv != DB_NOTFOUND;
230
	for (rv=cache_first_entry(cur, &dn, &entry); rv != MDB_NOTFOUND;
231
			rv=cache_next_entry(&cur, &dn, &entry)) {
231
			rv=cache_next_entry(cur, &dn, &entry)) {
232
		if (rv < -1) break;
232
		if (rv < -1) break;
233
233
234
		if (has_dn(dn)) {
234
		if (has_dn(dn)) {
 Lines 261-267    Link Here 
261
			char *dn = ldap_get_dn(ld, cur);
261
			char *dn = ldap_get_dn(ld, cur);
262
			if (has_dn(dn)) continue;
262
			if (has_dn(dn)) continue;
263
263
264
			if ((rv = cache_get_entry(dn, &entry)) == DB_NOTFOUND) {
264
			if ((rv = cache_get_entry(dn, &entry)) == MDB_NOTFOUND) {
265
				printf("E: %s only in LDAP\n", dn);
265
				printf("E: %s only in LDAP\n", dn);
266
			} else if (rv != 0) {
266
			} else if (rv != 0) {
267
				printf("E: error reading %s from cache", dn);
267
				printf("E: error reading %s from cache", dn);

Return to bug 23367