2 Unix SMB/CIFS mplementation.
4 The module that handles the Schema FSMO Role Owner
5 checkings, it also loads the dsdb_schema.
7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "lib/ldb/include/ldb.h"
26 #include "lib/ldb/include/ldb_errors.h"
27 #include "lib/ldb/include/ldb_private.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "librpc/gen_ndr/ndr_misc.h"
30 #include "librpc/gen_ndr/ndr_drsuapi.h"
31 #include "librpc/gen_ndr/ndr_drsblobs.h"
32 #include "lib/util/dlinklist.h"
33 #include "param/param.h"
35 static int schema_fsmo_init(struct ldb_module
*module
)
38 struct ldb_dn
*schema_dn
;
39 struct dsdb_schema
*schema
;
40 char *error_string
= NULL
;
43 if (dsdb_get_schema(module
->ldb
)) {
44 return ldb_next_init(module
);
47 schema_dn
= samdb_schema_dn(module
->ldb
);
49 ldb_reset_err_string(module
->ldb
);
50 ldb_debug(module
->ldb
, LDB_DEBUG_WARNING
,
51 "schema_fsmo_init: no schema dn present: (skip schema loading)\n");
52 return ldb_next_init(module
);
55 mem_ctx
= talloc_new(module
);
58 return LDB_ERR_OPERATIONS_ERROR
;
61 ret
= dsdb_schema_from_schema_dn(mem_ctx
, module
->ldb
,
62 lp_iconv_convenience(ldb_get_opaque(module
->ldb
, "loadparm")),
63 schema_dn
, &schema
, &error_string
);
65 if (ret
== LDB_ERR_NO_SUCH_OBJECT
) {
66 ldb_reset_err_string(module
->ldb
);
67 ldb_debug(module
->ldb
, LDB_DEBUG_WARNING
,
68 "schema_fsmo_init: no schema head present: (skip schema loading)\n");
70 return ldb_next_init(module
);
73 if (ret
!= LDB_SUCCESS
) {
74 ldb_asprintf_errstring(module
->ldb
,
75 "schema_fsmo_init: dsdb_schema load failed: %s",
80 /* dsdb_set_schema() steal schema into the ldb_context */
81 ret
= dsdb_set_schema(module
->ldb
, schema
);
82 if (ret
!= LDB_SUCCESS
) {
83 ldb_debug_set(module
->ldb
, LDB_DEBUG_FATAL
,
84 "schema_fsmo_init: dsdb_set_schema() failed: %d:%s",
85 ret
, ldb_strerror(ret
));
91 return ldb_next_init(module
);
94 static int schema_fsmo_add(struct ldb_module
*module
, struct ldb_request
*req
)
96 struct dsdb_schema
*schema
;
97 const char *attributeID
= NULL
;
98 const char *governsID
= NULL
;
99 const char *oid_attr
= NULL
;
100 const char *oid
= NULL
;
104 schema
= dsdb_get_schema(module
->ldb
);
106 return ldb_next_request(module
, req
);
109 if (!schema
->fsmo
.we_are_master
) {
110 ldb_debug_set(module
->ldb
, LDB_DEBUG_ERROR
,
111 "schema_fsmo_add: we are not master: reject request\n");
112 return LDB_ERR_UNWILLING_TO_PERFORM
;
115 attributeID
= samdb_result_string(req
->op
.add
.message
, "attributeID", NULL
);
116 governsID
= samdb_result_string(req
->op
.add
.message
, "governsID", NULL
);
119 oid_attr
= "attributeID";
121 } else if (governsID
) {
122 oid_attr
= "governsID";
127 return ldb_next_request(module
, req
);
130 status
= dsdb_map_oid2int(schema
, oid
, &id32
);
131 if (W_ERROR_IS_OK(status
)) {
132 return ldb_next_request(module
, req
);
133 } else if (!W_ERROR_EQUAL(WERR_DS_NO_MSDS_INTID
, status
)) {
134 ldb_debug_set(module
->ldb
, LDB_DEBUG_ERROR
,
135 "schema_fsmo_add: failed to map %s[%s]: %s\n",
136 oid_attr
, oid
, win_errstr(status
));
137 return LDB_ERR_UNWILLING_TO_PERFORM
;
140 status
= dsdb_create_prefix_mapping(module
->ldb
, schema
, oid
);
141 if (!W_ERROR_IS_OK(status
)) {
142 ldb_debug_set(module
->ldb
, LDB_DEBUG_ERROR
,
143 "schema_fsmo_add: failed to create prefix mapping for %s[%s]: %s\n",
144 oid_attr
, oid
, win_errstr(status
));
145 return LDB_ERR_UNWILLING_TO_PERFORM
;
148 return ldb_next_request(module
, req
);
151 static int schema_fsmo_extended(struct ldb_module
*module
, struct ldb_request
*req
)
154 struct ldb_dn
*schema_dn
;
155 struct dsdb_schema
*schema
;
156 char *error_string
= NULL
;
160 if (strcmp(req
->op
.extended
.oid
, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID
) != 0) {
161 return ldb_next_request(module
, req
);
164 schema_dn
= samdb_schema_dn(module
->ldb
);
166 ldb_reset_err_string(module
->ldb
);
167 ldb_debug(module
->ldb
, LDB_DEBUG_WARNING
,
168 "schema_fsmo_extended: no schema dn present: (skip schema loading)\n");
169 return ldb_next_request(module
, req
);
172 mem_ctx
= talloc_new(module
);
174 ldb_oom(module
->ldb
);
175 return LDB_ERR_OPERATIONS_ERROR
;
178 ret
= dsdb_schema_from_schema_dn(mem_ctx
, module
->ldb
,
179 lp_iconv_convenience(ldb_get_opaque(module
->ldb
, "loadparm")),
180 schema_dn
, &schema
, &error_string
);
182 if (ret
== LDB_ERR_NO_SUCH_OBJECT
) {
183 ldb_reset_err_string(module
->ldb
);
184 ldb_debug(module
->ldb
, LDB_DEBUG_WARNING
,
185 "schema_fsmo_extended: no schema head present: (skip schema loading)\n");
186 talloc_free(mem_ctx
);
187 return ldb_next_request(module
, req
);
190 if (ret
!= LDB_SUCCESS
) {
191 ldb_asprintf_errstring(module
->ldb
,
192 "schema_fsmo_extended: dsdb_schema load failed: %s",
194 talloc_free(mem_ctx
);
195 return ldb_next_request(module
, req
);
198 /* Replace the old schema*/
199 ret
= dsdb_set_schema(module
->ldb
, schema
);
200 if (ret
!= LDB_SUCCESS
) {
201 ldb_debug_set(module
->ldb
, LDB_DEBUG_FATAL
,
202 "schema_fsmo_extended: dsdb_set_schema() failed: %d:%s",
203 ret
, ldb_strerror(ret
));
204 talloc_free(mem_ctx
);
208 talloc_free(mem_ctx
);
212 _PUBLIC_
const struct ldb_module_ops ldb_schema_fsmo_module_ops
= {
213 .name
= "schema_fsmo",
214 .init_context
= schema_fsmo_init
,
215 .add
= schema_fsmo_add
,
216 .extended
= schema_fsmo_extended