]>
git.ipfire.org Git - people/stevee/pakfire.git/blob - src/libpakfire/fhs.c
1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2021 Pakfire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
23 #include <pakfire/fhs.h>
24 #include <pakfire/file.h>
25 #include <pakfire/logging.h>
26 #include <pakfire/pakfire.h>
27 #include <pakfire/util.h>
30 This struct defines any FHS checks.
32 They are being processed in order from top to bottom which is why we are starting
33 with some more prominent matches and have the less important stuff at the bottom.
35 static const struct pakfire_fhs_check
{
37 enum pakfire_fhs_check_flags
{
38 PAKFIRE_FHS_MUSTNOTEXIST
= (1 << 0),
43 } pakfire_fhs_check
[] = {
45 { "/usr", 0, S_IFDIR
|0755, "root", "root" },
46 { "/usr/bin", 0, S_IFDIR
|0755, "root", "root" },
47 { "/usr/include", 0, S_IFDIR
|0755, "root", "root" },
48 { "/usr/lib", 0, S_IFDIR
|0755, "root", "root" },
49 { "/usr/lib64", 0, S_IFDIR
|0755, "root", "root" },
50 { "/usr/sbin", 0, S_IFDIR
|0755, "root", "root" },
51 { "/usr/share", 0, S_IFDIR
|0755, "root", "root" },
52 { "/usr/src", 0, S_IFDIR
|0755, "root", "root" },
55 { "/var", 0, S_IFDIR
|0755, "root", "root" },
56 { "/var/cache", 0, S_IFDIR
|0755, "root", "root" },
57 { "/var/db", 0, S_IFDIR
|0755, "root", "root" },
58 { "/var/empty", 0, S_IFDIR
|0755, "root", "root" },
59 { "/var/lib", 0, S_IFDIR
|0755, "root", "root" },
60 { "/var/log", 0, S_IFDIR
|0755, "root", "root" },
61 { "/var/mail", 0, S_IFDIR
|0755, "root", "root" },
62 { "/var/opt", 0, S_IFDIR
|0755, "root", "root" },
63 { "/var/run", 0, S_IFLNK
|0777, "root", "root" },
64 { "/var/spool", 0, S_IFDIR
|0755, "root", "root" },
65 { "/var/tmp", 0, S_IFDIR
|1755, "root", "root" },
66 { "/var/tmp/**", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
69 { "/boot", 0, S_IFDIR
|0755, "root", "root" },
70 { "/boot/efi", 0, S_IFDIR
|0755, "root", "root" },
72 // /dev (nothing may exist in it)
73 { "/dev", 0, S_IFDIR
|0755, "root", "root" },
74 { "/dev/**", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
77 { "/etc", 0, S_IFDIR
|0755, "root", "root" },
80 { "/home", 0, S_IFDIR
|0755, "root", "root" },
81 { "/home/**", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
84 { "/opt", 0, S_IFDIR
|0755, "root", "root" },
85 // These directories belong to the "local administrator"
86 // https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s13.html
87 { "/opt/bin", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
88 { "/opt/doc", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
89 { "/opt/include", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
90 { "/opt/info", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
91 { "/opt/lib", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
92 { "/opt/man", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
95 { "/proc", 0, S_IFDIR
|0755, "root", "root" },
96 { "/proc/**", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
99 { "/run", 0, S_IFDIR
|0755, "root", "root" },
102 { "/sys", 0, S_IFDIR
|0755, "root", "root" },
103 { "/sys/**", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
106 { "/tmp", 0, S_IFDIR
|1755, "root", "root" },
107 { "/tmp/**", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
110 { "/media", 0, S_IFDIR
|0755, "root", "root" },
111 { "/mnt", 0, S_IFDIR
|0755, "root", "root" },
112 { "/srv", 0, S_IFDIR
|0755, "root", "root" },
114 // /bin, /sbin, /lib, and /lib64 have to be symlinks
115 { "/bin", 0, S_IFLNK
|0777, NULL
, NULL
},
116 { "/lib", 0, S_IFLNK
|0777, NULL
, NULL
},
117 { "/lib64", 0, S_IFLNK
|0777, NULL
, NULL
},
118 { "/sbin", 0, S_IFLNK
|0777, NULL
, NULL
},
120 // There cannot be anything else in /
121 { "/*", PAKFIRE_FHS_MUSTNOTEXIST
, 0, NULL
, NULL
},
123 // Catch all so that we won't throw an error
124 { "/**", 0, 0, NULL
, NULL
},
130 static const struct pakfire_fhs_check
* pakfire_fhs_find_check(
131 struct pakfire
* pakfire
, const char* path
) {
132 const struct pakfire_fhs_check
* check
= NULL
;
135 // Walk through all possible checks
136 for (check
= pakfire_fhs_check
; check
->path
; check
++) {
137 r
= pakfire_path_match(check
->path
, path
);
145 DEBUG(pakfire
, "%s matches check '%s'\n", path
, check
->path
);
156 ERROR(pakfire
, "Could not find FHS entry for %s: %m\n", path
);
161 static int pakfire_fhs_check_mode(struct pakfire
* pakfire
,
162 const struct pakfire_fhs_check
* check
, struct pakfire_file
* file
) {
163 // No mode defined. Skipping check...
167 const char* path
= pakfire_file_get_path(file
);
170 const mode_t mode
= pakfire_file_get_mode(file
);
172 // Check if mode matches straight away
173 if (check
->mode
== mode
)
176 const mode_t check_type
= check
->mode
& S_IFMT
;
177 const mode_t check_perms
= check
->mode
& ~S_IFMT
;
179 // Check the file type
181 if ((mode_t
)pakfire_file_get_type(file
) != check_type
) {
182 ERROR(pakfire
, "%s: Filetype does not match\n", path
);
187 // Check the file perms
189 if (pakfire_file_get_perms(file
) != check_perms
) {
190 ERROR(pakfire
, "%s: Permissions do not match\n", path
);
199 static int pakfire_fhs_check_ownership(struct pakfire
* pakfire
,
200 const struct pakfire_fhs_check
* check
, struct pakfire_file
* file
) {
201 const char* path
= pakfire_file_get_path(file
);
205 const char* uname
= pakfire_file_get_uname(file
);
209 if (strcmp(check
->uname
, uname
) != 0) {
210 DEBUG(pakfire
, "%s: uname does not match\n", path
);
217 const char* gname
= pakfire_file_get_gname(file
);
221 if (strcmp(check
->gname
, gname
) != 0) {
222 DEBUG(pakfire
, "%s: gname does not match\n", path
);
231 int pakfire_fhs_check_file(struct pakfire
* pakfire
, struct pakfire_file
* file
) {
232 const struct pakfire_fhs_check
* check
= NULL
;
236 const char* path
= pakfire_file_get_path(file
);
241 check
= pakfire_fhs_find_check(pakfire
, path
);
243 ERROR(pakfire
, "Could not match file %s: %m\n", path
);
247 // Should this file exist at all?
248 if (check
->flags
& PAKFIRE_FHS_MUSTNOTEXIST
) {
249 ERROR(pakfire
, "%s must not exist here\n", path
);
254 r
= pakfire_fhs_check_mode(pakfire
, check
, file
);
259 r
= pakfire_fhs_check_ownership(pakfire
, check
, file
);