1 /* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/modify.c,v 1.53.2.5 2008/02/11 23:26:48 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2008 The OpenLDAP Foundation.
5 * Portions Copyright 1999 Dmitry Kovalev.
6 * Portions Copyright 2002 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
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>.
18 * This work was initially developed by Dmitry Kovalev for inclusion
19 * by OpenLDAP Software. Additional significant contributors include
20 * Pierangelo Masarati.
26 #include <sys/types.h>
27 #include "ac/string.h"
30 #include "proto-sql.h"
33 backsql_modify( Operation
*op
, SlapReply
*rs
)
35 backsql_info
*bi
= (backsql_info
*)op
->o_bd
->be_private
;
36 SQLHDBC dbh
= SQL_NULL_HDBC
;
37 backsql_oc_map_rec
*oc
= NULL
;
38 backsql_srch_info bsi
= { 0 };
39 Entry m
= { 0 }, *e
= NULL
;
40 int manageDSAit
= get_manageDSAit( op
);
41 SQLUSMALLINT CompletionType
= SQL_ROLLBACK
;
44 * FIXME: in case part of the operation cannot be performed
45 * (missing mapping, SQL write fails or so) the entire operation
46 * should be rolled-back
48 Debug( LDAP_DEBUG_TRACE
, "==>backsql_modify(): modifying entry \"%s\"\n",
49 op
->o_req_ndn
.bv_val
, 0, 0 );
51 rs
->sr_err
= backsql_get_db_conn( op
, &dbh
);
52 if ( rs
->sr_err
!= LDAP_SUCCESS
) {
53 Debug( LDAP_DEBUG_TRACE
, " backsql_modify(): "
54 "could not get connection handle - exiting\n",
57 * FIXME: we don't want to send back
58 * excessively detailed messages
60 rs
->sr_text
= ( rs
->sr_err
== LDAP_OTHER
)
61 ? "SQL-backend error" : NULL
;
66 rs
->sr_err
= backsql_init_search( &bsi
, &op
->o_req_ndn
,
68 (time_t)(-1), NULL
, dbh
, op
, rs
,
69 slap_anlist_all_attributes
,
70 ( BACKSQL_ISF_MATCHED
| BACKSQL_ISF_GET_ENTRY
| BACKSQL_ISF_GET_OC
) );
71 switch ( rs
->sr_err
) {
76 if ( manageDSAit
&& !BER_BVISNULL( &bsi
.bsi_e
->e_nname
) &&
77 dn_match( &op
->o_req_ndn
, &bsi
.bsi_e
->e_nname
) )
79 rs
->sr_err
= LDAP_SUCCESS
;
81 rs
->sr_matched
= NULL
;
83 ber_bvarray_free( rs
->sr_ref
);
92 Debug( LDAP_DEBUG_TRACE
, "backsql_modify(): "
93 "could not retrieve modifyDN ID - no such entry\n",
95 if ( !BER_BVISNULL( &m
.e_nname
) ) {
96 /* FIXME: should always be true! */
105 #ifdef BACKSQL_ARBITRARY_KEY
106 Debug( LDAP_DEBUG_TRACE
, " backsql_modify(): "
107 "modifying entry \"%s\" (id=%s)\n",
108 bsi
.bsi_base_id
.eid_dn
.bv_val
,
109 bsi
.bsi_base_id
.eid_id
.bv_val
, 0 );
110 #else /* ! BACKSQL_ARBITRARY_KEY */
111 Debug( LDAP_DEBUG_TRACE
, " backsql_modify(): "
112 "modifying entry \"%s\" (id=%ld)\n",
113 bsi
.bsi_base_id
.eid_dn
.bv_val
, bsi
.bsi_base_id
.eid_id
, 0 );
114 #endif /* ! BACKSQL_ARBITRARY_KEY */
116 if ( get_assert( op
) &&
117 ( test_filter( op
, &m
, get_assertion( op
) )
118 != LDAP_COMPARE_TRUE
))
120 rs
->sr_err
= LDAP_ASSERTION_FAILED
;
125 slap_mods_opattrs( op
, &op
->orm_modlist
, 1 );
127 assert( bsi
.bsi_base_id
.eid_oc
!= NULL
);
128 oc
= bsi
.bsi_base_id
.eid_oc
;
130 if ( !acl_check_modlist( op
, &m
, op
->orm_modlist
) ) {
131 rs
->sr_err
= LDAP_INSUFFICIENT_ACCESS
;
136 rs
->sr_err
= backsql_modify_internal( op
, rs
, dbh
, oc
,
137 &bsi
.bsi_base_id
, op
->orm_modlist
);
138 if ( rs
->sr_err
!= LDAP_SUCCESS
) {
143 if ( BACKSQL_CHECK_SCHEMA( bi
) ) {
144 char textbuf
[ SLAP_TEXT_BUFLEN
] = { '\0' };
146 backsql_entry_clean( op
, &m
);
149 rs
->sr_err
= backsql_id2entry( &bsi
, &bsi
.bsi_base_id
);
150 if ( rs
->sr_err
!= LDAP_SUCCESS
) {
155 rs
->sr_err
= entry_schema_check( op
, &m
, NULL
, 0, 0,
156 &rs
->sr_text
, textbuf
, sizeof( textbuf
) );
157 if ( rs
->sr_err
!= LDAP_SUCCESS
) {
158 Debug( LDAP_DEBUG_TRACE
, " backsql_modify(\"%s\"): "
159 "entry failed schema check -- aborting\n",
160 m
.e_name
.bv_val
, 0, 0 );
168 * Commit only if all operations succeed
170 if ( rs
->sr_err
== LDAP_SUCCESS
&& !op
->o_noop
) {
172 CompletionType
= SQL_COMMIT
;
175 SQLTransact( SQL_NULL_HENV
, dbh
, CompletionType
);
179 if ( !access_allowed( op
, e
, slap_schema
.si_ad_entry
, NULL
,
180 ACL_DISCLOSE
, NULL
) )
182 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
184 rs
->sr_matched
= NULL
;
186 ber_bvarray_free( rs
->sr_ref
);
192 if ( op
->o_noop
&& rs
->sr_err
== LDAP_SUCCESS
) {
193 rs
->sr_err
= LDAP_X_NO_OPERATION
;
196 send_ldap_result( op
, rs
);
197 slap_graduate_commit_csn( op
);
199 if ( !BER_BVISNULL( &bsi
.bsi_base_id
.eid_ndn
) ) {
200 (void)backsql_free_entryID( &bsi
.bsi_base_id
, 0, op
->o_tmpmemctx
);
203 if ( !BER_BVISNULL( &m
.e_nname
) ) {
204 backsql_entry_clean( op
, &m
);
207 if ( bsi
.bsi_attrs
!= NULL
) {
208 op
->o_tmpfree( bsi
.bsi_attrs
, op
->o_tmpmemctx
);
212 ber_bvarray_free( rs
->sr_ref
);
216 Debug( LDAP_DEBUG_TRACE
, "<==backsql_modify()\n", 0, 0, 0 );