1 /* $NetBSD: dn2id.c,v 1.2 2021/08/14 16:15:02 christos Exp $ */
2
3 /* OpenLDAP WiredTiger backend */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 2002-2021 The OpenLDAP Foundation.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
12 * Public License.
13 *
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
17 */
18 /* ACKNOWLEDGEMENTS:
19 * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
20 * based on back-bdb for inclusion in OpenLDAP Software.
21 * WiredTiger is a product of MongoDB Inc.
22 */
23
24 #include <sys/cdefs.h>
25 __RCSID("$NetBSD: dn2id.c,v 1.2 2021/08/14 16:15:02 christos Exp $");
26
27 #include "portable.h"
28
29 #include <stdio.h>
30 #include "back-wt.h"
31 #include "slap-config.h"
32 #include "idl.h"
33
34 char *
mkrevdn(struct berval src)35 mkrevdn(struct berval src){
36 char *dst, *p;
37 char *rdn;
38 size_t rdn_len;
39
40 p = dst = ch_malloc(src.bv_len + 2);
41 while(src.bv_len){
42 rdn = ber_bvrchr( &src, ',' );
43 if (rdn) {
44 rdn_len = src.bv_len;
45 src.bv_len = rdn - src.bv_val;
46 rdn_len -= src.bv_len + 1;
47 rdn++;
48 }else{
49 /* first rdn */
50 rdn_len = src.bv_len;
51 rdn = src.bv_val;
52 src.bv_len = 0;
53 }
54 AC_MEMCPY( p, rdn, rdn_len );
55 p += rdn_len;
56 *p++ = ',';
57 }
58 *p = '\0';
59 return dst;
60 }
61
62 int
wt_dn2id_add(Operation * op,WT_SESSION * session,ID pid,Entry * e)63 wt_dn2id_add(
64 Operation *op,
65 WT_SESSION *session,
66 ID pid,
67 Entry *e)
68 {
69 int rc;
70 WT_CURSOR *cursor = NULL;
71 char *revdn = NULL;
72
73 Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_add 0x%lx: \"%s\"\n",
74 e->e_id, e->e_ndn );
75 assert( e->e_id != NOID );
76
77 /* make reverse dn */
78 revdn = mkrevdn(e->e_nname);
79
80 rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
81 NULL, &cursor);
82 if(rc){
83 Debug( LDAP_DEBUG_ANY,
84 LDAP_XSTRING(wt_dn2id_add)
85 ": open_cursor failed: %s (%d)\n",
86 wiredtiger_strerror(rc), rc );
87 goto done;
88 }
89 cursor->set_key(cursor, e->e_ndn);
90 cursor->set_value(cursor, e->e_id, pid, revdn);
91 rc = cursor->insert(cursor);
92 if(rc){
93 Debug( LDAP_DEBUG_ANY,
94 LDAP_XSTRING(wt_dn2id_add)
95 ": insert failed: %s (%d)\n",
96 wiredtiger_strerror(rc), rc );
97 goto done;
98 }
99
100 done:
101 if(revdn){
102 ch_free(revdn);
103 }
104 if(cursor){
105 cursor->close(cursor);
106 }
107 Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id_add 0x%lx: %d\n", e->e_id, rc );
108 return rc;
109 }
110
111 int
wt_dn2id_delete(Operation * op,WT_SESSION * session,struct berval * ndn)112 wt_dn2id_delete(
113 Operation *op,
114 WT_SESSION *session,
115 struct berval *ndn)
116 {
117 int rc = 0;
118 WT_CURSOR *cursor = NULL;
119
120 Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_delete %s\n", ndn->bv_val );
121
122 rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
123 NULL, &cursor);
124 if ( rc ) {
125 Debug( LDAP_DEBUG_ANY,
126 LDAP_XSTRING(wt_dn2id_delete)
127 ": open_cursor failed: %s (%d)\n",
128 wiredtiger_strerror(rc), rc );
129 goto done;
130 }
131
132 cursor->set_key(cursor, ndn->bv_val);
133 rc = cursor->remove(cursor);
134 if ( rc ) {
135 Debug( LDAP_DEBUG_ANY,
136 LDAP_XSTRING(wt_dn2id_delete)
137 ": remove failed: %s (%d)\n",
138 wiredtiger_strerror(rc), rc );
139 goto done;
140 }
141
142 Debug( LDAP_DEBUG_TRACE,
143 "<= wt_dn2id_delete %s: %d\n",
144 ndn->bv_val, rc );
145 done:
146 if(cursor){
147 cursor->close(cursor);
148 }
149 return rc;
150 }
151
152 int
wt_dn2id(Operation * op,WT_SESSION * session,struct berval * ndn,ID * id)153 wt_dn2id(
154 Operation *op,
155 WT_SESSION *session,
156 struct berval *ndn,
157 ID *id)
158 {
159 WT_CURSOR *cursor = NULL;
160 struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
161 int rc;
162 ID nid;
163
164 Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n",
165 ndn->bv_val );
166
167 if ( ndn->bv_len == 0 ) {
168 *id = 0;
169 goto done;
170 }
171
172 rc = session->open_cursor(session, WT_TABLE_DN2ID
173 "(id)",
174 NULL, NULL, &cursor);
175 if( rc ){
176 Debug( LDAP_DEBUG_ANY,
177 LDAP_XSTRING(wt_dn2id)
178 ": cursor open failed: %s (%d)\n",
179 wiredtiger_strerror(rc), rc );
180 goto done;
181 }
182
183 cursor->set_key(cursor, ndn->bv_val);
184 rc = cursor->search(cursor);
185 switch( rc ){
186 case 0:
187 break;
188 case WT_NOTFOUND:
189 goto done;
190 default:
191 Debug( LDAP_DEBUG_ANY,
192 LDAP_XSTRING(wt_dn2id)
193 ": search failed: %s (%d)\n",
194 wiredtiger_strerror(rc), rc );
195 goto done;
196 }
197 rc = cursor->get_value(cursor, id);
198 if( rc ){
199 Debug( LDAP_DEBUG_ANY,
200 LDAP_XSTRING(wt_dn2id)
201 ": get_value failed: %s (%d)\n",
202 wiredtiger_strerror(rc), rc );
203 goto done;
204 }
205
206 done:
207 if(cursor){
208 cursor->close(cursor);
209 }
210
211 if( rc ) {
212 Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: get failed: %s (%d)\n",
213 wiredtiger_strerror(rc), rc );
214 } else {
215 Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: got id=0x%lx\n",
216 *id );
217 }
218
219 return rc;
220 }
221
222 int
wt_dn2id_has_children(Operation * op,WT_SESSION * session,ID id)223 wt_dn2id_has_children(
224 Operation *op,
225 WT_SESSION *session,
226 ID id )
227 {
228 struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
229 WT_CURSOR *cursor = NULL;
230 int rc;
231 uint64_t key = id;
232
233 rc = session->open_cursor(session, WT_INDEX_PID,
234 NULL, NULL, &cursor);
235 if( rc ){
236 Debug( LDAP_DEBUG_ANY,
237 LDAP_XSTRING(wt_dn2id_has_children)
238 ": cursor open failed: %s (%d)\n",
239 wiredtiger_strerror(rc), rc );
240 goto done;
241 }
242
243 cursor->set_key(cursor, key);
244 rc = cursor->search(cursor);
245
246 done:
247 if(cursor){
248 cursor->close(cursor);
249 }
250
251 return rc;
252 }
253
254 int
wt_dn2idl(Operation * op,WT_SESSION * session,struct berval * ndn,Entry * e,ID * ids,ID * stack)255 wt_dn2idl(
256 Operation *op,
257 WT_SESSION *session,
258 struct berval *ndn,
259 Entry *e,
260 ID *ids,
261 ID *stack)
262 {
263 struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
264 WT_CURSOR *cursor = NULL;
265 int exact = 0;
266 int rc;
267 char *revdn = NULL;
268 size_t revdn_len;
269 char *key;
270 ID id, pid;
271
272 Debug( LDAP_DEBUG_TRACE,
273 "=> wt_dn2idl(\"%s\")\n",
274 ndn->bv_val );
275
276 if(op->ors_scope != LDAP_SCOPE_ONELEVEL &&
277 be_issuffix( op->o_bd, &e->e_nname )){
278 WT_IDL_ALL(wi, ids);
279 return 0;
280 }
281
282 revdn = mkrevdn(*ndn);
283 revdn_len = strlen(revdn);
284 rc = session->open_cursor(session, WT_INDEX_REVDN"(id, pid)",
285 NULL, NULL, &cursor);
286 if( rc ){
287 Debug( LDAP_DEBUG_ANY,
288 LDAP_XSTRING(wt_dn2idl)
289 ": cursor open failed: %s (%d)\n",
290 wiredtiger_strerror(rc), rc );
291 goto done;
292 }
293 cursor->set_key(cursor, revdn);
294 rc = cursor->search_near(cursor, &exact);
295 if( rc ){
296 Debug( LDAP_DEBUG_ANY,
297 LDAP_XSTRING(wt_dn2idl)
298 ": search failed: %s (%d)\n",
299 wiredtiger_strerror(rc), rc );
300 goto done;
301 }
302
303 do {
304 rc = cursor->get_key(cursor, &key);
305 if( rc ){
306 Debug( LDAP_DEBUG_ANY,
307 LDAP_XSTRING(wt_dn2idl)
308 ": get_key failed: %s (%d)\n",
309 wiredtiger_strerror(rc), rc );
310 goto done;
311 }
312
313 if( strncmp(revdn, key, revdn_len) ){
314 if(exact < 0){
315 rc = cursor->next(cursor);
316 if (rc) {
317 break;
318 }else{
319 continue;
320 }
321 }
322 break;
323 }
324 exact = 0;
325 rc = cursor->get_value(cursor, &id, &pid);
326 if( rc ){
327 Debug( LDAP_DEBUG_ANY,
328 LDAP_XSTRING(wt_dn2id)
329 ": get_value failed: %s (%d)\n",
330 wiredtiger_strerror(rc), rc );
331 goto done;
332 }
333 if( op->ors_scope == LDAP_SCOPE_ONELEVEL &&
334 e->e_id != pid){
335 rc = cursor->next(cursor);
336 if ( rc ) {
337 break;
338 }
339 continue;
340 }else{
341 wt_idl_append_one(ids, id);
342 }
343 rc = cursor->next(cursor);
344 }while(rc == 0);
345
346 if (rc == WT_NOTFOUND ) {
347 rc = LDAP_SUCCESS;
348 }
349
350 done:
351 if(revdn){
352 ch_free(revdn);
353 }
354 if(cursor){
355 cursor->close(cursor);
356 }
357 return rc;
358 }
359
360 #if 0
361 int
362 wt_dn2id(
363 Operation *op,
364 WT_SESSION *session,
365 struct berval *dn,
366 ID *id)
367 {
368 struct wt_info *wi = (struct wy_info *) op->o_bd->be_private;
369 WT_CURSOR *cursor = NULL;
370 int rc;
371 Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n", dn->bv_val );
372
373 rc = session->open_cursor(session, WT_INDEX_DN"(id)",
374 NULL, NULL, &cursor);
375 if( rc ){
376 Debug( LDAP_DEBUG_ANY,
377 LDAP_XSTRING(wt_dn2id)
378 ": cursor open failed: %s (%d)\n",
379 wiredtiger_strerror(rc), rc );
380 return rc;
381 }
382 cursor->set_key(cursor, dn->bv_val);
383 rc = cursor->search(cursor);
384 if( !rc ){
385 cursor->get_key(cursor, &id);
386 }
387 cursor->close(cursor);
388 return rc;
389 }
390 #endif
391
392 /*
393 * Local variables:
394 * indent-tabs-mode: t
395 * tab-width: 4
396 * c-basic-offset: 4
397 * End:
398 */
399