1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1999-2011 The OpenLDAP Foundation. 5 * Portions Copyright 1999 Dmitry Kovalev. 6 * Portions Copyright 2002 Pierangelo Mararati. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17/* ACKNOWLEDGEMENTS: 18 * This work was initially developed by Dmitry Kovalev for inclusion 19 * by OpenLDAP Software. Additional significant contributors include 20 * Pierangelo Masarati 21 */ 22 23/* 24 * The following changes have been addressed: 25 * 26 * Enhancements: 27 * - re-styled code for better readability 28 * - upgraded backend API to reflect recent changes 29 * - LDAP schema is checked when loading SQL/LDAP mapping 30 * - AttributeDescription/ObjectClass pointers used for more efficient 31 * mapping lookup 32 * - bervals used where string length is required often 33 * - atomized write operations by committing at the end of each operation 34 * and defaulting connection closure to rollback 35 * - added LDAP access control to write operations 36 * - fully implemented modrdn (with rdn attrs change, deleteoldrdn, 37 * access check, parent/children check and more) 38 * - added parent access control, children control to delete operation 39 * - added structuralObjectClass operational attribute check and 40 * value return on search 41 * - added hasSubordinate operational attribute on demand 42 * - search limits are appropriately enforced 43 * - function backsql_strcat() has been made more efficient 44 * - concat function has been made configurable by means of a pattern 45 * - added config switches: 46 * - fail_if_no_mapping write operations fail if there is no mapping 47 * - has_ldapinfo_dn_ru overrides autodetect 48 * - concat_pattern a string containing two '?' is used 49 * (note that "?||?" should be more portable 50 * than builtin function "CONCAT(?,?)") 51 * - strcast_func cast of string constants in "SELECT DISTINCT 52 * statements (needed by PostgreSQL) 53 * - upper_needs_cast cast the argument of upper when required 54 * (basically when building dn substring queries) 55 * - added noop control 56 * - added values return filter control 57 * - hasSubordinate can be used in search filters (with limitations) 58 * - eliminated oc->name; use oc->oc->soc_cname instead 59 * 60 * Todo: 61 * - add security checks for SQL statements that can be injected (?) 62 * - re-test with previously supported RDBMs 63 * - replace dn_ru and so with normalized dn (no need for upper() and so 64 * in dn match) 65 * - implement a backsql_normalize() function to replace the upper() 66 * conversion routines 67 * - note that subtree deletion, subtree renaming and so could be easily 68 * implemented (rollback and consistency checks are available :) 69 * - implement "lastmod" and other operational stuff (ldap_entries table ?) 70 * - check how to allow multiple operations with one statement, to remove 71 * BACKSQL_REALLOC_STMT from modify.c (a more recent unixODBC lib?) 72 */ 73 74#ifndef PROTO_SQL_H 75#define PROTO_SQL_H 76 77#include "back-sql.h" 78 79/* 80 * add.c 81 */ 82int backsql_modify_delete_all_values( 83 Operation *op, 84 SlapReply *rs, 85 SQLHDBC dbh, 86 backsql_entryID *e_id, 87 backsql_at_map_rec *at ); 88 89int backsql_modify_internal( 90 Operation *op, 91 SlapReply *rs, 92 SQLHDBC dbh, 93 backsql_oc_map_rec *oc, 94 backsql_entryID *e_id, 95 Modifications *modlist ); 96 97/* 98 * api.c 99 */ 100int backsql_api_config( backsql_info *bi, const char *name, 101 int argc, char *argv[] ); 102int backsql_api_destroy( backsql_info *bi ); 103int backsql_api_register( backsql_api *ba ); 104int backsql_api_dn2odbc( Operation *op, SlapReply *rs, struct berval *dn ); 105int backsql_api_odbc2dn( Operation *op, SlapReply *rs, struct berval *dn ); 106 107/* 108 * entry-id.c 109 */ 110#ifdef BACKSQL_ARBITRARY_KEY 111extern struct berval backsql_baseObject_bv; 112#endif /* BACKSQL_ARBITRARY_KEY */ 113 114/* stores in *id the ID in table ldap_entries corresponding to DN, if any */ 115extern int 116backsql_dn2id( Operation *op, SlapReply *rs, SQLHDBC dbh, 117 struct berval *ndn, backsql_entryID *id, 118 int matched, int muck ); 119 120/* stores in *nchildren the count of children for an entry */ 121extern int 122backsql_count_children( Operation *op, SQLHDBC dbh, 123 struct berval *dn, unsigned long *nchildren ); 124 125/* returns LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE if the entry corresponding 126 * to DN has/has not children */ 127extern int 128backsql_has_children( Operation *op, SQLHDBC dbh, struct berval *dn ); 129 130/* free *id and return next in list */ 131extern backsql_entryID * 132backsql_free_entryID( backsql_entryID *id, int freeit, void *ctx ); 133 134/* turn an ID into an entry */ 135extern int 136backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *id ); 137 138/* duplicate an entryID */ 139extern backsql_entryID * 140backsql_entryID_dup( backsql_entryID *eid, void *ctx ); 141 142/* 143 * operational.c 144 */ 145 146Attribute *backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id ); 147 148Attribute *backsql_operational_entryCSN( Operation *op ); 149 150/* 151 * schema-map.c 152 */ 153 154int backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ); 155 156backsql_oc_map_rec *backsql_oc2oc( backsql_info *si, ObjectClass *oc ); 157 158backsql_oc_map_rec *backsql_id2oc( backsql_info *si, unsigned long id ); 159 160backsql_oc_map_rec * backsql_name2oc( backsql_info *si, 161 struct berval *oc_name ); 162 163backsql_at_map_rec *backsql_ad2at( backsql_oc_map_rec *objclass, 164 AttributeDescription *ad ); 165 166int backsql_supad2at( backsql_oc_map_rec *objclass, 167 AttributeDescription *supad, backsql_at_map_rec ***pret ); 168 169int backsql_destroy_schema_map( backsql_info *si ); 170 171/* 172 * search.c 173 */ 174 175int backsql_init_search( backsql_srch_info *bsi, 176 struct berval *nbase, int scope, 177 time_t stoptime, Filter *filter, SQLHDBC dbh, 178 Operation *op, SlapReply *rs, AttributeName *attrs, 179 unsigned flags ); 180 181void backsql_entry_clean( Operation *op, Entry *e ); 182 183/* 184 * sql-wrap.h 185 */ 186 187RETCODE backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, const char* query, int timeout ); 188 189#define backsql_BindParamStr( sth, par_ind, io, str, maxlen ) \ 190 SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind), \ 191 (io), SQL_C_CHAR, SQL_VARCHAR, \ 192 (SQLULEN)(maxlen), 0, (SQLPOINTER)(str), \ 193 (SQLLEN)(maxlen), NULL ) 194 195#define backsql_BindParamBerVal( sth, par_ind, io, bv ) \ 196 SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind), \ 197 (io), SQL_C_CHAR, SQL_VARCHAR, \ 198 (SQLULEN)(bv)->bv_len, 0, \ 199 (SQLPOINTER)(bv)->bv_val, \ 200 (SQLLEN)(bv)->bv_len, NULL ) 201 202#define backsql_BindParamInt( sth, par_ind, io, val ) \ 203 SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind), \ 204 (io), SQL_C_ULONG, SQL_INTEGER, \ 205 0, 0, (SQLPOINTER)(val), 0, (SQLLEN*)NULL ) 206 207#define backsql_BindParamNumID( sth, par_ind, io, val ) \ 208 SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind), \ 209 (io), BACKSQL_C_NUMID, SQL_INTEGER, \ 210 0, 0, (SQLPOINTER)(val), 0, (SQLLEN*)NULL ) 211 212#ifdef BACKSQL_ARBITRARY_KEY 213#define backsql_BindParamID( sth, par_ind, io, id ) \ 214 backsql_BindParamBerVal( (sth), (par_ind), (io), (id) ) 215#else /* ! BACKSQL_ARBITRARY_KEY */ 216#define backsql_BindParamID( sth, par_ind, io, id ) \ 217 backsql_BindParamNumID( (sth), (par_ind), (io), (id) ) 218#endif /* ! BACKSQL_ARBITRARY_KEY */ 219 220RETCODE backsql_BindRowAsStrings_x( SQLHSTMT sth, BACKSQL_ROW_NTS *row, void *ctx ); 221 222RETCODE backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row ); 223 224RETCODE backsql_FreeRow_x( BACKSQL_ROW_NTS *row, void *ctx ); 225 226RETCODE backsql_FreeRow( BACKSQL_ROW_NTS *row ); 227 228void backsql_PrintErrors( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth, int rc ); 229 230int backsql_conn_destroy( backsql_info *bi ); 231 232int backsql_init_db_env( backsql_info *si ); 233 234int backsql_free_db_env( backsql_info *si ); 235 236int backsql_get_db_conn( Operation *op, SQLHDBC *dbh ); 237 238int backsql_free_db_conn( Operation *op, SQLHDBC dbh ); 239 240/* 241 * util.c 242 */ 243 244extern const char 245 backsql_def_oc_query[], 246 backsql_def_needs_select_oc_query[], 247 backsql_def_at_query[], 248 backsql_def_delentry_stmt[], 249 backsql_def_renentry_stmt[], 250 backsql_def_insentry_stmt[], 251 backsql_def_delobjclasses_stmt[], 252 backsql_def_subtree_cond[], 253 backsql_def_upper_subtree_cond[], 254 backsql_id_query[], 255 backsql_def_concat_func[], 256 backsql_check_dn_ru_query[]; 257 258struct berbuf * backsql_strcat_x( struct berbuf *dest, void *memctx, ... ); 259struct berbuf * backsql_strfcat_x( struct berbuf *dest, void *memctx, const char *fmt, ... ); 260 261int backsql_entry_addattr( Entry *e, AttributeDescription *ad, 262 struct berval *at_val, void *memctx ); 263 264int backsql_merge_from_clause( backsql_info *bi, struct berbuf *dest_from, 265 struct berval *src_from ); 266 267int backsql_split_pattern( const char *pattern, BerVarray *split_pattern, 268 int expected ); 269 270int backsql_prepare_pattern( BerVarray split_pattern, BerVarray values, 271 struct berval *res ); 272 273int backsql_entryUUID( backsql_info *bi, backsql_entryID *id, 274 struct berval *entryUUID, void *memctx ); 275int backsql_entryUUID_decode( struct berval *entryUUID, unsigned long *oc_id, 276#ifdef BACKSQL_ARBITRARY_KEY 277 struct berval *keyval 278#else /* ! BACKSQL_ARBITRARY_KEY */ 279 unsigned long *keyval 280#endif /* ! BACKSQL_ARBITRARY_KEY */ 281 ); 282 283/* 284 * former external.h 285 */ 286 287extern BI_init sql_back_initialize; 288 289extern BI_destroy backsql_destroy; 290 291extern BI_db_init backsql_db_init; 292extern BI_db_open backsql_db_open; 293extern BI_db_close backsql_db_close; 294extern BI_db_destroy backsql_db_destroy; 295extern BI_db_config backsql_db_config; 296 297extern BI_op_bind backsql_bind; 298extern BI_op_search backsql_search; 299extern BI_op_compare backsql_compare; 300extern BI_op_modify backsql_modify; 301extern BI_op_modrdn backsql_modrdn; 302extern BI_op_add backsql_add; 303extern BI_op_delete backsql_delete; 304 305extern BI_operational backsql_operational; 306extern BI_entry_get_rw backsql_entry_get; 307extern BI_entry_release_rw backsql_entry_release; 308 309extern BI_connection_destroy backsql_connection_destroy; 310 311int backsql_init_cf( BackendInfo * bi ); 312 313#endif /* PROTO_SQL_H */ 314