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 (-197 / +258 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);
113
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
114
			"database error: %s: %s (%d)\n",
115
			msg, mdb_strerror(rv), rv);
117
}
116
}
118
#endif
119
117
120
static void cache_error_message(const char *errpfx, char *msg)
118
int mdb_message_func(const char *msg, void *ctx) {
121
{
119
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO,
122
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
120
			"%s\n", msg);
123
			"database error: %s", msg);
121
	return 0;
124
}
122
}
125
123
126
int cache_lock(void)
124
int cache_lock(void)
 Lines 130-136    Link Here 
130
128
131
	assert(!lock_fp);
129
	assert(!lock_fp);
132
130
133
	rv = snprintf(lock_file, PATH_MAX, "%s/cache.db.lock", cache_dir);
131
	rv = snprintf(lock_file, PATH_MAX, "%s/cache.lock", cache_dir);
134
	if (rv < 0 || rv >= PATH_MAX)
132
	if (rv < 0 || rv >= PATH_MAX)
135
		abort();
133
		abort();
136
134
 Lines 155-219    Link Here 
155
int cache_init(void)
153
int cache_init(void)
156
{
154
{
157
	int rv;
155
	int rv;
158
	char file[PATH_MAX];
156
	char mdb_dir[PATH_MAX];
157
	MDB_txn *txn;
159
158
160
	snprintf(file, PATH_MAX, "%s/cache.db", cache_dir);
159
	snprintf(mdb_dir, PATH_MAX, "%s/cache", cache_dir);
161
160
162
#ifdef WITH_DB42
161
	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,
162
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
165
				"creating database environment failed");
163
				"creating environment handle failed");
164
		cache_error_message(rv, "mdb_env_create");
166
		return rv;
165
		return rv;
167
	}
166
	}
168
	dbenvp->set_errcall(dbenvp, cache_error_message);
167
	if ((rv = mdb_env_set_mapsize(env, 1992294400)) != 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,
168
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
174
				"opening database environment failed");
169
				"setting mdb mapsize failed");
175
		dbenvp->err(dbenvp, rv, "%s", "environment");
170
		cache_error_message(rv, "mdb_env_set_mapsize");
176
		return rv;
171
		return rv;
177
	}
172
	}
178
	if ((rv = db_create(&dbp, dbenvp, 0)) != 0) {
173
	if ((rv = mdb_env_open(env, mdb_dir, MDB_NORDAHEAD, 0600)) != 0) {
179
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
174
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
180
				"creating database handle failed");
175
				"opening database failed");
176
		cache_error_message(rv, "mdb_env_open");
181
		return rv;
177
		return rv;
182
	}
178
	}
183
	if ((rv = dbp->open(dbp, NULL, "cache.db", NULL, DB_BTREE,
179
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_init)");
184
				DB_CREATE | DB_CHKSUM | DB_AUTO_COMMIT,
180
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
185
				0600)) != 0) {
181
		cache_error_message(rv, "mdb_txn_begin");
186
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
182
		mdb_env_close(env);
187
				"opening database failed");
188
		dbp->err(dbp, rv, "open");
189
		// FIXME: free dbp
190
		return rv;
183
		return rv;
191
	}
184
	}
192
#else
185
	if ((rv = mdb_open(txn, NULL, 0, &dbi)) != 0) {
193
	if ((rv = db_create(&dbp, NULL, 0)) != 0) {
186
		cache_error_message(rv, "mdb_open");
194
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
187
		mdb_txn_abort(txn);
195
				"creating database handle failed");
188
		mdb_env_close(env);
196
		return rv;
189
		return rv;
197
	}
190
	}
198
	if ((rv = dbp->open(dbp, file, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) {
191
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_init)");
199
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
192
	if ((rv = mdb_txn_commit(txn)) != 0) {
200
				"opening database failed");
193
		cache_error_message(rv, "mdb_txn_commit");
201
		dbp->err(dbp, rv, "open");
194
		mdb_dbi_close(env, dbi);
202
		// FIXME: free dbp
195
		mdb_env_close(env);
203
		return rv;
196
		return rv;
204
	}
197
	}
205
	dbp->set_errcall(dbp, cache_error_message);
198
206
#endif
207
	setup_cache_filter();
199
	setup_cache_filter();
208
	return 0;
200
	return 0;
209
}
201
}
210
202
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)
203
int cache_set_schema_id(const NotifierID value)
218
{
204
{
219
	int rv, fd, len;
205
	int rv, fd, len;
 Lines 297-379    Link Here 
297
283
298
int cache_get_master_entry(CacheMasterEntry *master_entry)
284
int cache_get_master_entry(CacheMasterEntry *master_entry)
299
{
285
{
300
	DBT key, data;
286
	MDB_txn *txn;
287
	MDB_val key, data;
301
	int rv;
288
	int rv;
302
289
303
	memset(&key, 0, sizeof(DBT));
290
	memset(&key, 0, sizeof(MDB_val));
304
	memset(&data, 0, sizeof(DBT));
291
	memset(&data, 0, sizeof(MDB_val));
305
292
306
	key.data=MASTER_KEY;
293
	key.mv_data=MASTER_KEY;
307
	key.size=MASTER_KEY_SIZE;
294
	key.mv_size=MASTER_KEY_SIZE;
308
	data.flags = DB_DBT_REALLOC;
309
295
310
	if ((rv=dbp->get(dbp, NULL, &key, &data, 0)) == DB_NOTFOUND)
296
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_get_master_entry)");
297
	if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) {
298
		cache_error_message(rv, "mdb_txn_begin");
311
		return rv;
299
		return rv;
300
	}
301
	if ((rv = mdb_get(txn, dbi, &key, &data)) == MDB_NOTFOUND) {
302
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_master_entry)");
303
		mdb_txn_abort(txn);
304
		return rv;
305
	}
312
	else if (rv != 0) {
306
	else if (rv != 0) {
313
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
307
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
314
				"reading master entry from database failed");
308
				"reading master entry from database failed");
315
		dbp->err(dbp, rv, "get");
309
		cache_error_message(rv, "mdb_get");
310
		mdb_txn_abort(txn);
316
		return rv;
311
		return rv;
317
	}
312
	}
313
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_master_entry)");
314
	mdb_txn_abort(txn);
318
315
319
	if (data.size != sizeof(CacheMasterEntry)) {
316
	if (data.mv_size != sizeof(CacheMasterEntry)) {
320
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
317
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
321
				"master entry has unexpected length");
318
				"master entry has unexpected length");
322
		return 1;
319
		return 1;
323
	}
320
	}
324
321
325
	memcpy(master_entry, data.data, sizeof(CacheMasterEntry));
322
	memcpy(master_entry, data.mv_data, sizeof(CacheMasterEntry));
326
	free(data.data);
327
323
328
	return 0;
324
	return 0;
329
}
325
}
330
326
331
int cache_update_master_entry(CacheMasterEntry *master_entry, DB_TXN *dbtxnp)
327
/* The dbtxnp argument is only used when WITH_DB42 is defined - useless? */
328
int cache_update_master_entry(CacheMasterEntry *master_entry, MDB_txn *dbtxnp)
332
{
329
{
333
	DBT key, data;
330
	MDB_txn *txn = dbtxnp;
331
	MDB_val key, data;
334
	int rv;
332
	int rv;
335
	int flags;
333
	int flags;
336
334
337
	memset(&key, 0, sizeof(DBT));
335
	memset(&key, 0, sizeof(MDB_val));
338
	memset(&data, 0, sizeof(DBT));
336
	memset(&data, 0, sizeof(MDB_val));
339
337
340
	key.data=MASTER_KEY;
338
	key.mv_data=MASTER_KEY;
341
	key.size=MASTER_KEY_SIZE;
339
	key.mv_size=MASTER_KEY_SIZE;
342
340
343
	data.data=(void*)master_entry;
341
	data.mv_data=(void*)master_entry;
344
	data.size=sizeof(CacheMasterEntry);
342
	data.mv_size=sizeof(CacheMasterEntry);
345
343
346
#ifdef WITH_DB42
344
	flags = 0;
347
	if (dbtxnp == NULL)
348
		flags = DB_AUTO_COMMIT;
349
	else
350
#endif
351
		flags = 0;
352
345
353
	if ((rv=dbp->put(dbp, dbtxnp, &key, &data, flags)) != 0) {
346
	if (!dbtxnp) {
347
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_update_master_entry)");
348
	}
349
	if (!dbtxnp && (rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
350
		cache_error_message(rv, "mdb_txn_begin");
351
		return rv;
352
	}
353
	if ((rv = mdb_put(txn, dbi, &key, &data, flags)) != 0) {
354
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
354
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
355
				"storing master entry in database failed");
355
				"storing master entry in database failed");
356
		dbp->err(dbp, rv, "put");
356
		cache_error_message(rv, "mdb_put");
357
		mdb_txn_abort(txn);
357
		return rv;
358
		return rv;
358
	}
359
	}
360
	if (!dbtxnp) {
361
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_update_master_entry)");
362
	}
363
	if (!dbtxnp && (rv = mdb_txn_commit(txn)) != 0) {
364
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
365
				"storing master entry in database failed");
366
		cache_error_message(rv, "mdb_txn_commit");
367
		return rv;
368
	}
359
369
360
	cache_sync();
361
362
	return 0;
370
	return 0;
363
}
371
}
364
372
365
DB_TXN* cache_new_transaction(NotifierID id, char *dn)
373
MDB_txn *cache_new_transaction(NotifierID id, char *dn)
366
{
374
{
367
#ifdef WITH_DB42
375
#ifdef WITH_DB42
368
	DB_TXN			*dbtxnp;
376
	int rv;
377
	MDB_txn			*txn;
369
	CacheMasterEntry	 master_entry;
378
	CacheMasterEntry	 master_entry;
370
	NotifierID		*old_id;
379
	NotifierID		*old_id;
371
380
372
	dbenvp->txn_begin(dbenvp, NULL, &dbtxnp, 0);
381
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_new_transaction)");
382
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
383
		cache_error_message(rv, "mdb_txn_begin");
384
		return NULL;
385
	}
373
386
374
	if (id != 0) {
387
	if (id != 0) {
375
		if (cache_get_master_entry(&master_entry) != 0) {
388
		if (cache_get_master_entry(&master_entry) != 0) {
376
			dbtxnp->abort(dbtxnp);
389
			mdb_txn_abort(txn);
377
			return NULL;
390
			return NULL;
378
		}
391
		}
379
392
 Lines 386-403    Link Here 
386
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
399
			univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
387
					"New ID (%ld) is not greater than old"
400
					"New ID (%ld) is not greater than old"
388
					" ID (%ld): %s", id, *old_id, dn);
401
					" ID (%ld): %s", id, *old_id, dn);
389
			dbtxnp->abort(dbtxnp);
402
			mdb_txn_abort(txn);
390
			return NULL;
403
			return NULL;
391
		} else
404
		} else
392
			*old_id = id;
405
			*old_id = id;
393
406
394
		if (cache_update_master_entry(&master_entry, dbtxnp) != 0) {
407
		if (cache_update_master_entry(&master_entry, txn) != 0) {
395
			dbtxnp->abort(dbtxnp);
408
			mdb_txn_abort(txn);
396
			return NULL;
409
			return NULL;
397
		}
410
		}
398
	}
411
	}
399
412
400
	return dbtxnp;
413
	return txn;
401
#else
414
#else
402
	return NULL;
415
	return NULL;
403
#endif
416
#endif
 Lines 410-423    Link Here 
410
   cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */
423
   cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */
411
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry)
424
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry)
412
{
425
{
413
	DBT key, data;
426
	MDB_txn *txn;
414
	DB_TXN *dbtxnp;
427
	MDB_val key, data;
415
	int rv = 0;
428
	int rv = 0;
416
429
417
	memset(&key, 0, sizeof(DBT));
430
	memset(&key, 0, sizeof(MDB_val));
418
	memset(&data, 0, sizeof(DBT));
431
	memset(&data, 0, sizeof(MDB_val));
419
432
420
	if ((rv=unparse_entry(&data.data, &data.size, entry)) != 0) {
433
	if ((rv=unparse_entry(&data.mv_data, &data.mv_size, entry)) != 0) {
421
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
434
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
422
				"unparsing entry failed");
435
				"unparsing entry failed");
423
		return rv;
436
		return rv;
 Lines 426-465    Link Here 
426
439
427
	signals_block();
440
	signals_block();
428
#ifdef WITH_DB42
441
#ifdef WITH_DB42
429
	dbtxnp = cache_new_transaction(id, dn);
442
	txn = cache_new_transaction(id, dn);
430
	if (dbtxnp == NULL) {
443
	if (txn == NULL) {
431
		signals_unblock();
444
		signals_unblock();
432
		free(data.data);
433
		return 1;
445
		return 1;
434
	}
446
	}
435
#else
447
#else
436
	dbtxnp = NULL;
448
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_update_entry)");
449
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
450
		cache_error_message(rv, "mdb_txn_begin");
451
		signals_unblock();
452
		return rv;
453
	}
437
#endif
454
#endif
438
455
439
	key.data=dn;
456
	key.mv_data=dn;
440
	key.size=strlen(dn)+1;
457
	key.mv_size=strlen(dn)+1;
441
458
442
	if ((rv=dbp->put(dbp, dbtxnp, &key, &data, 0)) != 0) {
459
	if ((rv = mdb_put(txn, dbi, &key, &data, 0)) != 0) {
443
		signals_unblock();
460
		signals_unblock();
444
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
461
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
445
				"storing entry in database failed: %s", dn);
462
				"storing entry in database failed: %s", dn);
446
		dbp->err(dbp, rv, "put");
463
		cache_error_message(rv, "mdb_put");
447
#ifdef WITH_DB42
464
		mdb_txn_abort(txn);
448
		dbtxnp->abort(dbtxnp);
449
#endif
450
		free(data.data);
451
		return rv;
465
		return rv;
452
	}
466
	}
453
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %d bytes for %s", data.size, dn);
467
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %zu bytes for %s", data.mv_size, dn);
454
468
455
469
456
#ifdef WITH_DB42
470
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_update_entry)");
457
	dbtxnp->commit(dbtxnp, 0);
471
	if ((rv = mdb_txn_commit(txn)) != 0) {
458
#endif
472
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
459
	cache_sync();
473
				"storing updated entry in database failed");
474
		cache_error_message(rv, "mdb_txn_commit");
475
		return rv;
476
	}
477
460
	signals_unblock();
478
	signals_unblock();
461
479
462
	free(data.data);
463
	return rv;
480
	return rv;
464
}
481
}
465
482
 Lines 482-518    Link Here 
482
499
483
int cache_delete_entry(NotifierID id, char *dn)
500
int cache_delete_entry(NotifierID id, char *dn)
484
{
501
{
485
	DB_TXN	*dbtxnp;
502
	MDB_txn *txn;
486
	DBT	 key;
503
	MDB_val	 key;
487
	int	 rv;
504
	int	 rv;
488
505
489
	memset(&key, 0, sizeof(DBT));
506
	memset(&key, 0, sizeof(MDB_val));
490
507
491
	key.data=dn;
508
	key.mv_data=dn;
492
	key.size=strlen(dn)+1;
509
	key.mv_size=strlen(dn)+1;
493
510
494
	signals_block();
511
	signals_block();
495
#ifdef WITH_DB42
512
#ifdef WITH_DB42
496
	dbtxnp = cache_new_transaction(id, dn);
513
	txn = cache_new_transaction(id, dn);
497
	if (dbtxnp == NULL) {
514
	if (txn == NULL) {
498
		signals_unblock();
515
		signals_unblock();
499
		return 1;
516
		return 1;
500
	}
517
	}
501
#else
518
#else
502
	dbtxnp = NULL;
519
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_delete_entry)");
520
	if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) {
521
		cache_error_message(rv, "mdb_txn_begin");
522
		return rv;
523
	}
503
#endif
524
#endif
504
525
505
	if ((rv=dbp->del(dbp, dbtxnp, &key, 0)) != 0 && rv != DB_NOTFOUND) {
526
	if ((rv = mdb_del(txn, dbi, &key, 0)) != 0 && rv != MDB_NOTFOUND) {
506
		signals_unblock();
527
		signals_unblock();
507
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
528
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
508
				"removing from database failed: %s", dn);
529
				"removing from database failed: %s", dn);
509
		dbp->err(dbp, rv, "del");
530
		cache_error_message(rv, "mdb_del");
531
		mdb_txn_abort(txn);
532
		return rv;
510
	}
533
	}
511
534
512
#ifdef WITH_DB42
535
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_delete_entry)");
513
	dbtxnp->commit(dbtxnp, 0);
536
	if ((rv = mdb_txn_commit(txn)) != 0) {
514
#endif
537
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
515
	cache_sync();
538
				"storing entry removal from database failed");
539
		cache_error_message(rv, "mdb_txn_commit");
540
		return rv;
541
	}
516
	signals_unblock();
542
	signals_unblock();
517
543
518
	return rv;
544
	return rv;
 Lines 551-593    Link Here 
551
577
552
int cache_get_entry(char *dn, CacheEntry *entry)
578
int cache_get_entry(char *dn, CacheEntry *entry)
553
{
579
{
554
	DBT key, data;
580
	MDB_txn *txn;
581
	MDB_val key, data;
555
	int rv = 0;
582
	int rv = 0;
556
583
557
	memset(&key, 0, sizeof(DBT));
584
	memset(&key, 0, sizeof(MDB_val));
558
	memset(&data, 0, sizeof(DBT));
585
	memset(&data, 0, sizeof(MDB_val));
559
	memset(entry, 0, sizeof(CacheEntry));
586
	memset(entry, 0, sizeof(CacheEntry));
560
587
561
	key.data=dn;
588
	key.mv_data=dn;
562
	key.size=strlen(dn)+1;
589
	key.mv_size=strlen(dn)+1;
563
	data.flags = DB_DBT_REALLOC;
564
590
591
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_get_entry)");
592
	if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) {
593
		cache_error_message(rv, "mdb_txn_begin");
594
		return rv;
595
	}
565
	signals_block();
596
	signals_block();
566
	rv=dbp->get(dbp, NULL, &key, &data, 0);
597
	rv = mdb_get(txn, dbi, &key, &data);
567
	signals_unblock();
598
	signals_unblock();
599
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_entry)");
600
	mdb_txn_abort(txn);
568
601
569
	if (rv != 0 && rv != DB_NOTFOUND) {
602
	if (rv != 0 && rv != MDB_NOTFOUND) {
570
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
603
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
571
				"reading %s from database failed", dn);
604
				"reading %s from database failed", dn);
572
		dbp->err(dbp, rv, "get");
605
		cache_error_message(rv, "mdb_get");
573
		return rv;
606
		return rv;
574
	} else if (rv == DB_NOTFOUND) {
607
	} else if (rv == MDB_NOTFOUND) {
575
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "no cache entry found for %s",
608
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "no cache entry found for %s",
576
				dn);
609
				dn);
577
		return rv;
610
		return rv;
578
	}
611
	}
579
612
580
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes for %s",
613
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes for %s",
581
			data.size, dn);
614
			data.mv_size, dn);
582
615
583
	if ((rv=parse_entry(data.data, data.size, entry)) != 0) {
616
	if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) {
584
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
617
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
585
				"parsing entry failed");
618
				"parsing entry failed");
586
		free(data.data);
587
		exit(1);
619
		exit(1);
588
	}
620
	}
589
621
590
	free(data.data);
591
	return rv;
622
	return rv;
592
}
623
}
593
624
 Lines 604-610    Link Here 
604
	}
635
	}
605
636
606
	rv = cache_get_entry(lower_dn, entry);
637
	rv = cache_get_entry(lower_dn, entry);
607
	if (rv == DB_NOTFOUND && mixedcase ) {
638
	if (rv == MDB_NOTFOUND && mixedcase ) {
608
		// try again with original dn
639
		// try again with original dn
609
		rv = cache_get_entry(dn, entry);
640
		rv = cache_get_entry(dn, entry);
610
	}
641
	}
 Lines 613-720    Link Here 
613
	return rv;
644
	return rv;
614
}
645
}
615
646
616
int cache_first_entry(DBC **cur, char **dn, CacheEntry *entry)
647
int cache_first_entry(MDB_cursor **cursor, char **dn, CacheEntry *entry)
617
{
648
{
649
	MDB_txn *txn;
618
	int rv;
650
	int rv;
619
651
620
	if ((rv=dbp->cursor(dbp, NULL, cur, 0)) != 0) {
652
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_first_entry)");
621
		dbp->err(dbp, rv, "cursor");
653
	if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) {
654
		cache_error_message(rv, "mdb_txn_begin");
622
		return rv;
655
		return rv;
623
	}
656
	}
657
	if ((rv = mdb_cursor_open(txn, dbi, cursor)) != 0) {
658
		cache_error_message(rv, "mdb_cursor_open");
659
		mdb_txn_abort(txn);
660
		return rv;
661
	}
624
662
625
	return cache_next_entry(cur, dn, entry);
663
	/*
664
	// mdb_reader_list(env, &mdb_message_func, NULL);
665
	MDB_envinfo stat;
666
	MDB_env *env = mdb_txn_env(txn);
667
	mdb_env_info(env, &stat);
668
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "LAST COMMITTED TXN: %zu", stat.me_last_txnid);
669
	*/
670
671
	return cache_next_entry(cursor, dn, entry);
626
}
672
}
627
673
628
int cache_print_entries(char *dn)
674
int cache_print_entries(char *dn)
629
{
675
{
630
	DBT key, data;
676
	MDB_txn *txn;
631
	DBC *cur;
677
	MDB_val key, data;
632
	memset(&key, 0, sizeof(DBT));
678
	MDB_cursor *cursor;
633
	memset(&data, 0, sizeof(DBT));
679
	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
680
639
	dbp->cursor(dbp, NULL, &cur, 0);
681
	memset(&key, 0, sizeof(MDB_val));
640
	cur->c_get(cur, &key, &data, DB_FIRST);
682
	memset(&data, 0, sizeof(MDB_val));
683
	key.mv_data = strdup(dn);
684
	key.mv_size = strlen(dn)+1;
685
686
	if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) {
687
		cache_error_message(rv, "mdb_txn_begin");
688
		return rv;
689
	}
690
	if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) {
691
		cache_error_message(rv, "mdb_cursor_open");
692
		mdb_txn_abort(txn);
693
		return rv;
694
	}
695
	rv = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
641
	do {
696
	do {
642
		printf("%s\n", (char*)key.data);
697
		if (rv != 0) {
643
	} while (cur->c_get(cur, &key, &data, DB_NEXT) == 0);
698
			cache_error_message(rv, "mdb_cursor_get");
699
			mdb_txn_abort(txn);
700
			return rv;
701
		}
702
		printf("%s\n", (char*)key.mv_data);
703
	} while ((rv = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)));
644
704
645
	cur->c_close(cur);
705
	mdb_cursor_close(cursor);
646
	free(key.data);
706
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_print_entries)");
647
	free(data.data);
707
	mdb_txn_abort(txn);
648
	return 0;
708
	return 0;
649
}
709
}
650
710
651
int cache_next_entry(DBC **cur, char **dn, CacheEntry *entry)
711
int cache_next_entry(MDB_cursor **cursor, char **dn, CacheEntry *entry)
652
{
712
{
653
	DBT key, data;
713
	MDB_val key, data;
654
	int rv;
714
	int rv;
655
715
656
	memset(&key, 0, sizeof(DBT));
716
	memset(&key, 0, sizeof(MDB_val));
657
	key.flags = DB_DBT_REALLOC;
717
	memset(&data, 0, sizeof(MDB_val));
658
	memset(&data, 0, sizeof(DBT));
659
	data.flags = DB_DBT_REALLOC;
660
718
661
	if ((rv=(*cur)->c_get(*cur, &key, &data, DB_NEXT)) == DB_NOTFOUND) {
719
	if ((rv=mdb_cursor_get(*cursor, &key, &data, MDB_NEXT)) == MDB_NOTFOUND) {
662
		return rv;
720
		return rv;
663
	} else if (rv != 0) {
721
	} else if (rv != 0) {
664
		dbp->err(dbp, rv, "c_get");
722
		cache_error_message(rv, "mdb_cursor_get");
665
		return rv;
723
		return rv;
666
	}
724
	}
667
725
668
	/* skip master entry */
726
	/* skip master entry */
669
	if (strcmp(key.data, MASTER_KEY) == 0) {
727
	if (strcmp(key.mv_data, MASTER_KEY) == 0) {
670
		free(key.data);
728
		return cache_next_entry(cursor, dn, entry);
671
		free(data.data);
672
		return cache_next_entry(cur, dn, entry);
673
	}
729
	}
674
730
675
	if (*dn)
731
	if (*dn)
676
		free(*dn);
732
		free(*dn);
677
	*dn = strdup(key.data);
733
	*dn = strdup(key.mv_data);
678
734
679
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes", data.size);
735
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes", data.mv_size);
680
736
681
	if ((rv=parse_entry(data.data, data.size, entry)) != 0) {
737
	if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) {
682
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
738
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
683
				"parsing entry failed: %s", *dn);
739
				"parsing entry failed: %s", *dn);
684
		printf("%d\n", data.size);
740
		printf("%zu\n", data.mv_size);
685
		free(key.data);
686
		free(data.data);
687
		return rv;
741
		return rv;
688
	}
742
	}
689
743
690
	free(key.data);
691
	free(data.data);
692
693
	return 0;
744
	return 0;
694
}
745
}
695
746
696
int cache_free_cursor(DBC *cur)
747
int cache_free_cursor(MDB_cursor *cursor)
697
{
748
{
698
	return cur->c_close(cur);
749
	int rv;
750
	MDB_txn *txn;
751
752
	/*
753
	// mdb_reader_list(env, &mdb_message_func, NULL);
754
	MDB_envinfo stat;
755
	MDB_env *env = mdb_txn_env(txn);
756
	mdb_env_info(env, &stat);
757
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "LAST COMMITTED TXN: %zu", stat.me_last_txnid);
758
	*/
759
760
	txn = mdb_cursor_txn(cursor);
761
	mdb_cursor_close(cursor);
762
763
	univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_free_cursor)");
764
	if ((rv = mdb_txn_commit(txn)) != 0) {
765
		univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR,
766
				"Transation commit failed");
767
		cache_error_message(rv, "mdb_txn_commit");
768
	}
769
	return rv;
699
}
770
}
700
771
701
int cache_close(void)
772
void cache_close(void)
702
{
773
{
703
	int rv;
774
	mdb_close(env, dbi);
775
	mdb_env_close(env);
704
776
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) {
777
	if (lock_fp != NULL) {
716
		fclose(lock_fp);
778
		fclose(lock_fp);
717
		lock_fp = NULL;
779
		lock_fp = NULL;
718
	}
780
	}
719
	return rv;
720
}
781
}
(-)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
int	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 (-9 / +8 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-99    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;
 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 (-2 / +2 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-142    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);
(-)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 (-3 / +3 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-233    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
 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