xref: /openbmc/openbmc/poky/meta/lib/oe/rootfspostcommands.py (revision 8460358c3d24c71d9d38fd126c745854a6301564)
1*8460358cSPatrick Williams#
2*8460358cSPatrick Williams# Copyright OpenEmbedded Contributors
3*8460358cSPatrick Williams#
4*8460358cSPatrick Williams# SPDX-License-Identifier: GPL-2.0-only
5*8460358cSPatrick Williams#
6*8460358cSPatrick Williams
7*8460358cSPatrick Williamsimport os
8*8460358cSPatrick Williams
9*8460358cSPatrick Williamsdef sort_shadowutils_file(filename, mapping):
10*8460358cSPatrick Williams    """
11*8460358cSPatrick Williams    Sorts a passwd or group file based on the numeric ID in the third column.
12*8460358cSPatrick Williams    If a mapping is given, the name from the first column is mapped via that
13*8460358cSPatrick Williams    dictionary instead (necessary for /etc/shadow and /etc/gshadow). If not,
14*8460358cSPatrick Williams    a new mapping is created on the fly and returned.
15*8460358cSPatrick Williams    """
16*8460358cSPatrick Williams
17*8460358cSPatrick Williams    new_mapping = {}
18*8460358cSPatrick Williams    with open(filename, 'rb+') as f:
19*8460358cSPatrick Williams        lines = f.readlines()
20*8460358cSPatrick Williams        # No explicit error checking for the sake of simplicity. /etc
21*8460358cSPatrick Williams        # files are assumed to be well-formed, causing exceptions if
22*8460358cSPatrick Williams        # not.
23*8460358cSPatrick Williams        for line in lines:
24*8460358cSPatrick Williams            entries = line.split(b':')
25*8460358cSPatrick Williams            name = entries[0]
26*8460358cSPatrick Williams            if mapping is None:
27*8460358cSPatrick Williams                id = int(entries[2])
28*8460358cSPatrick Williams            else:
29*8460358cSPatrick Williams                id = mapping[name]
30*8460358cSPatrick Williams            new_mapping[name] = id
31*8460358cSPatrick Williams        # Sort by numeric id first, with entire line as secondary key
32*8460358cSPatrick Williams        # (just in case that there is more than one entry for the same id).
33*8460358cSPatrick Williams        lines.sort(key=lambda line: (new_mapping[line.split(b':')[0]], line))
34*8460358cSPatrick Williams        # We overwrite the entire file, i.e. no truncate() necessary.
35*8460358cSPatrick Williams        f.seek(0)
36*8460358cSPatrick Williams        f.write(b''.join(lines))
37*8460358cSPatrick Williams
38*8460358cSPatrick Williams    return new_mapping
39*8460358cSPatrick Williams
40*8460358cSPatrick Williamsdef sort_shadowutils_files(sysconfdir):
41*8460358cSPatrick Williams    """
42*8460358cSPatrick Williams    Sorts shadow-utils 'passwd' and 'group' files in a rootfs' /etc directory
43*8460358cSPatrick Williams    by ID.
44*8460358cSPatrick Williams    """
45*8460358cSPatrick Williams
46*8460358cSPatrick Williams    for main, shadow in (('passwd', 'shadow'),
47*8460358cSPatrick Williams                         ('group', 'gshadow')):
48*8460358cSPatrick Williams        filename = os.path.join(sysconfdir, main)
49*8460358cSPatrick Williams        if os.path.exists(filename):
50*8460358cSPatrick Williams            mapping = sort_shadowutils_file(filename, None)
51*8460358cSPatrick Williams            filename = os.path.join(sysconfdir, shadow)
52*8460358cSPatrick Williams            if os.path.exists(filename):
53*8460358cSPatrick Williams                 sort_shadowutils_file(filename, mapping)
54*8460358cSPatrick Williams
55*8460358cSPatrick Williamsdef remove_shadowutils_backup_file(filename):
56*8460358cSPatrick Williams    """
57*8460358cSPatrick Williams    Remove shadow-utils backup file for files like /etc/passwd.
58*8460358cSPatrick Williams    """
59*8460358cSPatrick Williams
60*8460358cSPatrick Williams    backup_filename = filename + '-'
61*8460358cSPatrick Williams    if os.path.exists(backup_filename):
62*8460358cSPatrick Williams        os.unlink(backup_filename)
63*8460358cSPatrick Williams
64*8460358cSPatrick Williamsdef remove_shadowutils_backup_files(sysconfdir):
65*8460358cSPatrick Williams    """
66*8460358cSPatrick Williams    Remove shadow-utils backup files in a rootfs /etc directory. They are not
67*8460358cSPatrick Williams    needed in the initial root filesystem and sorting them can be inconsistent
68*8460358cSPatrick Williams    (YOCTO #11043).
69*8460358cSPatrick Williams    """
70*8460358cSPatrick Williams
71*8460358cSPatrick Williams    for filename in (
72*8460358cSPatrick Williams            'group',
73*8460358cSPatrick Williams            'gshadow',
74*8460358cSPatrick Williams            'passwd',
75*8460358cSPatrick Williams            'shadow',
76*8460358cSPatrick Williams            'subgid',
77*8460358cSPatrick Williams            'subuid',
78*8460358cSPatrick Williams        ):
79*8460358cSPatrick Williams        filepath = os.path.join(sysconfdir, filename)
80*8460358cSPatrick Williams        remove_shadowutils_backup_file(filepath)
81*8460358cSPatrick Williams
82*8460358cSPatrick Williamsdef tidy_shadowutils_files(sysconfdir):
83*8460358cSPatrick Williams    """
84*8460358cSPatrick Williams    Tidy up shadow-utils files.
85*8460358cSPatrick Williams    """
86*8460358cSPatrick Williams
87*8460358cSPatrick Williams    remove_shadowutils_backup_files(sysconfdir)
88*8460358cSPatrick Williams    sort_shadowutils_files(sysconfdir)
89*8460358cSPatrick Williams
90*8460358cSPatrick Williams    return True
91