diff options
Diffstat (limited to 'src/firecfg/main.c')
-rw-r--r-- | src/firecfg/main.c | 104 |
1 files changed, 93 insertions, 11 deletions
diff --git a/src/firecfg/main.c b/src/firecfg/main.c index 1ecfbf524..5928b9ae5 100644 --- a/src/firecfg/main.c +++ b/src/firecfg/main.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <errno.h> | 31 | #include <errno.h> |
32 | #include <sys/mman.h> | 32 | #include <sys/mman.h> |
33 | #include <pwd.h> | 33 | #include <pwd.h> |
34 | #include <dirent.h> | ||
34 | 35 | ||
35 | #include "../include/common.h" | 36 | #include "../include/common.h" |
36 | static int arg_debug = 0; | 37 | static int arg_debug = 0; |
@@ -277,7 +278,8 @@ static void set_file(const char *name, const char *firejail_exec) { | |||
277 | free(fname); | 278 | free(fname); |
278 | } | 279 | } |
279 | 280 | ||
280 | static void set_links(void) { | 281 | // parse /usr/lib/firejail/firecfg.cfg file |
282 | static void set_links_firecfg(void) { | ||
281 | char *cfgfile; | 283 | char *cfgfile; |
282 | if (asprintf(&cfgfile, "%s/firejail/firecfg.config", LIBDIR) == -1) | 284 | if (asprintf(&cfgfile, "%s/firejail/firecfg.config", LIBDIR) == -1) |
283 | errExit("asprintf"); | 285 | errExit("asprintf"); |
@@ -286,12 +288,13 @@ static void set_links(void) { | |||
286 | if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1) | 288 | if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1) |
287 | errExit("asprintf"); | 289 | errExit("asprintf"); |
288 | 290 | ||
291 | // parse /usr/lib/firejail/firecfg.cfg file | ||
289 | FILE *fp = fopen(cfgfile, "r"); | 292 | FILE *fp = fopen(cfgfile, "r"); |
290 | if (!fp) { | 293 | if (!fp) { |
291 | fprintf(stderr, "Error: cannot open %s\n", cfgfile); | 294 | fprintf(stderr, "Error: cannot open %s\n", cfgfile); |
292 | exit(1); | 295 | exit(1); |
293 | } | 296 | } |
294 | printf("Configuring symlinks in /usr/local/bin\n"); | 297 | printf("Configuring symlinks in /usr/local/bin based on firecfg.config\n"); |
295 | 298 | ||
296 | char buf[MAX_BUF]; | 299 | char buf[MAX_BUF]; |
297 | int lineno = 0; | 300 | int lineno = 0; |
@@ -330,7 +333,69 @@ static void set_links(void) { | |||
330 | free(firejail_exec); | 333 | free(firejail_exec); |
331 | } | 334 | } |
332 | 335 | ||
333 | int have_profile(const char *filename) { | 336 | // parse ~/.config/firejail/ directory |
337 | static void set_links_homedir(const char *homedir) { | ||
338 | assert(homedir); | ||
339 | |||
340 | // check firejail config directory | ||
341 | char *dirname; | ||
342 | if (asprintf(&dirname, "%s/.config/firejail", homedir) == -1) | ||
343 | errExit("asprintf"); | ||
344 | struct stat s; | ||
345 | if (stat(dirname, &s) != 0) { | ||
346 | free(dirname); | ||
347 | return; | ||
348 | } | ||
349 | |||
350 | char *firejail_exec; | ||
351 | if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1) | ||
352 | errExit("asprintf"); | ||
353 | |||
354 | // parse ~/.config/firejail/ directory | ||
355 | printf("\nConfiguring symlinks in /usr/local/bin based on local firejail config directory\n"); | ||
356 | |||
357 | DIR *dir = opendir(dirname); | ||
358 | if (!dir) { | ||
359 | fprintf(stderr, "Error: cannot open ~/.config/firejail directory\n"); | ||
360 | free(dirname); | ||
361 | return; | ||
362 | } | ||
363 | |||
364 | struct dirent *entry; | ||
365 | while ((entry = readdir(dir))) { | ||
366 | if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) | ||
367 | continue; | ||
368 | |||
369 | char *exec = strdup(entry->d_name); | ||
370 | if (!exec) | ||
371 | errExit("strdup"); | ||
372 | char *ptr = strrchr(exec, '.'); | ||
373 | if (!ptr) { | ||
374 | free(exec); | ||
375 | continue; | ||
376 | } | ||
377 | if (strcmp(ptr, ".profile") != 0) { | ||
378 | free(exec); | ||
379 | continue; | ||
380 | } | ||
381 | |||
382 | *ptr = '\0'; | ||
383 | set_file(exec, firejail_exec); | ||
384 | free(exec); | ||
385 | } | ||
386 | closedir(dir); | ||
387 | |||
388 | free(firejail_exec); | ||
389 | } | ||
390 | |||
391 | // look for a profile file in /etc/firejail diectory and in homedir/.config/firejail directory | ||
392 | static int have_profile(const char *filename, const char *homedir) { | ||
393 | assert(filename); | ||
394 | assert(homedir); | ||
395 | |||
396 | if (arg_debug) | ||
397 | printf("checking profile for %s\n", filename); | ||
398 | |||
334 | // remove .desktop extension | 399 | // remove .desktop extension |
335 | char *f1 = strdup(filename); | 400 | char *f1 = strdup(filename); |
336 | if (!f1) | 401 | if (!f1) |
@@ -338,15 +403,29 @@ int have_profile(const char *filename) { | |||
338 | f1[strlen(filename) - 8] = '\0'; | 403 | f1[strlen(filename) - 8] = '\0'; |
339 | 404 | ||
340 | // build profile name | 405 | // build profile name |
341 | char *profname; | 406 | char *profname1; |
342 | if (asprintf(&profname, "%s/%s.profile", SYSCONFDIR, f1) == -1) | 407 | char *profname2; |
408 | if (asprintf(&profname1, "%s/%s.profile", SYSCONFDIR, f1) == -1) | ||
409 | errExit("asprintf"); | ||
410 | if (asprintf(&profname2, "%s/.config/firejail/%s.profile", homedir, f1) == -1) | ||
343 | errExit("asprintf"); | 411 | errExit("asprintf"); |
344 | 412 | ||
345 | struct stat s; | 413 | int rv = 0; |
346 | int rv = stat(profname, &s); | 414 | if (access(profname1, R_OK) == 0) { |
415 | if (arg_debug) | ||
416 | printf("found %s\n", profname1); | ||
417 | rv = 1; | ||
418 | } | ||
419 | else if (access(profname2, R_OK) == 0) { | ||
420 | if (arg_debug) | ||
421 | printf("found %s\n", profname2); | ||
422 | rv = 1; | ||
423 | } | ||
424 | |||
347 | free(f1); | 425 | free(f1); |
348 | free(profname); | 426 | free(profname1); |
349 | return (rv == 0)? 1: 0; | 427 | free(profname2); |
428 | return rv; | ||
350 | } | 429 | } |
351 | 430 | ||
352 | static void fix_desktop_files(char *homedir) { | 431 | static void fix_desktop_files(char *homedir) { |
@@ -411,7 +490,7 @@ static void fix_desktop_files(char *homedir) { | |||
411 | errExit("stat"); | 490 | errExit("stat"); |
412 | 491 | ||
413 | // no profile in /etc/firejail, no desktop file fixing | 492 | // no profile in /etc/firejail, no desktop file fixing |
414 | if (!have_profile(filename)) | 493 | if (!have_profile(filename, homedir)) |
415 | continue; | 494 | continue; |
416 | 495 | ||
417 | /* coverity[toctou] */ | 496 | /* coverity[toctou] */ |
@@ -599,7 +678,7 @@ int main(int argc, char **argv) { | |||
599 | } | 678 | } |
600 | } | 679 | } |
601 | } | 680 | } |
602 | set_links(); | 681 | set_links_firecfg(); |
603 | 682 | ||
604 | 683 | ||
605 | 684 | ||
@@ -623,6 +702,9 @@ int main(int argc, char **argv) { | |||
623 | goto errexit; | 702 | goto errexit; |
624 | } | 703 | } |
625 | 704 | ||
705 | // running as root | ||
706 | set_links_homedir(home); | ||
707 | |||
626 | // drop permissions | 708 | // drop permissions |
627 | if (setgroups(0, NULL) < 0) | 709 | if (setgroups(0, NULL) < 0) |
628 | errExit("setgroups"); | 710 | errExit("setgroups"); |