Revert "ldb: Permit desactivation of autocomit for every ldb_xxx_ctrl function"
[kai/samba.git] / lib / ldb / tools / ldbutil.c
1 /*
2    ldb database library utility
3
4    Copyright (C) Matthieu Patou 2009
5
6      ** NOTE! The following LGPL license applies to the ldb
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 3 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 /*
25  *  Name: ldb
26  *
27  *  Description: Common function used by ldb_add/ldb_modify/ldb_delete
28  *
29  *  Author: Matthieu Patou
30  */
31
32 #include "ldb.h"
33 #include "ldb_module.h"
34 #include "ldbutil.h"
35
36
37 /* autostarts a transacion if none active */
38 static int ldb_do_autotransaction(struct ldb_context *ldb,
39                                        struct ldb_request *req)
40 {
41         int ret;
42
43         ret = ldb_transaction_start(ldb);
44         if (ret != LDB_SUCCESS) {
45                 return ret;
46         }
47
48         ret = ldb_request(ldb, req);
49         if (ret == LDB_SUCCESS) {
50                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
51         }
52
53         if (ret == LDB_SUCCESS) {
54                 return ldb_transaction_commit(ldb);
55         }
56         ldb_transaction_cancel(ldb);
57
58         if (ldb_errstring(ldb) == NULL) {
59                 /* no error string was setup by the backend */
60                 ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret);
61         }
62
63         return ret;
64 }
65 /*
66   Same as ldb_add but accept control
67 */
68 int ldb_add_ctrl(struct ldb_context *ldb,
69                 const struct ldb_message *message,
70                 struct ldb_control **controls)
71 {
72         struct ldb_request *req;
73         int ret;
74
75         ret = ldb_msg_sanity_check(ldb, message);
76         if (ret != LDB_SUCCESS) {
77                 return ret;
78         }
79
80         ret = ldb_build_add_req(&req, ldb, ldb,
81                                         message,
82                                         controls,
83                                         NULL,
84                                         ldb_op_default_callback,
85                                         NULL);
86
87         if (ret != LDB_SUCCESS) return ret;
88
89         /* do request and autostart a transaction */
90         ret = ldb_do_autotransaction(ldb, req);
91
92         talloc_free(req);
93         return ret;
94 }
95
96 /*
97   same as ldb_delete but accept control
98 */
99 int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn,
100                 struct ldb_control **controls)
101 {
102         struct ldb_request *req;
103         int ret;
104
105         ret = ldb_build_del_req(&req, ldb, ldb,
106                                         dn,
107                                         controls,
108                                         NULL,
109                                         ldb_op_default_callback,
110                                         NULL);
111
112         if (ret != LDB_SUCCESS) return ret;
113
114         /* do request and autostart a transaction */
115         ret = ldb_do_autotransaction(ldb, req);
116
117         talloc_free(req);
118         return ret;
119 }
120
121
122 /*
123   same as ldb_modify, but accepts controls
124 */
125 int ldb_modify_ctrl(struct ldb_context *ldb,
126                     const struct ldb_message *message,
127                     struct ldb_control **controls)
128 {
129         struct ldb_request *req;
130         int ret;
131
132         ret = ldb_msg_sanity_check(ldb, message);
133         if (ret != LDB_SUCCESS) {
134                 return ret;
135         }
136
137         ret = ldb_build_mod_req(&req, ldb, ldb,
138                                         message,
139                                         controls,
140                                         NULL,
141                                         ldb_op_default_callback,
142                                         NULL);
143
144         if (ret != LDB_SUCCESS) return ret;
145
146         /* do request and autostart a transaction */
147         ret = ldb_do_autotransaction(ldb, req);
148
149         talloc_free(req);
150         return ret;
151 }
152
153
154 /*
155   ldb_search with controls
156 */
157 int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
158                     struct ldb_result **result, struct ldb_dn *base,
159                     enum ldb_scope scope, const char * const *attrs,
160                     struct ldb_control **controls,
161                     const char *exp_fmt, ...)
162 {
163         struct ldb_request *req;
164         struct ldb_result *res;
165         char *expression;
166         va_list ap;
167         int ret;
168
169         expression = NULL;
170         *result = NULL;
171         req = NULL;
172
173         res = talloc_zero(mem_ctx, struct ldb_result);
174         if (!res) {
175                 return LDB_ERR_OPERATIONS_ERROR;
176         }
177
178         if (exp_fmt) {
179                 va_start(ap, exp_fmt);
180                 expression = talloc_vasprintf(mem_ctx, exp_fmt, ap);
181                 va_end(ap);
182
183                 if (!expression) {
184                         talloc_free(res);
185                         return LDB_ERR_OPERATIONS_ERROR;
186                 }
187         }
188
189         ret = ldb_build_search_req(&req, ldb, mem_ctx,
190                                    base?base:ldb_get_default_basedn(ldb),
191                                    scope,
192                                    expression,
193                                    attrs,
194                                    controls,
195                                    res,
196                                    ldb_search_default_callback,
197                                    NULL);
198         ldb_req_set_location(req, "ldb_search_ctrl");
199
200         if (ret != LDB_SUCCESS) goto done;
201
202         ret = ldb_request(ldb, req);
203
204         if (ret == LDB_SUCCESS) {
205                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
206         }
207
208 done:
209         if (ret != LDB_SUCCESS) {
210                 talloc_free(res);
211                 res = NULL;
212         }
213
214         talloc_free(expression);
215         talloc_free(req);
216
217         *result = res;
218         return ret;
219 }