diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 2 | ||||
-rwxr-xr-x | source4/lib/ldb/tests/python/ldap.py | 8 | ||||
-rw-r--r-- | source4/lib/tdb/common/tdb.c | 80 | ||||
-rw-r--r-- | source4/scripting/python/STATUS | 1 | ||||
-rw-r--r-- | source4/scripting/python/samba/provision.py | 44 | ||||
-rwxr-xr-x | source4/setup/provision.py | 2 |
6 files changed, 81 insertions, 56 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index 559c91bd2d..f9dd131fd4 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -59,6 +59,7 @@ static int schema_fsmo_init(struct ldb_module *module) schema_dn = samdb_schema_dn(module->ldb); if (!schema_dn) { + ldb_reset_err_string(module->ldb); ldb_debug(module->ldb, LDB_DEBUG_WARNING, "schema_fsmo_init: no schema dn present: (skip schema loading)\n"); return ldb_next_init(module); @@ -91,6 +92,7 @@ static int schema_fsmo_init(struct ldb_module *module) NULL, schema_attrs, &schema_res); if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ldb_reset_err_string(module->ldb); ldb_debug(module->ldb, LDB_DEBUG_WARNING, "schema_fsmo_init: no schema head present: (skip schema loading)\n"); talloc_free(mem_ctx); diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py index d35f7767df..a425ddc830 100755 --- a/source4/lib/ldb/tests/python/ldap.py +++ b/source4/lib/ldb/tests/python/ldap.py @@ -523,12 +523,12 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + base_dn + """ assert len(res) == 0 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + base_dn - res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base="cn=ldaptestcontainer2," + base_dn, scope=SCOPE_ONELEVEL) - # FIXME: assert len(res) == 0 + res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + base_dn), scope=SCOPE_ONELEVEL) + assert len(res) == 0 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + base_dn - res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base="cn=ldaptestcontainer2," + base_dn, scope=SCOPE_SUBTREE) - #FIXME: assert len(res) == 0 + res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + base_dn), scope=SCOPE_SUBTREE) + assert len(res) == 0 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn) ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn)) diff --git a/source4/lib/tdb/common/tdb.c b/source4/lib/tdb/common/tdb.c index a25c3e7aca..767452c9b3 100644 --- a/source4/lib/tdb/common/tdb.c +++ b/source4/lib/tdb/common/tdb.c @@ -687,9 +687,35 @@ void tdb_enable_seqnum(struct tdb_context *tdb) /* + add a region of the file to the freelist. Length is the size of the region in bytes, + which includes the free list header that needs to be added + */ +static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) +{ + struct list_struct rec; + if (length <= sizeof(rec)) { + /* the region is not worth adding */ + return 0; + } + if (length + offset > tdb->map_size) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); + return -1; + } + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = length - sizeof(rec); + if (tdb_free(tdb, offset, &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n")); + return -1; + } + return 0; +} + +/* wipe the entire database, deleting all records. This can be done very fast by using a global lock. The entire data portion of the file becomes a single entry in the freelist. + + This code carefully steps around the recovery area, leaving it alone */ int tdb_wipe_all(struct tdb_context *tdb) { @@ -735,43 +761,31 @@ int tdb_wipe_all(struct tdb_context *tdb) goto failed; } - if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write recovery head\n")); - goto failed; - } - - /* add all the rest of the file to the freelist */ - data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)) - sizeof(struct list_struct); - if (data_len < recovery_size+sizeof(tdb_off_t)) { - recovery_size = 0; - } else { - data_len -= recovery_size; - } - if (data_len > 0) { - struct list_struct rec; - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = data_len; - if (tdb_free(tdb, TDB_DATA_START(tdb->header.hash_size), &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to add free record\n")); + /* add all the rest of the file to the freelist, possibly leaving a gap + for the recovery area */ + if (recovery_size == 0) { + /* the simple case - the whole file can be used as a freelist */ + data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)); + if (tdb_free_region(tdb, TDB_DATA_START(tdb->header.hash_size), data_len) != 0) { goto failed; } - } - - /* possibly add the recovery record */ - if (recovery_size != 0) { - struct list_struct rec; - - recovery_head = tdb->map_size - recovery_size; - - ZERO_STRUCT(rec); - rec.rec_len = recovery_size - sizeof(rec); - if (tdb_rec_write(tdb, recovery_head, &rec) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to add recovery record\n")); + } else { + /* we need to add two freelist entries - one on either + side of the recovery area + + Note that we cannot shift the recovery area during + this operation. Only the transaction.c code may + move the recovery area or we risk subtle data + corruption + */ + data_len = (recovery_head - TDB_DATA_START(tdb->header.hash_size)); + if (tdb_free_region(tdb, TDB_DATA_START(tdb->header.hash_size), data_len) != 0) { goto failed; } - if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write recovery head\n")); - goto failed; + /* and the 2nd free list entry after the recovery area - if any */ + data_len = tdb->map_size - (recovery_head+recovery_size); + if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { + goto failed; } } diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 6e6475bfde..ee67b8bc7a 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -1,6 +1,5 @@ dsdb/samdb/ldb_modules/tests/samba3sam.py: Fix remaining failing tests lib/ldb/tests/python/ldap.py: Fix remaining 3 FIXME's -provisioning in LDAP mode(TEST_LDAP=yes PROVISION_PYTHON=yes make test) command-line vampire provisioning: combine some of the python dictionaries finish scripting/bin/smbstatus.py diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index bcadcca583..0c16ab3bfe 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -323,10 +323,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, configdn_ldb = "configuration.ldb" if ldap_backend is not None: configdn_ldb = ldap_backend - schema_ldb = "schema.ldb" + schemadn_ldb = "schema.ldb" if ldap_backend is not None: schema_ldb = ldap_backend + schemadn_ldb = ldap_backend + if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid","paged_searches"] elif ldap_backend_type == "openldap": @@ -336,23 +338,31 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, else: backend_modules = ["objectguid"] - setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { - "SCHEMADN": schemadn, - "SCHEMADN_LDB": "schema.ldb", - "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": configdn, - "CONFIGDN_LDB": "configuration.ldb", - "DOMAINDN": domaindn, - "DOMAINDN_LDB": "users.ldb", - "SCHEMADN_MOD": "schema_fsmo,instancetype", - "CONFIGDN_MOD": "naming_fsmo,instancetype", - "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", - "MODULES_LIST": ",".join(modules_list), - "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), - "MODULES_LIST2": ",".join(modules_list2), - "BACKEND_MOD": ",".join(backend_modules), + samdb.transaction_start() + try: + setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { + "SCHEMADN": schemadn, + "SCHEMADN_LDB": schemadn_ldb, + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": configdn, + "CONFIGDN_LDB": configdn_ldb, + "DOMAINDN": domaindn, + "DOMAINDN_LDB": domaindn_ldb, + "SCHEMADN_MOD": "schema_fsmo,instancetype", + "CONFIGDN_MOD": "naming_fsmo,instancetype", + "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", + "MODULES_LIST": ",".join(modules_list), + "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "MODULES_LIST2": ",".join(modules_list2), + "BACKEND_MOD": ",".join(backend_modules), }) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) @@ -680,7 +690,7 @@ FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" def provision(lp, setup_dir, message, paths, session_info, - credentials, ldapbackend, samdb_fill=FILL_FULL, realm=None, rootdn=None, + credentials, samdb_fill=FILL_FULL, realm=None, rootdn=None, domain=None, hostname=None, hostip=None, domainsid=None, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, diff --git a/source4/setup/provision.py b/source4/setup/provision.py index c8087f7bd7..9f887e8b3b 100755 --- a/source4/setup/provision.py +++ b/source4/setup/provision.py @@ -150,7 +150,7 @@ elif opts.partitions_only: samdb_fill = FILL_DRS provision(lp, setup_dir, message, paths, - system_session(), creds, opts.ldap_backend, + system_session(), creds, samdb_fill=samdb_fill, realm=opts.realm, domainguid=opts.domain_guid, domainsid=opts.domain_sid, policyguid=opts.policy_guid, hostname=opts.host_name, |