]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb2/add.c
Code clean-up.
[openldap] / servers / slapd / back-bdb2 / add.c
1 /* add.c - ldap bdb2 back-end add routine */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/socket.h>
8 #include <ac/string.h>
9
10 #include "slap.h"
11 #include "back-bdb2.h"
12 #include "proto-back-bdb2.h"
13
14 static int
15 bdb2i_back_add_internal(
16     BackendDB   *be,
17     Connection  *conn,
18     Operation   *op,
19     Entry       *e
20 )
21 {
22         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
23         char            *pdn;
24         Entry           *p = NULL;
25         int                     rc; 
26
27         Debug(LDAP_DEBUG_ARGS, "==> bdb2i_back_add: %s\n", e->e_dn, 0, 0);
28
29         if ( ( bdb2i_dn2id( be, e->e_ndn ) ) != NOID ) {
30                 entry_free( e );
31                 send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" );
32                 return( -1 );
33         }
34
35         if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
36                 Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
37                         0, 0, 0 );
38
39                 entry_free( e );
40                 send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION, "",
41                     "" );
42                 return( -1 );
43         }
44
45         /*
46          * Get the parent dn and see if the corresponding entry exists.
47          * If the parent does not exist, only allow the "root" user to
48          * add the entry.
49          */
50
51         if ( (pdn = dn_parent( be, e->e_ndn )) != NULL ) {
52                 char *matched = NULL;
53
54                 /* get parent with writer lock */
55                 if ( (p = bdb2i_dn2entry_w( be, pdn, &matched )) == NULL ) {
56                         Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", 0,
57                             0, 0 );
58                         send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
59                             matched, "" );
60
61                         if ( matched != NULL ) {
62                                 free( matched );
63                         }
64
65                         entry_free( e );
66                         free( pdn );
67                         return -1;
68                 }
69
70                 free(pdn);
71
72                 if ( matched != NULL ) {
73                         free( matched );
74                 }
75
76                 if ( ! access_allowed( be, conn, op, p,
77                         "children", NULL, ACL_WRITE ) )
78                 {
79                         Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
80                             0, 0 );
81                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
82                             "", "" );
83
84                         /* free parent and writer lock */
85                         bdb2i_cache_return_entry_w( &li->li_cache, p ); 
86
87                         entry_free( e );
88                         return -1;
89                 }
90
91         } else {
92                 /* no parent, must be adding entry to root */
93                 if ( ! be_isroot( be, op->o_ndn ) ) {
94                         Debug( LDAP_DEBUG_TRACE, "no parent & not root\n", 0,
95                             0, 0 );
96                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
97                             "", "" );
98
99                         entry_free( e );
100                         return -1;
101                 }
102         }
103
104         e->e_id = bdb2i_next_id( be );
105
106         /*
107          * Try to add the entry to the cache, assign it a new dnid.
108          */
109         rc = bdb2i_cache_add_entry_rw( &li->li_cache, e, CACHE_WRITE_LOCK );
110
111         if ( rc != 0 ) {
112                 if( p != NULL) {
113                         /* free parent and writer lock */
114                         bdb2i_cache_return_entry_w( &li->li_cache, p ); 
115                 }
116
117                 Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
118                     0 );
119
120                 /* return the id */
121                 bdb2i_next_id_return( be, e->e_id );
122                 
123                 /* free the entry */
124                 entry_free( e );
125
126                 if(rc > 0) {
127                         send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" );
128                 } else {
129                         send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
130                 }
131
132                 return( -1 );
133         }
134
135         rc = -1;
136
137         /*
138          * add it to the id2children index for the parent
139          */
140
141         if ( bdb2i_id2children_add( be, p, e ) != 0 ) {
142                 Debug( LDAP_DEBUG_TRACE, "bdb2i_id2children_add failed\n", 0,
143                     0, 0 );
144                 send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
145
146                 goto return_results;
147         }
148
149         /*
150          * Add the entry to the attribute indexes, then add it to
151          * the id2children index, dn2id index, and the id2entry index.
152          */
153
154         /* attribute indexes */
155         if ( bdb2i_index_add_entry( be, e ) != 0 ) {
156                 Debug( LDAP_DEBUG_TRACE, "bdb2i_index_add_entry failed\n", 0,
157                     0, 0 );
158                 send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
159
160                 goto return_results;
161         }
162
163         /* dn2id index */
164         if ( bdb2i_dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
165                 Debug( LDAP_DEBUG_TRACE, "bdb2i_dn2id_add failed\n", 0,
166                     0, 0 );
167                 send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
168
169                 goto return_results;
170         }
171
172         /* id2entry index */
173         if ( bdb2i_id2entry_add( be, e ) != 0 ) {
174                 Debug( LDAP_DEBUG_TRACE, "bdb2i_id2entry_add failed\n", 0,
175                     0, 0 );
176                 (void) bdb2i_dn2id_delete( be, e->e_ndn );
177                 send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
178
179                 goto return_results;
180         }
181
182         send_ldap_result( conn, op, LDAP_SUCCESS, "", "" );
183         rc = 0;
184
185 return_results:;
186         if (p != NULL) {
187                 /* free parent and writer lock */
188                 bdb2i_cache_return_entry_w( &li->li_cache, p ); 
189
190         }
191
192         /* free entry and writer lock */
193         bdb2i_cache_return_entry_w( &li->li_cache, e ); 
194
195         return( rc );
196 }
197
198
199 int
200 bdb2_back_add(
201     BackendDB   *be,
202     Connection  *conn,
203     Operation   *op,
204     Entry       *e
205 )
206 {
207         DB_LOCK         lock;
208         struct ldbminfo *li  = (struct ldbminfo *) be->be_private;
209         struct timeval  time1;
210         int             ret;
211
212         bdb2i_start_timing( be->bd_info, &time1 );
213
214         if ( bdb2i_enter_backend_w( get_dbenv( be ), &lock ) != 0 ) {
215
216                 send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
217                 return( -1 );
218
219         }
220
221         /*  check, if a new default attribute index will be created,
222                 in which case we have to open the index file BEFORE TP  */
223         switch ( slapMode ) {
224                 case SLAP_SERVER_MODE:
225                 case SLAP_TIMEDSERVER_MODE:
226                 case SLAP_TOOL_MODE:
227                         bdb2i_check_default_attr_index_add( li, e );
228                         break;
229         }
230
231         ret = bdb2i_back_add_internal( be, conn, op, e );
232         (void) bdb2i_leave_backend( get_dbenv( be ), lock );
233         bdb2i_stop_timing( be->bd_info, time1, "ADD", conn, op );
234
235         return( ret );
236 }
237
238