s4:dsdb - Fixed attribute dereferencing for FDS
[ira/wip.git] / source4 / dsdb / samdb / ldb_modules / schema_load.c
1 /* 
2    Unix SMB/CIFS mplementation.
3
4    The module that handles the Schema FSMO Role Owner
5    checkings, it also loads the dsdb_schema.
6    
7    Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
8    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
9     
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program 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
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22    
23 */
24
25 #include "includes.h"
26 #include "ldb_module.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "librpc/gen_ndr/ndr_misc.h"
29 #include "librpc/gen_ndr/ndr_drsuapi.h"
30 #include "librpc/gen_ndr/ndr_drsblobs.h"
31 #include "param/param.h"
32 #include "dsdb/samdb/ldb_modules/util.h"
33
34 /*
35   Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
36 */
37
38 static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *module,
39                                       struct smb_iconv_convenience *iconv_convenience, 
40                                       struct ldb_dn *schema_dn,
41                                       struct dsdb_schema **schema) 
42 {
43         TALLOC_CTX *tmp_ctx;
44         char *error_string;
45         int ret;
46         struct ldb_context *ldb = ldb_module_get_ctx(module);
47         struct ldb_result *schema_res;
48         struct ldb_result *a_res;
49         struct ldb_result *c_res;
50         static const char *schema_attrs[] = {
51                 "prefixMap",
52                 "schemaInfo",
53                 "fSMORoleOwner",
54                 NULL
55         };
56         unsigned flags;
57
58         tmp_ctx = talloc_new(mem_ctx);
59         if (!tmp_ctx) {
60                 ldb_oom(ldb);
61                 return LDB_ERR_OPERATIONS_ERROR;
62         }
63
64         /* we don't want to trace the schema load */
65         flags = ldb_get_flags(ldb);
66         ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
67
68         /*
69          * setup the prefix mappings and schema info
70          */
71         ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res,
72                                     schema_dn, schema_attrs);
73         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
74                 goto failed;
75         } else if (ret != LDB_SUCCESS) {
76                 ldb_asprintf_errstring(ldb, 
77                                        "dsdb_schema: failed to search the schema head: %s",
78                                        ldb_errstring(ldb));
79                 goto failed;
80         }
81
82         /*
83          * load the attribute definitions
84          */
85         ret = dsdb_module_search(module, tmp_ctx, &a_res,
86                                  schema_dn, LDB_SCOPE_ONELEVEL, NULL,
87                                  "(objectClass=attributeSchema)");
88         if (ret != LDB_SUCCESS) {
89                 ldb_asprintf_errstring(ldb, 
90                                        "dsdb_schema: failed to search attributeSchema objects: %s",
91                                        ldb_errstring(ldb));
92                 goto failed;
93         }
94
95         /*
96          * load the objectClass definitions
97          */
98         ret = dsdb_module_search(module, tmp_ctx, &c_res,
99                                  schema_dn, LDB_SCOPE_ONELEVEL, NULL,
100                                  "(objectClass=classSchema)");
101         if (ret != LDB_SUCCESS) {
102                 ldb_asprintf_errstring(ldb, 
103                                        "dsdb_schema: failed to search attributeSchema objects: %s",
104                                        ldb_errstring(ldb));
105                 goto failed;
106         }
107
108         ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
109                                            lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
110                                            schema_res, a_res, c_res, schema, &error_string);
111         if (ret != LDB_SUCCESS) {
112                 ldb_asprintf_errstring(ldb, 
113                                                     "dsdb_schema load failed: %s",
114                                                     error_string);
115                 goto failed;
116         }
117         talloc_steal(mem_ctx, *schema);
118
119 failed:
120         if (flags & LDB_FLG_ENABLE_TRACING) {
121                 flags = ldb_get_flags(ldb);
122                 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
123         }
124         talloc_free(tmp_ctx);
125         return ret;
126 }       
127
128
129 static int schema_load_init(struct ldb_module *module)
130 {
131         struct ldb_context *ldb;
132         TALLOC_CTX *mem_ctx;
133         struct ldb_dn *schema_dn;
134         struct dsdb_schema *schema;
135         int ret;
136
137         ret = ldb_next_init(module);
138         if (ret != LDB_SUCCESS) {
139                 return ret;
140         }
141
142         ldb = ldb_module_get_ctx(module);
143         schema_dn = samdb_schema_dn(ldb);
144         if (!schema_dn) {
145                 ldb_reset_err_string(ldb);
146                 ldb_debug(ldb, LDB_DEBUG_WARNING,
147                           "schema_load_init: no schema dn present: (skip schema loading)\n");
148                 return LDB_SUCCESS;
149         }
150
151         if (dsdb_get_schema(ldb)) {
152                 return LDB_SUCCESS;
153         }
154
155         mem_ctx = talloc_new(module);
156         if (!mem_ctx) {
157                 ldb_oom(ldb);
158                 return LDB_ERR_OPERATIONS_ERROR;
159         }
160
161         ret = dsdb_schema_from_schema_dn(mem_ctx, module,
162                                          lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
163                                          schema_dn, &schema);
164
165         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
166                 ldb_reset_err_string(ldb);
167                 ldb_debug(ldb, LDB_DEBUG_WARNING,
168                           "schema_load_init: no schema head present: (skip schema loading)\n");
169                 talloc_free(mem_ctx);
170                 return LDB_SUCCESS;
171         }
172
173         if (ret != LDB_SUCCESS) {
174                 talloc_free(mem_ctx);
175                 return ret;
176         }
177
178         /* dsdb_set_schema() steal schema into the ldb_context */
179         ret = dsdb_set_schema(ldb, schema);
180         if (ret != LDB_SUCCESS) {
181                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
182                               "schema_load_init: dsdb_set_schema() failed: %d:%s",
183                               ret, ldb_strerror(ret));
184                 talloc_free(mem_ctx);
185                 return ret;
186         }
187
188         talloc_free(mem_ctx);
189         return LDB_SUCCESS;
190 }
191
192 static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
193 {
194         struct ldb_context *ldb;
195         struct ldb_dn *schema_dn;
196         struct dsdb_schema *schema;
197         int ret;
198         TALLOC_CTX *mem_ctx;
199
200         ldb = ldb_module_get_ctx(module);
201
202         if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
203                 return ldb_next_request(module, req);
204         }
205         
206         schema_dn = samdb_schema_dn(ldb);
207         if (!schema_dn) {
208                 ldb_reset_err_string(ldb);
209                 ldb_debug(ldb, LDB_DEBUG_WARNING,
210                           "schema_load_extended: no schema dn present: (skip schema loading)\n");
211                 return ldb_next_request(module, req);
212         }
213         
214         mem_ctx = talloc_new(module);
215         if (!mem_ctx) {
216                 ldb_oom(ldb);
217                 return LDB_ERR_OPERATIONS_ERROR;
218         }
219         
220         ret = dsdb_schema_from_schema_dn(mem_ctx, module,
221                                          lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
222                                          schema_dn, &schema);
223
224         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
225                 ldb_reset_err_string(ldb);
226                 ldb_debug(ldb, LDB_DEBUG_WARNING,
227                           "schema_load_extended: no schema head present: (skip schema loading)\n");
228                 talloc_free(mem_ctx);
229                 return ldb_next_request(module, req);
230         }
231
232         if (ret != LDB_SUCCESS) {
233                 talloc_free(mem_ctx);
234                 return ldb_next_request(module, req);
235         }
236
237         /* Replace the old schema*/
238         ret = dsdb_set_schema(ldb, schema);
239         if (ret != LDB_SUCCESS) {
240                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
241                               "schema_load_extended: dsdb_set_schema() failed: %d:%s",
242                               ret, ldb_strerror(ret));
243                 talloc_free(mem_ctx);
244                 return ret;
245         }
246
247         dsdb_make_schema_global(ldb);
248
249         talloc_free(mem_ctx);
250         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
251 }
252
253
254 _PUBLIC_ const struct ldb_module_ops ldb_schema_load_module_ops = {
255         .name           = "schema_load",
256         .init_context   = schema_load_init,
257         .extended       = schema_load_extended,
258 };