[SCM] Samba Shared Repository - branch master updated
Matthieu Patou
mat at samba.org
Fri Nov 12 15:09:43 MST 2010
Hi Mathias,
We try to get rid of the modify_ldif way of doing ldb modification.
It's better to create a ldb.Message() object and then do a ldb.modify()
with it like this:
--- a/source4/scripting/python/samba/upgradehelpers.py
+++ b/source4/scripting/python/samba/upgradehelpers.py
@@ -835,14 +835,13 @@ def update_machine_account_password(samdb,
secrets_ldb, names):
res = samdb.search(expression=expression, attrs=[])
assert(len(res) == 1)
+ msg = ldb.Message(res[0].dn)
machinepass = samba.generate_random_password(128, 255)
-
- samdb.modify_ldif("""
-dn: """ + str(res[0].dn) + """
-changetype: modify
-replace: clearTextPassword
-clearTextPassword:: """ +
base64.b64encode(machinepass.encode('utf-16-le')) + """
-""")
+ mpu = machinepass.encode('utf-16-le')
+ msg["clearTextPassword"] = ldb.MessageElement(mpu,
+ ldb.FLAG_MOD_REPLACE,
+ "clearTextPassword")
+ samdb.modify(msg)
res = samdb.search(expression=("samAccountName=%s$" %
names.netbiosname),
attrs=["msDs-keyVersionNumber"])
Matthieu.
On 11/11/2010 12:48, Matthias Dieter WallnXXfer wrote:
> The branch, master has been updated
> via bb241f5 s4:pytevent.c - fix a discard const warning
> via f036790 ldb:ldb_ldap.c rename operation - check for the RDN name and value
> via feb00fe s4:dsdb - proof against empty RDN values where expected
> via 4fe63d9 Cannot create OU using custom Schema class
> via e96c9df s4:objectclass LDB module - allow RDNs also to come from superclasses
> via 4f86f29 s4:passwords.py - add a test for the normal "userPassword" behaviour
> via 7f171a9 s4:password_hash and acl LDB modules - handle the "userPassword" attribute according to the "dSHeuristics"
> via d6c78fb s4:password_hash LDB module - move "samdb_msg_find_old_and_new_ldb_val" into the password_hash LDB module
> via eff1e8c s4:libnet/libnet_samsync_ldb.c - remove "userPassword" remove code
> via 39f8661 s4:local_password LDB module - remove schema checking code and fix some typos
> via ed704c2 s4:ldb_modules/util.c - "dsHeuristics" -> "dSHeuristics"
> via 79548f0 s4:selftest/tests.py - skip the "passwords.py" suite on Windows 2000 domain function level
> via 5ded90e s4:acl.py - two password change tests are expected to fails on Windows 2000 function level
> via 2403aaa s4:upgradehelpers.py - use "clearTextPassword" rather than "userPassword"
> via 7c59ece s4:speedtest.py - use "unicodePwd" for setting user's password
> via 0e94569 s4:speedtest.py - remove duplicated code
> via 0a29e55 s4:speedtest.py - fix script name in the help text
> via ed1ca1c s4:speedtest.py - make it executable
> via cc7f390 s4:python tests - fix script names in the help text
> from ee50bdd s4-loadparm: fix the FLAG_DEFAULT settings on specially handled parameters
>
> http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
>
>
> - Log -----------------------------------------------------------------
> commit bb241f5cf8424c2576d5bc33ac149e5720b82068
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 16:21:41 2010 +0100
>
> s4:pytevent.c - fix a discard const warning
>
> Autobuild-User: Matthias Dieter Wallnöfer<mdw at samba.org>
> Autobuild-Date: Thu Nov 11 09:47:55 UTC 2010 on sn-devel-104
>
> commit f0367905d9a6db76712f1dcf9734f64fe5c5e1b3
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 16:20:38 2010 +0100
>
> ldb:ldb_ldap.c rename operation - check for the RDN name and value
>
> Make it more similar to "ldb_ildap.c" and also more save
>
> commit feb00fe7cc238a78b3832c116cb4634936597735
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 16:05:16 2010 +0100
>
> s4:dsdb - proof against empty RDN values where expected
>
> This should prevent crashes as pointed out on the mailing list.
>
> commit 4fe63d927e5e684d3e2bec9642a1e77b056ab2ed
> Author: Zahari Zahariev<zahari.zahariev at postpath.com>
> Date: Tue Nov 9 14:55:32 2010 +0200
>
> Cannot create OU using custom Schema class
>
> If we define our own child class 'subClassOf' system Schema class
> e.g. organizationalUnit then we cannot create OU in the Dafualt
> Naming Context that has this custom Schama class in the objectClass
> attribute.
>
> commit e96c9df817326197a0866a18ad53621405b8bee8
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 15:12:02 2010 +0100
>
> s4:objectclass LDB module - allow RDNs also to come from superclasses
>
> Detected by a testcase written by Zahari Zahariev.
>
> commit 4f86f297a22655067006f88eed5f6cb980742b81
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Tue Nov 9 15:04:47 2010 +0100
>
> s4:passwords.py - add a test for the normal "userPassword" behaviour
>
> Just to make sure that this works now too
>
> commit 7f171a9e0f9b5945bd16a1330ba0908090659030
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Tue Nov 9 14:39:30 2010 +0100
>
> s4:password_hash and acl LDB modules - handle the "userPassword" attribute according to the "dSHeuristics"
>
> commit d6c78fbd3a88e9fc7b625a03d163e9b5098b94d6
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Tue Nov 9 14:45:18 2010 +0100
>
> s4:password_hash LDB module - move "samdb_msg_find_old_and_new_ldb_val" into the password_hash LDB module
>
> It's only used there and so I think it doesn't really belong in
> "dsdb/common/util.c" (I first thought that it could be useful for ACL checking
> but obviously it wasn't).
>
> commit eff1e8cd5d17ca990341e463da03fb1075bdb0d0
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Tue Nov 9 18:46:37 2010 +0100
>
> s4:libnet/libnet_samsync_ldb.c - remove "userPassword" remove code
>
> It could also be a normal attribute with a normal content, and if it's not
> like that then it's for sure empty.
>
> commit 39f86619f5f30461d3c1896e88b6b3df2b51a26e
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Tue Nov 9 18:42:26 2010 +0100
>
> s4:local_password LDB module - remove schema checking code and fix some typos
>
> This is now done by the "objectclass_attrs" LDB module.
>
> commit ed704c28b2f24228b61dee21d873f6b09bf98ca4
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Tue Nov 9 19:44:27 2010 +0100
>
> s4:ldb_modules/util.c - "dsHeuristics" -> "dSHeuristics"
>
> commit 79548f0da243884d60845f61fe2404e26eb52f65
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Thu Nov 11 10:01:26 2010 +0100
>
> s4:selftest/tests.py - skip the "passwords.py" suite on Windows 2000 domain function level
>
> The "userPassword" password change functionality isn't available and so it
> causes big parts of the testsuite to fail. On the other hand we've basic tests
> in "acl.py" and indirectly also over SAMR and kpasswd so I propose to simply
> skip it.
>
> commit 5ded90ef66744e8919868362ac455bdbf4b1568b
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Thu Nov 11 09:33:06 2010 +0100
>
> s4:acl.py - two password change tests are expected to fails on Windows 2000 function level
>
> commit 2403aaa7591e1827d91644579dbf503d8e9a7df6
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 14:01:58 2010 +0100
>
> s4:upgradehelpers.py - use "clearTextPassword" rather than "userPassword"
>
> It's the default internal s4 password change attribute
>
> commit 7c59ecec5078c0ab8587bb322a228419f5a8c978
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 13:26:31 2010 +0100
>
> s4:speedtest.py - use "unicodePwd" for setting user's password
>
> It's available on all AD hosts (including Windows 2000) and on all configurations!
>
> commit 0e945697f59b7215d46af0709ac698f7483850df
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 13:28:22 2010 +0100
>
> s4:speedtest.py - remove duplicated code
>
> commit 0a29e552cb29cadbb75e64d8cc1278891132a7b0
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 13:37:46 2010 +0100
>
> s4:speedtest.py - fix script name in the help text
>
> commit ed1ca1c49e10c9f97aa1334f9aedf631352d144c
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 13:29:14 2010 +0100
>
> s4:speedtest.py - make it executable
>
> commit cc7f390bf940a2f009e16c3811e38424d62ca2dd
> Author: Matthias Dieter Wallnöfer<mdw at samba.org>
> Date: Wed Nov 10 13:35:30 2010 +0100
>
> s4:python tests - fix script names in the help text
>
> -----------------------------------------------------------------------
>
> Summary of changes:
> lib/tevent/pytevent.c | 2 +-
> source4/dsdb/common/util.c | 67 +------------
> source4/dsdb/samdb/ldb_modules/acl.c | 25 ++++-
> source4/dsdb/samdb/ldb_modules/local_password.c | 18 +--
> source4/dsdb/samdb/ldb_modules/objectclass.c | 54 ++++++++--
> source4/dsdb/samdb/ldb_modules/password_hash.c | 117 +++++++++++++++++-----
> source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 ++
> source4/dsdb/samdb/ldb_modules/samldb.c | 13 ++-
> source4/dsdb/samdb/ldb_modules/util.c | 24 ++++-
> source4/dsdb/samdb/ldb_modules/wscript_build | 2 +-
> source4/dsdb/tests/python/acl.py | 19 +++-
> source4/dsdb/tests/python/ldap_schema.py | 58 +++++++++++-
> source4/dsdb/tests/python/passwords.py | 100 ++++++++++++++++++-
> source4/dsdb/tests/python/sec_descriptor.py | 2 +-
> source4/dsdb/tests/python/urgent_replication.py | 2 +-
> source4/lib/ldb/ldb_ldap/ldb_ldap.c | 14 ++-
> source4/lib/ldb/modules/rdn_name.c | 15 ++-
> source4/libnet/libnet_samsync_ldb.c | 6 -
> source4/scripting/devel/speedtest.py | 9 +-
> source4/scripting/python/samba/upgradehelpers.py | 13 ++-
> source4/selftest/tests.py | 6 +-
> 21 files changed, 424 insertions(+), 150 deletions(-)
> mode change 100644 => 100755 source4/scripting/devel/speedtest.py
>
>
> Changeset truncated at 500 lines:
>
> diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c
> index 5999802..22541bb 100644
> --- a/lib/tevent/pytevent.c
> +++ b/lib/tevent/pytevent.c
> @@ -629,7 +629,7 @@ static void py_tevent_context_dealloc(TeventContext_Object *self)
>
> static PyObject *py_tevent_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
> {
> - const char *kwnames[] = { "name", NULL };
> + const char * const kwnames[] = { "name", NULL };
> char *name = NULL;
> struct tevent_context *ev;
> TeventContext_Object *ret;
> diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
> index 16d5011..7f6ce64 100644
> --- a/source4/dsdb/common/util.c
> +++ b/source4/dsdb/common/util.c
> @@ -699,68 +699,6 @@ struct ldb_message_element *samdb_find_attribute(struct ldb_context *ldb,
> return NULL;
> }
>
> -/*
> - * This is intended for use by the "password hash" module since there
> - * password changes can be specified through one message element with the
> - * new password (to set) and another one with the old password (to unset).
> - *
> - * The first which sets a password (new value) can have flags
> - * (LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_REPLACE) but also none (on "add" operations
> - * for entries). The latter (old value) has always specified
> - * LDB_FLAG_MOD_DELETE.
> - *
> - * Returns LDB_ERR_CONSTRAINT_VIOLATION and LDB_ERR_UNWILLING_TO_PERFORM if
> - * matching message elements are malformed in respect to the set/change rules.
> - * Otherwise it returns LDB_SUCCESS.
> - */
> -int samdb_msg_find_old_and_new_ldb_val(const struct ldb_message *msg,
> - const char *name,
> - enum ldb_request_type operation,
> - const struct ldb_val **new_val,
> - const struct ldb_val **old_val)
> -{
> - unsigned int i;
> -
> - *new_val = NULL;
> - *old_val = NULL;
> -
> - if (msg == NULL) {
> - return LDB_SUCCESS;
> - }
> -
> - for (i = 0; i< msg->num_elements; i++) {
> - if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
> - continue;
> - }
> -
> - if ((operation == LDB_MODIFY)&&
> - (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE)) {
> - /* 0 values are allowed */
> - if (msg->elements[i].num_values == 1) {
> - *old_val =&msg->elements[i].values[0];
> - } else if (msg->elements[i].num_values> 1) {
> - return LDB_ERR_CONSTRAINT_VIOLATION;
> - }
> - } else if ((operation == LDB_MODIFY)&&
> - (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_REPLACE)) {
> - if (msg->elements[i].num_values> 0) {
> - *new_val =&msg->elements[i].values[msg->elements[i].num_values - 1];
> - } else {
> - return LDB_ERR_UNWILLING_TO_PERFORM;
> - }
> - } else {
> - /* Add operations and LDB_FLAG_MOD_ADD */
> - if (msg->elements[i].num_values> 0) {
> - *new_val =&msg->elements[i].values[msg->elements[i].num_values - 1];
> - } else {
> - return LDB_ERR_CONSTRAINT_VIOLATION;
> - }
> - }
> - }
> -
> - return LDB_SUCCESS;
> -}
> -
> int samdb_find_or_add_value(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value)
> {
> if (samdb_find_attribute(ldb, msg, name, set_value) == NULL) {
> @@ -1657,7 +1595,12 @@ int samdb_find_site_for_computer(struct ldb_context *ldb,
> talloc_free(dn);
> return LDB_ERR_INVALID_DN_SYNTAX;
> }
> +
> rdn_val = ldb_dn_get_rdn_val(dn);
> + if (rdn_val == NULL) {
> + return LDB_ERR_OPERATIONS_ERROR;
> + }
> +
> (*site_name) = talloc_strndup(mem_ctx, (const char *)rdn_val->data, rdn_val->length);
> talloc_free(dn);
> if (!*site_name) {
> diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
> index 3cf768e..b6635b1 100644
> --- a/source4/dsdb/samdb/ldb_modules/acl.c
> +++ b/source4/dsdb/samdb/ldb_modules/acl.c
> @@ -61,6 +61,7 @@ struct acl_context {
> bool allowedChildClasses;
> bool allowedChildClassesEffective;
> bool sDRightsEffective;
> + bool userPassword;
> const char * const *attrs;
> struct dsdb_schema *schema;
> };
> @@ -542,7 +543,8 @@ static int acl_check_password_rights(TALLOC_CTX *mem_ctx,
> struct ldb_request *req,
> struct security_descriptor *sd,
> struct dom_sid *sid,
> - const struct GUID *oc_guid)
> + const struct GUID *oc_guid,
> + bool userPassword)
> {
> int ret = LDB_SUCCESS;
> unsigned int del_attr_cnt = 0, add_attr_cnt = 0, rep_attr_cnt = 0;
> @@ -557,6 +559,10 @@ static int acl_check_password_rights(TALLOC_CTX *mem_ctx,
> return ldb_module_oom(module);
> }
> for (l = passwordAttrs; *l != NULL; l++) {
> + if ((!userPassword)&& (ldb_attr_cmp(*l, "userPassword") == 0)) {
> + continue;
> + }
> +
> while ((el = ldb_msg_find_element(msg, *l)) != NULL) {
> if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
> ++del_attr_cnt;
> @@ -632,6 +638,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req)
> struct security_descriptor *sd;
> struct dom_sid *sid = NULL;
> struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
> + bool userPassword = dsdb_user_password_support(module, req);
> TALLOC_CTX *tmp_ctx = talloc_new(req);
> static const char *acl_attrs[] = {
> "nTSecurityDescriptor",
> @@ -732,14 +739,15 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req)
> continue;
> }
> else if (ldb_attr_cmp("unicodePwd", req->op.mod.message->elements[i].name) == 0 ||
> - ldb_attr_cmp("userPassword", req->op.mod.message->elements[i].name) == 0 ||
> + (userPassword&& ldb_attr_cmp("userPassword", req->op.mod.message->elements[i].name) == 0) ||
> ldb_attr_cmp("clearTextPassword", req->op.mod.message->elements[i].name) == 0) {
> ret = acl_check_password_rights(tmp_ctx,
> module,
> req,
> sd,
> sid,
> - guid);
> + guid,
> + userPassword);
> if (ret != LDB_SUCCESS) {
> goto fail;
> }
> @@ -1074,6 +1082,11 @@ static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares)
> if (data&& data->password_attrs) {
> if (!ac->am_system) {
> for (i = 0; data->password_attrs[i]; i++) {
> + if ((!ac->userPassword)&&
> + (ldb_attr_cmp(data->password_attrs[i],
> + "userPassword") == 0))
> + continue;
> +
> ldb_msg_remove_attr(ares->message, data->password_attrs[i]);
> }
> }
> @@ -1115,6 +1128,7 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req)
> ac->allowedChildClasses = ldb_attr_in_list(req->op.search.attrs, "allowedChildClasses");
> ac->allowedChildClassesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedChildClassesEffective");
> ac->sDRightsEffective = ldb_attr_in_list(req->op.search.attrs, "sDRightsEffective");
> + ac->userPassword = dsdb_user_password_support(module, ac);
> ac->schema = dsdb_get_schema(ldb, ac);
>
> /* replace any attributes in the parse tree that are private,
> @@ -1125,6 +1139,11 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req)
> /* remove password attributes */
> if (data&& data->password_attrs) {
> for (i = 0; data->password_attrs[i]; i++) {
> + if ((!ac->userPassword)&&
> + (ldb_attr_cmp(data->password_attrs[i],
> + "userPassword") == 0))
> + continue;
> +
> ldb_parse_tree_attr_replace(req->op.search.tree,
> data->password_attrs[i],
> "kludgeACLredactedattribute");
> diff --git a/source4/dsdb/samdb/ldb_modules/local_password.c b/source4/dsdb/samdb/ldb_modules/local_password.c
> index f544689..c0e1e9a 100644
> --- a/source4/dsdb/samdb/ldb_modules/local_password.c
> +++ b/source4/dsdb/samdb/ldb_modules/local_password.c
> @@ -39,13 +39,15 @@
>
> #define PASSWORD_GUID_ATTR "masterGUID"
>
> -/* This module maintains a local password database, seperate from the main LDAP server.
> +/* This module maintains a local password database, separate from the main LDAP
> + server.
>
> - This allows the password database to be syncronised in a multi-master
> + This allows the password database to be synchronised in a multi-master
> fashion, seperate to the more difficult concerns of the main
> - database. (With passwords, the last writer always wins)
> + database. (With passwords, the last writer always wins)
>
> - Each incoming add/modify is split into a remote, and a local request, done in that order.
> + Each incoming add/modify is split into a remote, and a local request, done
> + in that order.
>
> We maintain a list of attributes that are kept locally - perhaps
> this should use the @KLUDGE_ACL list of passwordAttribute
> @@ -173,14 +175,6 @@ static int local_password_add(struct ldb_module *module, struct ldb_request *req
> return ldb_next_request(module, req);
> }
>
> - /* TODO: remove this when userPassword will be in schema */
> - if (!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "person")) {
> - ldb_asprintf_errstring(ldb,
> - "Cannot relocate a password on entry: %s, does not have objectClass 'person'",
> - ldb_dn_get_linearized(req->op.add.message->dn));
> - return LDB_ERR_OBJECT_CLASS_VIOLATION;
> - }
> -
> /* From here, we assume we have password attributes to split off */
> ac = lpdb_init_context(module, req);
> if (!ac) {
> diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
> index 6702b01..2e95eb5 100644
> --- a/source4/dsdb/samdb/ldb_modules/objectclass.c
> +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
> @@ -334,8 +334,10 @@ static int fix_dn(struct ldb_context *ldb,
> return ldb_operr(ldb);
> }
>
> -
> rdn_val = ldb_dn_get_rdn_val(newdn);
> + if (rdn_val == NULL) {
> + return ldb_operr(ldb);
> + }
>
> #if 0
> /* the rules for rDN length constraints are more complex than
> @@ -468,6 +470,8 @@ static int objectclass_do_add(struct oc_context *ac)
> const struct dsdb_class *objectclass;
> struct ldb_dn *objectcategory;
> int32_t systemFlags = 0;
> + unsigned int i, j;
> + bool found;
> int ret;
>
> ldb = ldb_module_get_ctx(ac->module);
> @@ -561,6 +565,7 @@ static int objectclass_do_add(struct oc_context *ac)
> talloc_free(mem_ctx);
> return ldb_oom(ldb);
> }
> +
> ret = ldb_msg_add_string(msg, "objectClass", value);
> if (ret != LDB_SUCCESS) {
> ldb_set_errstring(ldb,
> @@ -587,11 +592,25 @@ static int objectclass_do_add(struct oc_context *ac)
> }
>
> rdn_name = ldb_dn_get_rdn_name(msg->dn);
> - if (objectclass->rDNAttID
> - && ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0) {
> + if (rdn_name == NULL) {
> + return ldb_operr(ldb);
> + }
> + found = false;
> + for (i = 0; (!found)&& (i< objectclass_element->num_values);
> + i++) {
> + const struct dsdb_class *tmp_class =
> + dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
> + &objectclass_element->values[i]);
> +
> + if (tmp_class == NULL) continue;
> +
> + if (ldb_attr_cmp(rdn_name, tmp_class->rDNAttID) == 0)
> + found = true;
> + }
> + if (!found) {
> ldb_asprintf_errstring(ldb,
> - "RDN %s is not correct for most specific structural objectclass %s, should be %s",
> - rdn_name, objectclass->lDAPDisplayName, objectclass->rDNAttID);
> + "objectclass: Invalid RDN '%s' for objectclass '%s'!",
> + rdn_name, objectclass->lDAPDisplayName);
> return LDB_ERR_NAMING_VIOLATION;
> }
>
> @@ -616,7 +635,6 @@ static int objectclass_do_add(struct oc_context *ac)
> = ldb_msg_find_element(ac->search_res->message, "objectClass");
>
> bool allowed_class = false;
> - unsigned int i, j;
> for (i=0; allowed_class == false&& oc_el&& i< oc_el->num_values; i++) {
> const struct dsdb_class *sclass;
>
> @@ -1256,6 +1274,7 @@ static int objectclass_do_rename2(struct oc_context *ac)
> const char *rdn_name;
> bool allowed_class = false;
> unsigned int i, j;
> + bool found;
>
> oc_el_entry = ldb_msg_find_element(ac->search_res->message,
> "objectClass");
> @@ -1270,13 +1289,24 @@ static int objectclass_do_rename2(struct oc_context *ac)
> }
>
> rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn);
> - if ((objectclass->rDNAttID != NULL)&&
> - (ldb_attr_cmp(rdn_name, objectclass->rDNAttID) != 0)) {
> + if (rdn_name == NULL) {
> + return ldb_operr(ldb);
> + }
> + found = false;
> + for (i = 0; (!found)&& (i< oc_el_entry->num_values); i++) {
> + const struct dsdb_class *tmp_class =
> + dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema,
> + &oc_el_entry->values[i]);
> +
> + if (tmp_class == NULL) continue;
> +
> + if (ldb_attr_cmp(rdn_name, tmp_class->rDNAttID) == 0)
> + found = true;
> + }
> + if (!found) {
> ldb_asprintf_errstring(ldb,
> - "objectclass: RDN %s is not correct for most specific structural objectclass %s, should be %s",
> - rdn_name,
> - objectclass->lDAPDisplayName,
> - objectclass->rDNAttID);
> + "objectclass: Invalid RDN '%s' for objectclass '%s'!",
> + rdn_name, objectclass->lDAPDisplayName);
> return LDB_ERR_UNWILLING_TO_PERFORM;
> }
>
> diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
> index 83bee2f..9b6cf8c 100644
> --- a/source4/dsdb/samdb/ldb_modules/password_hash.c
> +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
> @@ -33,19 +33,16 @@
> */
>
> #include "includes.h"
> -#include "libcli/ldap/ldap_ndr.h"
> #include "ldb_module.h"
> -#include "librpc/gen_ndr/misc.h"
> -#include "librpc/gen_ndr/samr.h"
> +#include "auth/session.h"
> #include "libcli/auth/libcli_auth.h"
> #include "libcli/security/security.h"
> +#include "libcli/security/session.h"
> #include "system/kerberos.h"
> #include "auth/kerberos/kerberos.h"
> -#include "system/time.h"
> #include "dsdb/samdb/samdb.h"
> -#include "../libds/common/flags.h"
> +#include "dsdb/samdb/ldb_modules/util.h"
> #include "dsdb/samdb/ldb_modules/password_modules.h"
> -#include "librpc/ndr/libndr.h"
> #include "librpc/gen_ndr/ndr_drsblobs.h"
> #include "../lib/crypto/crypto.h"
> #include "param/param.h"
> @@ -1633,6 +1630,68 @@ static int check_password_restrictions(struct setup_password_fields_io *io)
> return LDB_SUCCESS;
> }
>
> +/*
> + * This is intended for use by the "password_hash" module since there
> + * password changes can be specified through one message element with the
> + * new password (to set) and another one with the old password (to unset).
> + *
> + * The first which sets a password (new value) can have flags
> + * (LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_REPLACE) but also none (on "add" operations
> + * for entries). The latter (old value) has always specified
> + * LDB_FLAG_MOD_DELETE.
> + *
> + * Returns LDB_ERR_CONSTRAINT_VIOLATION and LDB_ERR_UNWILLING_TO_PERFORM if
> + * matching message elements are malformed in respect to the set/change rules.
> + * Otherwise it returns LDB_SUCCESS.
> + */
> +static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
> + const char *name,
> + enum ldb_request_type operation,
> + const struct ldb_val **new_val,
> + const struct ldb_val **old_val)
> +{
> + unsigned int i;
> +
> + *new_val = NULL;
> + *old_val = NULL;
> +
> + if (msg == NULL) {
> + return LDB_SUCCESS;
> + }
> +
> + for (i = 0; i< msg->num_elements; i++) {
> + if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
> + continue;
> + }
> +
> + if ((operation == LDB_MODIFY)&&
> + (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE)) {
> + /* 0 values are allowed */
> + if (msg->elements[i].num_values == 1) {
> + *old_val =&msg->elements[i].values[0];
> + } else if (msg->elements[i].num_values> 1) {
> + return LDB_ERR_CONSTRAINT_VIOLATION;
> + }
> + } else if ((operation == LDB_MODIFY)&&
> + (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_REPLACE)) {
> + if (msg->elements[i].num_values> 0) {
> + *new_val =&msg->elements[i].values[msg->elements[i].num_values - 1];
> + } else {
> + return LDB_ERR_UNWILLING_TO_PERFORM;
> + }
> + } else {
> + /* Add operations and LDB_FLAG_MOD_ADD */
> + if (msg->elements[i].num_values> 0) {
> + *new_val =&msg->elements[i].values[msg->elements[i].num_values - 1];
> + } else {
> + return LDB_ERR_CONSTRAINT_VIOLATION;
> + }
> + }
> + }
> +
> + return LDB_SUCCESS;
> +}
> +
> static int setup_io(struct ph_context *ac,
> const struct ldb_message *orig_msg,
> const struct ldb_message *searched_msg,
> @@ -1687,11 +1746,10 @@ static int setup_io(struct ph_context *ac,
> }
>
> if (ac->userPassword) {
> - ret = samdb_msg_find_old_and_new_ldb_val(orig_msg,
> - "userPassword",
> - ac->req->operation,
> - &io->n.cleartext_utf8,
> - &io->og.cleartext_utf8);
> + ret = msg_find_old_and_new_pwd_val(orig_msg, "userPassword",
> + ac->req->operation,
> + &io->n.cleartext_utf8,
> + &io->og.cleartext_utf8);
> if (ret != LDB_SUCCESS) {
> ldb_asprintf_errstring(ldb,
> "setup_io: "
> @@ -1700,10 +1758,10 @@ static int setup_io(struct ph_context *ac,
> }
> }
>
> - ret = samdb_msg_find_old_and_new_ldb_val(orig_msg, "clearTextPassword",
> - ac->req->operation,
> - &io->n.cleartext_utf16,
> - &io->og.cleartext_utf16);
> + ret = msg_find_old_and_new_pwd_val(orig_msg, "clearTextPassword",
> + ac->req->operation,
> + &io->n.cleartext_utf16,
> + &io->og.cleartext_utf16);
> if (ret != LDB_SUCCESS) {
> ldb_asprintf_errstring(ldb,
> "setup_io: "
> @@ -1724,10 +1782,10 @@ static int setup_io(struct ph_context *ac,
> that would then be treated as a UTF16 password rather than
> a nthash */
>
> - ret = samdb_msg_find_old_and_new_ldb_val(orig_msg, "unicodePwd",
> - ac->req->operation,
> - "ed_utf16,
> - &old_quoted_utf16);
> + ret = msg_find_old_and_new_pwd_val(orig_msg, "unicodePwd",
> + ac->req->operation,
> + "ed_utf16,
> + &old_quoted_utf16);
> if (ret != LDB_SUCCESS) {
> ldb_asprintf_errstring(ldb,
> "setup_io: "
> @@ -1841,9 +1899,9 @@ static int setup_io(struct ph_context *ac,
>
> /* Handles the "dBCSPwd" attribute (LM hash) */
> io->n.lm_hash = NULL; io->og.lm_hash = NULL;
> - ret = samdb_msg_find_old_and_new_ldb_val(orig_msg, "dBCSPwd",
> - ac->req->operation,
> - &lm_hash,&old_lm_hash);
> + ret = msg_find_old_and_new_pwd_val(orig_msg, "dBCSPwd",
> + ac->req->operation,
> + &lm_hash,&old_lm_hash);
> if (ret != LDB_SUCCESS) {
> ldb_asprintf_errstring(ldb,
> "setup_io: "
> @@ -2232,7 +2290,7 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
> *ntAttr, *lmAttr;
> int ret;
> struct ldb_control *bypass = NULL;
> - bool userPassword = true;
> + bool userPassword = dsdb_user_password_support(module, req);
>
>
--
Matthieu Patou
Samba Team http://samba.org
Private repo http://git.samba.org/?p=mat/samba.git;a=summary
More information about the samba-technical
mailing list