|
Lines 146-192
Link Here
|
| 146 |
MDB_val key, data; |
146 |
MDB_val key, data; |
| 147 |
subDN *subdn; |
147 |
subDN *subdn; |
| 148 |
DNID id = dnid; |
148 |
DNID id = dnid; |
|
|
149 |
LDAPDN ldapdn = NULL; |
| 150 |
char *dn_str; |
| 151 |
char *p; |
| 152 |
int i = 0; |
| 149 |
|
153 |
|
| 150 |
key.mv_size = sizeof(DNID); |
154 |
do { |
| 151 |
key.mv_data = &id; |
155 |
key.mv_size = sizeof(DNID); |
|
|
156 |
key.mv_data = &id; |
| 152 |
|
157 |
|
| 153 |
data.mv_size = sizeof(subDN); |
158 |
data.mv_size = sizeof(subDN); |
| 154 |
data.mv_data = &(subDN){0, SUBDN_TYPE_NODE, ""}; |
159 |
data.mv_data = &(subDN){0, SUBDN_TYPE_NODE, ""}; |
| 155 |
|
160 |
|
| 156 |
rv = mdb_cursor_get(cur, &key, &data, MDB_GET_BOTH); |
161 |
rv = mdb_cursor_get(cur, &key, &data, MDB_GET_BOTH); |
| 157 |
data.mv_data = NULL; |
162 |
data.mv_data = NULL; |
| 158 |
data.mv_size = 0; |
163 |
data.mv_size = 0; |
| 159 |
|
164 |
|
| 160 |
if (rv != MDB_SUCCESS) { |
165 |
if (rv != MDB_SUCCESS) { |
| 161 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: mdb_cursor_get (MDB_GET_BOTH): %s (%d)", __func__, mdb_strerror(rv), rv); |
166 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: mdb_cursor_get (MDB_GET_BOTH): %s (%d)", __func__, mdb_strerror(rv), rv); |
| 162 |
return rv; |
167 |
return rv; |
| 163 |
}; |
168 |
}; |
| 164 |
|
169 |
|
| 165 |
// Workaround for (ITS#8393) LMDB - MDB_GET_BOTH broken on non-dup value |
170 |
// Workaround for (ITS#8393) LMDB - MDB_GET_BOTH broken on non-dup value |
| 166 |
rv = mdb_cursor_get(cur, &key, &data, MDB_GET_CURRENT); |
171 |
rv = mdb_cursor_get(cur, &key, &data, MDB_GET_CURRENT); |
| 167 |
if (rv != MDB_SUCCESS) { |
172 |
if (rv != MDB_SUCCESS) { |
| 168 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: mdb_cursor_get: %s (%d)", __func__, mdb_strerror(rv), rv); |
173 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: mdb_cursor_get: %s (%d)", __func__, mdb_strerror(rv), rv); |
| 169 |
return rv; |
174 |
return rv; |
| 170 |
}; |
175 |
}; |
| 171 |
|
176 |
|
| 172 |
/* |
177 |
/* |
| 173 |
// or simply use this instead of MDB_GET_BOTH + MDB_GET_CURRENT: |
178 |
// or simply use this instead of MDB_GET_BOTH + MDB_GET_CURRENT: |
| 174 |
MDB_txn *txn; |
179 |
MDB_txn *txn; |
| 175 |
MDB_dbi dbi; |
180 |
MDB_dbi dbi; |
| 176 |
txn = mdb_cursor_txn(cur); |
181 |
txn = mdb_cursor_txn(cur); |
| 177 |
dbi = mdb_cursor_dbi(cur); |
182 |
dbi = mdb_cursor_dbi(cur); |
| 178 |
rv = mdb_get(txn, dbi, &key, &data); |
183 |
rv = mdb_get(txn, dbi, &key, &data); |
| 179 |
if (rv != MDB_SUCCESS) { |
184 |
if (rv != MDB_SUCCESS) { |
| 180 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
185 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 181 |
"%s: mdb_get: %s (%d)", |
186 |
"%s: mdb_get: %s (%d)", |
| 182 |
__func__, mdb_strerror(rv), rv); |
187 |
__func__, mdb_strerror(rv), rv); |
| 183 |
return rv; |
188 |
return rv; |
| 184 |
}; |
189 |
}; |
| 185 |
*/ |
190 |
*/ |
| 186 |
|
191 |
|
| 187 |
subdn = (subDN *)data.mv_data; |
192 |
if (!ldapdn) { |
|
|
193 |
i = 0; |
| 194 |
ldapdn = calloc(2, sizeof(LDAPDN)); |
| 195 |
} else { |
| 196 |
i++; |
| 197 |
ldapdn = realloc(ldapdn, (i+2)*sizeof(LDAPDN)); |
| 198 |
} |
| 199 |
if (ldapdn == NULL) { |
| 200 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: %s failed", __func__, i?"realloc":"calloc"); |
| 201 |
abort(); |
| 202 |
} |
| 188 |
|
203 |
|
| 189 |
*dn = strdup(subdn->data); |
204 |
ldapdn[i+1] = NULL; |
|
|
205 |
|
| 206 |
subdn = (subDN *)data.mv_data; |
| 207 |
rv = ldap_str2rdn(subdn->data, &ldapdn[i], &p, LDAP_DN_FORMAT_LDAP); |
| 208 |
if (rv != LDAP_SUCCESS) { |
| 209 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: ldap_str2rdn failed: %s (%d)", __func__, ldap_err2string(rv), rv); |
| 210 |
return rv; |
| 211 |
} |
| 212 |
|
| 213 |
if (ldapdn[i] == NULL) { |
| 214 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: ldap_str2rdn NULL: %s (%d): %s", __func__, ldap_err2string(rv), rv, subdn->data); |
| 215 |
return 1; |
| 216 |
} |
| 217 |
id = subdn->id; |
| 218 |
} while (id != 0); |
| 219 |
|
| 220 |
rv = ldap_dn2str(ldapdn, &dn_str, LDAP_DN_FORMAT_LDAPV3); |
| 221 |
ldap_dnfree(ldapdn); |
| 222 |
if (rv != LDAP_SUCCESS) { |
| 223 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: ldap_dn2str failed: %s (%d)", __func__, ldap_err2string(rv), rv); |
| 224 |
return rv; |
| 225 |
} |
| 226 |
|
| 227 |
*dn = strdup(dn_str); |
| 228 |
ldap_memfree(dn_str); |
| 190 |
if (*dn == NULL) { |
229 |
if (*dn == NULL) { |
| 191 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: strdup failed", __func__); |
230 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: strdup failed", __func__); |
| 192 |
abort(); |
231 |
abort(); |
|
Lines 218-224
Link Here
|
| 218 |
DNID id; |
257 |
DNID id; |
| 219 |
char *rdn_str; |
258 |
char *rdn_str; |
| 220 |
char *dn_str; |
259 |
char *dn_str; |
| 221 |
size_t dn_len; |
|
|
| 222 |
size_t rdn_len; |
260 |
size_t rdn_len; |
| 223 |
subDN *subdn; |
261 |
subDN *subdn; |
| 224 |
|
262 |
|
|
Lines 241-248
Link Here
|
| 241 |
|
279 |
|
| 242 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "%s: child=%lu, parent=%lu: \"%s\"", __func__, child, parent, rdn_str); |
280 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "%s: child=%lu, parent=%lu: \"%s\"", __func__, child, parent, rdn_str); |
| 243 |
|
281 |
|
| 244 |
dn_len = strlen(dn_str); |
282 |
rdn_len = strlen(rdn_str); |
| 245 |
subdn = calloc(1, sizeof(subDN) + dn_len); |
283 |
subdn = calloc(1, sizeof(subDN) + rdn_len); |
| 246 |
if (subdn == NULL) { |
284 |
if (subdn == NULL) { |
| 247 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: calloc failed", __func__); |
285 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "%s: calloc failed", __func__); |
| 248 |
ldap_memfree(dn_str); |
286 |
ldap_memfree(dn_str); |
|
Lines 249-261
Link Here
|
| 249 |
ldap_memfree(rdn_str); |
287 |
ldap_memfree(rdn_str); |
| 250 |
abort(); |
288 |
abort(); |
| 251 |
} |
289 |
} |
| 252 |
rdn_len = strlen(rdn_str); |
|
|
| 253 |
assert(dn_len >= rdn_len); |
| 254 |
data.mv_size = sizeof(subDN) + rdn_len; |
290 |
data.mv_size = sizeof(subDN) + rdn_len; |
| 255 |
subdn->type = SUBDN_TYPE_LINK; |
291 |
subdn->type = SUBDN_TYPE_LINK; |
| 256 |
subdn->id = child; |
292 |
subdn->id = child; |
| 257 |
strcpy(subdn->data, rdn_str); |
293 |
strcpy(subdn->data, rdn_str); |
| 258 |
ldap_memfree(rdn_str); |
|
|
| 259 |
data.mv_data = subdn; |
294 |
data.mv_data = subdn; |
| 260 |
|
295 |
|
| 261 |
// Store subdn link |
296 |
// Store subdn link |
|
Lines 265-274
Link Here
|
| 265 |
if (rv == MDB_SUCCESS) { |
300 |
if (rv == MDB_SUCCESS) { |
| 266 |
id = child; |
301 |
id = child; |
| 267 |
|
302 |
|
| 268 |
data.mv_size = sizeof(subDN) + dn_len; |
303 |
data.mv_size = sizeof(subDN) + rdn_len; |
| 269 |
subdn->type = SUBDN_TYPE_NODE; |
304 |
subdn->type = SUBDN_TYPE_NODE; |
| 270 |
subdn->id = parent; // backlink |
305 |
subdn->id = parent; // backlink |
| 271 |
strcpy(subdn->data, dn_str); |
306 |
strcpy(subdn->data, rdn_str); |
| 272 |
|
307 |
|
| 273 |
rv = mdb_cursor_put(write_cursor_p, &key, &data, MDB_NODUPDATA); |
308 |
rv = mdb_cursor_put(write_cursor_p, &key, &data, MDB_NODUPDATA); |
| 274 |
if (rv != MDB_SUCCESS) { |
309 |
if (rv != MDB_SUCCESS) { |
|
Lines 280-285
Link Here
|
| 280 |
abort(); |
315 |
abort(); |
| 281 |
} |
316 |
} |
| 282 |
|
317 |
|
|
|
318 |
ldap_memfree(rdn_str); |
| 283 |
ldap_memfree(dn_str); |
319 |
ldap_memfree(dn_str); |
| 284 |
free(subdn); |
320 |
free(subdn); |
| 285 |
|
321 |
|