]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/modify.c
Import ITS#4158 fixes from HEAD
[openldap] / servers / slapd / back-sql / modify.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2005 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 "ac/string.h"
28
29 #include "slap.h"
30 #include "ldap_pvt.h"
31 #include "proto-sql.h"
32
33 int
34 backsql_modify( Operation *op, SlapReply *rs )
35 {
36         backsql_info            *bi = (backsql_info*)op->o_bd->be_private;
37         SQLHDBC                 dbh;
38         backsql_oc_map_rec      *oc = NULL;
39         backsql_entryID         e_id = BACKSQL_ENTRYID_INIT;
40         Entry                   e;
41
42         /*
43          * FIXME: in case part of the operation cannot be performed
44          * (missing mapping, SQL write fails or so) the entire operation
45          * should be rolled-back
46          */
47         Debug( LDAP_DEBUG_TRACE, "==>backsql_modify(): modifying entry \"%s\"\n",
48                 op->o_req_ndn.bv_val, 0, 0 );
49
50         rs->sr_err = backsql_get_db_conn( op, &dbh );
51         if ( rs->sr_err != LDAP_SUCCESS ) {
52                 Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
53                         "could not get connection handle - exiting\n", 
54                         0, 0, 0 );
55                 /*
56                  * FIXME: we don't want to send back 
57                  * excessively detailed messages
58                  */
59                 rs->sr_text = ( rs->sr_err == LDAP_OTHER )
60                         ? "SQL-backend error" : NULL;
61                 send_ldap_result( op, rs );
62                 return 1;
63         }
64
65         rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn );
66         if ( rs->sr_err != LDAP_SUCCESS ) {
67                 Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
68                         "could not lookup entry id\n", 0, 0, 0 );
69                 rs->sr_text = ( rs->sr_err == LDAP_OTHER )
70                         ? "SQL-backend error" : NULL;
71                 send_ldap_result( op, rs );
72                 return 1;
73         }
74
75 #ifdef BACKSQL_ARBITRARY_KEY
76         Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
77                 "modifying entry \"%s\" (id=%s)\n", 
78                 e_id.eid_dn.bv_val, e_id.eid_id.bv_val, 0 );
79 #else /* ! BACKSQL_ARBITRARY_KEY */
80         Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
81                 "modifying entry \"%s\" (id=%ld)\n", 
82                 e_id.eid_dn.bv_val, e_id.eid_id, 0 );
83 #endif /* ! BACKSQL_ARBITRARY_KEY */
84
85         oc = backsql_id2oc( bi, e_id.eid_oc_id );
86         if ( oc == NULL ) {
87                 Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
88                         "cannot determine objectclass of entry -- aborting\n",
89                         0, 0, 0 );
90                 /*
91                  * FIXME: should never occur, since the entry was built!!!
92                  */
93
94                 /*
95                  * FIXME: we don't want to send back 
96                  * excessively detailed messages
97                  */
98                 rs->sr_err = LDAP_OTHER;
99                 rs->sr_text = "SQL-backend error";
100                 send_ldap_result( op, rs );
101                 return 1;
102         }
103
104         e.e_attrs = NULL;
105         e.e_name = op->o_req_dn;
106         e.e_nname = op->o_req_ndn;
107         if ( !acl_check_modlist( op, &e, op->oq_modify.rs_modlist ) ) {
108                 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
109
110         } else {
111                 rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id,
112                                 op->oq_modify.rs_modlist );
113         }
114
115         if ( rs->sr_err == LDAP_SUCCESS ) {
116                 /*
117                  * Commit only if all operations succeed
118                  */
119                 SQLTransact( SQL_NULL_HENV, dbh, 
120                                 op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
121         }
122         send_ldap_result( op, rs );
123         Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
124
125         return op->o_noop;
126 }
127
128 #endif /* SLAPD_SQL */
129