From ffd51a5c78549839465085ab6480bd5b6642d637 Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Tue, 9 Oct 2018 05:41:17 -0500 Subject: Allow specifying a profile "name" with the profile option (eg. --profile=firefox). --- src/firejail/firejail.h | 3 ++- src/firejail/main.c | 57 ++++++++++++++++++++++++++----------------------- src/firejail/profile.c | 33 ++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 85a4fbddb..8145c1bb5 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -458,7 +458,8 @@ void fs_mnt(const int enforce); // profile.c // find and read the profile specified by name from dir directory -int profile_find(const char *name, const char *dir); +int profile_find(const char *name, const char *dir, int add_ext); +int profile_find_firejail(const char *name, int add_ext); // read a profile file void profile_read(const char *fname); // check profile line; if line == 0, this was generated from a command line option diff --git a/src/firejail/main.c b/src/firejail/main.c index e0a149085..680ce5800 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1485,8 +1485,33 @@ int main(int argc, char **argv) { if (!ppath) errExit("strdup"); - profile_read(ppath); - custom_profile = 1; + if (access(ppath, R_OK)) { + char *ptr = ppath; + while (*ptr != '/' && *ptr != '.' && *ptr != '\0') + ptr++; + // profile path contains no / or . chars, + // assume its a profile name + if (*ptr != '\0') { + fprintf(stderr, "Error: inaccessible profile file: %s\n", ppath); + exit(1); + } + + // profile was not read in previously, try to see if + // we were given a profile name. + if (!profile_find_firejail(ppath, 1)) { + // do not fall through to default profile, + // because the user should be notified that + // given profile arg could not be used. + fprintf(stderr, "Error: no profile with name \"%s\" found.\n", ppath); + exit(1); + } + else + custom_profile = 1; + } + else { + profile_read(ppath); + custom_profile = 1; + } free(ppath); } else if (strcmp(argv[i], "--noprofile") == 0) { @@ -2327,21 +2352,8 @@ int main(int argc, char **argv) { // load the profile - if (!arg_noprofile) { - if (!custom_profile) { - // look for a profile in ~/.config/firejail directory - char *usercfgdir; - if (asprintf(&usercfgdir, "%s/.config/firejail", cfg.homedir) == -1) - errExit("asprintf"); - int rv = profile_find(cfg.command_name, usercfgdir); - free(usercfgdir); - custom_profile = rv; - } - if (!custom_profile) { - // look for a user profile in /etc/firejail directory - int rv = profile_find(cfg.command_name, SYSCONFDIR); - custom_profile = rv; - } + if (!arg_noprofile && !custom_profile) { + custom_profile = profile_find_firejail(cfg.command_name, 1); } // use default.profile as the default @@ -2352,16 +2364,7 @@ int main(int argc, char **argv) { if (arg_debug) printf("Attempting to find %s.profile...\n", profile_name); - // look for the profile in ~/.config/firejail directory - char *usercfgdir; - if (asprintf(&usercfgdir, "%s/.config/firejail", cfg.homedir) == -1) - errExit("asprintf"); - custom_profile = profile_find(profile_name, usercfgdir); - free(usercfgdir); - - if (!custom_profile) - // look for the profile in /etc/firejail directory - custom_profile = profile_find(profile_name, SYSCONFDIR); + custom_profile = profile_find_firejail(profile_name, 1); if (!custom_profile) { fprintf(stderr, "Error: no default.profile installed\n"); diff --git a/src/firejail/profile.c b/src/firejail/profile.c index f70c0c9d1..4fc710f39 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -25,26 +25,29 @@ extern char *xephyr_screen; #define MAX_READ 8192 // line buffer for profile files // find and read the profile specified by name from dir directory -int profile_find(const char *name, const char *dir) { +int profile_find(const char *name, const char *dir, int add_ext) { EUID_ASSERT(); assert(name); assert(dir); int rv = 0; DIR *dp; - char *pname; - if (asprintf(&pname, "%s.profile", name) == -1) - errExit("asprintf"); + char *pname = NULL; + if (add_ext) + if (asprintf(&pname, "%s.profile", name) == -1) + errExit("asprintf"); + else + name = pname; dp = opendir (dir); if (dp != NULL) { struct dirent *ep; while ((ep = readdir(dp)) != NULL) { - if (strcmp(ep->d_name, pname) == 0) { + if (strcmp(ep->d_name, name) == 0) { if (arg_debug) printf("Found %s profile in %s directory\n", name, dir); char *etcpname; - if (asprintf(&etcpname, "%s/%s", dir, pname) == -1) + if (asprintf(&etcpname, "%s/%s", dir, name) == -1) errExit("asprintf"); profile_read(etcpname); free(etcpname); @@ -55,10 +58,26 @@ int profile_find(const char *name, const char *dir) { (void) closedir (dp); } - free(pname); + if (pname) + free(pname); return rv; } +// search and read the profile specified by name from firejail directories +int profile_find_firejail(const char *name, int add_ext) { + // look for a profile in ~/.config/firejail directory + char *usercfgdir; + if (asprintf(&usercfgdir, "%s/.config/firejail", cfg.homedir) == -1) + errExit("asprintf"); + int rv = profile_find(name, usercfgdir, add_ext); + free(usercfgdir); + + if (!rv) + // look for a user profile in /etc/firejail directory + rv = profile_find(name, SYSCONFDIR, add_ext); + + return rv; +} //*************************************************** // run-time profiles -- cgit v1.2.3-54-g00ecf