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