aboutsummaryrefslogtreecommitdiffstats
path: root/src/firecfg
diff options
context:
space:
mode:
authorLibravatar startx2017 <vradu.startx@yandex.com>2018-08-26 08:15:34 -0400
committerLibravatar startx2017 <vradu.startx@yandex.com>2018-08-26 08:15:34 -0400
commita6555dfa2dc9ad8dc2ea994f64ddd39c07b2d2fa (patch)
tree6ac2ca71d65fd2ce12aa6215ef56d87de9b606b6 /src/firecfg
parentremoved --ls, --get, --put (diff)
downloadfirejail-a6555dfa2dc9ad8dc2ea994f64ddd39c07b2d2fa.tar.gz
firejail-a6555dfa2dc9ad8dc2ea994f64ddd39c07b2d2fa.tar.zst
firejail-a6555dfa2dc9ad8dc2ea994f64ddd39c07b2d2fa.zip
merge from mainline
Diffstat (limited to 'src/firecfg')
-rw-r--r--src/firecfg/firecfg.config2
-rw-r--r--src/firecfg/main.c181
2 files changed, 112 insertions, 71 deletions
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index a33aaeb49..0bbafb343 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -77,6 +77,7 @@ cinelerra
77clamdscan 77clamdscan
78clamdtop 78clamdtop
79clamscan 79clamscan
80clamtk
80claws-mail 81claws-mail
81clementine 82clementine
82clipit 83clipit
@@ -328,6 +329,7 @@ pluma
328polari 329polari
329ppsspp 330ppsspp
330psi-plus 331psi-plus
332pybitmessage
331# pycharm-community - FB note: may enable later 333# pycharm-community - FB note: may enable later
332# pycharm-professional 334# pycharm-professional
333qbittorrent 335qbittorrent
diff --git a/src/firecfg/main.c b/src/firecfg/main.c
index 6fe220d35..298314d4f 100644
--- a/src/firecfg/main.c
+++ b/src/firecfg/main.c
@@ -21,6 +21,7 @@
21#include "firecfg.h" 21#include "firecfg.h"
22#include "../include/firejail_user.h" 22#include "../include/firejail_user.h"
23int arg_debug = 0; 23int arg_debug = 0;
24char *arg_bindir = "/usr/local/bin";
24 25
25static char *usage_str = 26static char *usage_str =
26 "Firecfg is the desktop configuration utility for Firejail software. The utility\n" 27 "Firecfg is the desktop configuration utility for Firejail software. The utility\n"
@@ -31,6 +32,7 @@ static char *usage_str =
31 "DESKTOP INTEGRATION section in man 1 firejail.\n\n" 32 "DESKTOP INTEGRATION section in man 1 firejail.\n\n"
32 "Usage: firecfg [OPTIONS]\n\n" 33 "Usage: firecfg [OPTIONS]\n\n"
33 " --add-users user [user] - add the users to Firejail user access database.\n\n" 34 " --add-users user [user] - add the users to Firejail user access database.\n\n"
35 " --bindir=directory - install in directory instead of /usr/local/bin.\n\n"
34 " --clean - remove all firejail symbolic links.\n\n" 36 " --clean - remove all firejail symbolic links.\n\n"
35 " --debug - print debug messages.\n\n" 37 " --debug - print debug messages.\n\n"
36 " --fix - fix .desktop files.\n\n" 38 " --fix - fix .desktop files.\n\n"
@@ -62,9 +64,9 @@ static void usage(void) {
62 64
63 65
64static void list(void) { 66static void list(void) {
65 DIR *dir = opendir("/usr/local/bin"); 67 DIR *dir = opendir(arg_bindir);
66 if (!dir) { 68 if (!dir) {
67 fprintf(stderr, "Error: cannot open /usr/local/bin directory\n"); 69 fprintf(stderr, "Error: cannot open %s directory\n", arg_bindir);
68 exit(1); 70 exit(1);
69 } 71 }
70 72
@@ -78,7 +80,7 @@ static void list(void) {
78 continue; 80 continue;
79 81
80 char *fullname; 82 char *fullname;
81 if (asprintf(&fullname, "/usr/local/bin/%s", entry->d_name) == -1) 83 if (asprintf(&fullname, "%s/%s", arg_bindir, entry->d_name) == -1)
82 errExit("asprintf"); 84 errExit("asprintf");
83 85
84 if (is_link(fullname)) { 86 if (is_link(fullname)) {
@@ -98,14 +100,10 @@ static void list(void) {
98 100
99static void clean(void) { 101static void clean(void) {
100 printf("Removing all firejail symlinks:\n"); 102 printf("Removing all firejail symlinks:\n");
101 if (getuid() != 0) {
102 fprintf(stderr, "Error: you need to be root to run this command\n");
103 exit(1);
104 }
105 103
106 DIR *dir = opendir("/usr/local/bin"); 104 DIR *dir = opendir(arg_bindir);
107 if (!dir) { 105 if (!dir) {
108 fprintf(stderr, "Error: cannot open /usr/local/bin directory\n"); 106 fprintf(stderr, "Error: cannot open %s directory\n", arg_bindir);
109 exit(1); 107 exit(1);
110 } 108 }
111 109
@@ -119,7 +117,7 @@ static void clean(void) {
119 continue; 117 continue;
120 118
121 char *fullname; 119 char *fullname;
122 if (asprintf(&fullname, "/usr/local/bin/%s", entry->d_name) == -1) 120 if (asprintf(&fullname, "%s/%s", arg_bindir, entry->d_name) == -1)
123 errExit("asprintf"); 121 errExit("asprintf");
124 122
125 if (is_link(fullname)) { 123 if (is_link(fullname)) {
@@ -129,8 +127,11 @@ static void clean(void) {
129 char *ptr = strrchr(fullname, '/'); 127 char *ptr = strrchr(fullname, '/');
130 assert(ptr); 128 assert(ptr);
131 ptr++; 129 ptr++;
132 unlink(fullname); 130 int rv = unlink(fullname);
133 printf(" %s removed\n", ptr); 131 if (rv)
132 fprintf(stderr, "Warning: cannot remove %s\n", fullname);
133 else
134 printf(" %s removed\n", ptr);
134 } 135 }
135 free(fname); 136 free(fname);
136 } 137 }
@@ -148,7 +149,7 @@ static void set_file(const char *name, const char *firejail_exec) {
148 return; 149 return;
149 150
150 char *fname; 151 char *fname;
151 if (asprintf(&fname, "/usr/local/bin/%s", name) == -1) 152 if (asprintf(&fname, "%s/%s", arg_bindir, name) == -1)
152 errExit("asprintf"); 153 errExit("asprintf");
153 154
154 struct stat s; 155 struct stat s;
@@ -161,6 +162,9 @@ static void set_file(const char *name, const char *firejail_exec) {
161 else 162 else
162 printf(" %s created\n", name); 163 printf(" %s created\n", name);
163 } 164 }
165 else {
166 fprintf(stderr, "Warning: cannot create %s - already exists! Skipping...\n", fname);
167 }
164 168
165 free(fname); 169 free(fname);
166} 170}
@@ -181,7 +185,7 @@ static void set_links_firecfg(void) {
181 fprintf(stderr, "Error: cannot open %s\n", cfgfile); 185 fprintf(stderr, "Error: cannot open %s\n", cfgfile);
182 exit(1); 186 exit(1);
183 } 187 }
184 printf("Configuring symlinks in /usr/local/bin based on firecfg.config\n"); 188 printf("Configuring symlinks in %s based on firecfg.config\n", arg_bindir);
185 189
186 char buf[MAX_BUF]; 190 char buf[MAX_BUF];
187 int lineno = 0; 191 int lineno = 0;
@@ -239,7 +243,7 @@ static void set_links_homedir(const char *homedir) {
239 errExit("asprintf"); 243 errExit("asprintf");
240 244
241 // parse ~/.config/firejail/ directory 245 // parse ~/.config/firejail/ directory
242 printf("\nConfiguring symlinks in /usr/local/bin based on local firejail config directory\n"); 246 printf("\nConfiguring symlinks in %s based on local firejail config directory\n", arg_bindir);
243 247
244 DIR *dir = opendir(dirname); 248 DIR *dir = opendir(dirname);
245 if (!dir) { 249 if (!dir) {
@@ -275,9 +279,68 @@ static void set_links_homedir(const char *homedir) {
275 free(firejail_exec); 279 free(firejail_exec);
276} 280}
277 281
282static char *get_user(void) {
283 char *user = getlogin();
284 if (!user) {
285 user = getenv("SUDO_USER");
286 if (!user) {
287 fprintf(stderr, "Error: cannot detect login user\n");
288 exit(1);
289 }
290 }
291
292 return user;
293}
294
295static char *get_homedir(const char *user, uid_t *uid, gid_t *gid) {
296 // find home directory
297 struct passwd *pw = getpwnam(user);
298 if (!pw)
299 goto errexit;
300
301 char *home = pw->pw_dir;
302 if (!home)
303 goto errexit;
304
305 *uid = pw->pw_uid;
306 *gid = pw->pw_gid;
307
308 return home;
309
310errexit:
311 fprintf(stderr, "Error: cannot find home directory for user %s\n", user);
312 exit(1);
313}
278 314
279int main(int argc, char **argv) { 315int main(int argc, char **argv) {
280 int i; 316 int i;
317 int bindir_set = 0;
318
319 // user setup
320 char *user = get_user();
321 uid_t uid;
322 gid_t gid;
323 char *home = get_homedir(user, &uid, &gid);
324
325
326 // check for --bindir
327 for (i = i; i < argc; i++) {
328 if (strncmp(argv[i], "--bindir=", 9) == 0) {
329 if (strncmp(argv[i] + 9, "~/", 2) == 0) {
330 if (asprintf(&arg_bindir, "%s/%s", home, argv[i] + 11) == -1)
331 errExit("asprintf");
332 }
333 else
334 arg_bindir = argv[i] + 9;
335 bindir_set = 1;
336
337 // exit if the directory does not exist, or if we don't have access to it
338 if (access(arg_bindir, R_OK | W_OK | X_OK)) {
339 fprintf(stderr, "Error: directory %s not found\n", arg_bindir);
340 exit(1);
341 }
342 }
343 }
281 344
282 for (i = 1; i < argc; i++) { 345 for (i = 1; i < argc; i++) {
283 // default options 346 // default options
@@ -297,15 +360,6 @@ int main(int argc, char **argv) {
297 return 0; 360 return 0;
298 } 361 }
299 else if (strcmp(argv[i], "--fix") == 0) { 362 else if (strcmp(argv[i], "--fix") == 0) {
300 // find home directory
301 struct passwd *pw = getpwuid(getuid());
302 if (!pw) {
303 goto errexit;
304 }
305 char *home = pw->pw_dir;
306 if (!home) {
307 goto errexit;
308 }
309 fix_desktop_files(home); 363 fix_desktop_files(home);
310 return 0; 364 return 0;
311 } 365 }
@@ -331,19 +385,24 @@ int main(int argc, char **argv) {
331 return 0; 385 return 0;
332 } 386 }
333 else { 387 else {
334 fprintf(stderr, "Error: invalid command line option\n"); 388 if (strncmp(argv[i], "--bindir=", 9) != 0) { // already handled
335 usage(); 389 fprintf(stderr, "Error: invalid command line option\n");
336 return 1; 390 usage();
391 return 1;
392 }
337 } 393 }
338 } 394 }
339 395
396 if (arg_debug)
397 printf("%s %d %d %d %d\n", user, getuid(), getgid(), geteuid(), getegid());
398
340 // set symlinks in /usr/local/bin 399 // set symlinks in /usr/local/bin
341 if (getuid() != 0) { 400 if (bindir_set == 0 && getuid() != 0) {
342 fprintf(stderr, "Error: cannot set the symbolic links in /usr/local/bin\n"); 401 fprintf(stderr, "Error: cannot set the symbolic links in %s\n", arg_bindir);
343 fprintf(stderr, "The proper way to run this command is \"sudo firecfg\".\n"); 402 fprintf(stderr, "The proper way to run this command is \"sudo firecfg\".\n");
344 return 1; 403 return 1;
345 } 404 }
346 else { 405 else if (bindir_set == 0) {
347 // create /usr/local directory if it doesn't exist (Solus distro) 406 // create /usr/local directory if it doesn't exist (Solus distro)
348 struct stat s; 407 struct stat s;
349 if (stat("/usr/local", &s) != 0) { 408 if (stat("/usr/local", &s) != 0) {
@@ -354,66 +413,46 @@ int main(int argc, char **argv) {
354 return 1; 413 return 1;
355 } 414 }
356 } 415 }
357 if (stat("/usr/local/bin", &s) != 0) { 416 if (stat(arg_bindir, &s) != 0) {
358 printf("Creating /usr/local directory\n"); 417 printf("Creating /usr/local directory\n");
359 int rv = mkdir("/usr/local/bin", 0755); 418 int rv = mkdir(arg_bindir, 0755);
360 if (rv != 0) { 419 if (rv != 0) {
361 fprintf(stderr, "Error: cannot create /usr/local/bin directory\n"); 420 fprintf(stderr, "Error: cannot create %s directory\n", arg_bindir);
362 return 1; 421 return 1;
363 } 422 }
364 } 423 }
365 } 424 }
366 clean();
367 set_links_firecfg();
368
369 425
426 // clear all symlinks
427 clean();
370 428
371 // user setup 429 // set new symlinks based on /usr/lib/firejail/firecfg.cfg
372 char *user = getlogin(); 430 set_links_firecfg();
373 if (!user) {
374 user = getenv("SUDO_USER");
375 if (!user) {
376 goto errexit;
377 }
378 }
379 431
380 // add user to firejail access database 432 // add user to firejail access database - only for root
381 if (user) { 433 if (user && getuid() == 0) {
382 printf("\nAdding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR); 434 printf("\nAdding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR);
383 firejail_user_add(user); 435 firejail_user_add(user);
384 } 436 }
385 437
386 // switch to the local user, and fix desktop files 438 // set new symlinks based on ~/.config/firejail directory
387 if (user) { 439 set_links_homedir(home);
388 // find home directory
389 struct passwd *pw = getpwnam(user);
390 if (!pw) {
391 goto errexit;
392 }
393 char *home = pw->pw_dir;
394 if (!home) {
395 goto errexit;
396 }
397
398 // running as root
399 set_links_homedir(home);
400 440
401 // drop permissions 441 // drop permissions
442 if (getuid() == 0) {
402 if (setgroups(0, NULL) < 0) 443 if (setgroups(0, NULL) < 0)
403 errExit("setgroups"); 444 errExit("setgroups");
404 // set uid/gid 445 if (setgid(gid) < 0)
405 if (setgid(pw->pw_gid) < 0)
406 errExit("setgid"); 446 errExit("setgid");
407 if (setuid(pw->pw_uid) < 0) 447 if (setuid(uid) < 0)
408 errExit("setuid"); 448 errExit("setuid");
409 if (arg_debug)
410 printf("%s %d %d %d %d\n", user, getuid(), getgid(), geteuid(), getegid());
411 fix_desktop_files(home);
412 } 449 }
413 450
414 return 0; 451 if (arg_debug)
452 printf("%s %d %d %d %d\n", user, getuid(), getgid(), geteuid(), getegid());
415 453
416errexit: 454 // fix .desktop files in ~/.local/share/applications directory
417 fprintf(stderr, "Error: cannot detect login user in order to set desktop files in ~/.local/share/applications\n"); 455 fix_desktop_files(home);
418 return 1; 456
457 return 0;
419} 458}