This file is indexed.

/usr/bin/dupdb-admin is in apport-retrace 2.14.1-0ubuntu3.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/python3

# CLI for maintaining the duplicate database
#
# Copyright (c) 2007 - 2012 Canonical Ltd.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
#
# 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 2 of the License, or (at your
# option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.

import optparse, sys, os.path

#from apport.crashdb import get_crashdb
import apport.crashdb_impl.memory
import apport


def command_dump(crashdb, opts, args):
    '''Print out all entries.'''

    for (sig, (id, version, lastchange)) in crashdb._duplicate_db_dump(True).items():
        sys.stdout.write('%7i: %s ' % (id, sig))
        if version == '':
            sys.stdout.write('[fixed] ')
        elif version:
            sys.stdout.write('[fixed in: %s] ' % version)
        else:
            sys.stdout.write('[open] ')
        print('last change: %s' % str(lastchange))


def command_changeid(crashdb, opts, args):
    '''Change the master ID of a crash.'''

    if len(args) != 2:
        apport.fatal('changeid needs exactly two arguments (use --help for a short help)')
    (oldid, newid) = args

    crashdb.duplicate_db_change_master_id(oldid, newid)


def command_removeid(crashdb, opts, args):
    '''Remove a crash.'''

    if len(args) != 1:
        apport.fatal('removeid needs exactly one argument (use --help for a short help)')
    crashdb.duplicate_db_remove(args[0])


def command_publish(crashdb, opts, args):
    '''Publish crash database to a directory.'''

    if len(args) != 1:
        apport.fatal('publish needs exactly one argument (use --help for a short help)')
    crashdb.duplicate_db_publish(args[0])

#
# main
#

# parse command line options
optparser = optparse.OptionParser('''%prog [options] dump
%prog [options] changeid <old ID> <new ID>
%prog [options] removeid <ID>
%prog [options] publish <path>''')

optparser.add_option('-f', '--database-file', dest='db_file', metavar='PATH',
                     default='apport_duplicates.db',
                     help='Location of the database file')
options, args = optparser.parse_args()

if len(args) == 0:
    optparser.error('No command specified')

if not os.path.exists(options.db_file):
    apport.fatal('file does not exist: %s', options.db_file)

# pure DB operations don't need a real backend, and thus no crashdb.conf
crashdb = apport.crashdb_impl.memory.CrashDatabase(None, {})

#if args[0] in ():
#    # these commands require a real DB
#    crashdb = get_crashdb(None, None, {})
#else:

crashdb.init_duplicate_db(options.db_file)

try:
    command = globals()['command_' + args.pop(0)]
except KeyError:
    apport.fatal('unknown command (use --help for a short help)')

command(crashdb, options, args)