|
Lines 42-48
Link Here
|
| 42 |
#include <string.h> |
42 |
#include <string.h> |
| 43 |
#include <lmdb.h> |
43 |
#include <lmdb.h> |
| 44 |
|
44 |
|
| 45 |
#include <univention/debug.h> |
|
|
| 46 |
#include <univention/config.h> |
45 |
#include <univention/config.h> |
| 47 |
|
46 |
|
| 48 |
#include "common.h" |
47 |
#include "common.h" |
|
Lines 78-93
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 78 |
int i; |
77 |
int i; |
| 79 |
bool abort_init = false; |
78 |
bool abort_init = false; |
| 80 |
|
79 |
|
| 81 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "initializing module %s", handler->name); |
80 |
LOG(WARN, "initializing module %s", handler->name); |
| 82 |
|
81 |
|
| 83 |
memset(&old_cache_entry, 0, sizeof(CacheEntry)); |
82 |
memset(&old_cache_entry, 0, sizeof(CacheEntry)); |
| 84 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "call handler_clean for module %s", handler->name); |
83 |
LOG(INFO, "call handler_clean for module %s", handler->name); |
| 85 |
handler_clean(handler); |
84 |
handler_clean(handler); |
| 86 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "call handler_initialize for module %s", handler->name); |
85 |
LOG(INFO, "call handler_initialize for module %s", handler->name); |
| 87 |
handler_initialize(handler); |
86 |
handler_initialize(handler); |
| 88 |
|
87 |
|
| 89 |
/* remove old entries for module */ |
88 |
/* remove old entries for module */ |
| 90 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "remove old entries for module %s", handler->name); |
89 |
LOG(INFO, "remove old entries for module %s", handler->name); |
| 91 |
for (rv = cache_first_entry(&id2entry_cursor_p, &id2dn_cursor_p, &dn, &cache_entry); rv != MDB_NOTFOUND; rv = cache_next_entry(&id2entry_cursor_p, &id2dn_cursor_p, &dn, &cache_entry)) { |
90 |
for (rv = cache_first_entry(&id2entry_cursor_p, &id2dn_cursor_p, &dn, &cache_entry); rv != MDB_NOTFOUND; rv = cache_next_entry(&id2entry_cursor_p, &id2dn_cursor_p, &dn, &cache_entry)) { |
| 92 |
if (rv == -1) |
91 |
if (rv == -1) |
| 93 |
continue; |
92 |
continue; |
|
Lines 99-112
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 99 |
cache_free_entry(&dn, &cache_entry); |
98 |
cache_free_entry(&dn, &cache_entry); |
| 100 |
} |
99 |
} |
| 101 |
|
100 |
|
| 102 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "call cache_free_cursor for module %s", handler->name); |
101 |
LOG(INFO, "call cache_free_cursor for module %s", handler->name); |
| 103 |
cache_free_cursor(id2entry_cursor_p, id2dn_cursor_p); |
102 |
cache_free_cursor(id2entry_cursor_p, id2dn_cursor_p); |
| 104 |
|
103 |
|
| 105 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "initialize schema for module %s", handler->name); |
104 |
LOG(INFO, "initialize schema for module %s", handler->name); |
| 106 |
/* initialize schema; if it's not in cache yet (it really should be), it'll |
105 |
/* initialize schema; if it's not in cache yet (it really should be), it'll |
| 107 |
be initialized on the regular schema check after ldapsearches */ |
106 |
be initialized on the regular schema check after ldapsearches */ |
| 108 |
if ((rv = cache_get_entry_lower_upper("cn=Subschema", &cache_entry)) != 0 && rv != MDB_NOTFOUND) { |
107 |
if ((rv = cache_get_entry_lower_upper("cn=Subschema", &cache_entry)) != 0 && rv != MDB_NOTFOUND) { |
| 109 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while reading from database"); |
108 |
LOG(WARN, "error while reading from database"); |
| 110 |
return LDAP_OTHER; |
109 |
return LDAP_OTHER; |
| 111 |
} else if (rv == 0) { |
110 |
} else if (rv == 0) { |
| 112 |
signals_block(); |
111 |
signals_block(); |
|
Lines 116-122
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 116 |
cache_free_entry(NULL, &cache_entry); |
115 |
cache_free_entry(NULL, &cache_entry); |
| 117 |
} |
116 |
} |
| 118 |
|
117 |
|
| 119 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "module %s for relating objects", handler->name); |
118 |
LOG(INFO, "module %s for relating objects", handler->name); |
| 120 |
rv = LDAP_SUCCESS; |
119 |
rv = LDAP_SUCCESS; |
| 121 |
for (f = handler->filters; !abort_init && f != NULL && *f != NULL; f++) { |
120 |
for (f = handler->filters; !abort_init && f != NULL && *f != NULL; f++) { |
| 122 |
/* When initializing a module, only search for the DNs. If the |
121 |
/* When initializing a module, only search for the DNs. If the |
|
Lines 136-142
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 136 |
int sizelimit0 = 0; |
135 |
int sizelimit0 = 0; |
| 137 |
rv = LDAP_RETRY(lp, ldap_search_ext_s(lp->ld, (*f)->base, (*f)->scope, (*f)->filter, _attrs, attrsonly1, serverctrls, clientctrls, &timeout, sizelimit0, &res)); |
136 |
rv = LDAP_RETRY(lp, ldap_search_ext_s(lp->ld, (*f)->base, (*f)->scope, (*f)->filter, _attrs, attrsonly1, serverctrls, clientctrls, &timeout, sizelimit0, &res)); |
| 138 |
if (rv != LDAP_SUCCESS) { |
137 |
if (rv != LDAP_SUCCESS) { |
| 139 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "could not get DNs when initializing %s: %s", handler->name, ldap_err2string(rv)); |
138 |
LOG(ERROR, "could not get DNs when initializing %s: %s", handler->name, ldap_err2string(rv)); |
| 140 |
return rv; |
139 |
return rv; |
| 141 |
} |
140 |
} |
| 142 |
|
141 |
|
|
Lines 150-156
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 150 |
} |
149 |
} |
| 151 |
|
150 |
|
| 152 |
if (!(dns = malloc(dn_count * sizeof(struct dn_list)))) { |
151 |
if (!(dns = malloc(dn_count * sizeof(struct dn_list)))) { |
| 153 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "malloc failed"); |
152 |
LOG(ERROR, "malloc failed"); |
| 154 |
abort(); // FIXME |
153 |
abort(); // FIXME |
| 155 |
} |
154 |
} |
| 156 |
|
155 |
|
|
Lines 172-178
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 172 |
} |
171 |
} |
| 173 |
|
172 |
|
| 174 |
for (i = 0; i < dn_count; i++) { |
173 |
for (i = 0; i < dn_count; i++) { |
| 175 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "DN: %s", dns[i].dn); |
174 |
LOG(ALL, "DN: %s", dns[i].dn); |
| 176 |
|
175 |
|
| 177 |
if ((rv = cache_get_entry_lower_upper(dns[i].dn, &cache_entry)) == MDB_NOTFOUND) { /* XXX */ |
176 |
if ((rv = cache_get_entry_lower_upper(dns[i].dn, &cache_entry)) == MDB_NOTFOUND) { /* XXX */ |
| 178 |
LDAPMessage *res2, *first; |
177 |
LDAPMessage *res2, *first; |
|
Lines 183-189
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 183 |
cache_new_entry_from_ldap(NULL, &cache_entry, lp->ld, first); |
182 |
cache_new_entry_from_ldap(NULL, &cache_entry, lp->ld, first); |
| 184 |
ldap_msgfree(res2); |
183 |
ldap_msgfree(res2); |
| 185 |
} else if (rv != LDAP_NO_SUCH_OBJECT) { |
184 |
} else if (rv != LDAP_NO_SUCH_OBJECT) { |
| 186 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "could not get DN %s for handler %s: %s", dns[i].dn, handler->name, ldap_err2string(rv)); |
185 |
LOG(ERROR, "could not get DN %s for handler %s: %s", dns[i].dn, handler->name, ldap_err2string(rv)); |
| 187 |
cache_free_entry(NULL, &cache_entry); |
186 |
cache_free_entry(NULL, &cache_entry); |
| 188 |
abort_init = true; |
187 |
abort_init = true; |
| 189 |
goto cleanup; |
188 |
goto cleanup; |
|
Lines 192-198
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 192 |
deleted after we do the ldapsearch. We |
191 |
deleted after we do the ldapsearch. We |
| 193 |
shouldn't need to care here. */ |
192 |
shouldn't need to care here. */ |
| 194 |
} else if (rv != 0) { |
193 |
} else if (rv != 0) { |
| 195 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while reading from database"); |
194 |
LOG(WARN, "error while reading from database"); |
| 196 |
rv = LDAP_OTHER; |
195 |
rv = LDAP_OTHER; |
| 197 |
abort_init = true; |
196 |
abort_init = true; |
| 198 |
goto cleanup; |
197 |
goto cleanup; |
|
Lines 211-217
static int change_init_module(univention_ldap_parameters_t *lp, Handler *handler
Link Here
|
| 211 |
free(dns); |
210 |
free(dns); |
| 212 |
} |
211 |
} |
| 213 |
cache_free_entry(NULL, &old_cache_entry); |
212 |
cache_free_entry(NULL, &old_cache_entry); |
| 214 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "finished initializing module %s with rv=%d", handler->name, rv); |
213 |
LOG(WARN, "finished initializing module %s with rv=%d", handler->name, rv); |
| 215 |
return rv; |
214 |
return rv; |
| 216 |
} |
215 |
} |
| 217 |
|
216 |
|
|
Lines 250-266
int change_update_entry(univention_ldap_parameters_t *lp, NotifierID id, LDAPMes
Link Here
|
| 250 |
memset(&old_cache_entry, 0, sizeof(CacheEntry)); |
249 |
memset(&old_cache_entry, 0, sizeof(CacheEntry)); |
| 251 |
|
250 |
|
| 252 |
if ((rv = cache_new_entry_from_ldap(&dn, &cache_entry, lp->ld, ldap_entry)) != 0) { |
251 |
if ((rv = cache_new_entry_from_ldap(&dn, &cache_entry, lp->ld, ldap_entry)) != 0) { |
| 253 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while converting LDAP entry to cache entry"); |
252 |
LOG(WARN, "error while converting LDAP entry to cache entry"); |
| 254 |
goto result; |
253 |
goto result; |
| 255 |
} |
254 |
} |
| 256 |
if ((rv = cache_get_entry_lower_upper(dn, &old_cache_entry)) != 0 && rv != MDB_NOTFOUND) { |
255 |
if ((rv = cache_get_entry_lower_upper(dn, &old_cache_entry)) != 0 && rv != MDB_NOTFOUND) { |
| 257 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while reading from database"); |
256 |
LOG(WARN, "error while reading from database"); |
| 258 |
rv = LDAP_OTHER; |
257 |
rv = LDAP_OTHER; |
| 259 |
} else { |
258 |
} else { |
| 260 |
signals_block(); |
259 |
signals_block(); |
| 261 |
handlers_update(dn, &cache_entry, &old_cache_entry, command); |
260 |
handlers_update(dn, &cache_entry, &old_cache_entry, command); |
| 262 |
if ((rv = cache_update_entry_lower(id, dn, &cache_entry)) != 0) { |
261 |
if ((rv = cache_update_entry_lower(id, dn, &cache_entry)) != 0) { |
| 263 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while writing to database"); |
262 |
LOG(WARN, "error while writing to database"); |
| 264 |
} |
263 |
} |
| 265 |
rv = 0; |
264 |
rv = 0; |
| 266 |
signals_unblock(); |
265 |
signals_unblock(); |
|
Lines 281-295
static void change_delete(struct transaction *trans) {
Link Here
|
| 281 |
|
280 |
|
| 282 |
rv = handlers_delete(trans->cur.notify.dn, &trans->cur.cache, 'd'); |
281 |
rv = handlers_delete(trans->cur.notify.dn, &trans->cur.cache, 'd'); |
| 283 |
if (rv == 0) |
282 |
if (rv == 0) |
| 284 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "deleted from cache: %s", trans->cur.notify.dn); |
283 |
LOG(INFO, "deleted from cache: %s", trans->cur.notify.dn); |
| 285 |
if (cache_entry_valid(&trans->cur.cache)) { |
284 |
if (cache_entry_valid(&trans->cur.cache)) { |
| 286 |
if (rv != 0) |
285 |
if (rv != 0) |
| 287 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "at least one delete handler failed"); |
286 |
LOG(WARN, "at least one delete handler failed"); |
| 288 |
cache_delete_entry_lower_upper(trans->cur.notify.id, trans->cur.notify.dn); |
287 |
cache_delete_entry_lower_upper(trans->cur.notify.id, trans->cur.notify.dn); |
| 289 |
cache_free_entry(NULL, &trans->cur.cache); |
288 |
cache_free_entry(NULL, &trans->cur.cache); |
| 290 |
} else { |
289 |
} else { |
| 291 |
if (rv != 0) |
290 |
if (rv != 0) |
| 292 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "not in cache: %s", trans->cur.notify.dn); |
291 |
LOG(INFO, "not in cache: %s", trans->cur.notify.dn); |
| 293 |
} |
292 |
} |
| 294 |
|
293 |
|
| 295 |
signals_unblock(); |
294 |
signals_unblock(); |
|
Lines 320-326
int change_update_schema(univention_ldap_parameters_t *lp) {
Link Here
|
| 320 |
free(server_role); |
319 |
free(server_role); |
| 321 |
|
320 |
|
| 322 |
if ((notifier_get_schema_id_s(NULL, &new_id)) != 0) { |
321 |
if ((notifier_get_schema_id_s(NULL, &new_id)) != 0) { |
| 323 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "failed to get schema DN"); |
322 |
LOG(ERROR, "failed to get schema DN"); |
| 324 |
return LDAP_OTHER; |
323 |
return LDAP_OTHER; |
| 325 |
} |
324 |
} |
| 326 |
|
325 |
|
|
Lines 328-346
int change_update_schema(univention_ldap_parameters_t *lp) {
Link Here
|
| 328 |
rv = LDAP_RETRY(lp, ldap_search_ext_s(lp->ld, "cn=Subschema", LDAP_SCOPE_BASE, "(objectClass=*)", attrs, attrsonly0, serverctrls, clientctrls, &timeout, sizelimit0, &res)); |
327 |
rv = LDAP_RETRY(lp, ldap_search_ext_s(lp->ld, "cn=Subschema", LDAP_SCOPE_BASE, "(objectClass=*)", attrs, attrsonly0, serverctrls, clientctrls, &timeout, sizelimit0, &res)); |
| 329 |
if (rv == LDAP_SUCCESS) { |
328 |
if (rv == LDAP_SUCCESS) { |
| 330 |
if ((cur = ldap_first_entry(lp->ld, res)) == NULL) { |
329 |
if ((cur = ldap_first_entry(lp->ld, res)) == NULL) { |
| 331 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "got no entry for schema"); |
330 |
LOG(ERROR, "got no entry for schema"); |
| 332 |
return LDAP_OTHER; |
331 |
return LDAP_OTHER; |
| 333 |
} else { |
332 |
} else { |
| 334 |
rv = change_update_entry(lp, new_id, cur, 'n'); |
333 |
rv = change_update_entry(lp, new_id, cur, 'n'); |
| 335 |
} |
334 |
} |
| 336 |
ldap_memfree(res); |
335 |
ldap_memfree(res); |
| 337 |
} else { |
336 |
} else { |
| 338 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "could not receive schema (%s)", ldap_err2string(rv)); |
337 |
LOG(ERROR, "could not receive schema (%s)", ldap_err2string(rv)); |
| 339 |
} |
338 |
} |
| 340 |
cache_master_entry.schema_id = new_id; |
339 |
cache_master_entry.schema_id = new_id; |
| 341 |
rv = cache_update_master_entry(&cache_master_entry); |
340 |
rv = cache_update_master_entry(&cache_master_entry); |
| 342 |
if (cache_set_schema_id(new_id)) |
341 |
if (cache_set_schema_id(new_id)) |
| 343 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "failed to write schema ID"); |
342 |
LOG(WARN, "failed to write schema ID"); |
| 344 |
} |
343 |
} |
| 345 |
|
344 |
|
| 346 |
return rv; |
345 |
return rv; |
|
Lines 384-390
static int fake_container(struct transaction *trans, char *dn) {
Link Here
|
| 384 |
} else if (!strcasecmp(name, "dc")) { |
383 |
} else if (!strcasecmp(name, "dc")) { |
| 385 |
cache_entry_add1(&cache_entry, "objectClass", "domain"); |
384 |
cache_entry_add1(&cache_entry, "objectClass", "domain"); |
| 386 |
} else { |
385 |
} else { |
| 387 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "unknown container: %s", name); |
386 |
LOG(ERROR, "unknown container: %s", name); |
| 388 |
goto out; |
387 |
goto out; |
| 389 |
} |
388 |
} |
| 390 |
free(name); |
389 |
free(name); |
|
Lines 400-406
static int fake_container(struct transaction *trans, char *dn) {
Link Here
|
| 400 |
|
399 |
|
| 401 |
// 5. Store cache entry at intermediate location |
400 |
// 5. Store cache entry at intermediate location |
| 402 |
if ((rv = cache_update_entry_lower(trans->cur.notify.id, dn, &cache_entry)) != 0) |
401 |
if ((rv = cache_update_entry_lower(trans->cur.notify.id, dn, &cache_entry)) != 0) |
| 403 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while writing to database"); |
402 |
LOG(WARN, "error while writing to database"); |
| 404 |
|
403 |
|
| 405 |
out: |
404 |
out: |
| 406 |
free(name); |
405 |
free(name); |
|
Lines 418-424
static int check_parent_dn(struct transaction *trans, char *dn) {
Link Here
|
| 418 |
return LDAP_SUCCESS; |
417 |
return LDAP_SUCCESS; |
| 419 |
|
418 |
|
| 420 |
if (same_dn(dn, trans->lp_local->base)) { |
419 |
if (same_dn(dn, trans->lp_local->base)) { |
| 421 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "Ignore parent_dn check because dn is ldap base."); |
420 |
LOG(INFO, "Ignore parent_dn check because dn is ldap base."); |
| 422 |
return LDAP_SUCCESS; |
421 |
return LDAP_SUCCESS; |
| 423 |
} |
422 |
} |
| 424 |
|
423 |
|
|
Lines 433-439
static int check_parent_dn(struct transaction *trans, char *dn) {
Link Here
|
| 433 |
return rv; |
432 |
return rv; |
| 434 |
|
433 |
|
| 435 |
if (same_dn(parent_dn, trans->lp_local->base)) { |
434 |
if (same_dn(parent_dn, trans->lp_local->base)) { |
| 436 |
// univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "parent of DN: %s is base", dn); |
435 |
// LOG(INFO, "parent of DN: %s is base", dn); |
| 437 |
goto out; |
436 |
goto out; |
| 438 |
} |
437 |
} |
| 439 |
|
438 |
|
|
Lines 449-461
static int check_parent_dn(struct transaction *trans, char *dn) {
Link Here
|
| 449 |
}; |
448 |
}; |
| 450 |
int sizelimit0 = 0; |
449 |
int sizelimit0 = 0; |
| 451 |
|
450 |
|
| 452 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "checking parent_dn of %s in local LDAP", dn); |
451 |
LOG(INFO, "checking parent_dn of %s in local LDAP", dn); |
| 453 |
|
452 |
|
| 454 |
/* try to open a connection to the local LDAP for the parent DN check */ |
453 |
/* try to open a connection to the local LDAP for the parent DN check */ |
| 455 |
if (trans->lp_local->ld == NULL) { |
454 |
if (trans->lp_local->ld == NULL) { |
| 456 |
rv = univention_ldap_open(trans->lp_local); |
455 |
rv = univention_ldap_open(trans->lp_local); |
| 457 |
if (rv != LDAP_SUCCESS) { |
456 |
if (rv != LDAP_SUCCESS) { |
| 458 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "check_parent_dn: bind to local LDAP failed"); |
457 |
LOG(ERROR, "bind to local LDAP failed"); |
| 459 |
goto out; |
458 |
goto out; |
| 460 |
} |
459 |
} |
| 461 |
} |
460 |
} |
|
Lines 469-475
static int check_parent_dn(struct transaction *trans, char *dn) {
Link Here
|
| 469 |
/* lookup parent_dn object in remote LDAP */ |
468 |
/* lookup parent_dn object in remote LDAP */ |
| 470 |
rv = LDAP_RETRY(trans->lp, ldap_search_ext_s(trans->lp->ld, parent_dn, LDAP_SCOPE_BASE, filter, attrs, attrsonly0, serverctrls, clientctrls, &timeout, sizelimit0, &res)); |
469 |
rv = LDAP_RETRY(trans->lp, ldap_search_ext_s(trans->lp->ld, parent_dn, LDAP_SCOPE_BASE, filter, attrs, attrsonly0, serverctrls, clientctrls, &timeout, sizelimit0, &res)); |
| 471 |
if (rv == LDAP_NO_SUCH_OBJECT) { |
470 |
if (rv == LDAP_NO_SUCH_OBJECT) { |
| 472 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "could not find parent container of dn: %s from %s (%s)", dn, trans->lp->host, ldap_err2string(rv)); |
471 |
LOG(ERROR, "could not find parent container of dn: %s from %s (%s)", dn, trans->lp->host, ldap_err2string(rv)); |
| 473 |
if (is_move(trans)) |
472 |
if (is_move(trans)) |
| 474 |
rv = fake_container(trans, parent_dn); |
473 |
rv = fake_container(trans, parent_dn); |
| 475 |
} else { /* parent_dn found in remote LDAP */ |
474 |
} else { /* parent_dn found in remote LDAP */ |
|
Lines 478-490
static int check_parent_dn(struct transaction *trans, char *dn) {
Link Here
|
| 478 |
/* entry exists (since we didn't get NO_SUCH_OBJECT), |
477 |
/* entry exists (since we didn't get NO_SUCH_OBJECT), |
| 479 |
* but was probably excluded through ACLs which makes it |
478 |
* but was probably excluded through ACLs which makes it |
| 480 |
* non-existent for us */ |
479 |
* non-existent for us */ |
| 481 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "could not get parent object of dn: %s from %s (%s)", dn, trans->lp->host, ldap_err2string(rv)); |
480 |
LOG(ERROR, "could not get parent object of dn: %s from %s (%s)", dn, trans->lp->host, ldap_err2string(rv)); |
| 482 |
if (is_move(trans)) |
481 |
if (is_move(trans)) |
| 483 |
rv = fake_container(trans, parent_dn); |
482 |
rv = fake_container(trans, parent_dn); |
| 484 |
else |
483 |
else |
| 485 |
rv = LDAP_INSUFFICIENT_ACCESS; |
484 |
rv = LDAP_INSUFFICIENT_ACCESS; |
| 486 |
} else { /* found data for parent_dn in remote LDAP */ |
485 |
} else { /* found data for parent_dn in remote LDAP */ |
| 487 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_PROCESS, "change_update_entry for parent_dn: %s", parent_dn); |
486 |
LOG(PROCESS, "change_update_entry for parent_dn: %s", parent_dn); |
| 488 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, cur, 'n'); /* add parent_dn object */ |
487 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, cur, 'n'); /* add parent_dn object */ |
| 489 |
} |
488 |
} |
| 490 |
} |
489 |
} |
|
Lines 560-578
static int process_move(struct transaction *trans) {
Link Here
|
| 560 |
rv = check_parent_dn(trans, current_dn); |
559 |
rv = check_parent_dn(trans, current_dn); |
| 561 |
signals_block(); |
560 |
signals_block(); |
| 562 |
if (same_dn(trans->prev.notify.dn, current_dn)) |
561 |
if (same_dn(trans->prev.notify.dn, current_dn)) |
| 563 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_PROCESS, "move_same_dn(%s)", current_dn); |
562 |
LOG(PROCESS, "move_same_dn(%s)", current_dn); |
| 564 |
rv = handlers_delete(trans->prev.notify.dn, &trans->prev.cache, 'r'); |
563 |
rv = handlers_delete(trans->prev.notify.dn, &trans->prev.cache, 'r'); |
| 565 |
rv = handlers_update(current_dn, &trans->cur.cache, &dummy, 'a'); |
564 |
rv = handlers_update(current_dn, &trans->cur.cache, &dummy, 'a'); |
| 566 |
signals_unblock(); |
565 |
signals_unblock(); |
| 567 |
|
566 |
|
| 568 |
// 5. Store cache entry at new location |
567 |
// 5. Store cache entry at new location |
| 569 |
if ((rv = cache_update_entry_lower(trans->cur.notify.id, current_dn, &trans->cur.cache)) != 0) { |
568 |
if ((rv = cache_update_entry_lower(trans->cur.notify.id, current_dn, &trans->cur.cache)) != 0) { |
| 570 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while writing to database"); |
569 |
LOG(WARN, "error while writing to database"); |
| 571 |
} |
570 |
} |
| 572 |
|
571 |
|
| 573 |
// 6. Check for final destination |
572 |
// 6. Check for final destination |
| 574 |
if (final) { |
573 |
if (final) { |
| 575 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Object finally moved to '%s'", current_dn); |
574 |
LOG(ALL, "Object finally moved to '%s'", current_dn); |
| 576 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, trans->ldap, 'm'); |
575 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, trans->ldap, 'm'); |
| 577 |
} |
576 |
} |
| 578 |
|
577 |
|
|
Lines 592-605
static int change_update_cache(struct transaction *trans) {
Link Here
|
| 592 |
|
591 |
|
| 593 |
trans->cur.ldap_dn = ldap_get_dn(trans->lp->ld, trans->ldap); |
592 |
trans->cur.ldap_dn = ldap_get_dn(trans->lp->ld, trans->ldap); |
| 594 |
if (!trans->cur.ldap_dn) { |
593 |
if (!trans->cur.ldap_dn) { |
| 595 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "failed to get current DN %s", trans->cur.notify.dn); |
594 |
LOG(ERROR, "failed to get current DN %s", trans->cur.notify.dn); |
| 596 |
goto out; |
595 |
goto out; |
| 597 |
} |
596 |
} |
| 598 |
|
597 |
|
| 599 |
switch (trans->cur.notify.command) { |
598 |
switch (trans->cur.notify.command) { |
| 600 |
case 'm': // modify |
599 |
case 'm': // modify |
| 601 |
if (!same_dn(trans->cur.notify.dn, trans->cur.ldap_dn)) { |
600 |
if (!same_dn(trans->cur.notify.dn, trans->cur.ldap_dn)) { |
| 602 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_PROCESS, "Delaying update for '%s' until moved to '%s'", trans->cur.notify.dn, trans->cur.ldap_dn); |
601 |
LOG(PROCESS, "Delaying update for '%s' until moved to '%s'", trans->cur.notify.dn, trans->cur.ldap_dn); |
| 603 |
} else { |
602 |
} else { |
| 604 |
rv = check_parent_dn(trans, trans->cur.ldap_dn); |
603 |
rv = check_parent_dn(trans, trans->cur.ldap_dn); |
| 605 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, trans->ldap, trans->cur.notify.command); |
604 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, trans->ldap, trans->cur.notify.command); |
|
Lines 610-623
static int change_update_cache(struct transaction *trans) {
Link Here
|
| 610 |
rv = process_move(trans); |
609 |
rv = process_move(trans); |
| 611 |
} else { // add |
610 |
} else { // add |
| 612 |
if (!same_dn(trans->cur.notify.dn, trans->cur.ldap_dn)) |
611 |
if (!same_dn(trans->cur.notify.dn, trans->cur.ldap_dn)) |
| 613 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "Schizophrenia: a NEW object '%s' is added, which ALREADY is in our cache for '%s'?", trans->cur.ldap_dn, trans->cur.notify.dn); |
612 |
LOG(WARN, "Schizophrenia: a NEW object '%s' is added, which ALREADY is in our cache for '%s'?", |
|
|
613 |
trans->cur.ldap_dn, trans->cur.notify.dn); |
| 614 |
rv = check_parent_dn(trans, trans->cur.ldap_dn); |
614 |
rv = check_parent_dn(trans, trans->cur.ldap_dn); |
| 615 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, trans->ldap, trans->cur.notify.command); |
615 |
rv = change_update_entry(trans->lp, trans->cur.notify.id, trans->ldap, trans->cur.notify.command); |
| 616 |
} |
616 |
} |
| 617 |
break; |
617 |
break; |
| 618 |
case 'd': // delete |
618 |
case 'd': // delete |
| 619 |
if (!same_dn(trans->cur.notify.dn, trans->cur.ldap_dn)) |
619 |
if (!same_dn(trans->cur.notify.dn, trans->cur.ldap_dn)) |
| 620 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "Resurrection: DELETED object '%s' will re-appear at '%s'?", trans->cur.notify.dn, trans->cur.ldap_dn); |
620 |
LOG(WARN, "Resurrection: DELETED object '%s' will re-appear at '%s'?", trans->cur.notify.dn, trans->cur.ldap_dn); |
| 621 |
change_delete(trans); |
621 |
change_delete(trans); |
| 622 |
rv = 0; |
622 |
rv = 0; |
| 623 |
break; |
623 |
break; |
|
Lines 628-634
static int change_update_cache(struct transaction *trans) {
Link Here
|
| 628 |
rv = 0; |
628 |
rv = 0; |
| 629 |
break; |
629 |
break; |
| 630 |
default: |
630 |
default: |
| 631 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "Unknown command: %c", trans->cur.notify.command); |
631 |
LOG(ERROR, "Unknown command: %c", trans->cur.notify.command); |
| 632 |
} |
632 |
} |
| 633 |
|
633 |
|
| 634 |
out: |
634 |
out: |
|
Lines 655-665
int change_update_dn(struct transaction *trans) {
Link Here
|
| 655 |
int rv; |
655 |
int rv; |
| 656 |
const char *uuid = NULL; |
656 |
const char *uuid = NULL; |
| 657 |
|
657 |
|
| 658 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_PROCESS, "updating '%s' command %c", trans->cur.notify.dn, trans->cur.notify.command); |
658 |
LOG(PROCESS, "updating '%s' command %c", trans->cur.notify.dn, trans->cur.notify.command); |
| 659 |
|
659 |
|
| 660 |
rv = cache_get_entry_lower_upper(trans->cur.notify.dn, &trans->cur.cache); |
660 |
rv = cache_get_entry_lower_upper(trans->cur.notify.dn, &trans->cur.cache); |
| 661 |
if (rv != 0 && rv != MDB_NOTFOUND) { |
661 |
if (rv != 0 && rv != MDB_NOTFOUND) { |
| 662 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error reading database for %s", trans->cur.notify.dn); |
662 |
LOG(WARN, "error reading database for %s", trans->cur.notify.dn); |
| 663 |
return LDAP_OTHER; |
663 |
return LDAP_OTHER; |
| 664 |
} |
664 |
} |
| 665 |
switch (trans->prev.notify.command) { |
665 |
switch (trans->prev.notify.command) { |
|
Lines 669-679
int change_update_dn(struct transaction *trans) {
Link Here
|
| 669 |
break; |
669 |
break; |
| 670 |
case 'r': // move_from ... move_to |
670 |
case 'r': // move_from ... move_to |
| 671 |
if (!cache_entry_valid(&trans->prev.cache)) { |
671 |
if (!cache_entry_valid(&trans->prev.cache)) { |
| 672 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "move_to without history '%s'", trans->prev.notify.dn); |
672 |
LOG(ERROR, "move_to without history '%s'", trans->prev.notify.dn); |
| 673 |
break; |
673 |
break; |
| 674 |
} |
674 |
} |
| 675 |
if (rv == 0) { |
675 |
if (rv == 0) { |
| 676 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "move_to collision at '%s'", trans->cur.notify.dn); |
676 |
LOG(INFO, "move_to collision at '%s'", trans->cur.notify.dn); |
| 677 |
cache_free_entry(NULL, &trans->cur.cache); |
677 |
cache_free_entry(NULL, &trans->cur.cache); |
| 678 |
} |
678 |
} |
| 679 |
if (is_move(trans)) { |
679 |
if (is_move(trans)) { |
|
Lines 684-704
int change_update_dn(struct transaction *trans) {
Link Here
|
| 684 |
break; |
684 |
break; |
| 685 |
} |
685 |
} |
| 686 |
default: |
686 |
default: |
| 687 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "non consecutive move: %ld:%c:%s << %ld:%c:%s", trans->prev.notify.id, trans->prev.notify.command, trans->prev.notify.dn, trans->cur.notify.id, |
687 |
LOG(ERROR, "non consecutive move: %ld:%c:%s << %ld:%c:%s", trans->prev.notify.id, trans->prev.notify.command, trans->prev.notify.dn, trans->cur.notify.id, trans->cur.notify.command, trans->cur.notify.dn); |
| 688 |
trans->cur.notify.command, trans->cur.notify.dn); |
|
|
| 689 |
rv = 1; |
688 |
rv = 1; |
| 690 |
goto out; |
689 |
goto out; |
| 691 |
} |
690 |
} |
| 692 |
|
691 |
|
| 693 |
if (uuid) { |
692 |
if (uuid) { |
| 694 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "updating by UUID %s", uuid); |
693 |
LOG(ALL, "updating by UUID %s", uuid); |
| 695 |
base = trans->lp->base; |
694 |
base = trans->lp->base; |
| 696 |
scope = LDAP_SCOPE_SUBTREE; |
695 |
scope = LDAP_SCOPE_SUBTREE; |
| 697 |
snprintf(filter, sizeof(filter), "(entryUUID=%s)", uuid); |
696 |
snprintf(filter, sizeof(filter), "(entryUUID=%s)", uuid); |
| 698 |
trans->cur.uuid = strdup(uuid); |
697 |
trans->cur.uuid = strdup(uuid); |
| 699 |
} else { |
698 |
} else { |
| 700 |
retry_dn: |
699 |
retry_dn: |
| 701 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "updating by DN %s", trans->cur.notify.dn); |
700 |
LOG(ALL, "updating by DN %s", trans->cur.notify.dn); |
| 702 |
base = trans->cur.notify.dn; |
701 |
base = trans->cur.notify.dn; |
| 703 |
scope = LDAP_SCOPE_BASE; |
702 |
scope = LDAP_SCOPE_BASE; |
| 704 |
snprintf(filter, sizeof(filter), "(objectClass=*)"); |
703 |
snprintf(filter, sizeof(filter), "(objectClass=*)"); |
|
Lines 719-725
int change_update_dn(struct transaction *trans) {
Link Here
|
| 719 |
} |
718 |
} |
| 720 |
trans->ldap = NULL; |
719 |
trans->ldap = NULL; |
| 721 |
} else { |
720 |
} else { |
| 722 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error searching DN %s: %d", trans->cur.notify.dn, rv); |
721 |
LOG(WARN, "error searching DN %s: %d", trans->cur.notify.dn, rv); |
| 723 |
_free_transaction_op(&trans->cur); |
722 |
_free_transaction_op(&trans->cur); |
| 724 |
} |
723 |
} |
| 725 |
ldap_msgfree(res); |
724 |
ldap_msgfree(res); |