[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Sat Nov 13 03:50:17 MST 2010


Well basically yes, ekacnet.

But I don't see any problem to use "modify_ldif"/"add_ldif" when sending 
very special requests as password changes and others. Sometimes it's 
really needed due to encoding constraints.

Greets,
Matthias

Matthieu Patou wrote:
> 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,
>> - &quoted_utf16,
>> - &old_quoted_utf16);
>> +    ret = msg_find_old_and_new_pwd_val(orig_msg, "unicodePwd",
>> +                       ac->req->operation,
>> + &quoted_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);
>>
>>
>
>



More information about the samba-cvs mailing list