s4:dsdb Add 'dsdb_flags' to dsdb_module_search() to enable often-used features
[kai/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4
5    Copyright (C) Andrew Tridgell 2009
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "ldb.h"
24 #include "ldb_module.h"
25 #include "dsdb/samdb/ldb_modules/util.h"
26 #include "dsdb/samdb/samdb.h"
27
28 int dsdb_module_search_handle_flags(struct ldb_module *module, struct ldb_request *req, int dsdb_flags) 
29 {
30         int ret;
31         if (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) {
32                 struct ldb_search_options_control *options;
33                 /* Using the phantom root control allows us to search all partitions */
34                 options = talloc(req, struct ldb_search_options_control);
35                 if (options == NULL) {
36                         ldb_module_oom(module);
37                         return LDB_ERR_OPERATIONS_ERROR;
38                 }
39                 options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
40                 
41                 ret = ldb_request_add_control(req,
42                                               LDB_CONTROL_SEARCH_OPTIONS_OID,
43                                               true, options);
44                 if (ret != LDB_SUCCESS) {
45                         return ret;
46                 }
47         }
48
49         if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) {
50                 ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
51                 if (ret != LDB_SUCCESS) {
52                         return ret;
53                 }
54         }
55
56         if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) {
57                 ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL);
58                 if (ret != LDB_SUCCESS) {
59                         return ret;
60                 }
61         }
62
63         if (dsdb_flags & DSDB_SEARCH_SHOW_EXTENDED_DN) {
64                 struct ldb_extended_dn_control *extended_ctrl = talloc(req, struct ldb_extended_dn_control);
65                 if (!extended_ctrl) {
66                         ldb_module_oom(module);
67                         return LDB_ERR_OPERATIONS_ERROR;
68                 }
69                 extended_ctrl->type = 1;
70                 
71                 ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, true, extended_ctrl);
72                 if (ret != LDB_SUCCESS) {
73                         return ret;
74                 }
75         }
76
77         return LDB_SUCCESS;
78 }
79
80 /*
81   search for attrs on one DN, in the modules below
82  */
83 int dsdb_module_search_dn(struct ldb_module *module,
84                           TALLOC_CTX *mem_ctx,
85                           struct ldb_result **_res,
86                           struct ldb_dn *basedn,
87                           const char * const *attrs,
88                           int dsdb_flags)
89 {
90         int ret;
91         struct ldb_request *req;
92         TALLOC_CTX *tmp_ctx;
93         struct ldb_result *res;
94
95         tmp_ctx = talloc_new(mem_ctx);
96
97         res = talloc_zero(tmp_ctx, struct ldb_result);
98         if (!res) {
99                 return LDB_ERR_OPERATIONS_ERROR;
100         }
101
102         ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
103                                    basedn,
104                                    LDB_SCOPE_BASE,
105                                    NULL,
106                                    attrs,
107                                    NULL,
108                                    res,
109                                    ldb_search_default_callback,
110                                    NULL);
111         if (ret != LDB_SUCCESS) {
112                 talloc_free(tmp_ctx);
113                 return ret;
114         }
115
116         ret = dsdb_module_search_handle_flags(module, req, dsdb_flags);
117         if (ret != LDB_SUCCESS) {
118                 talloc_free(tmp_ctx);
119                 return ret;
120         }
121
122         ret = ldb_next_request(module, req);
123         if (ret == LDB_SUCCESS) {
124                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
125         }
126
127         if (ret != LDB_SUCCESS) {
128                 talloc_free(tmp_ctx);
129                 return ret;
130         }
131
132         if (res->count != 1) {
133                 /* we may be reading a DB that does not have the 'check base on search' option... */
134                 ret = LDB_ERR_NO_SUCH_OBJECT;
135                 ldb_asprintf_errstring(ldb_module_get_ctx(module), 
136                                        "dsdb_module_search_dn: did not find base dn %s (%d results)", 
137                                        ldb_dn_get_linearized(basedn), res->count);
138         } else {
139                 *_res = talloc_steal(mem_ctx, res);
140         }
141         talloc_free(tmp_ctx);
142         return ret;
143 }
144
145 /*
146   search for attrs in the modules below
147  */
148 int dsdb_module_search(struct ldb_module *module,
149                        TALLOC_CTX *mem_ctx,
150                        struct ldb_result **_res,
151                        struct ldb_dn *basedn, enum ldb_scope scope, 
152                        const char * const *attrs,
153                        int dsdb_flags, 
154                        const char *expression)
155 {
156         int ret;
157         struct ldb_request *req;
158         TALLOC_CTX *tmp_ctx;
159         struct ldb_result *res;
160
161         tmp_ctx = talloc_new(mem_ctx);
162
163         res = talloc_zero(tmp_ctx, struct ldb_result);
164         if (!res) {
165                 return LDB_ERR_OPERATIONS_ERROR;
166         }
167
168         ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
169                                    basedn,
170                                    scope,
171                                    expression,
172                                    attrs,
173                                    NULL,
174                                    res,
175                                    ldb_search_default_callback,
176                                    NULL);
177         if (ret != LDB_SUCCESS) {
178                 talloc_free(tmp_ctx);
179                 return ret;
180         }
181
182         ret = dsdb_module_search_handle_flags(module, req, dsdb_flags);
183         if (ret != LDB_SUCCESS) {
184                 talloc_free(tmp_ctx);
185                 return ret;
186         }
187
188         ret = ldb_next_request(module, req);
189         if (ret == LDB_SUCCESS) {
190                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
191         }
192
193         talloc_free(req);
194         if (ret == LDB_SUCCESS) {
195                 *_res = talloc_steal(mem_ctx, res);
196         }
197         talloc_free(tmp_ctx);
198         return ret;
199 }
200