blob: fdb9f5b85093c35970a057614acee4ce7b4e28e5 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: GPL-2.0-only
3#
4
Brad Bishop6e60e8b2018-02-01 10:27:11 -05005import os
6
7def sort_file(filename, mapping):
8 """
9 Sorts a passwd or group file based on the numeric ID in the third column.
10 If a mapping is given, the name from the first column is mapped via that
11 dictionary instead (necessary for /etc/shadow and /etc/gshadow). If not,
12 a new mapping is created on the fly and returned.
13 """
14 new_mapping = {}
15 with open(filename, 'rb+') as f:
16 lines = f.readlines()
17 # No explicit error checking for the sake of simplicity. /etc
18 # files are assumed to be well-formed, causing exceptions if
19 # not.
20 for line in lines:
21 entries = line.split(b':')
22 name = entries[0]
23 if mapping is None:
24 id = int(entries[2])
25 else:
26 id = mapping[name]
27 new_mapping[name] = id
28 # Sort by numeric id first, with entire line as secondary key
29 # (just in case that there is more than one entry for the same id).
30 lines.sort(key=lambda line: (new_mapping[line.split(b':')[0]], line))
31 # We overwrite the entire file, i.e. no truncate() necessary.
32 f.seek(0)
33 f.write(b''.join(lines))
34 return new_mapping
35
36def remove_backup(filename):
37 """
38 Removes the backup file for files like /etc/passwd.
39 """
40 backup_filename = filename + '-'
41 if os.path.exists(backup_filename):
42 os.unlink(backup_filename)
43
44def sort_passwd(sysconfdir):
45 """
46 Sorts passwd and group files in a rootfs /etc directory by ID.
47 Backup files are sometimes are inconsistent and then cannot be
48 sorted (YOCTO #11043), and more importantly, are not needed in
49 the initial rootfs, so they get deleted.
50 """
51 for main, shadow in (('passwd', 'shadow'),
52 ('group', 'gshadow')):
53 filename = os.path.join(sysconfdir, main)
54 remove_backup(filename)
55 if os.path.exists(filename):
56 mapping = sort_file(filename, None)
57 filename = os.path.join(sysconfdir, shadow)
58 remove_backup(filename)
59 if os.path.exists(filename):
60 sort_file(filename, mapping)