xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-wt/dn2id.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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