tests: Avoid hardcoding relative filepath
[garming/samba-autobuild/.git] / source4 / scripting / bin / sambadowngradedatabase
1 #!/usr/bin/python3
2 #
3 # Unix SMB/CIFS implementation.
4 # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2019
5 #
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.
9 #
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.
14 #
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.
19 #
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/>.
22 from __future__ import print_function
23 import optparse
24 import sys
25
26 # Find right directory when running from source tree
27 sys.path.insert(0, "bin/python")
28
29
30 import samba
31 import ldb
32 import urllib
33 import os
34 from samba import getopt as options
35 from samba.samdb import SamDB
36 from samba.dbchecker import dbcheck
37 from samba.credentials import Credentials
38 parser = optparse.OptionParser("sambaundoguididx")
39 sambaopts = options.SambaOptions(parser)
40 parser.add_option_group(options.VersionOptions(parser))
41 parser.add_option("-H", "--URL", help="LDB URL for database",
42                   type=str, metavar="URL", dest="H")
43 opts, args = parser.parse_args()
44
45 if len(args) != 0:
46     parser.print_usage()
47     sys.exit(1)
48
49 lp_ctx = sambaopts.get_loadparm()
50
51 if opts.H is None:
52     url = lp_ctx.private_path("sam.ldb")
53 else:
54     url = opts.H
55
56 samdb = ldb.Ldb(url=url,
57                 flags=ldb.FLG_DONT_CREATE_DB,
58                 options=["modules:"])
59
60 partitions = samdb.search(base="@PARTITION",
61                           scope=ldb.SCOPE_BASE,
62                           attrs=["backendStore", "partition"])
63
64 backend = str(partitions[0].get('backendStore', 'tdb'))
65
66 if backend == "mdb":
67     samdb = None
68     options = ["pack_format_override=%d" % ldb.PACKING_FORMAT]
69     # We can't remove GUID indexes from LMDB in case there are very
70     # long DNs, so we just move down the pack format, which also removes
71     # references to ORDERED_INTEGER in @ATTRIBUTES.
72
73     # Reopen the DB with pack_format_override set
74     samdb = SamDB(url=url,
75                   flags=ldb.FLG_DONT_CREATE_DB,
76                   lp=lp_ctx,
77                   options=options)
78     samdb.transaction_start()
79     samdb.transaction_commit()
80     print("Your database has been downgraded to LDB pack format version %0x (v1)." % ldb.PACKING_FORMAT)
81
82     print("NOTE: Any use of a Samba 4.11 tool that modifies the DB will "
83           "auto-upgrade back to pack format version %0x (v2)" %
84           ldb.PACKING_FORMAT_V2)
85     exit(0);
86
87 # This is needed to force the @ATTRIBUTES and @INDEXLIST to be correct
88 lp_ctx.set("dsdb:guid index", "false")
89
90 modmsg = ldb.Message()
91 modmsg.dn = ldb.Dn(samdb, '@INDEXLIST')
92 modmsg.add(ldb.MessageElement(
93     elements=[],
94     flags=ldb.FLAG_MOD_REPLACE,
95     name='@IDXGUID'))
96 modmsg.add(ldb.MessageElement(
97     elements=[],
98     flags=ldb.FLAG_MOD_REPLACE,
99     name='@IDX_DN_GUID'))
100
101 samdb.transaction_start()
102 samdb.modify(modmsg)
103
104 privatedir = os.path.dirname(url)
105
106 dbs = []
107 for part in partitions[0]['partition']:
108     dbname = str(part).split(":")[1]
109     dbpath = os.path.join(privatedir, dbname)
110     if os.path.isfile(dbpath):
111         dbpath = "ldb://" + dbpath
112     db = ldb.Ldb(url=dbpath,
113                  options=["modules:"],
114                  flags=ldb.FLG_DONT_CREATE_DB)
115     db.transaction_start()
116     db.modify(modmsg)
117     dbs.append(db)
118
119 for db in dbs:
120     db.transaction_commit()
121
122 samdb.transaction_commit()
123
124 print("Re-opening with the full DB stack")
125 samdb = SamDB(url=url,
126               flags=ldb.FLG_DONT_CREATE_DB,
127               lp=lp_ctx)
128 print("Re-triggering another re-index")
129 chk = dbcheck(samdb)
130
131 chk.reindex_database()
132
133 print("Your database has been downgraded to DN-based index values.")
134
135 print("NOTE: Any use of a Samba 4.8 or later tool including ldbsearch will "
136       "auto-upgrade back to GUID index mode")