summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-03-23 11:47:38 +1100
committerAndrew Tridgell <tridge@samba.org>2009-03-23 11:47:38 +1100
commit7f113904eba5361d963075bcea7e36fd98ca34aa (patch)
tree2d5f22f3418a3439c306b3aaf570f52ff1d0823e /source4
parent9709ddcd3db3a96ff4d86aa1a5daf7f9261f13d3 (diff)
parent979a1b06d01817a01967d9137e4f70f222fa8eab (diff)
downloadsamba-7f113904eba5361d963075bcea7e36fd98ca34aa.tar.gz
samba-7f113904eba5361d963075bcea7e36fd98ca34aa.tar.bz2
samba-7f113904eba5361d963075bcea7e36fd98ca34aa.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source4')
-rw-r--r--source4/lib/ldb/modules/paged_searches.c115
-rw-r--r--source4/lib/ldb/pyldb.c80
-rwxr-xr-xsource4/lib/ldb/tests/python/api.py13
-rw-r--r--source4/main.mk1
-rwxr-xr-xsource4/script/uninstallman.sh2
-rw-r--r--source4/scripting/bin/fullschema179
-rwxr-xr-xsource4/scripting/bin/minschema200
-rw-r--r--source4/scripting/python/samba/__init__.py6
-rw-r--r--source4/scripting/python/samba/provision.py2
-rw-r--r--source4/selftest/config.mk12
-rw-r--r--source4/smbd/server.c2
-rw-r--r--source4/torture/ldap/cldap.c4
12 files changed, 405 insertions, 211 deletions
diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c
index 01e77cb22c..c5430eb9bf 100644
--- a/source4/lib/ldb/modules/paged_searches.c
+++ b/source4/lib/ldb/modules/paged_searches.c
@@ -2,6 +2,7 @@
ldb database library
Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
@@ -52,23 +53,40 @@ struct ps_context {
char **saved_referrals;
int num_referrals;
+
+ struct ldb_request *down_req;
};
-static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares)
+static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares)
{
- struct ps_context *ac;
- struct ldb_paged_control *rep_control, *req_control;
+ struct ldb_context *ldb;
+ struct ldb_control *rep_control, *req_control;
+ struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL;
+ ldb = ldb_module_get_ctx(ac->module);
- ac = talloc_get_type(req->context, struct ps_context);
+ rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID);
+ if (rep_control) {
+ paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control);
+ }
- /* look up our paged control */
- if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) {
- /* something wrong here */
- return LDB_ERR_OPERATIONS_ERROR;
+ req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID);
+ paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control);
+
+ if (!rep_control || !paged_rep_control) {
+ if (paged_req_control->cookie) {
+ /* something wrong here - why give us a control back befre, but not one now? */
+ ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!");
+ return LDB_ERR_OPERATIONS_ERROR;
+ } else {
+ /* No cookie recived yet, valid to just return the full data set */
+
+ /* we are done */
+ ac->pending = false;
+ return LDB_SUCCESS;
+ }
}
- rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control);
- if (rep_control->cookie_len == 0) {
+ if (paged_rep_control->cookie_len == 0) {
/* we are done */
ac->pending = false;
return LDB_SUCCESS;
@@ -79,21 +97,14 @@ static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares
/* if there's a reply control we must find a request
* control matching it */
- if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, req->controls[0]->oid) != 0) {
- /* something wrong here */
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- req_control = talloc_get_type(req->controls[0]->data, struct ldb_paged_control);
-
- if (req_control->cookie) {
- talloc_free(req_control->cookie);
+ if (paged_req_control->cookie) {
+ talloc_free(paged_req_control->cookie);
}
- req_control->cookie = talloc_memdup(req_control,
- rep_control->cookie,
- rep_control->cookie_len);
- req_control->cookie_len = rep_control->cookie_len;
+ paged_req_control->cookie = talloc_memdup(req_control,
+ paged_rep_control->cookie,
+ paged_rep_control->cookie_len);
+ paged_req_control->cookie_len = paged_rep_control->cookie_len;
ac->pending = true;
return LDB_SUCCESS;
@@ -141,8 +152,6 @@ static int send_referrals(struct ps_context *ac)
return LDB_SUCCESS;
}
-static int ps_next_request(struct ps_context *ac);
-
static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct ps_context *ac;
@@ -176,14 +185,15 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
case LDB_REPLY_DONE:
- ret = check_ps_continuation(req, ares);
+ ret = check_ps_continuation(ac, req, ares);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
if (ac->pending) {
- ret = ps_next_request(ac);
+ ret = ldb_next_request(ac->module, ac->down_req);
+
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req,
NULL, NULL, ret);
@@ -214,14 +224,16 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
struct ldb_context *ldb;
struct private_data *private_data;
struct ps_context *ac;
+ struct ldb_paged_control *control;
+ int ret;
private_data = talloc_get_type(ldb_module_get_private(module), struct private_data);
ldb = ldb_module_get_ctx(module);
- /* check if paging is supported and if there is a any control */
- if (!private_data || !private_data->paged_supported || req->controls) {
+ /* check if paging is supported */
+ if (!private_data || !private_data->paged_supported) {
/* do not touch this request paged controls not
- * supported or explicit controls have been set or we
+ * supported or we
* are just not setup yet */
return ldb_next_request(module, req);
}
@@ -238,30 +250,9 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
ac->saved_referrals = NULL;
ac->num_referrals = 0;
- return ps_next_request(ac);
-}
-
-static int ps_next_request(struct ps_context *ac) {
-
- struct ldb_context *ldb;
- struct ldb_paged_control *control;
- struct ldb_control **controls;
- struct ldb_request *new_req;
- int ret;
-
ldb = ldb_module_get_ctx(ac->module);
- controls = talloc_array(ac, struct ldb_control *, 2);
- if (!controls) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- controls[0] = talloc(controls, struct ldb_control);
- if (!controls[0]) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- control = talloc(controls[0], struct ldb_paged_control);
+ control = talloc(ac, struct ldb_paged_control);
if (!control) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -270,26 +261,28 @@ static int ps_next_request(struct ps_context *ac) {
control->cookie = NULL;
control->cookie_len = 0;
- controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
- controls[0]->critical = 1;
- controls[0]->data = control;
- controls[1] = NULL;
-
- ret = ldb_build_search_req_ex(&new_req, ldb, ac,
+ ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac,
ac->req->op.search.base,
ac->req->op.search.scope,
ac->req->op.search.tree,
ac->req->op.search.attrs,
- controls,
+ ac->req->controls,
ac,
ps_callback,
ac->req);
if (ret != LDB_SUCCESS) {
return ret;
}
- talloc_steal(new_req, controls);
- return ldb_next_request(ac->module, new_req);
+ ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID,
+ true, control);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ talloc_steal(ac->down_req, control);
+
+ return ldb_next_request(ac->module, ac->down_req);
}
static int check_supported_paged(struct ldb_request *req,
diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
index 81b960979f..bceda05e4f 100644
--- a/source4/lib/ldb/pyldb.c
+++ b/source4/lib/ldb/pyldb.c
@@ -5,7 +5,7 @@
Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
Copyright (C) 2006 Simo Sorce <idra@samba.org>
- Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
+ Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
@@ -65,18 +65,7 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
PyObject *ret;
new_val = *val;
-
- if (ldb_ctx != NULL) {
- a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
-
- if (a != NULL) {
- if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
- talloc_free(mem_ctx);
- return NULL;
- }
- }
- }
-
+
ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
talloc_free(mem_ctx);
@@ -84,6 +73,14 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
return ret;
}
+/**
+ * Obtain a ldb DN from a Python object.
+ *
+ * @param mem_ctx Memory context
+ * @param object Python object
+ * @param ldb_ctx LDB context
+ * @return Whether or not the conversion succeeded
+ */
bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
struct ldb_context *ldb_ctx, struct ldb_dn **dn)
{
@@ -104,6 +101,12 @@ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
return false;
}
+/**
+ * Create a Python object from a ldb_result.
+ *
+ * @param result LDB result to convert
+ * @return Python object with converted result (a list object)
+ */
static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
{
PyObject *ret;
@@ -119,7 +122,16 @@ static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
return ret;
}
-static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, PyObject *obj)
+/**
+ * Create a LDB Result from a Python object.
+ * If conversion fails, NULL will be returned and a Python exception set.
+ *
+ * @param mem_ctx Memory context in which to allocate the LDB Result
+ * @param obj Python object to convert
+ * @return a ldb_result, or NULL if the conversion failed
+ */
+static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
+ PyObject *obj)
{
struct ldb_result *res;
int i;
@@ -451,7 +463,6 @@ static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
return PyLdbDn_FromDn(dn);
}
-
static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
{
struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
@@ -460,7 +471,6 @@ static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
return PyLdbDn_FromDn(dn);
}
-
static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
{
struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
@@ -469,19 +479,20 @@ static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
return PyLdbDn_FromDn(dn);
}
-static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list)
+static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
+ const char *paramname)
{
const char **ret;
int i;
if (!PyList_Check(list)) {
- PyErr_SetString(PyExc_TypeError, "options is not a list");
+ PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
return NULL;
}
ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
for (i = 0; i < PyList_Size(list); i++) {
PyObject *item = PyList_GetItem(list, i);
if (!PyString_Check(item)) {
- PyErr_SetString(PyExc_TypeError, "options should be strings");
+ PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
return NULL;
}
ret[i] = PyString_AsString(item);
@@ -510,7 +521,7 @@ static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
if (py_options == Py_None) {
options = NULL;
} else {
- options = PyList_AsStringList(ldb, py_options);
+ options = PyList_AsStringList(ldb, py_options, "options");
if (options == NULL)
return -1;
}
@@ -563,7 +574,7 @@ static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwa
if (py_options == Py_None) {
options = NULL;
} else {
- options = PyList_AsStringList(NULL, py_options);
+ options = PyList_AsStringList(NULL, py_options, "options");
if (options == NULL)
return NULL;
}
@@ -651,8 +662,6 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
Py_RETURN_NONE;
}
-
-
static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
{
PyObject *py_dn;
@@ -813,7 +822,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
if (py_attrs == Py_None) {
attrs = NULL;
} else {
- attrs = PyList_AsStringList(ldb_ctx, py_attrs);
+ attrs = PyList_AsStringList(ldb_ctx, py_attrs, "attrs");
if (attrs == NULL)
return NULL;
}
@@ -828,7 +837,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
if (py_controls == Py_None) {
parsed_controls = NULL;
} else {
- const char **controls = PyList_AsStringList(ldb_ctx, py_controls);
+ const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
talloc_free(controls);
}
@@ -1129,7 +1138,7 @@ static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, P
mod = self->mod;
ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base),
- scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs),
+ scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs, "attrs"),
NULL /* controls */, NULL, NULL, NULL);
PyErr_LDB_ERROR_IS_ERR_RAISE(ret, mod->ldb);
@@ -1256,6 +1265,21 @@ PyTypeObject PyLdbModule = {
.tp_flags = Py_TPFLAGS_DEFAULT,
};
+
+/**
+ * Create a ldb_message_element from a Python object.
+ *
+ * This will accept any sequence objects that contains strings, or
+ * a string object.
+ *
+ * A reference to set_obj will be borrowed.
+ *
+ * @param mem_ctx Memory context
+ * @param set_obj Python object to convert
+ * @param flags ldb_message_element flags to set
+ * @param attr_name Name of the attribute
+ * @return New ldb_message_element, allocated as child of mem_ctx
+ */
struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
PyObject *set_obj, int flags,
const char *attr_name)
@@ -1273,9 +1297,7 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
me->num_values = 1;
me->values = talloc_array(me, struct ldb_val, me->num_values);
me->values[0].length = PyString_Size(set_obj);
- me->values[0].data = (uint8_t *)talloc_strndup(me->values,
- PyString_AsString(set_obj),
- me->values[0].length);
+ me->values[0].data = (uint8_t *)PyString_AsString(set_obj);
} else if (PySequence_Check(set_obj)) {
int i;
me->num_values = PySequence_Size(set_obj);
diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py
index c372b8fa71..07500e2372 100755
--- a/source4/lib/ldb/tests/python/api.py
+++ b/source4/lib/ldb/tests/python/api.py
@@ -258,6 +258,19 @@ class SimpleLdb(unittest.TestCase):
l = ldb.Ldb(filename())
l.set_debug(my_report_fn)
+ def test_zero_byte_string(self):
+ """Testing we do not get trapped in the \0 byte in a property string."""
+ l = ldb.Ldb(filename())
+ l.add({
+ "dn" : "dc=somedn",
+ "objectclass" : "user",
+ "cN" : "LDAPtestUSER",
+ "givenname" : "ldap",
+ "displayname" : "foo\0bar",
+ })
+ res = l.search(expression="(dn=dc=somedn)")
+ self.assertEquals("foo\0bar", res[0]["displayname"][0])
+
class DnTests(unittest.TestCase):
def setUp(self):
diff --git a/source4/main.mk b/source4/main.mk
index a143604f33..d7db0580e9 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -46,6 +46,7 @@ mkinclude torture/config.mk
mkinclude librpc/config.mk
mkinclude client/config.mk
mkinclude libcli/config.mk
+mkinclude ../libcli/cldap/config.mk
mkinclude scripting/python/config.mk
mkinclude kdc/config.mk
mkinclude ../lib/smbconf/config.mk
diff --git a/source4/script/uninstallman.sh b/source4/script/uninstallman.sh
index 9b087c68bb..edc1c47e4d 100755
--- a/source4/script/uninstallman.sh
+++ b/source4/script/uninstallman.sh
@@ -8,7 +8,7 @@ MANPAGES=$*
for I in $MANPAGES
do
- SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"
+ SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"`
FNAME=$MANDIR/man$SECTION/$I
if test -f $FNAME; then
echo Deleting $FNAME
diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema
new file mode 100644
index 0000000000..41c45f30c8
--- /dev/null
+++ b/source4/scripting/bin/fullschema
@@ -0,0 +1,179 @@
+#!/usr/bin/python
+#
+# work out the minimal schema for a set of objectclasses
+#
+
+import base64
+import optparse
+import os
+import sys
+
+# Find right directory when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba
+from samba import getopt as options, Ldb
+from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError
+import sys
+
+parser = optparse.OptionParser("fullschema <URL>")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--dump-classes", action="store_true")
+parser.add_option("--dump-attributes", action="store_true")
+
+opts, args = parser.parse_args()
+opts.dump_all = True
+
+if opts.dump_classes:
+ opts.dump_all = False
+if opts.dump_attributes:
+ opts.dump_all = False
+if opts.dump_all:
+ opts.dump_classes = True
+ opts.dump_attributes = True
+
+if len(args) != 1:
+ parser.print_usage()
+ sys.exit(1)
+
+url = args[0]
+
+lp_ctx = sambaopts.get_loadparm()
+
+creds = credopts.get_credentials(lp_ctx)
+ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"])
+
+# the attributes we need for objectclasses
+class_attrs = ["objectClass",
+ "cn",
+ "subClassOf",
+ "governsID",
+ "possSuperiors",
+ "possibleInferiors",
+ "mayContain",
+ "mustContain",
+ "auxiliaryClass",
+ "rDNAttID",
+ "adminDisplayName",
+ "adminDescription",
+ "objectClassCategory",
+ "lDAPDisplayName",
+ "schemaIDGUID",
+ "systemOnly",
+ "systemPossSuperiors",
+ "systemMayContain",
+ "systemMustContain",
+ "systemAuxiliaryClass",
+ "defaultSecurityDescriptor",
+ "systemFlags",
+ "defaultHidingValue",
+ "defaultObjectCategory",
+
+ # this attributes are not used by w2k3
+ "schemaFlagsEx",
+ "msDs-IntId",
+ "msDs-Schema-Extensions",
+ "classDisplayName",
+ "isDefunct"]
+
+attrib_attrs = ["objectClass",
+ "cn",
+ "attributeID",
+ "attributeSyntax",
+ "isSingleValued",
+ "rangeLower",
+ "rangeUpper",
+ "mAPIID",
+ "linkID",
+ "adminDisplayName",
+ "oMObjectClass",
+ "adminDescription",
+ "oMSyntax",
+ "searchFlags",
+ "extendedCharsAllowed",
+ "lDAPDisplayName",
+ "schemaIDGUID",
+ "attributeSecurityGUID",
+ "systemOnly",
+ "systemFlags",
+ "isMemberOfPartialAttributeSet",
+
+ # this attributes are not used by w2k3
+ "schemaFlagsEx",
+ "msDs-IntId",
+ "msDs-Schema-Extensions",
+ "classDisplayName",
+ "isEphemeral",
+ "isDefunct"]
+
+class Objectclass(dict):
+
+ def __init__(self, ldb, name):
+ """create an objectclass object"""
+ self.name = name
+
+
+class Attribute(dict):
+
+ def __init__(self, ldb, name):
+ """create an attribute object"""
+ self.name = name
+ self["cn"] = get_object_cn(ldb, name)
+
+
+
+def fix_dn(dn):
+ """fix a string DN to use ${SCHEMADN}"""
+ return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}")
+
+
+def write_ldif_one(o, attrs):
+ """dump an object as ldif"""
+ print "dn: CN=%s,${SCHEMADN}" % o["cn"]
+ for a in attrs:
+ if not o.has_key(a):
+ continue
+ # special case for oMObjectClass, which is a binary object
+ v = o[a]
+ for j in v:
+ value = fix_dn(j)
+ if a != "cn":
+ if a == "oMObjectClass":
+ print "%s:: %s" % (a, base64.b64encode(value))
+ elif a.endswith("GUID"):
+ print "%s: %s" % (a, ldb.schema_format_value(a, value))
+ else:
+ print "%s: %s" % (a, value)
+ print ""
+
+
+# get the rootDSE
+res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
+rootDse = res[0]
+
+if opts.dump_attributes:
+ res = ldb.search(expression="objectClass=attributeSchema",
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs,
+ controls=["server_sort:1:0:cn"])
+
+ for msg in res:
+ o = Objectclass(ldb, msg["ldapDisplayName"])
+ for a in msg:
+ o[a] = msg[a]
+ write_ldif_one(o, attrib_attrs)
+
+if opts.dump_classes:
+ res = ldb.search(expression="objectClass=classSchema",
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs,
+ controls=["server_sort:1:0:cn"])
+
+ for msg in res:
+ o = Objectclass(ldb, msg["ldapDisplayName"])
+ for a in msg:
+ o[a] = msg[a]
+ write_ldif_one(o, class_attrs)
+
diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema
index e7d7ed4979..c860495e96 100755
--- a/source4/scripting/bin/minschema
+++ b/source4/scripting/bin/minschema
@@ -3,9 +3,10 @@
# work out the minimal schema for a set of objectclasses
#
+import base64
import optparse
-
-import os, sys
+import os
+import sys
# Find right directory when running from source tree
sys.path.insert(0, "bin/python")
@@ -54,10 +55,10 @@ if len(args) != 2:
lp_ctx = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp_ctx)
-ldb = Ldb(url, credentials=creds)
+ldb = Ldb(url, credentials=creds, lp=lp_ctx)
-objectclasses = []
-attributes = []
+objectclasses = {}
+attributes = {}
objectclasses_expanded = set()
@@ -71,7 +72,6 @@ class_attrs = ["objectClass",
"mustContain",
"auxiliaryClass",
"rDNAttID",
- "showInAdvancedViewOnly",
"adminDisplayName",
"adminDescription",
"objectClassCategory",
@@ -103,7 +103,6 @@ attrib_attrs = ["objectClass",
"rangeUpper",
"mAPIID",
"linkID",
- "showInAdvancedViewOnly",
"adminDisplayName",
"oMObjectClass",
"adminDescription",
@@ -136,24 +135,25 @@ attrib_attrs = ["objectClass",
def get_object_cn(ldb, name):
attrs = ["cn"]
-
- res = ldb.search("(ldapDisplayName=%s)" % name, rootDse["schemaNamingContext"], SCOPE_SUBTREE, attrs)
+ res = ldb.search(expression="(ldapDisplayName=%s)" % name, base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs)
assert len(res) == 1
-
return res[0]["cn"]
-class Objectclass:
+
+class Objectclass(dict):
+
def __init__(self, ldb, name):
"""create an objectclass object"""
self.name = name
- self.cn = get_object_cn(ldb, name)
+ self["cn"] = get_object_cn(ldb, name)
+
+class Attribute(dict):
-class Attribute:
def __init__(self, ldb, name):
"""create an attribute object"""
self.name = name
- self.cn = get_object_cn(ldb, name)
+ self["cn"] = get_object_cn(ldb, name)
syntaxmap = dict()
@@ -180,36 +180,38 @@ syntaxmap['2.5.5.17'] = '1.3.6.1.4.1.1466.115.121.1.40'
def map_attribute_syntax(s):
"""map some attribute syntaxes from some apparently MS specific
syntaxes to the standard syntaxes"""
- if syntaxmap.has_key(s):
+ if s in list(syntaxmap):
return syntaxmap[s]
return s
def fix_dn(dn):
"""fix a string DN to use ${SCHEMADN}"""
- return dn.replace(rootDse["schemaNamingContext"], "${SCHEMADN}")
+ return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}")
def write_ldif_one(o, attrs):
"""dump an object as ldif"""
- print "dn: CN=%s,${SCHEMADN}\n" % o["cn"]
+ print "dn: CN=%s,${SCHEMADN}" % o["cn"]
for a in attrs:
if not o.has_key(a):
continue
# special case for oMObjectClass, which is a binary object
- if a == "oMObjectClass":
- print "%s:: %s\n" % (a, o[a])
- continue
v = o[a]
- if isinstance(v, str):
- v = [v]
for j in v:
- print "%s: %s\n" % (a, fix_dn(j))
- print "\n"
+ value = fix_dn(j)
+ if a == "oMObjectClass":
+ print "%s:: %s" % (a, base64.b64encode(value))
+ elif a.endswith("GUID"):
+ print "%s: %s" % (a, ldb.schema_format_value(a, value))
+ else:
+ print "%s: %s" % (a, value)
+ print ""
+
def write_ldif(o, attrs):
"""dump an array of objects as ldif"""
- for i in o:
+ for n, i in o.items():
write_ldif_one(i, attrs)
@@ -225,7 +227,7 @@ def find_objectclass_properties(ldb, o):
"""the properties of an objectclass"""
res = ldb.search(
expression="(ldapDisplayName=%s)" % o.name,
- base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, attrs=class_attrs)
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=class_attrs)
assert(len(res) == 1)
msg = res[0]
for a in msg:
@@ -235,15 +237,11 @@ def find_attribute_properties(ldb, o):
"""find the properties of an attribute"""
res = ldb.search(
expression="(ldapDisplayName=%s)" % o.name,
- base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE,
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,
attrs=attrib_attrs)
assert(len(res) == 1)
msg = res[0]
for a in msg:
- # special case for oMObjectClass, which is a binary object
- if a == "oMObjectClass":
- o[a] = ldb.encode(msg[a])
- continue
o[a] = msg[a]
@@ -254,15 +252,15 @@ def find_objectclass_auto(ldb, o):
return
testdn = create_testdn(o.exampleDN)
- print "testdn is '%s'\n" % testdn
+ print "testdn is '%s'" % testdn
ldif = "dn: " + testdn
ldif += "\nobjectClass: " + o.name
try:
ldb.add(ldif)
except LdbError, e:
- print "error adding %s: %s\n" % (o.name, e)
- print "%s\n" % ldif
+ print "error adding %s: %s" % (o.name, e)
+ print "%s" % ldif
return
res = ldb.search(base=testdn, scope=ldb.SCOPE_BASE)
@@ -280,20 +278,20 @@ def expand_objectclass(ldb, o):
"subClassOf"]
res = ldb.search(
expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name,
- base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE,
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,
attrs=attrs)
- print "Expanding class %s\n" % o.name
+ print >>sys.stderr, "Expanding class %s" % o.name
assert(len(res) == 1)
msg = res[0]
- for a in attrs:
- if not msg.has_key(aname):
+ for aname in attrs:
+ if not aname in msg:
continue
list = msg[aname]
if isinstance(list, str):
list = [msg[aname]]
for name in list:
if not objectclasses.has_key(name):
- print "Found new objectclass '%s'\n" % name
+ print >>sys.stderr, "Found new objectclass '%s'" % name
objectclasses[name] = Objectclass(ldb, name)
@@ -320,13 +318,13 @@ def walk_dn(ldb, dn):
try:
res = ldb.search("objectClass=*", dn, SCOPE_BASE, attrs)
except LdbError, e:
- print "Unable to fetch allowedAttributes for '%s' - %r\n" % (dn, e)
+ print >>sys.stderr, "Unable to fetch allowedAttributes for '%s' - %r" % (dn, e)
return
allattrs = res[0]["allowedAttributes"]
try:
res = ldb.search("objectClass=*", dn, SCOPE_BASE, allattrs)
except LdbError, e:
- print "Unable to fetch all attributes for '%s' - %s\n" % (dn, e)
+ print >>sys.stderr, "Unable to fetch all attributes for '%s' - %s" % (dn, e)
return
msg = res[0]
for a in msg:
@@ -339,7 +337,7 @@ def walk_naming_context(ldb, namingContext):
res = ldb.search("objectClass=*", namingContext, SCOPE_DEFAULT,
["objectClass"])
except LdbError, e:
- print "Unable to fetch objectClasses for '%s' - %s\n" % (namingContext, e)
+ print >>sys.stderr, "Unable to fetch objectClasses for '%s' - %s" % (namingContext, e)
return
for msg in res:
msg = res.msgs[r]["objectClass"]
@@ -356,12 +354,9 @@ def trim_objectclass_attributes(ldb, objectclass):
if objectclass.has_key("possibleInferiors"):
possinf = objectclass["possibleInferiors"]
newpossinf = []
- if isinstance(possinf, str):
- possinf = [possinf]
for x in possinf:
if objectclasses.has_key(x):
- newpossinf[n] = x
- n+=1
+ newpossinf.append(x)
objectclass["possibleInferiors"] = newpossinf
# trim systemMayContain,
@@ -369,8 +364,6 @@ def trim_objectclass_attributes(ldb, objectclass):
if objectclass.has_key("systemMayContain"):
sysmay = objectclass["systemMayContain"]
newsysmay = []
- if isinstance(sysmay, str):
- sysmay = [sysmay]
for x in sysmay:
if not x in newsysmay:
newsysmay.append(x)
@@ -378,7 +371,7 @@ def trim_objectclass_attributes(ldb, objectclass):
# trim mayContain,
# remove duplicates
- if not objectclass.has_key("mayContain"):
+ if objectclass.has_key("mayContain"):
may = objectclass["mayContain"]
newmay = []
if isinstance(may, str):
@@ -388,71 +381,65 @@ def trim_objectclass_attributes(ldb, objectclass):
newmay.append(x)
objectclass["mayContain"] = newmay
+
def build_objectclass(ldb, name):
"""load the basic attributes of an objectClass"""
attrs = ["name"]
- try:
- res = ldb.search(
- expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name,
- base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE,
- attrs=attrs)
- except LdbError, e:
- print "unknown class '%s'\n" % name
- return None
+ res = ldb.search(
+ expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name,
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,
+ attrs=attrs)
if len(res) == 0:
- print "unknown class '%s'\n" % name
+ print >>sys.stderr, "unknown class '%s'" % name
return None
return Objectclass(ldb, name)
+
def attribute_list(objectclass, attr1, attr2):
"""form a coalesced attribute list"""
- a1 = objectclass[attr1]
- a2 = objectclass[attr2]
- if isinstance(a1, str):
- a1 = [a1]
- if isinstance(a2, str):
- a2 = [a2]
+ a1 = list(objectclass.get(attr1, []))
+ a2 = list(objectclass.get(attr2, []))
return a1 + a2
def aggregate_list(name, list):
"""write out a list in aggregate form"""
- if list is None:
- return
- print "%s ( %s )" % (name, "$ ".join(list))
+ if list == []:
+ return ""
+ return " %s ( %s )" % (name, " $ ".join(list))
def write_aggregate_objectclass(objectclass):
"""write the aggregate record for an objectclass"""
- print "objectClasses: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name)
+ line = "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name)
if not objectclass.has_key('subClassOf'):
- print "SUP %s " % objectclass['subClassOf']
- if objectclass.objectClassCategory == 1:
- print "STRUCTURAL "
- elif objectclass.objectClassCategory == 2:
- print "ABSTRACT "
- elif objectclass.objectClassCategory == 3:
- print "AUXILIARY "
+ line += "SUP %s" % objectclass['subClassOf']
+ if objectclass["objectClassCategory"] == 1:
+ line += "STRUCTURAL"
+ elif objectclass["objectClassCategory"] == 2:
+ line += "ABSTRACT"
+ elif objectclass["objectClassCategory"] == 3:
+ line += "AUXILIARY"
list = attribute_list(objectclass, "systemMustContain", "mustContain")
- aggregate_list("MUST", list)
+ line += aggregate_list("MUST", list)
list = attribute_list(objectclass, "systemMayContain", "mayContain")
- aggregate_list("MAY", list)
+ line += aggregate_list("MAY", list)
- print ")\n"
+ print line + " )"
def write_aggregate_ditcontentrule(objectclass):
"""write the aggregate record for an ditcontentrule"""
list = attribute_list(objectclass, "auxiliaryClass", "systemAuxiliaryClass")
- if list is None:
+ if list == []:
return
- print "dITContentRules: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name)
+ line = "dITContentRules: ( %s NAME '%s'" % (objectclass["governsID"], objectclass.name)
- aggregate_list("AUX", list)
+ line += aggregate_list("AUX", list)
- may_list = None
- must_list = None
+ may_list = []
+ must_list = []
for c in list:
list2 = attribute_list(objectclasses[c],
@@ -462,44 +449,43 @@ def write_aggregate_ditcontentrule(objectclass):
"mustContain", "systemMustContain")
must_list = must_list + list2
- aggregate_list("MUST", must_list)
- aggregate_list("MAY", may_list)
+ line += aggregate_list("MUST", must_list)
+ line += aggregate_list("MAY", may_list)
- print ")\n"
+ print line + " )"
def write_aggregate_attribute(attrib):
"""write the aggregate record for an attribute"""
- print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
- attrib.attributeID, attrib.name,
- map_attribute_syntax(attrib.attributeSyntax))
- if attrib['isSingleValued'] == "TRUE":
- print "SINGLE-VALUE "
- if attrib['systemOnly'] == "TRUE":
- print "NO-USER-MODIFICATION "
+ line = "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
+ attrib["attributeID"], attrib.name,
+ map_attribute_syntax(attrib["attributeSyntax"]))
+ if attrib.get('isSingleValued') == "TRUE":
+ line += "SINGLE-VALUE "
+ if attrib.get('systemOnly') == "TRUE":
+ line += "NO-USER-MODIFICATION "
- print ")\n"
+ print line + ")"
def write_aggregate():
"""write the aggregate record"""
- print "dn: CN=Aggregate,${SCHEMADN}\n"
+ print "dn: CN=Aggregate,${SCHEMADN}"
print """objectClass: top
objectClass: subSchema
-objectCategory: CN=SubSchema,${SCHEMADN}
-"""
+objectCategory: CN=SubSchema,${SCHEMADN}"""
if not opts.dump_subschema_auto:
return
- for objectclass in objectclasses:
+ for objectclass in objectclasses.values():
write_aggregate_objectclass(objectclass)
- for attr in attributes:
+ for attr in attributes.values():
write_aggregate_attribute(attr)
- for objectclass in objectclasses:
+ for objectclass in objectclasses.values():
write_aggregate_ditcontentrule(objectclass)
def load_list(file):
"""load a list from a file"""
- return open(file, 'r').readlines()
+ return [l.strip("\n") for l in open(file, 'r').readlines()]
# get the rootDSE
res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
@@ -523,32 +509,32 @@ expanded = 0
# than necessary to recursively expand all classes
#
for inf in range(500):
- for n in objectclasses:
+ for n, o in objectclasses.items():
if not n in objectclasses_expanded:
- expand_objectclass(ldb, objectclasses[i])
+ expand_objectclass(ldb, o)
objectclasses_expanded.add(n)
#
# find objectclass properties
#
-for objectclass in objectclasses:
+for name, objectclass in objectclasses.items():
find_objectclass_properties(ldb, objectclass)
#
# form the full list of attributes
#
-for objectclass in objectclasses:
+for name, objectclass in objectclasses.items():
add_objectclass_attributes(ldb, objectclass)
# and attribute properties
-for attr in attributes:
+for name, attr in attributes.items():
find_attribute_properties(ldb, attr)
#
# trim the 'may' attribute lists to those really needed
#
-for objectclass in objectclasses:
+for name, objectclass in objectclasses.items():
trim_objectclass_attributes(ldb, objectclass)
#
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index a49e6e1ead..c5827b96e0 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py
@@ -54,7 +54,7 @@ class Ldb(ldb.Ldb):
functions see samdb.py.
"""
def __init__(self, url=None, session_info=None, credentials=None,
- modules_dir=None, lp=None):
+ modules_dir=None, lp=None, options=None):
"""Open a Samba Ldb file.
:param url: Optional LDB URL to open
@@ -67,7 +67,7 @@ class Ldb(ldb.Ldb):
modules-dir is used by default and that credentials and session_info
can be passed through (required by some modules).
"""
- super(Ldb, self).__init__()
+ super(Ldb, self).__init__(options=options)
if modules_dir is not None:
self.set_modules_dir(modules_dir)
@@ -90,7 +90,7 @@ class Ldb(ldb.Ldb):
#self.set_debug(msg)
if url is not None:
- self.connect(url)
+ self.connect(url, options=options)
def set_credentials(self, credentials):
glue.ldb_set_credentials(self, credentials)
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index d96857661e..896f237bd7 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -1056,7 +1056,7 @@ def provision(setup_dir, message, session_info,
serverrole=serverrole, ldap_backend=ldap_backend,
ldap_backend_type=ldap_backend_type)
- if lp.get("server role") == "domain controller":
+ if serverrole == "domain controller":
if paths.netlogon is None:
message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.")
message("Please either remove %s or see the template at %s" %
diff --git a/source4/selftest/config.mk b/source4/selftest/config.mk
index 324532c22a..1838a0bb38 100644
--- a/source4/selftest/config.mk
+++ b/source4/selftest/config.mk
@@ -59,31 +59,31 @@ test-%::
valgrindtest:: valgrindtest-all
valgrindtest-quick:: all
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS)
valgrindtest-all:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS)
valgrindtest-env:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv
gdbtest:: gdbtest-all
gdbtest-quick:: all
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS)
gdbtest-all:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS)
gdbtest-env:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index d576782ab1..635e84fafe 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -365,5 +365,5 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
int main(int argc, const char *argv[])
{
- return binary_smbd_main("smbd", argc, argv);
+ return binary_smbd_main("samba", argc, argv);
}
diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c
index 98669288a8..814c9ac86d 100644
--- a/source4/torture/ldap/cldap.c
+++ b/source4/torture/ldap/cldap.c
@@ -59,8 +59,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
CHECK_STATUS(status, NT_STATUS_OK);
ZERO_STRUCT(search);
- search.in.dest_address = NULL;//dest;
- search.in.dest_port = 0;//lp_cldap_port(tctx->lp_ctx);
+ search.in.dest_address = NULL;
+ search.in.dest_port = 0;
search.in.acct_control = -1;
search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
search.in.map_response = true;