summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/dsdb/repl/replicated_objects.c5
-rw-r--r--source4/dsdb/schema/schema_init.c4
-rw-r--r--source4/dsdb/schema/schema_set.c4
-rwxr-xr-xsource4/heimdal_build/asn1_deps.pl2
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c11
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_pack.c4
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c18
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h2
-rwxr-xr-xsource4/scripting/bin/rebuildextendeddn141
-rw-r--r--source4/scripting/python/samba/provision.py9
-rw-r--r--source4/torture/basic/delaywrite.c131
11 files changed, 321 insertions, 10 deletions
diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index fb6d4c18ec..2f4efc0fee 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -297,6 +297,11 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb,
return WERR_FOOBAR;
}
+ DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n",
+ out->num_objects, out->linked_attributes_count,
+ ldb_dn_get_linearized(out->partition_dn)));
+
+
if (_out) {
*_out = out;
} else {
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 3b701ad31c..9f7d967158 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -967,7 +967,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
return LDB_ERR_CONSTRAINT_VIOLATION;
}
- DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
+ DLIST_ADD(schema->attributes, sa);
}
for (i=0; i < objectclass_res->count; i++) {
@@ -988,7 +988,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
return LDB_ERR_CONSTRAINT_VIOLATION;
}
- DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
+ DLIST_ADD(schema->classes, sc);
}
schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner");
diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c
index 6745bde127..6f09f63596 100644
--- a/source4/dsdb/schema/schema_set.c
+++ b/source4/dsdb/schema/schema_set.c
@@ -555,7 +555,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
goto failed;
}
- DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
+ DLIST_ADD(schema->attributes, sa);
} else if (is_sc) {
struct dsdb_class *sc;
@@ -569,7 +569,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
goto failed;
}
- DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
+ DLIST_ADD(schema->classes, sc);
}
}
diff --git a/source4/heimdal_build/asn1_deps.pl b/source4/heimdal_build/asn1_deps.pl
index 504f66d535..b71abc72c5 100755
--- a/source4/heimdal_build/asn1_deps.pl
+++ b/source4/heimdal_build/asn1_deps.pl
@@ -31,7 +31,7 @@ my $output_file = "$dirname/" . $prefix . "_asn1_files";
print "basics:: $header\n";
print "$output_file: \$(heimdalsrcdir)/$file \$(ASN1C)\n";
print "\t\@echo \"Compiling ASN1 file \$(heimdalsrcdir)/$file\"\n";
-print "\t\@\$(heimdalbuildsrcdir)/asn1_compile_wrapper.sh \$(builddir) $dirname \$(ASN1C) \$(call abspath,\$(heimdalsrcdir)/$file) $prefix $options --one-code-file\n\n";
+print "\t\@\$(heimdalbuildsrcdir)/asn1_compile_wrapper.sh \$(builddir) $dirname \$(ASN1C) \$(call abspath,\$(heimdalsrcdir)/$file) $prefix $options --one-code-file && touch $output_file\n";
print "$headerx: $output_file\n";
print "$header: $headerx\n";
print "\t\@cp $headerx $header\n";
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index 85fbfa0458..b959471d16 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -1037,7 +1037,8 @@ static int ltdb_index_dn(struct ldb_module *module,
extracting just the given attributes
*/
static int ltdb_index_filter(const struct dn_list *dn_list,
- struct ltdb_context *ac)
+ struct ltdb_context *ac,
+ uint32_t *match_count)
{
struct ldb_context *ldb;
struct ldb_message *msg;
@@ -1093,6 +1094,8 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
ac->request_terminated = true;
return ret;
}
+
+ (*match_count)++;
}
return LDB_SUCCESS;
@@ -1103,7 +1106,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
returns -1 if an indexed search is not possible, in which
case the caller should call ltdb_search_full()
*/
-int ltdb_search_indexed(struct ltdb_context *ac)
+int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
{
struct ldb_context *ldb;
void *data = ldb_module_get_private(ac->module);
@@ -1166,7 +1169,7 @@ int ltdb_search_indexed(struct ltdb_context *ac)
if (ret == LDB_SUCCESS) {
/* we've got a candidate list - now filter by the full tree
and extract the needed attributes */
- ret = ltdb_index_filter(dn_list, ac);
+ ret = ltdb_index_filter(dn_list, ac, match_count);
}
talloc_free(dn_list);
@@ -1578,6 +1581,8 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
ret = ltdb_unpack_data(module, &data, msg);
if (ret != 0) {
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
+ ldb_dn_get_linearized(msg->dn));
talloc_free(msg);
return -1;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c
index 5640e7053c..e7aeb47e72 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_pack.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c
@@ -236,6 +236,10 @@ int ltdb_unpack_data(struct ldb_module *module,
errno = EIO;
goto failed;
}
+ if (len == 0) {
+ errno = EIO;
+ goto failed;
+ }
message->elements[i].flags = 0;
message->elements[i].name = talloc_strndup(message->elements, (char *)p, len);
if (message->elements[i].name == NULL) {
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index b307c5fb2f..a6647ccd50 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -265,6 +265,9 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes
ret = ltdb_unpack_data(module, &tdb_data, msg);
free(tdb_data.dptr);
if (ret == -1) {
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
+ ldb_dn_get_linearized(msg->dn));
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -535,7 +538,9 @@ int ltdb_search(struct ltdb_context *ctx)
ctx->attrs = req->op.search.attrs;
if (ret == LDB_SUCCESS) {
- ret = ltdb_search_indexed(ctx);
+ uint32_t match_count = 0;
+
+ ret = ltdb_search_indexed(ctx, &match_count);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
/* Not in the index, therefore OK! */
ret = LDB_SUCCESS;
@@ -553,6 +558,17 @@ int ltdb_search(struct ltdb_context *ctx)
printf("FULL SEARCH: %s\n", expression);
talloc_free(expression);
#endif
+ if (match_count != 0) {
+ /* the indexing code gave an error
+ * after having returned at least one
+ * entry. This means the indexes are
+ * corrupt or a database record is
+ * corrupt. We cannot continue with a
+ * full search or we may return
+ * duplicate entries
+ */
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
ret = ltdb_search_full(ctx);
if (ret != LDB_SUCCESS) {
ldb_set_errstring(ldb, "Indexed and full searches both failed!\n");
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index 75034dcf4b..c8c1dad5de 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -82,7 +82,7 @@ int ltdb_check_at_attributes_values(const struct ldb_val *value);
struct ldb_parse_tree;
-int ltdb_search_indexed(struct ltdb_context *ctx);
+int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *);
int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg);
int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg);
int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add);
diff --git a/source4/scripting/bin/rebuildextendeddn b/source4/scripting/bin/rebuildextendeddn
new file mode 100755
index 0000000000..618d179719
--- /dev/null
+++ b/source4/scripting/bin/rebuildextendeddn
@@ -0,0 +1,141 @@
+#!/usr/bin/python
+#
+# Unix SMB/CIFS implementation.
+# Extended attributes (re)building
+# Copyright (C) Matthieu Patou <mat@matws.net> 2009
+#
+# Based on provision a Samba4 server by
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import getopt
+import optparse
+import os
+import sys
+# Find right directory when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba
+from samba.credentials import DONT_USE_KERBEROS
+from samba.auth import system_session
+from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
+from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
+ timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE
+import ldb
+import samba.getopt as options
+from samba.samdb import SamDB
+from samba import param
+from samba.provision import ProvisionPaths, ProvisionNames,provision_paths_from_lp,get_dnsyntax_attributes,get_linked_attributes
+
+parser = optparse.OptionParser("provision [options]")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+parser.add_option_group(options.VersionOptions(parser))
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option("--targetdir", type="string", metavar="DIR",
+ help="Set target directory")
+
+opts = parser.parse_args()[0]
+
+def message(text):
+ """print a message if quiet is not set."""
+ if not opts.quiet:
+ print text
+
+if len(sys.argv) == 1:
+ opts.interactive = True
+
+lp = sambaopts.get_loadparm()
+smbconf = lp.configfile
+
+creds = credopts.get_credentials(lp)
+
+creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+session = system_session()
+
+
+def get_paths(targetdir=None,smbconf=None):
+ if targetdir is not None:
+ if (not os.path.exists(os.path.join(targetdir, "etc"))):
+ os.makedirs(os.path.join(targetdir, "etc"))
+ smbconf = os.path.join(targetdir, "etc", "smb.conf")
+ if smbconf is None:
+ smbconf = param.default_path()
+
+ if not os.path.exists(smbconf):
+ print >>sys.stderr, "Unable to find smb.conf .. "+smbconf
+ parser.print_usage()
+ sys.exit(1)
+
+ lp = param.LoadParm()
+ lp.load(smbconf)
+ paths = provision_paths_from_lp(lp,"foo")
+ return paths
+
+
+
+def rebuild_en_dn(credentials,session_info,paths):
+ lp = param.LoadParm()
+ lp.load(paths.smbconf)
+ names = ProvisionNames()
+ names.domain = lp.get("workgroup")
+ names.realm = lp.get("realm")
+ names.rootdn = "DC=" + names.realm.replace(".",",DC=")
+
+ attrs = ["dn" ]
+ dn = ""
+ sam_ldb = Ldb(paths.samdb, session_info=session_info, credentials=credentials,lp=lp)
+ attrs2 = ["schemaNamingContext"]
+ res2 = sam_ldb.search(expression="(objectClass=*)",base="", scope=SCOPE_BASE, attrs=attrs2)
+ attrs.extend(get_linked_attributes(ldb.Dn(sam_ldb,str(res2[0]["schemaNamingContext"])),sam_ldb).keys())
+ attrs.extend(get_dnsyntax_attributes(ldb.Dn(sam_ldb,str(res2[0]["schemaNamingContext"])),sam_ldb)),
+ sam_ldb.transaction_start()
+ res = sam_ldb.search(expression="(cn=*)", scope=SCOPE_SUBTREE, attrs=attrs,controls=["search_options:1:2"]
+)
+ mod = ""
+ for i in range (0,len(res)):
+ #print >>sys.stderr,res[i].dn
+ dn = res[i].dn
+ for att in res[i]:
+ if ( (att != "dn" and att != "cn") and not (res[i][att] is None) ):
+ m = ldb.Message()
+ m.dn = ldb.Dn(sam_ldb, str(dn))
+ saveatt = []
+ for j in range (0,len( res[i][att])):
+ mod = mod +att +": "+str(res[i][att][j])+"\n"
+ saveatt.append(str(res[i][att][j]))
+ m[att] = ldb.MessageElement(saveatt, ldb.FLAG_MOD_REPLACE, att)
+ sam_ldb.modify(m)
+ res3 = sam_ldb.search(expression="(&(dn=%s)(%s=*))"%(dn,att),scope=SCOPE_SUBTREE, attrs=[att],controls=["search_options:1:2"])
+ if( len(res3) == 0 or (len(res3[0][att])!= len(saveatt))):
+ print >>sys.stderr, str(dn) + " has no attr " +att+ " or a wrong value"
+ for satt in saveatt:
+ print >>sys.stderr,str(att)+" = "+satt
+ sam_ldb.transaction_cancel()
+ sam_ldb.transaction_commit()
+
+
+
+
+paths = get_paths(targetdir=opts.targetdir,smbconf=smbconf)
+
+
+rebuild_en_dn(creds,session,paths)
+
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index e21a3cbee1..8f7859c215 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -421,6 +421,15 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
if not valid_netbios_name(domain):
raise InvalidNetbiosName(domain)
+ if netbiosname.upper() == realm.upper():
+ raise Exception("realm %s must not be equal to netbios domain name %s", realm, netbiosname)
+
+ if hostname.upper() == realm.upper():
+ raise Exception("realm %s must not be equal to hostname %s", realm, hostname)
+
+ if domain.upper() == realm.upper():
+ raise Exception("realm %s must not be equal to domain name %s", realm, domain)
+
if rootdn is None:
rootdn = domaindn
diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c
index eb553ed0af..71d8cc901f 100644
--- a/source4/torture/basic/delaywrite.c
+++ b/source4/torture/basic/delaywrite.c
@@ -1455,6 +1455,26 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
#define SET_INFO_FILE(finfo, wrtime) \
SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1)
+#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \
+ NTSTATUS _status; \
+ union smb_setfileinfo sfinfo; \
+ sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \
+ sfinfo.basic_info.in.file.fnum = tfnum; \
+ sfinfo.basic_info.in.create_time = 0; \
+ sfinfo.basic_info.in.access_time = 0; \
+ unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \
+ sfinfo.basic_info.in.write_time += (ns); \
+ sfinfo.basic_info.in.change_time = 0; \
+ sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \
+ _status = smb_raw_setfileinfo(tree, &sfinfo); \
+ if (!NT_STATUS_IS_OK(_status)) { \
+ torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \
+ nt_errstr(_status)); \
+ ret = false; \
+ goto done; \
+ } \
+} while (0)
+
static bool test_delayed_write_update3(struct torture_context *tctx,
struct smbcli_state *cli,
struct smbcli_state *cli2)
@@ -2884,6 +2904,115 @@ again:
return ret;
}
+static bool test_delayed_write_update7(struct torture_context *tctx, struct smbcli_state *cli)
+{
+ union smb_open open_parms;
+ union smb_fileinfo finfo1, finfo2, finfo3;
+ const char *fname = BASEDIR "\\torture_file7.txt";
+ NTSTATUS status;
+ int fnum1 = -1;
+ bool ret = true;
+ TALLOC_CTX *mem_ctx;
+
+ torture_comment(tctx, "\nRunning test_delayed_write_update7 (timestamp resolution test)\n");
+
+ mem_ctx = talloc_init("test_delayed_write_update7");
+ if (!mem_ctx) return false;
+
+ ZERO_STRUCT(finfo1);
+ ZERO_STRUCT(finfo2);
+ ZERO_STRUCT(finfo3);
+ ZERO_STRUCT(open_parms);
+
+ if (!torture_setup_dir(cli, BASEDIR)) {
+ return false;
+ }
+
+ /* Create the file. */
+ fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+ if (fnum1 == -1) {
+ torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
+ return false;
+ }
+
+ finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+ finfo1.basic_info.in.file.fnum = fnum1;
+ finfo2 = finfo1;
+ finfo3 = finfo1;
+
+ /* Get the initial timestamps. */
+ status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
+
+ torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
+
+ /* Set the pending write time to a value with ns. */
+ SET_INFO_FILE_NS(finfo, time(NULL) + 86400, 103, cli->tree, fnum1);
+
+ /* Get the current pending write time by fnum. */
+ status = smb_raw_fileinfo(cli->tree, tctx, &finfo2);
+
+ torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
+
+ /* Ensure the time is actually different. */
+ if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
+ torture_result(tctx, TORTURE_FAIL,
+ "setfileinfo time matches original fileinfo time");
+ ret = false;
+ }
+
+ /* Get the current pending write time by path. */
+ finfo3.basic_info.in.file.path = fname;
+ status = smb_raw_pathinfo(cli->tree, tctx, &finfo3);
+
+ if (finfo2.basic_info.out.write_time != finfo3.basic_info.out.write_time) {
+ torture_result(tctx, TORTURE_FAIL,
+ "qpathinfo time doens't match fileinfo time");
+ ret = false;
+ }
+
+ /* Now close the file. Re-open and check that the write
+ time is identical to the one we wrote. */
+
+ smbcli_close(cli->tree, fnum1);
+
+ open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX;
+ open_parms.ntcreatex.in.flags = 0;
+ open_parms.ntcreatex.in.access_mask = SEC_GENERIC_READ;
+ open_parms.ntcreatex.in.file_attr = 0;
+ open_parms.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE|
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ open_parms.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ open_parms.ntcreatex.in.create_options = 0;
+ open_parms.ntcreatex.in.fname = fname;
+
+ status = smb_raw_open(cli->tree, mem_ctx, &open_parms);
+ talloc_free(mem_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ torture_result(tctx, TORTURE_FAIL,
+ "setfileinfo time matches original fileinfo time");
+ ret = false;
+ }
+
+ fnum1 = open_parms.ntcreatex.out.file.fnum;
+
+ /* Check the returned time matches. */
+ if (open_parms.ntcreatex.out.write_time != finfo2.basic_info.out.write_time) {
+ torture_result(tctx, TORTURE_FAIL,
+ "final open time does not match set time");
+ ret = false;
+ }
+
+ done:
+
+ smbcli_close(cli->tree, fnum1);
+
+ smbcli_unlink(cli->tree, fname);
+ smbcli_deltree(cli->tree, BASEDIR);
+ return ret;
+}
+
/*
testing of delayed update of write_time
*/
@@ -2906,6 +3035,8 @@ struct torture_suite *torture_delay_write(void)
torture_suite_add_2smb_test(suite, "delayed update of write time 5", test_delayed_write_update5);
torture_suite_add_2smb_test(suite, "delayed update of write time 5b", test_delayed_write_update5b);
torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6);
+ torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7);
+ torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7);
return suite;
}