]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/entry-id.c
Experimental cruft to propagate valid Operation to SASL callbacks.
[openldap] / servers / slapd / back-sql / entry-id.c
1 /*
2  *       Copyright 1999, Dmitry Kovalev <mit@openldap.org>, All rights reserved.
3  *
4  *       Redistribution and use in source and binary forms are permitted only
5  *       as authorized by the OpenLDAP Public License.  A copy of this
6  *       license is available at http://www.OpenLDAP.org/license.html or
7  *       in file LICENSE in the top-level directory of the distribution.
8  */
9
10 #include "portable.h"
11
12 #ifdef SLAPD_SQL
13
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include "ac/string.h"
17 #include "ldap_pvt.h"
18 #include "slap.h"
19 #include "back-sql.h"
20 #include "sql-wrap.h"
21 #include "schema-map.h"
22 #include "entry-id.h"
23 #include "util.h"
24
25 backsql_entryID *
26 backsql_free_entryID( backsql_entryID *id, int freeit )
27 {
28         backsql_entryID         *next;
29
30         assert( id );
31
32         next = id->next;
33
34         if ( id->dn.bv_val != NULL ) {
35                 free( id->dn.bv_val );
36         }
37
38         if ( freeit ) {
39                 free( id );
40         }
41
42         return next;
43 }
44
45 int
46 backsql_dn2id(
47         backsql_info            *bi,
48         backsql_entryID         *id,
49         SQLHDBC                 dbh,
50         struct berval           *dn )
51 {
52         SQLHSTMT                sth; 
53         BACKSQL_ROW_NTS         row;
54         RETCODE                 rc;
55         int                     res;
56
57         /* TimesTen */
58         char                    upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
59         char                    *toBind;
60         int                     i, j;
61
62         Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn='%s'\n", 
63                         dn->bv_val, 0, 0 );
64
65         assert( id );
66
67         if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
68                 Debug( LDAP_DEBUG_TRACE, 
69                         "backsql_dn2id(): DN \"%s\" (%ld bytes) "
70                         "exceeds max DN length (%d):\n",
71                         dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
72                 return LDAP_OTHER;
73         }
74         
75         /* begin TimesTen */
76         Debug(LDAP_DEBUG_TRACE, "id_query '%s'\n", bi->id_query, 0, 0);
77         assert( bi->id_query );
78         rc = backsql_Prepare( dbh, &sth, bi->id_query, 0 );
79         if ( rc != SQL_SUCCESS ) {
80                 Debug( LDAP_DEBUG_TRACE, 
81                         "backsql_dn2id(): error preparing SQL:\n%s", 
82                         bi->id_query, 0, 0);
83                 backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
84                 SQLFreeStmt( sth, SQL_DROP );
85                 return LDAP_OTHER;
86         }
87
88         if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
89                 /*
90                  * Prepare an upper cased, byte reversed version 
91                  * that can be searched using indexes
92                  */
93
94                 for ( i = 0, j = dn->bv_len - 1; dn->bv_val[ i ]; i++, j--) {
95                         upperdn[ i ] = dn->bv_val[ j ];
96                 }
97                 upperdn[ i ] = '\0';
98                 ldap_pvt_str2upper( upperdn );
99
100                 Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): upperdn='%s'\n",
101                                 upperdn, 0, 0 );
102                 toBind = upperdn;
103         } else {
104                 if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
105                         AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 );
106                         ldap_pvt_str2upper( upperdn );
107                         Debug( LDAP_DEBUG_TRACE,
108                                 "==>backsql_dn2id(): upperdn='%s'\n",
109                                 upperdn, 0, 0 );
110                         toBind = upperdn;
111
112                 } else {
113                         toBind = dn->bv_val;
114                 }
115         }
116
117         rc = backsql_BindParamStr( sth, 1, toBind, BACKSQL_MAX_DN_LEN );
118         if ( rc != SQL_SUCCESS) {
119                 /* end TimesTen */ 
120                 Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
121                         "error binding dn=\"%s\" parameter:\n", 
122                         toBind, 0, 0 );
123                 backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
124                 SQLFreeStmt( sth, SQL_DROP );
125                 return LDAP_OTHER;
126         }
127
128         rc = SQLExecute( sth );
129         if ( rc != SQL_SUCCESS ) {
130                 Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
131                         "error executing query (\"%s\", \"%s\"):\n", 
132                         bi->id_query, toBind, 0 );
133                 backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
134                 SQLFreeStmt( sth, SQL_DROP );
135                 return LDAP_OTHER;
136         }
137
138         backsql_BindRowAsStrings( sth, &row );
139         rc = SQLFetch( sth );
140         if ( BACKSQL_SUCCESS( rc ) ) {
141                 id->id = strtol( row.cols[ 0 ], NULL, 0 );
142                 id->keyval = strtol( row.cols[ 1 ], NULL, 0 );
143                 id->oc_id = strtol( row.cols[ 2 ], NULL, 0 );
144                 ber_dupbv( &id->dn, dn );
145                 id->next = NULL;
146
147                 res = LDAP_SUCCESS;
148
149         } else {
150                 res = LDAP_NO_SUCH_OBJECT;
151         }
152         backsql_FreeRow( &row );
153
154         SQLFreeStmt( sth, SQL_DROP );
155         if ( res == LDAP_SUCCESS ) {
156                 Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%ld\n",
157                                 id->id, 0, 0 );
158         } else {
159                 Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): no match\n",
160                                 0, 0, 0 );
161         }
162         return res;
163 }
164
165 int
166 backsql_has_children(
167         backsql_info            *bi,
168         SQLHDBC                 dbh,
169         struct berval           *dn )
170 {
171         SQLHSTMT                sth; 
172         BACKSQL_ROW_NTS         row;
173         RETCODE                 rc;
174         int                     res;
175
176         Debug( LDAP_DEBUG_TRACE, "==>backsql_has_children(): dn='%s'\n", 
177                         dn->bv_val, 0, 0 );
178
179         if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
180                 Debug( LDAP_DEBUG_TRACE, 
181                         "backsql_has_children(): DN \"%s\" (%ld bytes) "
182                         "exceeds max DN length (%d):\n",
183                         dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
184                 return LDAP_OTHER;
185         }
186         
187         /* begin TimesTen */
188         Debug(LDAP_DEBUG_TRACE, "children id query '%s'\n", 
189                         bi->has_children_query, 0, 0);
190         assert( bi->has_children_query );
191         rc = backsql_Prepare( dbh, &sth, bi->has_children_query, 0 );
192         if ( rc != SQL_SUCCESS ) {
193                 Debug( LDAP_DEBUG_TRACE, 
194                         "backsql_has_children(): error preparing SQL:\n%s", 
195                         bi->has_children_query, 0, 0);
196                 backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
197                 SQLFreeStmt( sth, SQL_DROP );
198                 return LDAP_OTHER;
199         }
200
201         rc = backsql_BindParamStr( sth, 1, dn->bv_val, BACKSQL_MAX_DN_LEN );
202         if ( rc != SQL_SUCCESS) {
203                 /* end TimesTen */ 
204                 Debug( LDAP_DEBUG_TRACE, "backsql_has_children(): "
205                         "error binding dn=\"%s\" parameter:\n", 
206                         dn->bv_val, 0, 0 );
207                 backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
208                 SQLFreeStmt( sth, SQL_DROP );
209                 return LDAP_OTHER;
210         }
211
212         rc = SQLExecute( sth );
213         if ( rc != SQL_SUCCESS ) {
214                 Debug( LDAP_DEBUG_TRACE, "backsql_has_children(): "
215                         "error executing query (\"%s\", \"%s\"):\n", 
216                         bi->has_children_query, dn->bv_val, 0 );
217                 backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
218                 SQLFreeStmt( sth, SQL_DROP );
219                 return LDAP_OTHER;
220         }
221
222         backsql_BindRowAsStrings( sth, &row );
223         
224         rc = SQLFetch( sth );
225         if ( BACKSQL_SUCCESS( rc ) ) {
226                 if ( strtol( row.cols[ 0 ], NULL, 0 ) > 0 ) {
227                         res = LDAP_COMPARE_TRUE;
228                 } else {
229                         res = LDAP_COMPARE_FALSE;
230                 }
231
232         } else {
233                 res = LDAP_OTHER;
234         }
235         backsql_FreeRow( &row );
236
237         SQLFreeStmt( sth, SQL_DROP );
238
239         Debug( LDAP_DEBUG_TRACE, "<==backsql_has_children(): %s\n",
240                         res == LDAP_COMPARE_TRUE ? "yes" : "no", 0, 0 );
241
242         return res;
243 }
244
245 int
246 backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
247 {
248         RETCODE         rc;
249         SQLHSTMT        sth;
250         BACKSQL_ROW_NTS row;
251         int             i;
252
253         assert( at );
254         assert( bsi );
255  
256         Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
257                 "oc='%s' attr='%s' keyval=%ld\n",
258                 // bsi->oc->name.bv_val, at->name.bv_val, 
259                 bsi->oc->oc->soc_names[0], at->ad->ad_cname.bv_val, 
260                 bsi->c_eid->keyval );
261
262         rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 );
263         if ( rc != SQL_SUCCESS ) {
264                 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
265                         "error preparing query: %s\n", at->query, 0, 0 );
266                 backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
267                 return 1;
268         }
269
270         rc = backsql_BindParamID( sth, 1, &bsi->c_eid->keyval );
271         if ( rc != SQL_SUCCESS ) {
272                 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
273                         "error binding key value parameter\n", 0, 0, 0 );
274                 return 1;
275         }
276
277         rc = SQLExecute( sth );
278         if ( ! BACKSQL_SUCCESS( rc ) ) {
279                 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
280                         "error executing attribute query '%s'\n",
281                         at->query, 0, 0 );
282                 backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
283                 SQLFreeStmt( sth, SQL_DROP );
284                 return 1;
285         }
286
287         backsql_BindRowAsStrings( sth, &row );
288
289         rc = SQLFetch( sth );
290         for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
291                 for ( i = 0; i < row.ncols; i++ ) {
292                         if ( row.is_null[ i ] > 0 ) {
293                                 struct berval   bv;
294
295                                 bv.bv_val = row.cols[ i ];
296 #if 0
297                                 bv.bv_len = row.col_prec[ i ];
298 #else
299                                 /*
300                                  * FIXME: what if a binary 
301                                  * is fetched?
302                                  */
303                                 bv.bv_len = strlen( row.cols[ i ] );
304 #endif
305                                 backsql_entry_addattr( bsi->e, 
306                                                 &row.col_names[ i ], &bv );
307
308 #ifdef BACKSQL_TRACE
309                                 Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
310                                         (int)row.col_prec[ i ], 0, 0 );
311                         } else {
312                                 Debug( LDAP_DEBUG_TRACE, "NULL value "
313                                         "in this row for attribute '%s'\n",
314                                         row.col_names[ i ].bv_val, 0, 0 );
315 #endif /* BACKSQL_TRACE */
316                         }
317                 }
318         }
319
320         backsql_FreeRow( &row );
321         SQLFreeStmt( sth, SQL_DROP );
322         Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
323
324         return 1;
325 }
326
327 Entry *
328 backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
329 {
330         int                     i;
331         backsql_at_map_rec      *at;
332         int                     rc;
333         AttributeDescription    *ad_oc = slap_schema.si_ad_objectClass;
334
335         Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
336
337         rc = dnPrettyNormal( NULL, &eid->dn, &e->e_name, &e->e_nname );
338         if ( rc != LDAP_SUCCESS ) {
339                 return NULL;
340         }
341
342         bsi->oc = backsql_id2oc( bsi->bi, eid->oc_id );
343         bsi->e = e;
344         bsi->c_eid = eid;
345         e->e_attrs = NULL;
346         e->e_private = NULL;
347  
348         /* if ( bsi->base_dn != NULL)??? */
349         
350         e->e_id = eid->id;
351  
352         if ( bsi->attrs != NULL ) {
353                 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
354                         "custom attribute list\n", 0, 0, 0 );
355                 for ( i = 0; bsi->attrs[ i ].an_name.bv_val; i++ ) {
356                         AttributeName *attr = &bsi->attrs[ i ];
357
358                         if ( attr->an_desc == ad_oc
359 #if 0   /* FIXME: what is 0.10 ? */
360                                         || !BACKSQL_NCMP( &attr->an_name, &bv_n_0_10 ) 
361 #endif
362                                         ) {
363 #if 0
364                                 backsql_entry_addattr( bsi->e, 
365                                                 &bv_n_objectclass,
366                                                 &bsi->oc->name );
367 #endif
368                                 continue;
369                         }
370
371                         at = backsql_ad2at( bsi->oc, attr->an_desc );
372                         if ( at != NULL ) {
373                                 backsql_get_attr_vals( at, bsi );
374                         } else {
375                                 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
376                                         "attribute '%s' is not defined "
377                                         "for objectlass '%s'\n",
378                                         attr->an_name.bv_val, 
379                                         bsi->oc->name.bv_val, 0 );
380                         }
381                 }
382
383         } else {
384                 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
385                         "retrieving all attributes\n", 0, 0, 0 );
386                 avl_apply( bsi->oc->attrs, (AVL_APPLY)backsql_get_attr_vals,
387                                 bsi, 0, AVL_INORDER );
388         }
389
390         if ( attr_merge_one( bsi->e, ad_oc, &bsi->oc->name ) ) {
391                 entry_free( e );
392                 return NULL;
393         }
394
395         if ( global_schemacheck ) {
396                 const char      *text = NULL;
397                 char            textbuf[ 1024 ];
398                 size_t          textlen = sizeof( textbuf );
399                 struct berval   bv[ 2 ] = { bsi->oc->name, { 0, NULL } };
400                 struct berval   soc;
401                 AttributeDescription    *ad_soc
402                         = slap_schema.si_ad_structuralObjectClass;
403
404                 int rc = structural_class( bv, &soc, NULL, 
405                                 &text, textbuf, textlen );
406                 if ( rc != LDAP_SUCCESS ) {
407                         entry_free( e );
408                         return NULL;
409                 }
410
411                 if ( bsi->attr_flags | BSQL_SF_ALL_OPER 
412                                 || an_find( bsi->attrs, &AllOper ) ) {
413                         if ( attr_merge_one( bsi->e, ad_soc, &soc ) ) {
414                                 entry_free( e );
415                                 return NULL;
416                         }
417                 }
418         }
419
420         Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
421
422         return e;
423 }
424
425 #endif /* SLAPD_SQL */
426