Updates on upgradeprovision

Matthieu Patou mat at samba.org
Sun Sep 5 04:25:29 MDT 2010


  Hi all,

This batch of patch should help people with old provision (ie. alpha8, 
alpha9) facing errors like:
_ldb.LdbError: (16, 'Attribute not found'), first it will normally tells 
us which attribute is missing on which object (and it's not always the 
object that is manipulated ...) and also I fixed pb with missing rid set 
that is needed for removing wrongly created object. All of this should 
lead to easier upgrade.

Last months I've been in touch with a couple of persons which were 
unable to upgrade their provision, please if you recognize yourself give 
this version a try (of course you must backup everything and not be in 
an hurry !).

Cheers.

Matthieu.

On 05/09/2010 12:52, Matthieu Patou wrote:
> The branch, master has been updated
>         via  4932157 upgradeprovision: avoid working with None objects ...
>         via  b153558 upgradeprovision: do not try to remove/change attribute before the RID Set object is present
>         via  13d575d upgradeprovision: cleanup
>         via  1d08152 s4 upgradeprovision: add dns_update_list if missing
>         via  e2d575e python-ldb: allow ldb_rename to take optional control(s)
>         via  42dfa71 dsdb: make the ATTRIBUTE NOT FOUND more clear
>        from  e4d1bdb s4/selftest: Fix path to include/config.h, set BUILDDIR automatically.
>
> http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
>
>
> - Log -----------------------------------------------------------------
> commit 49321571ea592be2307eef101cc783f883aa2503
> Author: Matthieu Patou<mat at matws.net>
> Date:   Sun Sep 5 03:00:05 2010 +0400
>
>      upgradeprovision: avoid working with None objects ...
>
> commit b1535582100a551cedc245f12cf63a1340985bdd
> Author: Matthieu Patou<mat at matws.net>
> Date:   Sun Sep 5 02:59:20 2010 +0400
>
>      upgradeprovision: do not try to remove/change attribute before the RID Set object is present
>
> commit 13d575d6e320961153d7071bc4f9b5cccdfb71b6
> Author: Matthieu Patou<mat at matws.net>
> Date:   Sun Sep 5 02:58:31 2010 +0400
>
>      upgradeprovision: cleanup
>
> commit 1d0815281e41cb1ca2cf72a3dba28a9ca75fb65d
> Author: Matthieu Patou<mat at matws.net>
> Date:   Sat Aug 14 20:44:35 2010 +0400
>
>      s4 upgradeprovision: add dns_update_list if missing
>
> commit e2d575ee8099bb31e3bc926cf6730a3ca77e69ef
> Author: Matthieu Patou<mat at matws.net>
> Date:   Sun Sep 5 02:57:16 2010 +0400
>
>      python-ldb: allow ldb_rename to take optional control(s)
>
> commit 42dfa71ef5d08b500e911e2ba54dba0b1b4a4599
> Author: Matthieu Patou<mat at matws.net>
> Date:   Sun Sep 5 02:56:30 2010 +0400
>
>      dsdb: make the ATTRIBUTE NOT FOUND more clear
>
> -----------------------------------------------------------------------
>
> Summary of changes:
>   source4/dsdb/common/util.c                   |    2 +
>   source4/dsdb/samdb/ldb_modules/objectclass.c |    3 +
>   source4/lib/ldb/pyldb.c                      |   54 +++++++++++++++++++++--
>   source4/scripting/bin/upgradeprovision       |   61 ++++++++++++++++++-------
>   4 files changed, 99 insertions(+), 21 deletions(-)
>
>
> Changeset truncated at 500 lines:
>
> diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
> index fc117b9..c409adb 100644
> --- a/source4/dsdb/common/util.c
> +++ b/source4/dsdb/common/util.c
> @@ -1644,6 +1644,8 @@ int samdb_reference_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_
>   	*dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0], attribute);
>   	if (!*dn) {
>   		talloc_free(res);
> +		ldb_asprintf_errstring(ldb, "Cannot find dn of attribute %s of %s", attribute,
> +					ldb_dn_get_linearized(base));
>   		return LDB_ERR_NO_SUCH_ATTRIBUTE;
>   	}
>
> diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
> index cd45963..005f0f2 100644
> --- a/source4/dsdb/samdb/ldb_modules/objectclass.c
> +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
> @@ -1005,6 +1005,9 @@ static int objectclass_do_mod(struct oc_context *ac)
>   			}
>   			if (!found) {
>   				/* we cannot delete a not existing object class */
> +				ldb_asprintf_errstring(ldb, "Cannot delete this %.*s ",
> +					       (int)oc_el_change->values[i].length, (const char *)oc_el_change->values[i].data);
> +
>   				talloc_free(mem_ctx);
>   				return LDB_ERR_NO_SUCH_ATTRIBUTE;
>   			}
> diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
> index f1b73a9..b60f4fc 100644
> --- a/source4/lib/ldb/pyldb.c
> +++ b/source4/lib/ldb/pyldb.c
> @@ -898,18 +898,33 @@ static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
>   	int ret;
>   	struct ldb_context *ldb;
>   	TALLOC_CTX *mem_ctx;
> +	PyObject *py_controls = Py_None;
> +	struct ldb_control **parsed_controls;
> +	struct ldb_context *ldb_ctx;
> +	struct ldb_request *req;
>
> -	if (!PyArg_ParseTuple(args, "OO",&py_dn1,&py_dn2))
> +	ldb_ctx = PyLdb_AsLdbContext(self);
> +
> +	if (!PyArg_ParseTuple(args, "OO|O",&py_dn1,&py_dn2,&py_controls))
>   		return NULL;
>
> +
>   	mem_ctx = talloc_new(NULL);
>   	if (mem_ctx == NULL) {
>   		PyErr_NoMemory();
>   		return NULL;
>   	}
> -
>   	ldb = PyLdb_AsLdbContext(self);
>
> +	if (py_controls == Py_None) {
> +		parsed_controls = NULL;
> +	} else {
> +		const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
> +		parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
> +		talloc_free(controls);
> +	}
> +
> +
>   	if (!PyObject_AsDn(mem_ctx, py_dn1, ldb,&dn1)) {
>   		talloc_free(mem_ctx);
>   		return NULL;
> @@ -920,9 +935,40 @@ static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
>   		return NULL;
>   	}
>
> -	ret = ldb_rename(ldb, dn1, dn2);
> +	ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
> +				NULL, ldb_op_default_callback, NULL);
> +	if (ret != LDB_SUCCESS) {
> +		PyErr_SetString(PyExc_TypeError, "failed to build request");
> +		talloc_free(mem_ctx);
> +		return NULL;
> +	}
> +
> +	/* do request and autostart a transaction */
> +	/* Then let's LDB handle the message error in case of pb as they are meaningful */
> +
> +	ret = ldb_transaction_start(ldb_ctx);
> +	if (ret != LDB_SUCCESS) {
> +		talloc_free(mem_ctx);
> +		PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
> +	}
> +
> +	ret = ldb_request(ldb_ctx, req);
> +	if (ret == LDB_SUCCESS) {
> +		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
> +	}
> +
> +	if (ret == LDB_SUCCESS) {
> +		ret = ldb_transaction_commit(ldb_ctx);
> +	} else {
> +		ldb_transaction_cancel(ldb_ctx);
> +		if (ldb_ctx->err_string == NULL) {
> +			/* no error string was setup by the backend */
> +			ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
> +		}
> +	}
> +
>   	talloc_free(mem_ctx);
> -	PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
> +	PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
>
>   	Py_RETURN_NONE;
>   }
> diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
> index 90586de..6697c82 100755
> --- a/source4/scripting/bin/upgradeprovision
> +++ b/source4/scripting/bin/upgradeprovision
> @@ -197,6 +197,7 @@ def check_for_DNS(refprivate, private):
>                       provision"""
>
>       spnfile = "%s/spn_update_list" % private
> +    dnsfile = "%s/dns_update_list" % private
>       namedfile = lp.get("dnsupdate:path")
>
>       if not namedfile:
> @@ -205,6 +206,9 @@ def check_for_DNS(refprivate, private):
>       if not os.path.exists(spnfile):
>           shutil.copy("%s/spn_update_list" % refprivate, "%s" % spnfile)
>
> +    if not os.path.exists(dnsfile):
> +        shutil.copy("%s/dns_update_list" % refprivate, "%s" % dnsfile)
> +
>       destdir = "%s/new_dns" % private
>       dnsdir = "%s/dns" % private
>
> @@ -452,7 +456,6 @@ def handle_special_add(samdb, dn, names):
>           #This entry was misplaced lets remove it if it exists
>           dntoremove = "CN=Certificate Service DCOM Access,"\
>                        "CN=Users, %s" % names.rootdn
> -        print dntoremove
>
>       objDn = Dn(samdb, "CN=Cryptographic Operators, CN=Builtin, %s" % names.rootdn)
>       if dn == objDn:
> @@ -475,14 +478,27 @@ def handle_special_add(samdb, dn, names):
>                               base=str(names.rootdn),
>                               scope=SCOPE_SUBTREE, attrs=["dn"],
>                               controls=["search_options:1:2"])
> -        if len(res)>  0:
> +
> +        res2 = samdb.search(expression="(dn=%s)" % dn,
> +                            base=str(names.rootdn),
> +                            scope=SCOPE_SUBTREE, attrs=["dn"],
> +                            controls=["search_options:1:2"])
> +
> +        if len(res)>  0 and len(res2) == 0:
>               message(CHANGE, "Existing object %s must be replaced by %s,"
>                               "Renaming old object" % (str(oldDn), str(dn)))
> -            samdb.rename(oldDn, objDn)
> +            samdb.rename(oldDn, objDn, ["relax:0"])
>
> -        return 1
> +        return 0
>
>       if dntoremove is not None:
> +        res = samdb.search(expression="(cn=RID Set)",
> +                            base=str(names.rootdn),
> +                            scope=SCOPE_SUBTREE, attrs=["dn"],
> +                            controls=["search_options:1:2"])
> +
> +        if len(res) == 0:
> +            return 2
>           res = samdb.search(expression="(dn=%s)" % dntoremove,
>                               base=str(names.rootdn),
>                               scope=SCOPE_SUBTREE, attrs=["dn"],
> @@ -491,7 +507,9 @@ def handle_special_add(samdb, dn, names):
>               message(CHANGE, "Existing object %s must be replaced by %s,"
>                               "removing old object" % (dntoremove, str(dn)))
>               samdb.delete(res[0]["dn"])
> -    return 0
> +            return 0
> +
> +    return 1
>
>
>   def check_dn_nottobecreated(hash, index, listdn):
> @@ -538,8 +556,15 @@ def add_missing_object(ref_samdb, samdb, dn, names, basedn, hash, index):
>       :param index: Current creation order
>       :return: True if the object was created False otherwise"""
>
> -    if handle_special_add(samdb, dn, names):
> -        return
> +    ret = handle_special_add(samdb, dn, names)
> +
> +    if ret == 2:
> +        return False
> +
> +    if ret == 0:
> +        return True
> +
> +
>       reference = ref_samdb.search(expression="dn=%s" % (str(dn)), base=basedn,
>                       scope=SCOPE_SUBTREE, controls=["search_options:1:2"])
>       empty = Message()
> @@ -683,8 +708,9 @@ def add_missing_entries(ref_samdb, samdb, names, basedn, list):
>                   # DN can't be created because it depends on some
>                   # other DN in the list
>                   listDefered.append(dn)
> +
>       if len(listDefered) != 0:
> -        raise ProvisioningError("Unable to insert missing elements:" \
> +        raise ProvisioningError("Unable to insert missing elements:"
>                                   "circular references")
>
>   def handle_links(samdb, att, basedn, dn, value, ref_value, delta):
> @@ -1631,15 +1657,16 @@ if __name__ == '__main__':
>               doit = False
>               if deltaattr is not None and len(deltaattr)>  1:
>                   doit = True
> -            deltaattr.remove("dn")
> -            for att in deltaattr:
> -                if att.lower() == "dn":
> -                    continue
> -                if deltaattr.get(att) is not None \
> -                    and deltaattr.get(att).flags() != FLAG_MOD_ADD:
> -                    doit = False
> -                elif deltaattr.get(att) is None:
> -                    doit = False
> +            if doit:
> +                deltaattr.remove("dn")
> +                for att in deltaattr:
> +                    if att.lower() == "dn":
> +                        continue
> +                    if deltaattr.get(att) is not None \
> +                        and deltaattr.get(att).flags() != FLAG_MOD_ADD:
> +                        doit = False
> +                    elif deltaattr.get(att) is None:
> +                        doit = False
>               if doit:
>                   message(CHANGE, "Applying delta to @ATTRIBUTES")
>                   deltaattr.dn = ldb.Dn(basesam, "@ATTRIBUTES")
>
>


-- 
Matthieu Patou
Samba Team        http://samba.org



More information about the samba-technical mailing list