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<m...@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<m...@samba.org>
Autobuild-Date: Thu Nov 11 09:47:55 UTC 2010 on sn-devel-104
commit f0367905d9a6db76712f1dcf9734f64fe5c5e1b3
Author: Matthias Dieter Wallnöfer<m...@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<m...@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.zahar...@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<m...@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<m...@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<m...@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<m...@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<m...@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<m...@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<m...@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<m...@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<m...@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<m...@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<m...@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<m...@samba.org>
Date: Wed Nov 10 13:28:22 2010 +0100
s4:speedtest.py - remove duplicated code
commit 0a29e552cb29cadbb75e64d8cc1278891132a7b0
Author: Matthias Dieter Wallnöfer<m...@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<m...@samba.org>
Date: Wed Nov 10 13:29:14 2010 +0100
s4:speedtest.py - make it executable
commit cc7f390bf940a2f009e16c3811e38424d62ca2dd
Author: Matthias Dieter Wallnöfer<m...@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);