aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schlemmer <azarah@gentoo.org>2006-07-06 16:37:20 +0000
committerMartin Schlemmer <azarah@gentoo.org>2006-07-06 16:37:20 +0000
commit27feeab6e5eb6e2ff389943899691b18c970b08c (patch)
treeb300e0395e2b6b673900292f7d27dbef9a4c5ad8 /src
parentOnly print info if we have a controlling terminal. (diff)
downloadsandbox-27feeab6e5eb6e2ff389943899691b18c970b08c.tar.gz
sandbox-27feeab6e5eb6e2ff389943899691b18c970b08c.tar.bz2
sandbox-27feeab6e5eb6e2ff389943899691b18c970b08c.zip
Set default values via a config file. Also support sandbox.d
config directory for package specific configuration files. Signed-off-by: Martin Schlemmer <azarah@gentoo.org>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/sandbox.c264
-rw-r--r--src/sandbox.h4
3 files changed, 197 insertions, 74 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 0eb7bd3..20b8ef0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,8 @@ lib_LTLIBRARIES = libsandbox.la
bin_PROGRAMS = sandbox
AM_CPPFLAGS = \
- -DPIC -fPIC -D_REENTRANT \
+ -DPIC -fPIC -D_REENTRANT \
+ -DETCDIR=\"$(sysconfdir)\" \
-DLIBSANDBOX_PATH=\"$(libdir)\" \
-DSANDBOX_BASHRC_PATH=\"$(pkgdatadir)\" \
-I$(top_srcdir) -Wall
diff --git a/src/sandbox.c b/src/sandbox.c
index 019d9b1..027301e 100644
--- a/src/sandbox.c
+++ b/src/sandbox.c
@@ -50,7 +50,7 @@ static char log_domain[] = "sandbox";
extern char **environ;
-int sandbox_setup(struct sandbox_info_t *sandbox_info)
+int sandbox_setup(struct sandbox_info_t *sandbox_info, bool interactive)
{
if (NULL != getenv(ENV_PORTAGE_TMPDIR)) {
/* Portage handle setting SANDBOX_WRITE itself. */
@@ -60,6 +60,8 @@ int sandbox_setup(struct sandbox_info_t *sandbox_info)
perror("sandbox: Failed to get current directory");
return -1;
}
+ if (interactive)
+ setenv(ENV_SANDBOX_WORKDIR, sandbox_info->work_dir, 1);
}
/* Do not resolve symlinks, etc .. libsandbox will handle that. */
@@ -194,68 +196,198 @@ void usr1_handler(int signum, siginfo_t *siginfo, void *ucontext)
}
}
-int get_sandbox_write_envvar(char *buf, struct sandbox_info_t *sandbox_info)
+char *sandbox_subst_env_vars(dyn_buf_t *env_data)
{
- int retval = 0;
-
- /* bzero out entire buffer then append trailing 0 */
- memset(buf, 0, SB_BUF_LEN);
-
- /* these could go into make.globals later on */
- retval = snprintf(buf, SB_BUF_LEN,
- "%s:%s/.gconfd/lock:%s/.bash_history:%s:%s:%s:%s",
- "/dev/zero:/dev/null:/dev/full:/dev/fd:/proc/self/fd:/dev/pts/:"
- "/dev/vc/:/dev/pty:/dev/tty:/dev/tts:/dev/console:"
- "/dev/shm:/dev/shm/ngpt:/var/log/scrollkeeper.log:"
- "/usr/tmp/conftest:/usr/lib/conftest:"
- "/usr/lib32/conftest:/usr/lib64/conftest:"
- "/usr/tmp/cf:/usr/lib/cf:/usr/lib32/cf:/usr/lib64/cf",
- sandbox_info->home_dir, sandbox_info->home_dir,
- sandbox_info->work_dir[0] != '\0' ? sandbox_info->work_dir
- : "",
- sandbox_info->tmp_dir, sandbox_info->var_tmp_dir,
- "/tmp/:/var/tmp/");
- if (SB_BUF_LEN <= retval) {
- errno = EMSGSIZE;
- perror("sandbox: Failed to generate SANDBOX_WRITE");
+ dyn_buf_t *new_data = NULL;
+ char *tmp_ptr, *tmp_data = NULL;
+ char *var_start, *var_stop;
+
+ new_data = new_dyn_buf();
+ if (NULL == new_data)
+ return NULL;
+
+ tmp_data = read_line_dyn_buf(env_data);
+ if (NULL == tmp_data)
+ goto error;
+ tmp_ptr = tmp_data;
+
+ while (NULL != (var_start = strchr(tmp_ptr, '$'))) {
+ char *env = NULL;
+
+ var_stop = strchr(var_start, '}');
+
+ /* We only support ${} style env var names, so just skip any
+ * '$' that do not follow this syntax */
+ if (('{' != var_start[1]) || (NULL == var_stop)) {
+ tmp_ptr = var_start + 1;
+ continue;
+ }
+
+ /* Terminate part before env string so that we can copy it */
+ var_start[0] = '\0';
+ /* Move var_start past '${' */
+ var_start += 2;
+ /* Terminate the name of the env var */
+ var_stop[0] = '\0';
+
+ if (strlen(var_start) > 0)
+ env = getenv(var_start);
+ if (-1 == sprintf_dyn_buf(new_data, "%s%s",
+ tmp_ptr ? tmp_ptr : "",
+ env ? env : ""))
+ goto error;
+
+ /* Move tmp_ptr past the '}' of the env var */
+ tmp_ptr = var_stop + 1;
+ }
+
+ if (0 != strlen(tmp_ptr))
+ if (-1 == write_dyn_buf(new_data, tmp_ptr, strlen(tmp_ptr)))
+ goto error;
+
+ free(tmp_data);
+
+ tmp_data = read_line_dyn_buf(new_data);
+ if (NULL == tmp_data)
+ goto error;
+
+ free_dyn_buf(new_data);
+
+ return tmp_data;
+
+error:
+ if (NULL != new_data)
+ free_dyn_buf(new_data);
+ if (NULL != tmp_data)
+ free(tmp_data);
+
+ return NULL;
+}
+
+void sandbox_set_env_var(const char *env_var)
+{
+ char *config;
+
+ /* We check if the variable is set in the environment, and if not, we
+ * get it from sandbox.conf, and if they exist, we just add them to the
+ * environment if not already present. */
+ if (NULL == getenv(env_var)) {
+ config = rc_get_cnf_entry(SANDBOX_CONF_FILE, env_var, NULL);
+ if (NULL != config) {
+ setenv(ENV_SANDBOX_VERBOSE, config, 0);
+ free(config);
+ }
+ }
+}
+
+int sandbox_set_env_access_var(const char *access_var)
+{
+ dyn_buf_t *env_data = NULL;
+ int count = 0;
+ char *config = NULL;
+ char **confd_files = NULL;
+ bool use_confd = TRUE;
+
+ env_data = new_dyn_buf();
+ if (NULL == env_data)
return -1;
+
+ /* Now get the defaults for the access variable from sandbox.conf.
+ * These do not get overridden via the environment. */
+ config = rc_get_cnf_entry(SANDBOX_CONF_FILE, access_var, ":");
+ if (NULL != config) {
+ if (-1 == write_dyn_buf(env_data, config, strlen(config)))
+ goto error;
+ free(config);
+ config = NULL;
+ }
+ /* Append whatever might be already set. If anything is set, we do
+ * not process the sandbox.d/ files for this variable. */
+ if (NULL != getenv(access_var)) {
+ use_confd = FALSE;
+ if (-1 == sprintf_dyn_buf(env_data, env_data->wr_index ? ":%s" : "%s",
+ getenv(access_var)))
+ goto error;
}
+ if (!use_confd)
+ goto done;
+
+ /* Now scan the files in sandbox.d/ if the access variable was not
+ * alreay set. */
+ confd_files = rc_ls_dir(SANDBOX_CONFD_DIR, FALSE, TRUE);
+ if (NULL != confd_files) {
+ while (NULL != confd_files[count]) {
+ config = rc_get_cnf_entry(confd_files[count], access_var, ":");
+ if (NULL != config) {
+ if (-1 == sprintf_dyn_buf(env_data,
+ env_data->wr_index ? ":%s" : "%s",
+ config))
+ goto error;
+ free(config);
+ config = NULL;
+ }
+ count++;
+ }
+
+ str_list_free(confd_files);
+ }
+
+done:
+ if (env_data->wr_index > 0) {
+ char *subst;
+
+ subst = sandbox_subst_env_vars(env_data);
+ if (NULL == subst)
+ goto error;
+
+ setenv(access_var, subst, 1);
+ free(subst);
+ }
+
+ free_dyn_buf(env_data);
+
return 0;
+
+error:
+ if (NULL != env_data)
+ free_dyn_buf(env_data);
+ if (NULL != config)
+ free(config);
+ if (NULL != confd_files)
+ str_list_free(confd_files);
+
+ return -1;
}
-int get_sandbox_predict_envvar(char *buf, struct sandbox_info_t *sandbox_info)
+int sandbox_setup_env_config(struct sandbox_info_t *sandbox_info)
{
- int retval = 0;
- /* bzero out entire buffer then append trailing 0 */
- memset(buf, 0, SB_BUF_LEN);
-
- /* these should go into make.globals later on */
- retval = snprintf(buf, SB_BUF_LEN, "%s/.:"
- "/usr/lib/python2.0/:"
- "/usr/lib/python2.1/:"
- "/usr/lib/python2.2/:"
- "/usr/lib/python2.3/:"
- "/usr/lib/python2.4/:"
- "/usr/lib/python2.5/:"
- "/usr/lib/python3.0/:"
- "/var/db/aliases.db:"
- "/var/db/netgroup.db:"
- "/var/db/netmasks.db:"
- "/var/db/ethers.db:"
- "/var/db/rpc.db:"
- "/var/db/protocols.db:"
- "/var/db/services.db:"
- "/var/db/networks.db:"
- "/var/db/hosts.db:"
- "/var/db/group.db:"
- "/var/db/passwd.db",
- sandbox_info->home_dir);
- if (SB_BUF_LEN <= retval) {
- errno = EMSGSIZE;
- perror("sandbox: Failed to generate SANDBOX_PREDICT");
+ sandbox_set_env_var(ENV_SANDBOX_VERBOSE);
+ sandbox_set_env_var(ENV_SANDBOX_DEBUG);
+ sandbox_set_env_var(ENV_SANDBOX_BEEP);
+ sandbox_set_env_var(ENV_NOCOLOR);
+
+ if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_DENY))
return -1;
- }
+ if (NULL == getenv(ENV_SANDBOX_DENY))
+ setenv(ENV_SANDBOX_DENY, LD_PRELOAD_FILE, 1);
+
+ if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_READ))
+ return -1;
+ if (NULL == getenv(ENV_SANDBOX_READ))
+ setenv(ENV_SANDBOX_READ, "/", 1);
+
+ if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_WRITE))
+ return -1;
+ if ((NULL == getenv(ENV_SANDBOX_WRITE)) &&
+ (NULL != sandbox_info->work_dir))
+ setenv(ENV_SANDBOX_WRITE, sandbox_info->work_dir, 1);
+
+ if (-1 == sandbox_set_env_access_var(ENV_SANDBOX_PREDICT))
+ return -1;
+ if ((NULL == getenv(ENV_SANDBOX_PREDICT)) &&
+ (NULL != sandbox_info->home_dir))
+ setenv(ENV_SANDBOX_PREDICT, sandbox_info->home_dir, 1);
return 0;
}
@@ -295,12 +427,13 @@ char **sandbox_setup_environ(struct sandbox_info_t *sandbox_info, bool interacti
char **new_environ;
char **env_ptr = environ;
- char sandbox_write_envvar[SB_BUF_LEN];
- char sandbox_predict_envvar[SB_BUF_LEN];
char *ld_preload_envvar = NULL;
char *orig_ld_preload_envvar = NULL;
char sb_pid[64];
+ if (-1 == sandbox_setup_env_config(sandbox_info))
+ return NULL;
+
/* Unset these, as its easier than replacing when setting up our
* new environment below */
unsetenv(ENV_SANDBOX_ON);
@@ -309,6 +442,7 @@ char **sandbox_setup_environ(struct sandbox_info_t *sandbox_info, bool interacti
unsetenv(ENV_SANDBOX_BASHRC);
unsetenv(ENV_SANDBOX_LOG);
unsetenv(ENV_SANDBOX_DEBUG_LOG);
+ unsetenv(ENV_SANDBOX_WORKDIR);
unsetenv(ENV_SANDBOX_ACTIVE);
if (NULL != getenv(ENV_LD_PRELOAD)) {
@@ -372,22 +506,6 @@ char **sandbox_setup_environ(struct sandbox_info_t *sandbox_info, bool interacti
if (1 != have_ld_preload)
sandbox_setenv(new_environ, ENV_LD_PRELOAD, ld_preload_envvar);
- if (!getenv(ENV_SANDBOX_DENY))
- sandbox_setenv(new_environ, ENV_SANDBOX_DENY, LD_PRELOAD_FILE);
-
- if (!getenv(ENV_SANDBOX_READ))
- sandbox_setenv(new_environ, ENV_SANDBOX_READ, "/");
-
- if (-1 == get_sandbox_write_envvar(sandbox_write_envvar, sandbox_info))
- return NULL;
- if (!getenv(ENV_SANDBOX_WRITE))
- sandbox_setenv(new_environ, ENV_SANDBOX_WRITE, sandbox_write_envvar);
-
- if (-1 == get_sandbox_predict_envvar(sandbox_predict_envvar, sandbox_info))
- return NULL;
- if (!getenv(ENV_SANDBOX_PREDICT))
- sandbox_setenv(new_environ, ENV_SANDBOX_PREDICT, sandbox_predict_envvar);
-
/* Make sure our bashrc gets preference */
sandbox_setenv(new_environ, ENV_BASH_ENV, sandbox_info->sandbox_rc);
@@ -484,7 +602,7 @@ int main(int argc, char **argv)
if (print_debug)
printf("Detection of the support files.\n");
- if (-1 == sandbox_setup(&sandbox_info)) {
+ if (-1 == sandbox_setup(&sandbox_info, print_debug)) {
fprintf(stderr, "sandbox: Failed to setup sandbox.");
exit(EXIT_FAILURE);
}
diff --git a/src/sandbox.h b/src/sandbox.h
index cc1845a..a9cd3b4 100644
--- a/src/sandbox.h
+++ b/src/sandbox.h
@@ -14,6 +14,9 @@
#include "config.h"
#include "rcscripts/rctypes.h"
+#define SANDBOX_CONF_FILE ETCDIR "/sandbox.conf"
+#define SANDBOX_CONFD_DIR ETCDIR "/sandbox.d"
+
#define LD_PRELOAD_EQ "LD_PRELOAD="
#define LD_PRELOAD_FILE "/etc/ld.so.preload"
#define LIB_NAME "libsandbox.so"
@@ -43,6 +46,7 @@
#define ENV_SANDBOX_BASHRC "SANDBOX_BASHRC"
#define ENV_SANDBOX_LOG "SANDBOX_LOG"
#define ENV_SANDBOX_DEBUG_LOG "SANDBOX_DEBUG_LOG"
+#define ENV_SANDBOX_WORKDIR "SANDBOX_WORKDIR"
#define ENV_SANDBOX_DENY "SANDBOX_DENY"
#define ENV_SANDBOX_READ "SANDBOX_READ"