|
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); |