]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/modify.c
Sync with 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-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 "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;
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         Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
76                 "modifying entry \"%s\" (id=%ld)\n", 
77                 e_id.dn.bv_val, e_id.id, 0 );
78
79         oc = backsql_id2oc( bi, e_id.oc_id );
80         if ( oc == NULL ) {
81                 Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
82                         "cannot determine objectclass of entry -- aborting\n",
83                         0, 0, 0 );
84                 /*
85                  * FIXME: should never occur, since the entry was built!!!
86                  */
87
88                 /*
89                  * FIXME: we don't want to send back 
90                  * excessively detailed messages
91                  */
92                 rs->sr_err = LDAP_OTHER;
93                 rs->sr_text = "SQL-backend error";
94                 send_ldap_result( op, rs );
95                 return 1;
96         }
97
98         e.e_attrs = NULL;
99         e.e_name = op->o_req_dn;
100         e.e_nname = op->o_req_ndn;
101         if ( !acl_check_modlist( op, &e, op->oq_modify.rs_modlist ) ) {
102                 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
103
104         } else {
105                 rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id,
106                                 op->oq_modify.rs_modlist );
107         }
108
109         if ( rs->sr_err == LDAP_SUCCESS ) {
110                 /*
111                  * Commit only if all operations succeed
112                  */
113                 SQLTransact( SQL_NULL_HENV, dbh, 
114                                 op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
115         }
116         send_ldap_result( op, rs );
117         Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
118
119         return op->o_noop;
120 }
121
122 #endif /* SLAPD_SQL */
123