[SCM] Samba Shared Repository - branch master updated
Matthias Dieter Wallnöfer
mdw at samba.org
Sun Nov 15 06:27:00 MST 2009
The branch, master has been updated
via cc08074... ldb:python bindings - add a context on "py_ldb_delete"
via 6cf43db... s4:ldap.py - enhance schema addition test
via df95d5c... s4:dsdb/repl/replicated_objects - Applicate also here the new "lDAPDisplayName" generator
via 2c7294b... s4:SAMLDB module - Add support for required and generated schema attributes
via da3d471... s4:samdb util - add a call for generating a correct "lDAPDisplayName"
from bf4e8ba... s3: Fix a memleak in sys_popen
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit cc080742bd29d56f863abcb33f26d1719dacaaf7
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Sun Nov 15 14:23:32 2009 +0100
ldb:python bindings - add a context on "py_ldb_delete"
So the converted DN will be freed after usage.
commit 6cf43db7fc3e2eea2cd72a026b8cd20012387e12
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Fri Nov 13 22:31:53 2009 +0100
s4:ldap.py - enhance schema addition test
Don't add only a new objectclass but also a new attribute. Plus let now the
server itself calculate the "lDAPDisplayName" attribute and compare the result.
commit df95d5c29292968b465bff24c3cf78800677a4d4
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Sat Nov 14 20:14:45 2009 +0100
s4:dsdb/repl/replicated_objects - Applicate also here the new "lDAPDisplayName" generator
Also here we've to be sure to generate the attribute correctly if it doesn't
exist yet.
commit 2c7294bd8faad339d090ee7a7d8d1bb44c9837fc
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Sep 23 21:14:37 2009 -0700
s4:SAMLDB module - Add support for required and generated schema attributes
This missing support found by Microsoft test suite at AD interop event.
Patch by Andrew Bartlett
Enhancements by Matthias Dieter Wallnöfer
commit da3d471d10a822713fea937b3e1951bdbdc7dc83
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Sat Nov 14 20:12:42 2009 +0100
s4:samdb util - add a call for generating a correct "lDAPDisplayName"
This is needed for the SAMLDB module enhancement regarding schema objects.
The algorithm in pseudo code is located in MS-ADTS 3.1.1.2.3.4.
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/common/util.c | 28 +++
source4/dsdb/repl/replicated_objects.c | 5 +-
source4/dsdb/samdb/ldb_modules/samldb.c | 292 ++++++++++++++++++++++++++++++-
source4/lib/ldb/pyldb.c | 12 +-
source4/lib/ldb/tests/python/ldap.py | 52 +++++--
5 files changed, 367 insertions(+), 22 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index dcbb462..4175928 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -37,6 +37,7 @@
#include "param/param.h"
#include "libcli/auth/libcli_auth.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "system/locale.h"
/*
search the sam for the specified attributes in a specific domain, filter on
@@ -2617,3 +2618,30 @@ failed:
talloc_free(tmp_ctx);
return LDB_ERR_NO_SUCH_OBJECT;
}
+
+/*
+ * Function which generates a "lDAPDisplayName" attribute from a "CN" one.
+ * Algorithm implemented according to MS-ADTS 3.1.1.2.3.4
+ */
+const char *samdb_cn_to_lDAPDisplayName(TALLOC_CTX *mem_ctx, const char *cn)
+{
+ char **tokens, *ret;
+ size_t i;
+
+ tokens = str_list_make(mem_ctx, cn, " -_");
+ if (tokens == NULL)
+ return NULL;
+
+ /* "tolower()" and "toupper()" should also work properly on 0x00 */
+ tokens[0][0] = tolower(tokens[0][0]);
+ for (i = 1; i < str_list_length((const char **)tokens); i++)
+ tokens[i][0] = toupper(tokens[i][0]);
+
+ ret = talloc_strdup(mem_ctx, tokens[0]);
+ for (i = 1; i < str_list_length((const char **)tokens); i++)
+ ret = talloc_asprintf_append_buffer(ret, "%s", tokens[i]);
+
+ talloc_free(tokens);
+
+ return ret;
+}
diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index 020d5f1..043c620 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -153,7 +153,10 @@ static WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
struct ldb_message_element *el;
el = ldb_msg_find_element(msg, rdn_attr->lDAPDisplayName);
if (!el) {
- ret = ldb_msg_add_value(msg, rdn_attr->lDAPDisplayName, rdn_value, NULL);
+ /* we assume that the RDN has prefix "CN" */
+ ret = ldb_msg_add_string(msg, rdn_attr->lDAPDisplayName,
+ samdb_cn_to_lDAPDisplayName(mem_ctx,
+ (const char *) rdn_value->data));
if (ret != LDB_SUCCESS) {
return WERR_FOOBAR;
}
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 0f314b2..390950b 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -97,6 +97,9 @@ struct samldb_ctx {
/* all the async steps necessary to complete the operation */
struct samldb_step *steps;
struct samldb_step *curstep;
+
+ /* If someone set an ares to forward controls and response back to the caller */
+ struct ldb_reply *ares;
};
static struct samldb_ctx *samldb_ctx_init(struct ldb_module *module,
@@ -161,9 +164,14 @@ static int samldb_next_step(struct samldb_ctx *ac)
return ac->curstep->fn(ac);
}
- /* it is an error if the last step does not properly
- * return to the upper module by itself */
- return LDB_ERR_OPERATIONS_ERROR;
+ /* we exit the samldb module here */
+ /* If someone set an ares to forward controls and response back to the caller, use them */
+ if (ac->ares) {
+ return ldb_module_done(ac->req, ac->ares->controls,
+ ac->ares->response, LDB_SUCCESS);
+ } else {
+ return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
+ }
}
/*
@@ -868,6 +876,152 @@ static int samldb_notice_sid(struct samldb_ctx *ac)
}
/*
+ * samldb_set_defaultObjectCategory_callback (async)
+ */
+
+static int samldb_set_defaultObjectCategory_callback(struct ldb_request *req,
+ struct ldb_reply *ares)
+{
+ struct ldb_context *ldb;
+ struct samldb_ctx *ac;
+ int ret;
+
+ ac = talloc_get_type(req->context, struct samldb_ctx);
+ ldb = ldb_module_get_ctx(ac->module);
+
+ if (!ares) {
+ ret = LDB_ERR_OPERATIONS_ERROR;
+ goto done;
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+ if (ares->type != LDB_REPLY_DONE) {
+ ldb_set_errstring(ldb,
+ "Invalid reply type!\n");
+ ret = LDB_ERR_OPERATIONS_ERROR;
+ goto done;
+ }
+
+ ret = samldb_next_step(ac);
+
+done:
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int samldb_set_defaultObjectCategory(struct samldb_ctx *ac)
+{
+ int ret;
+ if (ac->dn) {
+ struct ldb_request *req;
+ struct ldb_context *ldb;
+ struct ldb_message *msg = ldb_msg_new(ac);
+
+ msg->dn = ac->dn;
+
+ ldb_msg_add_empty(msg, "defaultObjectCategory", LDB_FLAG_MOD_REPLACE, NULL);
+
+ ldb_msg_add_steal_string(msg, "defaultObjectCategory", ldb_dn_alloc_linearized(msg, ac->dn));
+
+ ldb = ldb_module_get_ctx(ac->module);
+
+ ret = ldb_build_mod_req(&req, ldb, ac,
+ msg, NULL,
+ ac, samldb_set_defaultObjectCategory_callback,
+ ac->req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ return ldb_next_request(ac->module, req);
+ }
+
+ ret = samldb_next_step(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ return ret;
+}
+
+/*
+ * samldb_find_for_defaultObjectCategory (async)
+ */
+
+static int samldb_find_for_defaultObjectCategory_callback(struct ldb_request *req,
+ struct ldb_reply *ares)
+{
+ struct samldb_ctx *ac;
+ int ret;
+
+ ac = talloc_get_type(req->context, struct samldb_ctx);
+
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+ ac->dn = talloc_steal(ac, ares->message->dn);
+ break;
+ case LDB_REPLY_REFERRAL:
+ /* this should not happen */
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+
+ case LDB_REPLY_DONE:
+ /* found or not found, go on */
+ talloc_free(ares);
+ ret = samldb_next_step(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ break;
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
+{
+ struct ldb_context *ldb;
+ struct ldb_request *req;
+ int ret;
+ const char *no_attrs[] = { NULL };
+
+ ldb = ldb_module_get_ctx(ac->module);
+
+ ac->dn = NULL;
+
+ if (ldb_msg_find_element(ac->msg, "defaultObjectCategory") == NULL) {
+ ret = ldb_build_search_req(&req, ldb, ac,
+ ac->msg->dn, LDB_SCOPE_BASE,
+ "objectClass=classSchema", no_attrs,
+ NULL,
+ ac, samldb_find_for_defaultObjectCategory_callback,
+ ac->req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ return ldb_next_request(ac->module, req);
+ }
+
+ ret = samldb_next_step(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ return ret;
+
+}
+
+
+
+/*
* samldb_add_entry (async)
*/
@@ -876,6 +1030,7 @@ static int samldb_add_entry_callback(struct ldb_request *req,
{
struct ldb_context *ldb;
struct samldb_ctx *ac;
+ int ret;
ac = talloc_get_type(req->context, struct samldb_ctx);
ldb = ldb_module_get_ctx(ac->module);
@@ -895,9 +1050,14 @@ static int samldb_add_entry_callback(struct ldb_request *req,
LDB_ERR_OPERATIONS_ERROR);
}
- /* we exit the samldb module here */
- return ldb_module_done(ac->req, ares->controls,
- ares->response, LDB_SUCCESS);
+ /* The caller may wish to get controls back from the add */
+ ac->ares = talloc_steal(ac, ares);
+
+ ret = samldb_next_step(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ return ret;
}
static int samldb_add_entry(struct samldb_ctx *ac)
@@ -975,8 +1135,102 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
ret = samdb_find_or_add_attribute(ldb, ac->msg,
"groupType", "-2147483646");
if (ret != LDB_SUCCESS) return ret;
+ } else if (strcmp(ac->type, "classSchema") == 0) {
+ const struct ldb_val *rdn_value;
+
+ ret = samdb_find_or_add_attribute(ldb, ac->msg,
+ "rdnAttId", "cn");
+ if (ret != LDB_SUCCESS) return ret;
+
+ rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
+ if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) {
+ /* the RDN has prefix "CN" */
+ ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName",
+ samdb_cn_to_lDAPDisplayName(ac,
+ (const char *) rdn_value->data));
+ if (ret != LDB_SUCCESS) {
+ ldb_oom(ldb);
+ return ret;
+ }
+ }
+
+ if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
+ enum ndr_err_code ndr_err;
+ struct ldb_val guid_value;
+ struct GUID guid;
+ /* a new GUID */
+ guid = GUID_random();
+ /* generated NDR encoded values */
+ ndr_err = ndr_push_struct_blob(&guid_value, ac->msg,
+ NULL,
+ &guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ret = ldb_msg_add_value(ac->msg, "schemaIDGUID", &guid_value, NULL);
+ if (ret != LDB_SUCCESS) {
+ ldb_oom(ldb);
+ return ret;
+ }
+ }
+
+ ret = samldb_add_step(ac, samldb_add_entry);
+ if (ret != LDB_SUCCESS) return ret;
+
+ ret = samldb_add_step(ac, samldb_find_for_defaultObjectCategory);
+ if (ret != LDB_SUCCESS) return ret;
+
+ ret = samldb_add_step(ac, samldb_set_defaultObjectCategory);
+ if (ret != LDB_SUCCESS) return ret;
+
+ return samldb_first_step(ac);
+ } else if (strcmp(ac->type, "attributeSchema") == 0) {
+ const struct ldb_val *rdn_value;
+ rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
+ if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) {
+ /* the RDN has prefix "CN" */
+ ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName",
+ samdb_cn_to_lDAPDisplayName(ac,
+ (const char *) rdn_value->data));
+ if (ret != LDB_SUCCESS) {
+ ldb_oom(ldb);
+ return ret;
+ }
+ }
+
+ ret = samdb_find_or_add_attribute(ldb, ac->msg,
+ "isSingleValued", "FALSE");
+ if (ret != LDB_SUCCESS) return ret;
+
+ if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
+ enum ndr_err_code ndr_err;
+ struct ldb_val guid_value;
+ struct GUID guid;
+ /* a new GUID */
+ guid = GUID_random();
+ /* generated NDR encoded values */
+ ndr_err = ndr_push_struct_blob(&guid_value, ac->msg,
+ NULL,
+ &guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ret = ldb_msg_add_value(ac->msg, "schemaIDGUID", &guid_value, NULL);
+ if (ret != LDB_SUCCESS) {
+ ldb_oom(ldb);
+ return ret;
+ }
+ }
+
+ ret = samldb_add_step(ac, samldb_add_entry);
+ if (ret != LDB_SUCCESS) return ret;
+
+ return samldb_first_step(ac);
} else {
- /* we should only have "user" and "group" */
ldb_asprintf_errstring(ldb,
"Invalid entry type!\n");
return LDB_ERR_OPERATIONS_ERROR;
@@ -1952,6 +2206,30 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
return samldb_fill_foreignSecurityPrincipal_object(ac);
}
+ if (samdb_find_attribute(ldb, ac->msg,
+ "objectclass", "classSchema") != NULL) {
+
+ ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
+ return ret;
+ }
+
+ return samldb_fill_object(ac, "classSchema");
+ }
+
+ if (samdb_find_attribute(ldb, ac->msg,
+ "objectclass", "attributeSchema") != NULL) {
+
+ ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
+ return ret;
+ }
+
+ return samldb_fill_object(ac, "attributeSchema");
+ }
+
talloc_free(ac);
/* nothing matched, go on */
diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
index 901d121..1f1dcf8 100644
--- a/source4/lib/ldb/pyldb.c
+++ b/source4/lib/ldb/pyldb.c
@@ -783,15 +783,23 @@ static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
struct ldb_dn *dn;
int ret;
struct ldb_context *ldb;
+ TALLOC_CTX *mem_ctx;
if (!PyArg_ParseTuple(args, "O", &py_dn))
return NULL;
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
ldb = PyLdb_AsLdbContext(self);
-
- if (!PyObject_AsDn(NULL, py_dn, ldb, &dn))
+ if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
+ talloc_free(mem_ctx);
return NULL;
+ }
ret = ldb_delete(ldb, dn);
+ talloc_free(mem_ctx);
PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
Py_RETURN_NONE;
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
index eb686df..a77a777 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -1895,32 +1895,46 @@ class SchemaTests(unittest.TestCase):
def test_schemaUpdateNow(self):
"""Testing schemaUpdateNow"""
- class_name = "test-class" + time.strftime("%s", time.gmtime())
+ attr_name = "test-Attr" + time.strftime("%s", time.gmtime())
+ attr_ldap_display_name = attr_name.replace("-", "")
+
+ ldif = """
+dn: CN=%s,%s""" % (attr_name, self.schema_dn) + """
+objectClass: top
+objectClass: attributeSchema
+adminDescription: """ + attr_name + """
+adminDisplayName: """ + attr_name + """
+cn: """ + attr_name + """
+attributeId: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9940
+attributeSyntax: 2.5.5.12
+omSyntax: 64
+instanceType: 4
+isSingleValued: TRUE
+systemOnly: FALSE
+"""
+ self.ldb.add_ldif(ldif)
+
+ class_name = "test-Class" + time.strftime("%s", time.gmtime())
class_ldap_display_name = class_name.replace("-", "")
- object_name = "obj" + time.strftime("%s", time.gmtime())
ldif = """
dn: CN=%s,%s""" % (class_name, self.schema_dn) + """
-lDAPDisplayName: """ + class_ldap_display_name + """
objectClass: top
objectClass: classSchema
adminDescription: """ + class_name + """
adminDisplayName: """ + class_name + """
cn: """ + class_name + """
-objectCategory: CN=Class-Schema,""" + self.schema_dn + """
-defaultObjectCategory: CN=%s,%s""" % (class_name, self.schema_dn) + """
-distinguishedName: CN=%s,%s""" % (class_name, self.schema_dn) + """
-governsID: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
+governsId: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
instanceType: 4
-name: """ + class_name + """
objectClassCategory: 1
subClassOf: organizationalPerson
systemFlags: 16
rDNAttID: cn
-systemMustContain: cn
+systemMustContain: cn, """ + attr_ldap_display_name + """
systemOnly: FALSE
"""
self.ldb.add_ldif(ldif)
+
ldif = """
dn:
changetype: modify
@@ -1928,6 +1942,9 @@ add: schemaUpdateNow
schemaUpdateNow: 1
"""
self.ldb.modify_ldif(ldif)
+
--
Samba Shared Repository
More information about the samba-cvs
mailing list