1 /* $NetBSD: id2entry.c,v 1.3 2025/09/05 21:16:31 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-2024 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 (at) 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 "back-wt.h" 25 #include "slap-config.h" 26 27 static int wt_id2entry_put( 28 Operation *op, 29 wt_ctx *wc, 30 Entry *e, 31 WT_CURSOR *cursor) 32 { 33 struct berval bv; 34 WT_ITEM item; 35 int rc; 36 37 rc = entry_encode( e, &bv ); 38 if(rc != LDAP_SUCCESS){ 39 return -1; 40 } 41 item.size = bv.bv_len; 42 item.data = bv.bv_val; 43 44 cursor->set_key(cursor, e->e_id); 45 cursor->set_value(cursor, e->e_ndn, &item); 46 rc = cursor->insert(cursor); 47 if ( rc ) { 48 Debug( LDAP_DEBUG_ANY, 49 "wt_id2entry_put: insert failed: %s (%d)\n", 50 wiredtiger_strerror(rc), rc ); 51 goto done; 52 } 53 54 done: 55 ch_free( bv.bv_val ); 56 57 return rc; 58 } 59 60 int wt_id2entry_add( 61 Operation *op, 62 wt_ctx *wc, 63 Entry *e ) 64 { 65 WT_SESSION *session = wc->session; 66 WT_CURSOR *cursor = wc->id2entry_add; 67 int rc; 68 69 if(!cursor){ 70 rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL, 71 "overwrite=false", &cursor); 72 if ( rc ) { 73 Debug( LDAP_DEBUG_ANY, 74 "wt_id2entry_put: open_cursor failed: %s (%d)\n", 75 wiredtiger_strerror(rc), rc ); 76 return rc; 77 } 78 wc->id2entry_add = cursor; 79 } 80 81 rc = wt_id2entry_put(op, wc, e, cursor); 82 83 #ifdef WT_CURSOR_CACHE 84 if(cursor){ 85 cursor->reset(cursor); 86 } 87 #else 88 if(cursor){ 89 cursor->close(cursor); 90 wc->id2entry_add = NULL; 91 } 92 #endif 93 94 return rc; 95 } 96 97 int wt_id2entry_update( 98 Operation *op, 99 wt_ctx *wc, 100 Entry *e ) 101 { 102 WT_SESSION *session = wc->session; 103 WT_CURSOR *cursor = wc->id2entry_update; 104 int rc; 105 106 if(!cursor){ 107 rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL, 108 "overwrite=true", &cursor); 109 if ( rc ) { 110 Debug( LDAP_DEBUG_ANY, 111 "wt_id2entry_put: open_cursor failed: %s (%d)\n", 112 wiredtiger_strerror(rc), rc ); 113 return rc; 114 } 115 wc->id2entry_update = cursor; 116 } 117 rc = wt_id2entry_put(op, wc, e, cursor); 118 119 #ifdef WT_CURSOR_CACHE 120 if(cursor){ 121 cursor->reset(cursor); 122 } 123 #else 124 if(cursor){ 125 cursor->close(cursor); 126 wc->id2entry_update = NULL; 127 } 128 #endif 129 return rc; 130 } 131 132 int wt_id2entry_delete( 133 Operation *op, 134 wt_ctx *wc, 135 Entry *e ) 136 { 137 int rc; 138 WT_SESSION *session = wc->session; 139 WT_CURSOR *cursor = NULL; 140 141 rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL, 142 NULL, &cursor); 143 if ( rc ) { 144 Debug( LDAP_DEBUG_ANY, 145 "wt_id2entry_delete: open_cursor failed: %s (%d)\n", 146 wiredtiger_strerror(rc), rc ); 147 goto done; 148 } 149 cursor->set_key(cursor, e->e_id); 150 rc = cursor->remove(cursor); 151 if ( rc ) { 152 Debug( LDAP_DEBUG_ANY, 153 "wt_id2entry_delete: remove failed: %s (%d)\n", 154 wiredtiger_strerror(rc), rc ); 155 goto done; 156 } 157 158 done: 159 if(cursor){ 160 cursor->close(cursor); 161 } 162 return rc; 163 } 164 165 int wt_id2entry( BackendDB *be, 166 wt_ctx *wc, 167 ID id, 168 Entry **ep ){ 169 int rc; 170 WT_SESSION *session = wc->session; 171 WT_CURSOR *cursor = wc->id2entry; 172 WT_ITEM item; 173 EntryHeader eh; 174 int eoff; 175 Entry *e = NULL; 176 177 if(!cursor){ 178 rc = session->open_cursor(session, WT_TABLE_ID2ENTRY"(entry)", NULL, 179 NULL, &cursor); 180 if ( rc ) { 181 Debug( LDAP_DEBUG_ANY, 182 "wt_id2entry: open_cursor failed: %s (%d)\n", 183 wiredtiger_strerror(rc), rc ); 184 goto done; 185 } 186 wc->id2entry = cursor; 187 } 188 189 cursor->set_key(cursor, id); 190 rc = cursor->search(cursor); 191 if ( rc ) { 192 goto done; 193 } 194 195 cursor->get_value(cursor, &item); 196 rc = wt_entry_header( &item, &eh ); 197 eoff = eh.data - (char *)item.data; 198 eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + item.size; 199 eh.bv.bv_val = ch_malloc( eh.bv.bv_len ); 200 memset(eh.bv.bv_val, 0xff, eh.bv.bv_len); 201 eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval ); 202 memcpy(eh.data, item.data, item.size); 203 eh.data += eoff; 204 rc = entry_decode( &eh, &e ); 205 if ( rc ) { 206 Debug( LDAP_DEBUG_ANY, 207 "wt_id2entry: entry decode error: %s (%d)\n", 208 wiredtiger_strerror(rc), rc ); 209 goto done; 210 } 211 e->e_id = id; 212 *ep = e; 213 214 done: 215 216 #ifdef WT_CURSOR_CACHE 217 if(cursor){ 218 cursor->reset(cursor); 219 } 220 #else 221 if(cursor){ 222 cursor->close(cursor); 223 wc->id2entry = NULL; 224 } 225 #endif 226 return rc; 227 } 228 229 int wt_entry_return( 230 Entry *e 231 ) 232 { 233 if ( !e ) { 234 return 0; 235 } 236 237 /* Our entries are allocated in two blocks; the data comes from 238 * the db itself and the Entry structure and associated pointers 239 * are allocated in entry_decode. The db data pointer is saved 240 * in e_bv. 241 */ 242 if ( e->e_bv.bv_val ) { 243 #if 0 244 /* See if the DNs were changed by modrdn */ 245 if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > 246 e->e_bv.bv_val + e->e_bv.bv_len ) { 247 ch_free(e->e_name.bv_val); 248 ch_free(e->e_nname.bv_val); 249 } 250 #endif 251 e->e_name.bv_val = NULL; 252 e->e_nname.bv_val = NULL; 253 /* In tool mode the e_bv buffer is realloc'd, leave it alone */ 254 if( !(slapMode & SLAP_TOOL_MODE) ) { 255 free( e->e_bv.bv_val ); 256 } 257 BER_BVZERO( &e->e_bv ); 258 } 259 260 entry_free( e ); 261 return 0; 262 } 263 264 int wt_entry_release( 265 Operation *op, 266 Entry *e, 267 int rw ) 268 { 269 return wt_entry_return( e ); 270 } 271 272 /* 273 * return LDAP_SUCCESS IFF we can retrieve the specified entry. 274 */ 275 int wt_entry_get( 276 Operation *op, 277 struct berval *ndn, 278 ObjectClass *oc, 279 AttributeDescription *at, 280 int rw, 281 Entry **ent ) 282 { 283 struct wt_info *wi = (struct wt_info *) op->o_bd->be_private; 284 wt_ctx *wc; 285 Entry *e = NULL; 286 int rc; 287 const char *at_name = at ? at->ad_cname.bv_val : "(null)"; 288 289 Debug( LDAP_DEBUG_ARGS, 290 "wt_entry_get: ndn: \"%s\"\n", ndn->bv_val ); 291 Debug( LDAP_DEBUG_ARGS, 292 "wt_entry_get: oc: \"%s\", at: \"%s\"\n", 293 oc ? oc->soc_cname.bv_val : "(null)", at_name ); 294 295 wc = wt_ctx_get(op, wi); 296 if( !wc ){ 297 Debug( LDAP_DEBUG_ANY, 298 "wt_entry_get: wt_ctx_get failed\n" ); 299 return LDAP_OTHER; 300 } 301 rc = wt_dn2entry(op->o_bd, wc, ndn, &e); 302 switch( rc ) { 303 case 0: 304 break; 305 case WT_NOTFOUND: 306 Debug( LDAP_DEBUG_ACL, 307 "wt_entry_get: cannot find entry: \"%s\"\n", 308 ndn->bv_val ); 309 return LDAP_NO_SUCH_OBJECT; 310 default: 311 Debug( LDAP_DEBUG_ANY, 312 "wt_entry_get: wt_dn2entry failed %s rc=%d\n", 313 wiredtiger_strerror(rc), rc ); 314 rc = LDAP_OTHER; 315 } 316 317 Debug( LDAP_DEBUG_ACL, 318 "wt_entry_get: found entry: \"%s\"\n", ndn->bv_val ); 319 320 if ( oc && !is_entry_objectclass( e, oc, 0 )) { 321 Debug( LDAP_DEBUG_ACL, 322 "wt_entry_get: failed to find objectClass %s\n", 323 oc->soc_cname.bv_val ); 324 rc = LDAP_NO_SUCH_ATTRIBUTE; 325 goto return_results; 326 } 327 328 /* NOTE: attr_find() or attrs_find()? */ 329 if ( at && attr_find( e->e_attrs, at ) == NULL ) { 330 Debug( LDAP_DEBUG_ACL, 331 "wt_entry_get: failed to find attribute %s\n", 332 at->ad_cname.bv_val ); 333 rc = LDAP_NO_SUCH_ATTRIBUTE; 334 goto return_results; 335 } 336 337 return_results: 338 if( rc != LDAP_SUCCESS ) { 339 wt_entry_return( e ); 340 }else{ 341 *ent = e; 342 } 343 344 Debug( LDAP_DEBUG_TRACE, "wt_entry_get: rc=%d\n", rc ); 345 346 return rc; 347 } 348 349 /* 350 * Local variables: 351 * indent-tabs-mode: t 352 * tab-width: 4 353 * c-basic-offset: 4 354 * End: 355 */ 356