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