LDB:test-generic.sh - fix smaller/greater comparison tests
[mdw/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 "replace.h"
33 #include "ldb.h"
34 #include "ldb_module.h"
35 #include "ldbutil.h"
36
37
38 /* autostarts a transacion if none active */
39 static int ldb_do_autotransaction(struct ldb_context *ldb,
40                                        struct ldb_request *req)
41 {
42         int ret;
43
44         ret = ldb_transaction_start(ldb);
45         if (ret != LDB_SUCCESS) {
46                 return ret;
47         }
48
49         ret = ldb_request(ldb, req);
50         if (ret == LDB_SUCCESS) {
51                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
52         }
53
54         if (ret == LDB_SUCCESS) {
55                 return ldb_transaction_commit(ldb);
56         }
57         ldb_transaction_cancel(ldb);
58
59         if (ldb_errstring(ldb) == NULL) {
60                 /* no error string was setup by the backend */
61                 ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret);
62         }
63
64         return ret;
65 }
66 /*
67   Same as ldb_add but accept control
68 */
69 int ldb_add_ctrl(struct ldb_context *ldb,
70                 const struct ldb_message *message,
71                 struct ldb_control **controls)
72 {
73         struct ldb_request *req;
74         int ret;
75
76         ret = ldb_msg_sanity_check(ldb, message);
77         if (ret != LDB_SUCCESS) {
78                 return ret;
79         }
80
81         ret = ldb_build_add_req(&req, ldb, ldb,
82                                         message,
83                                         controls,
84                                         NULL,
85                                         ldb_op_default_callback,
86                                         NULL);
87
88         if (ret != LDB_SUCCESS) return ret;
89
90         /* do request and autostart a transaction */
91         ret = ldb_do_autotransaction(ldb, req);
92
93         talloc_free(req);
94         return ret;
95 }
96
97 /*
98   same as ldb_delete but accept control
99 */
100 int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn,
101                 struct ldb_control **controls)
102 {
103         struct ldb_request *req;
104         int ret;
105
106         ret = ldb_build_del_req(&req, ldb, ldb,
107                                         dn,
108                                         controls,
109                                         NULL,
110                                         ldb_op_default_callback,
111                                         NULL);
112
113         if (ret != LDB_SUCCESS) return ret;
114
115         /* do request and autostart a transaction */
116         ret = ldb_do_autotransaction(ldb, req);
117
118         talloc_free(req);
119         return ret;
120 }
121
122
123 /*
124   same as ldb_modify, but accepts controls
125 */
126 int ldb_modify_ctrl(struct ldb_context *ldb,
127                     const struct ldb_message *message,
128                     struct ldb_control **controls)
129 {
130         struct ldb_request *req;
131         int ret;
132
133         ret = ldb_msg_sanity_check(ldb, message);
134         if (ret != LDB_SUCCESS) {
135                 return ret;
136         }
137
138         ret = ldb_build_mod_req(&req, ldb, ldb,
139                                         message,
140                                         controls,
141                                         NULL,
142                                         ldb_op_default_callback,
143                                         NULL);
144
145         if (ret != LDB_SUCCESS) return ret;
146
147         /* do request and autostart a transaction */
148         ret = ldb_do_autotransaction(ldb, req);
149
150         talloc_free(req);
151         return ret;
152 }
153
154
155 /*
156   ldb_search with controls
157 */
158 int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
159                     struct ldb_result **result, struct ldb_dn *base,
160                     enum ldb_scope scope, const char * const *attrs,
161                     struct ldb_control **controls,
162                     const char *exp_fmt, ...)
163 {
164         struct ldb_request *req;
165         struct ldb_result *res;
166         char *expression;
167         va_list ap;
168         int ret;
169
170         expression = NULL;
171         *result = NULL;
172         req = NULL;
173
174         res = talloc_zero(mem_ctx, struct ldb_result);
175         if (!res) {
176                 return LDB_ERR_OPERATIONS_ERROR;
177         }
178
179         if (exp_fmt) {
180                 va_start(ap, exp_fmt);
181                 expression = talloc_vasprintf(mem_ctx, exp_fmt, ap);
182                 va_end(ap);
183
184                 if (!expression) {
185                         talloc_free(res);
186                         return LDB_ERR_OPERATIONS_ERROR;
187                 }
188         }
189
190         ret = ldb_build_search_req(&req, ldb, mem_ctx,
191                                    base?base:ldb_get_default_basedn(ldb),
192                                    scope,
193                                    expression,
194                                    attrs,
195                                    controls,
196                                    res,
197                                    ldb_search_default_callback,
198                                    NULL);
199         ldb_req_set_location(req, "ldb_search_ctrl");
200
201         if (ret != LDB_SUCCESS) goto done;
202
203         ret = ldb_request(ldb, req);
204
205         if (ret == LDB_SUCCESS) {
206                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
207         }
208
209 done:
210         if (ret != LDB_SUCCESS) {
211                 talloc_free(res);
212                 res = NULL;
213         }
214
215         talloc_free(expression);
216         talloc_free(req);
217
218         *result = res;
219         return ret;
220 }