3 # Unix SMB/CIFS implementation.
4 # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2019
6 # Downgrade a database from 4.11 format to 4.7 format. 4.7 Format will
7 # run on any version of Samba AD, and Samba will repack/reconfigure the
8 # database if necessary.
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # Find right directory when running from source tree
26 sys.path.insert(0, "bin/python")
33 from samba import getopt as options
34 from samba.samdb import SamDB
35 from samba.dbchecker import dbcheck
36 from samba.credentials import Credentials
37 parser = optparse.OptionParser("samba_downgrade_db")
38 sambaopts = options.SambaOptions(parser)
39 parser.add_option_group(options.VersionOptions(parser))
40 parser.add_option("-H", "--URL", help="LDB URL for database",
41 type=str, metavar="URL", dest="H")
42 opts, args = parser.parse_args()
48 lp_ctx = sambaopts.get_loadparm()
51 url = lp_ctx.private_path("sam.ldb")
55 samdb = ldb.Ldb(url=url,
56 flags=ldb.FLG_DONT_CREATE_DB,
59 partitions = samdb.search(base="@PARTITION",
61 attrs=["backendStore", "partition"])
63 backend = str(partitions[0].get('backendStore', 'tdb'))
67 options = ["pack_format_override=%d" % ldb.PACKING_FORMAT]
68 # We can't remove GUID indexes from LMDB in case there are very
69 # long DNs, so we just move down the pack format, which also removes
70 # references to ORDERED_INTEGER in @ATTRIBUTES.
72 # Reopen the DB with pack_format_override set
73 samdb = SamDB(url=url,
74 flags=ldb.FLG_DONT_CREATE_DB,
77 samdb.transaction_start()
78 samdb.transaction_commit()
79 print("Your database has been downgraded to LDB pack format version %0x (v1)." % ldb.PACKING_FORMAT)
81 print("NOTE: Any use of a Samba 4.11 tool that modifies the DB will "
82 "auto-upgrade back to pack format version %0x (v2)" %
83 ldb.PACKING_FORMAT_V2)
86 # This is needed to force the @ATTRIBUTES and @INDEXLIST to be correct
87 lp_ctx.set("dsdb:guid index", "false")
89 modmsg = ldb.Message()
90 modmsg.dn = ldb.Dn(samdb, '@INDEXLIST')
91 modmsg.add(ldb.MessageElement(
93 flags=ldb.FLAG_MOD_REPLACE,
95 modmsg.add(ldb.MessageElement(
97 flags=ldb.FLAG_MOD_REPLACE,
100 samdb.transaction_start()
103 privatedir = os.path.dirname(url)
106 for part in partitions[0]['partition']:
107 dbname = str(part).split(":")[1]
108 dbpath = os.path.join(privatedir, dbname)
109 if os.path.isfile(dbpath):
110 dbpath = "ldb://" + dbpath
111 db = ldb.Ldb(url=dbpath,
112 options=["modules:"],
113 flags=ldb.FLG_DONT_CREATE_DB)
114 db.transaction_start()
119 db.transaction_commit()
121 samdb.transaction_commit()
123 print("Re-opening with the full DB stack")
124 samdb = SamDB(url=url,
125 flags=ldb.FLG_DONT_CREATE_DB,
127 print("Re-triggering another re-index")
130 chk.reindex_database()
132 print("Your database has been downgraded to DN-based index values.")
134 print("NOTE: Any use of a Samba 4.8 or later tool including ldbsearch will "
135 "auto-upgrade back to GUID index mode")