]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/other.c
More changes to CHANGES
[openldap] / servers / slapd / back-sql / other.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2004 The OpenLDAP Foundation.
5  * Portions Copyright 1999 Dmitry Kovalev.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by Dmitry Kovalev for inclusion
18  * by OpenLDAP Software.
19  */
20
21 #include "portable.h"
22
23 #ifdef SLAPD_SQL
24
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include "slap.h"
28 #include "back-sql.h"
29 #include "sql-wrap.h"
30 #include "entry-id.h"
31 #include "util.h"
32
33 int
34 backsql_compare( Operation *op, SlapReply *rs )
35 {
36         backsql_info            *bi = (backsql_info*)op->o_bd->be_private;
37         backsql_entryID         user_id;
38         SQLHDBC                 dbh;
39         Entry                   *e = NULL, user_entry;
40         Attribute               *a = NULL, *a_op = NULL;
41         backsql_srch_info       bsi;
42         int                     rc;
43         AttributeName           anlist[2];
44
45         user_entry.e_name.bv_val = NULL;
46         user_entry.e_name.bv_len = 0;
47         user_entry.e_nname.bv_val = NULL;
48         user_entry.e_nname.bv_len = 0;
49         user_entry.e_attrs = NULL;
50  
51         Debug( LDAP_DEBUG_TRACE, "==>backsql_compare()\n", 0, 0, 0 );
52
53         rs->sr_err = backsql_get_db_conn( op, &dbh );
54         if (!dbh) {
55                 Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
56                         "could not get connection handle - exiting\n",
57                         0, 0, 0 );
58
59                 rs->sr_text = ( rs->sr_err == LDAP_OTHER )
60                         ? "SQL-backend error" : NULL;
61                 goto return_results;
62         }
63
64         rc = backsql_dn2id( bi, &user_id, dbh, &op->o_req_ndn );
65         if ( rc != LDAP_SUCCESS ) {
66                 Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
67                         "could not retrieve compare dn id - no such entry\n", 
68                         0, 0, 0 );
69                 rs->sr_err = LDAP_NO_SUCH_OBJECT;
70                 goto return_results;
71         }
72
73         anlist[0].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
74         anlist[0].an_desc = op->oq_compare.rs_ava->aa_desc;
75         anlist[1].an_name.bv_val = NULL;
76
77         /*
78          * Try to get attr as dynamic operational
79          */
80         if ( is_at_operational( op->oq_compare.rs_ava->aa_desc->ad_type ) ) {
81                 AttributeName   *an_old;
82                 Entry           *e_old;
83
84                 user_entry.e_attrs = NULL;
85                 user_entry.e_name = op->o_req_dn;
86                 user_entry.e_nname = op->o_req_ndn;
87
88                 an_old = rs->sr_attrs;
89                 e_old = rs->sr_entry;
90
91                 rs->sr_attrs = anlist;
92                 rs->sr_entry = &user_entry;
93                 rs->sr_err = backsql_operational( op, rs, 0, &a_op );
94                 rs->sr_attrs = an_old;
95                 rs->sr_entry = e_old;
96
97                 if ( rs->sr_err != LDAP_SUCCESS ) {
98                         goto return_results;
99                 }
100                 
101         }
102
103         /*
104          * attr was dynamic operational
105          */
106         if ( a_op != NULL ) {
107                 user_entry.e_attrs = a_op;
108                 e = &user_entry;
109
110         } else {
111                 backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE, 
112                                 -1, -1, -1, NULL, dbh, op, anlist );
113                 e = backsql_id2entry( &bsi, &user_entry, &user_id );
114                 if ( e == NULL ) {
115                         Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
116                                 "error in backsql_id2entry() "
117                                 "- compare failed\n", 0, 0, 0 );
118                         rs->sr_err = LDAP_OTHER;
119                         goto return_results;
120                 }
121         }
122
123         if ( ! access_allowed( op, e, op->oq_compare.rs_ava->aa_desc, 
124                                 &op->oq_compare.rs_ava->aa_value,
125                                 ACL_COMPARE, NULL ) ) {
126                 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
127                 goto return_results;
128         }
129
130         rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;
131         for ( a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc );
132                         a != NULL;
133                         a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ))
134         {
135                 rs->sr_err = LDAP_COMPARE_FALSE;
136                 if ( value_find_ex( op->oq_compare.rs_ava->aa_desc,
137                                         SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
138                                         SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
139                                         a->a_nvals,
140                                         &op->oq_compare.rs_ava->aa_value,
141                                         op->o_tmpmemctx ) == 0 )
142                 {
143                         rs->sr_err = LDAP_COMPARE_TRUE;
144                         break;
145                 }
146         }
147
148 return_results:;
149         send_ldap_result( op, rs );
150
151         if ( e != NULL ) {
152                 if ( e->e_name.bv_val != NULL ) {
153                         free( e->e_name.bv_val );
154                 }
155
156                 if ( e->e_nname.bv_val != NULL ) {
157                         free( e->e_nname.bv_val );
158                 }
159
160                 if ( e->e_attrs != NULL ) {
161                         attrs_free( e->e_attrs );
162                 }
163         }
164
165         Debug(LDAP_DEBUG_TRACE,"<==backsql_compare()\n",0,0,0);
166         switch ( rs->sr_err ) {
167         case LDAP_COMPARE_TRUE:
168         case LDAP_COMPARE_FALSE:
169                 return 0;
170
171         default:
172                 return 1;
173         }
174 }
175  
176 /*
177  * sets the supported operational attributes (if required)
178  */
179
180 int
181 backsql_operational(
182         Operation       *op,
183         SlapReply       *rs,
184         int             opattrs,
185         Attribute       **a )
186 {
187
188         backsql_info            *bi = (backsql_info*)op->o_bd->be_private;
189         SQLHDBC                 dbh = SQL_NULL_HDBC;
190         Attribute               **aa = a;
191         int                     rc = 0;
192
193         Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry '%s'\n",
194                         rs->sr_entry->e_nname.bv_val, 0, 0 );
195
196
197         if ( ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) 
198                         && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL ) {
199                 
200                 rc = backsql_get_db_conn( op, &dbh );
201                 if ( rc != LDAP_SUCCESS ) {
202                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
203                                 "could not get connection handle - exiting\n", 
204                                 0, 0, 0 );
205                         return 1;
206                 }
207                 
208                 rc = backsql_has_children( bi, dbh, &rs->sr_entry->e_nname );
209
210                 switch( rc ) {
211                 case LDAP_COMPARE_TRUE:
212                 case LDAP_COMPARE_FALSE:
213                         *aa = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
214                         if ( *aa != NULL ) {
215                                 aa = &(*aa)->a_next;
216                         }
217                         rc = 0;
218                         break;
219
220                 default:
221                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
222                                 "has_children failed( %d)\n", rc, 0, 0 );
223                         rc = 1;
224                         break;
225                 }
226         }
227
228         Debug( LDAP_DEBUG_TRACE, "<==backsql_operational()\n", 0, 0, 0);
229
230         return rc;
231 }
232
233 #endif /* SLAPD_SQL */
234