mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
dsdb: Add routine to check the DB vs lp functional levels
This will be called at server startup (as well as from Python tests) Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
This commit is contained in:
parent
4919e8d808
commit
b8a613b4b1
@ -3994,6 +3994,123 @@ int dsdb_dc_functional_level(struct ldb_context *ldb)
|
||||
return *dcFunctionality;
|
||||
}
|
||||
|
||||
int dsdb_check_and_update_fl(struct ldb_context *ldb_ctx, struct loadparm_context *lp_ctx)
|
||||
{
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
int ret;
|
||||
|
||||
int db_dc_functional_level;
|
||||
int db_domain_functional_level;
|
||||
int db_forest_functional_level;
|
||||
int lp_dc_functional_level = lpcfg_ad_dc_functional_level(lp_ctx);
|
||||
bool am_rodc;
|
||||
struct ldb_message *msg = NULL;
|
||||
struct ldb_dn *dc_ntds_settings_dn = NULL;
|
||||
|
||||
|
||||
db_dc_functional_level = dsdb_dc_functional_level(ldb_ctx);
|
||||
db_domain_functional_level = dsdb_functional_level(ldb_ctx);
|
||||
db_forest_functional_level = dsdb_forest_functional_level(ldb_ctx);
|
||||
|
||||
if (lp_dc_functional_level < db_domain_functional_level) {
|
||||
DBG_ERR("Refusing to start as smb.conf 'ad dc functional level' maps to %d, "
|
||||
"which is less than the domain functional level of %d\n",
|
||||
lp_dc_functional_level, db_domain_functional_level);
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
if (lp_dc_functional_level < db_forest_functional_level) {
|
||||
DBG_ERR("Refusing to start as smb.conf 'ad dc functional level' maps to %d, "
|
||||
"which is less than the forest functional level of %d\n",
|
||||
lp_dc_functional_level, db_forest_functional_level);
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
/* Check if we need to update the DB */
|
||||
if (db_dc_functional_level == lp_dc_functional_level) {
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
/* Confirm we are not an RODC before we try a modify */
|
||||
ret = samdb_rodc(ldb_ctx, &am_rodc);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DBG_ERR("Failed to determine if this server is an RODC\n");
|
||||
TALLOC_FREE(frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (am_rodc) {
|
||||
DBG_WARNING("Unable to update DC's msDS-Behavior-Version "
|
||||
"to correct value (%d from %d) as we are an RODC\n",
|
||||
db_forest_functional_level, lp_dc_functional_level);
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
dc_ntds_settings_dn = samdb_ntds_settings_dn(ldb_ctx, frame);
|
||||
|
||||
if (dc_ntds_settings_dn == NULL) {
|
||||
DBG_ERR("Failed to find own NTDS Settings DN\n");
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_ERR_NO_SUCH_OBJECT;
|
||||
}
|
||||
|
||||
/* Now update our msDS-Behavior-Version */
|
||||
|
||||
msg = ldb_msg_new(frame);
|
||||
if (msg == NULL) {
|
||||
DBG_ERR("Failed to allocate message to update msDS-Behavior-Version\n");
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
msg->dn = dc_ntds_settings_dn;
|
||||
|
||||
ret = samdb_msg_add_int(ldb_ctx, frame, msg, "msDS-Behavior-Version", lp_dc_functional_level);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DBG_ERR("Failed to set new msDS-Behavior-Version on message\n");
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = dsdb_replace(ldb_ctx, msg, 0);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DBG_ERR("Failed to update DB with new msDS-Behavior-Version on %s: %s\n",
|
||||
ldb_dn_get_linearized(dc_ntds_settings_dn),
|
||||
ldb_errstring(ldb_ctx));
|
||||
TALLOC_FREE(frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to update the opaque because this particular ldb_context
|
||||
* will not re-read the DB
|
||||
*/
|
||||
{
|
||||
int *val = talloc(ldb_ctx, int);
|
||||
if (!val) {
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
*val = lp_dc_functional_level;
|
||||
ret = ldb_set_opaque(ldb_ctx,
|
||||
"domainControllerFunctionality", val);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
DBG_ERR("Failed to re-set domainControllerFunctionality opaque\n");
|
||||
TALLOC_FREE(val);
|
||||
TALLOC_FREE(frame);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
set a GUID in an extended DN structure
|
||||
*/
|
||||
|
@ -1426,6 +1426,38 @@ static PyObject *py_dsdb_user_account_control_flag_bit_to_string(PyObject *self,
|
||||
return PyUnicode_FromString(str);
|
||||
}
|
||||
|
||||
static PyObject *py_dsdb_check_and_update_fl(PyObject *self, PyObject *args)
|
||||
{
|
||||
TALLOC_CTX *frame = NULL;
|
||||
|
||||
PyObject *py_ldb = NULL, *py_lp = NULL;
|
||||
struct ldb_context *ldb = NULL;
|
||||
struct loadparm_context *lp_ctx = NULL;
|
||||
|
||||
int ret;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_lp)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyErr_LDB_OR_RAISE(py_ldb, ldb);
|
||||
|
||||
frame = talloc_stackframe();
|
||||
|
||||
lp_ctx = lpcfg_from_py_object(frame, py_lp);
|
||||
if (lp_ctx == NULL) {
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = dsdb_check_and_update_fl(ldb, lp_ctx);
|
||||
TALLOC_FREE(frame);
|
||||
|
||||
PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef py_dsdb_methods[] = {
|
||||
{ "_samdb_server_site_name", (PyCFunction)py_samdb_server_site_name,
|
||||
METH_VARARGS, "Get the server site name as a string"},
|
||||
@ -1512,6 +1544,12 @@ static PyMethodDef py_dsdb_methods[] = {
|
||||
METH_VARARGS,
|
||||
"user_account_control_flag_bit_to_string(bit)"
|
||||
" -> string name" },
|
||||
{ "check_and_update_fl",
|
||||
(PyCFunction)py_dsdb_check_and_update_fl,
|
||||
METH_VARARGS,
|
||||
"check_and_update_fl(ldb, lp) -> None\n"
|
||||
"Hook to run in testing the code run on samba server startup "
|
||||
"to validate and update DC functional levels"},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user