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
34char *
35mkrevdn(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
62int
63wt_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
100done:
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
111int
112wt_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 );
145done:
146	if(cursor){
147		cursor->close(cursor);
148	}
149	return rc;
150}
151
152int
153wt_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
206done:
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
222int
223wt_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
246done:
247	if(cursor){
248		cursor->close(cursor);
249	}
250
251	return rc;
252}
253
254int
255wt_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
350done:
351	if(revdn){
352		ch_free(revdn);
353	}
354	if(cursor){
355		cursor->close(cursor);
356	}
357	return rc;
358}
359
360#if 0
361int
362wt_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