2 Unix SMB/CIFS mplementation.
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008
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.
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.
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/>.
24 #include "dsdb/samdb/samdb.h"
25 #include "lib/ldb/include/ldb_errors.h"
26 #include "lib/ldb/include/ldb_private.h"
27 #include "lib/util/dlinklist.h"
28 #include "param/param.h"
31 static int schema_set_attributes(struct ldb_context *ldb, struct dsdb_schema *schema)
33 int ret = LDB_SUCCESS;
35 struct dsdb_attribute *attr;
37 for (attr = schema->attributes; attr; attr = attr->next) {
38 const struct ldb_schema_syntax *s;
42 if (attr->syntax->ldb_syntax) {
43 ret = ldb_schema_attribute_add(ldb, attr->lDAPDisplayName, 0,
44 attr->syntax->ldb_syntax);
46 s = ldb_standard_syntax_by_name(ldb, attr->syntax->ldap_oid);
48 ret = ldb_schema_attribute_add_with_syntax(ldb, attr->lDAPDisplayName, 0, s);
50 s = ldb_samba_syntax_by_name(ldb, attr->syntax->ldap_oid);
52 ret = ldb_schema_attribute_add_with_syntax(ldb, attr->lDAPDisplayName, 0, s);
54 ret = LDB_SUCCESS; /* Nothing to do here */
58 if (ret != LDB_SUCCESS) {
63 /* Now put back the hardcoded Samba special handlers */
64 return ldb_register_samba_handlers(ldb);
69 * Attach the schema to an opaque pointer on the ldb, so ldb modules
73 int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
77 ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
78 if (ret != LDB_SUCCESS) {
82 ret = schema_set_attributes(ldb, schema);
83 if (ret != LDB_SUCCESS) {
87 talloc_steal(ldb, schema);
93 * Global variable to hold one copy of the schema, used to avoid memory bloat
95 static struct dsdb_schema *global_schema;
98 * Make this ldb use the 'global' schema, setup to avoid having multiple copies in this process
100 int dsdb_set_global_schema(struct ldb_context *ldb)
103 if (!global_schema) {
106 ret = ldb_set_opaque(ldb, "dsdb_schema", global_schema);
107 if (ret != LDB_SUCCESS) {
111 ret = schema_set_attributes(ldb, global_schema);
112 if (ret != LDB_SUCCESS) {
116 /* Keep a reference to this schema, just incase the global copy is replaced */
117 if (talloc_reference(ldb, global_schema) == NULL) {
118 return LDB_ERR_OPERATIONS_ERROR;
125 * Find the schema object for this ldb
128 struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb)
131 struct dsdb_schema *schema;
133 /* see if we have a cached copy */
134 p = ldb_get_opaque(ldb, "dsdb_schema");
139 schema = talloc_get_type(p, struct dsdb_schema);
148 * Make the schema found on this ldb the 'global' schema
151 void dsdb_make_schema_global(struct ldb_context *ldb)
153 struct dsdb_schema *schema = dsdb_get_schema(ldb);
159 talloc_unlink(talloc_autofree_context(), schema);
162 talloc_steal(talloc_autofree_context(), schema);
163 global_schema = schema;
165 dsdb_set_global_schema(ldb);
170 * Rather than read a schema from the LDB itself, read it from an ldif
171 * file. This allows schema to be loaded and used while adding the
172 * schema itself to the directory.
175 WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df)
177 struct ldb_ldif *ldif;
178 struct ldb_message *msg;
182 struct dsdb_schema *schema;
183 const struct ldb_val *prefix_val;
184 const struct ldb_val *info_val;
185 struct ldb_val info_val_default;
187 mem_ctx = talloc_new(ldb);
192 schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")));
194 schema->fsmo.we_are_master = true;
195 schema->fsmo.master_dn = ldb_dn_new_fmt(schema, ldb, "@PROVISION_SCHEMA_MASTER");
196 if (!schema->fsmo.master_dn) {
201 * load the prefixMap attribute from pf
203 ldif = ldb_ldif_read_string(ldb, &pf);
205 status = WERR_INVALID_PARAM;
208 talloc_steal(mem_ctx, ldif);
210 msg = ldb_msg_canonicalize(ldb, ldif->msg);
214 talloc_steal(mem_ctx, msg);
217 prefix_val = ldb_msg_find_ldb_val(msg, "prefixMap");
219 status = WERR_INVALID_PARAM;
223 info_val = ldb_msg_find_ldb_val(msg, "schemaInfo");
225 info_val_default = strhex_to_data_blob("FF0000000000000000000000000000000000000000");
226 if (!info_val_default.data) {
229 talloc_steal(mem_ctx, info_val_default.data);
230 info_val = &info_val_default;
233 status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val);
234 if (!W_ERROR_IS_OK(status)) {
239 * load the attribute and class definitions outof df
241 while ((ldif = ldb_ldif_read_string(ldb, &df))) {
245 talloc_steal(mem_ctx, ldif);
247 msg = ldb_msg_canonicalize(ldb, ldif->msg);
252 talloc_steal(mem_ctx, msg);
255 is_sa = ldb_msg_check_string_attribute(msg, "objectClass", "attributeSchema");
256 is_sc = ldb_msg_check_string_attribute(msg, "objectClass", "classSchema");
259 struct dsdb_attribute *sa;
261 sa = talloc_zero(schema, struct dsdb_attribute);
266 status = dsdb_attribute_from_ldb(schema, msg, sa, sa);
267 if (!W_ERROR_IS_OK(status)) {
271 DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
273 struct dsdb_class *sc;
275 sc = talloc_zero(schema, struct dsdb_class);
280 status = dsdb_class_from_ldb(schema, msg, sc, sc);
281 if (!W_ERROR_IS_OK(status)) {
285 DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
289 ret = dsdb_set_schema(ldb, schema);
290 if (ret != LDB_SUCCESS) {
291 status = WERR_FOOBAR;
301 talloc_free(mem_ctx);