------------------------------------------------------------
revno: 1410
committer: James Hunt <[email protected]>
branch nick: upstart-setenv+getenv
timestamp: Tue 2013-01-08 15:57:31 +0000
message:
* dbus/com.ubuntu.Upstart.xml:
- Added UnsetEnv and ResetEnv methods.
* init/control.c:
- control_set_env(): Now uses job_class_environment_set() rather than
directly manipulating job_environ array.
- control_unset_env(): New function.
- control_get_env(): Now calls job_class_environment_get().
- control_list_env(): Now calls job_class_environment_get_all().
- control_reset_env(): New function.
* init/environ.c:
- environ_remove(): New function.
* init/job_class.c:
- job_environ now static.
- job_class_environment_reset(): New function.
- job_class_environment_set(): New function.
- job_class_environment_unset(): New function.
- job_class_environment_get(): Simplified.
- job_class_environment_get_all(): New function.
modified:
dbus/com.ubuntu.Upstart.xml
init/control.c
init/environ.c
init/environ.h
init/job_class.c
init/job_class.h
init/main.c
--
lp:upstart
https://code.launchpad.net/~upstart-devel/upstart/trunk
Your team Upstart Reviewers is subscribed to branch lp:upstart.
To unsubscribe from this branch go to
https://code.launchpad.net/~upstart-devel/upstart/trunk/+edit-subscription
=== modified file 'dbus/com.ubuntu.Upstart.xml'
--- dbus/com.ubuntu.Upstart.xml 2012-12-19 16:26:16 +0000
+++ dbus/com.ubuntu.Upstart.xml 2013-01-08 15:57:31 +0000
@@ -52,10 +52,16 @@
<arg name="replace" type="b" direction="in" />
</method>
+ <method name="UnsetEnv">
+ <arg name="name" type="s" direction="in" />
+ </method>
+
<method name="ListEnv">
<arg name="env" type="as" direction="out" />
</method>
+ <method name="ResetEnv"/>
+
<!-- Signals for changes to the job list -->
<signal name="JobAdded">
<arg name="job" type="o" />
=== modified file 'init/control.c'
--- init/control.c 2012-12-19 16:26:16 +0000
+++ init/control.c 2013-01-08 15:57:31 +0000
@@ -1126,13 +1126,12 @@
* Returns: zero on success, negative value on raised error.
**/
int
-control_set_env (void *data,
- NihDBusMessage *message,
- const char *var,
- int replace)
+control_set_env (void *data,
+ NihDBusMessage *message,
+ const char *var,
+ int replace)
{
Session *session;
- char **ret;
uid_t uid;
nih_assert (message != NULL);
@@ -1162,17 +1161,75 @@
return -1;
}
- job_class_environment_init ();
-
- ret = environ_add (&job_environ, NULL, NULL, replace, var);
-
- if (! ret)
+ if (job_class_environment_set (var, replace) < 0)
nih_return_no_memory_error (-1);
return 0;
}
/**
+ * control_unset_env:
+ *
+ * @data: not used,
+ * @message: D-Bus connection and message received,
+ * @name: variable to clear from the job environment array.
+ *
+ * Implements the UnsetEnv method of the com.ubuntu.Upstart
+ * interface.
+ *
+ * Called to request Upstart remove a particular variable from the job
+ * environment array.
+ *
+ * Returns: zero on success, negative value on raised error.
+ **/
+int
+control_unset_env (void *data,
+ NihDBusMessage *message,
+ const char *name)
+{
+ Session *session;
+ uid_t uid;
+
+ nih_assert (message != NULL);
+ nih_assert (name);
+
+ uid = getuid ();
+
+ /* Get the relevant session */
+ session = session_from_dbus (NULL, message);
+
+ /* Chroot sessions must not be able to influence
+ * the outside system.
+ */
+ if (session && session->chroot) {
+ nih_warn (_("Ignoring unset env request from chroot session"));
+ return 0;
+ }
+
+ /* Disallow users from changing Upstarts environment, unless they happen to
+ * own this process (which they may do in the test scenario and
+ * when running Upstart as a non-privileged user).
+ */
+ if (session && session->user != uid) {
+ nih_dbus_error_raise_printf (
+ DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
+ _("You do not have permission to modify the init environment"));
+ return -1;
+ }
+
+ if (job_class_environment_unset (name) < 0)
+ goto error;
+
+ return 0;
+
+error:
+ nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
+ "%s: %s",
+ _("No such variable"), name);
+ return -1;
+}
+
+/**
* control_get_env:
*
* @data: not used,
@@ -1194,8 +1251,8 @@
char **value)
{
Session *session;
+ uid_t uid;
const char *tmp;
- uid_t uid;
nih_assert (message != NULL);
nih_assert (name);
@@ -1225,9 +1282,7 @@
return -1;
}
- job_class_environment_init ();
-
- tmp = environ_get (job_environ, name);
+ tmp = job_class_environment_get (name);
if (! tmp)
goto error;
@@ -1260,9 +1315,9 @@
* Returns: zero on success, negative value on raised error.
**/
int
-control_list_env (void *data,
- NihDBusMessage *message,
- char ***env)
+control_list_env (void *data,
+ NihDBusMessage *message,
+ char ***env)
{
Session *session;
uid_t uid;
@@ -1286,11 +1341,61 @@
return -1;
}
- job_class_environment_init ();
-
- *env = job_class_environment_get (message);
+ *env = job_class_environment_get_all (message);
if (! *env)
nih_return_no_memory_error (-1);
return 0;
}
+
+/**
+ * control_reset_env:
+ *
+ * @data: not used,
+ * @message: D-Bus connection and message received.
+ *
+ * Implements the ResetEnv method of the com.ubuntu.Upstart
+ * interface.
+ *
+ * Called to reset the environment all subsequent jobs will run in to
+ * the default minimal environment.
+ *
+ * Returns: zero on success, negative value on raised error.
+ **/
+int
+control_reset_env (void *data,
+ NihDBusMessage *message)
+{
+ Session *session;
+ uid_t uid;
+
+ nih_assert (message != NULL);
+
+ /* Get the relevant session */
+ session = session_from_dbus (NULL, message);
+
+ uid = getuid ();
+
+ /* Chroot sessions must not be able to influence
+ * the outside system.
+ */
+ if (session && session->chroot) {
+ nih_warn (_("Ignoring reset env request from chroot session"));
+ return 0;
+ }
+
+ /* Disallow users from modifying Upstarts environment, unless they happen to
+ * own this process (which they may do in the test scenario and
+ * when running Upstart as a non-privileged user).
+ */
+ if (session && session->user != uid) {
+ nih_dbus_error_raise_printf (
+ DBUS_INTERFACE_UPSTART ".Error.PermissionDenied",
+ _("You do not have permission to reset the init environment"));
+ return -1;
+ }
+
+ job_class_environment_reset ();
+
+ return 0;
+}
=== modified file 'init/environ.c'
--- init/environ.c 2011-06-06 17:05:11 +0000
+++ init/environ.c 2013-01-08 15:57:31 +0000
@@ -155,6 +155,67 @@
}
/**
+ * environ_remove:
+ * @env: pointer to environment table,
+ * @parent: parent object for new array,
+ * @len: length of @env,
+ * @str: string to remove.
+ *
+ * Remove @str from environment table @env. If @str does not exist in
+ * @env, the returned array will have the same contents as the original
+ * @env.
+ *
+ * Returns: new array pointer or NULL if insufficient memory (or @env is
+ * too small to reduce).
+ **/
+char **
+environ_remove (char ***env,
+ const void *parent,
+ size_t *len,
+ const char *str)
+{
+ size_t _len;
+ size_t keylen;
+ size_t new_len = 0;
+ char **e;
+ char **new_env;
+
+ nih_assert (env);
+ nih_assert (str);
+
+ if (! len) {
+ len = &_len;
+
+ _len = 0;
+ for (e = *env; e && *e; e++)
+ _len++;
+ }
+
+ /* Can't manipulate an empty array */
+ if (*len < 1)
+ return NULL;
+
+ new_env = nih_str_array_new (NULL);
+ if (! new_env)
+ return NULL;
+
+ for (e = *env; e && *e; e++) {
+ keylen = strcspn (*e, "=");
+
+ if (! strncmp (str, *e, keylen))
+ continue;
+
+ if (! environ_add (&new_env, parent, &new_len, TRUE, *e))
+ return NULL;
+ }
+
+ *env = new_env;
+ *len = new_len;
+
+ return new_env;
+}
+
+/**
* environ_append:
* @env: pointer to environment table,
* @parent: parent object for new array,
=== modified file 'init/environ.h'
--- init/environ.h 2011-06-06 17:05:11 +0000
+++ init/environ.h 2013-01-08 15:57:31 +0000
@@ -28,6 +28,9 @@
char ** environ_add (char ***env, const void *parent, size_t *len,
int replace, const char *str)
__attribute__ ((warn_unused_result));
+char ** environ_remove (char ***env, const void *parent, size_t *len,
+ const char *str)
+ __attribute__ ((warn_unused_result));
char ** environ_append (char ***env, const void *parent, size_t *len,
int replace, char * const *new_env)
__attribute__ ((warn_unused_result));
=== modified file 'init/job_class.c'
--- init/job_class.c 2012-12-19 16:26:16 +0000
+++ init/job_class.c 2013-01-08 15:57:31 +0000
@@ -91,7 +91,7 @@
* Array of environment variables that will be set in the jobs
* environment.
**/
-char **job_environ = NULL;
+static char **job_environ = NULL;
/**
* job_class_init:
@@ -122,25 +122,106 @@
}
/**
+ * job_class_environment_reset:
+ *
+ * Reset the environment back to defaults.
+ **/
+void
+job_class_environment_reset (void)
+{
+ if (job_environ)
+ nih_free (job_environ);
+
+ job_environ = NULL;
+
+ job_class_environment_init ();
+}
+
+/**
+ * job_class_environment_set:
+ *
+ * @var: name[/value] pair of environment variable to set,
+ * @replace: TRUE if @name should be overwritten if already set, else
+ * FALSE.
+ *
+ * Set specified variable in job environment.
+ *
+ * Returns: 0 on success, -1 on error.
+ **/
+int
+job_class_environment_set (const char *var, int replace)
+{
+ nih_assert (var);
+
+ job_class_environment_init ();
+
+ if (! environ_add (&job_environ, NULL, NULL, replace, var))
+ return -1;
+
+ return 0;
+}
+
+/**
+ * job_class_environment_unset:
+ *
+ * @var: name of environment variable to unset.
+ *
+ * Remove specified variable from job environment array.
+ *
+ * Returns: 0 on success, -1 on error.
+ **/
+int
+job_class_environment_unset (const char *name)
+{
+ nih_assert (name);
+
+ job_class_environment_init ();
+
+ if (! environ_remove (&job_environ, NULL, NULL, name))
+ return -1;
+
+ return 0;
+}
+
+/**
+ * job_class_environment_get_all:
+ *
+ * @parent: parent for new environment array.
+ *
+ * Obtain a copy of the entire environment a job will be provided with.
+ *
+ * Returns: Newly-allocated copy of the job environment array,
+ * or NULL on error.
+ **/
+char **
+job_class_environment_get_all (const void *parent)
+{
+ job_class_environment_init ();
+
+ return nih_str_array_copy (parent, NULL, job_environ);
+}
+
+/**
* job_class_environment_get:
*
- * Obtain a copy of the environment a job will be provided with.
- *
- * Returns: Newly-allocated copy of the job environment array, or NULL
- * on error.
+ * @name: name of variable to query.
+ *
+ * Determine value of variable @name in job environment.
+ *
+ * XXX: The returned value must not be freed.
+ *
+ * Returns: pointer to static storage value of @name, or NULL if @name
+ * does not exist in job environment.
+ *
**/
-char **
-job_class_environment_get (const void *parent)
+const char *
+job_class_environment_get (const char *name)
{
- char **env = NULL;
+ nih_assert (name);
job_class_environment_init ();
- env = nih_str_array_copy (parent, NULL, job_environ);
- if (! env)
- return NULL;
-
- return env;
+ return environ_get (job_environ, name);
}
/**
=== modified file 'init/job_class.h'
--- init/job_class.h 2012-12-19 16:26:16 +0000
+++ init/job_class.h 2013-01-08 15:57:31 +0000
@@ -226,13 +226,22 @@
NIH_BEGIN_EXTERN
extern NihHash *job_classes;
-extern char **job_environ;
-
void job_class_init (void);
void job_class_environment_init (void);
+void job_class_environment_reset (void);
+
+int job_class_environment_set (const char *var, int replace);
+int job_class_environment_unset (const char *name);
+
+char ** job_class_environment_get_all (const void *parent)
+ __attribute__ ((warn_unused_result, malloc));
+
+const char *job_class_environment_get (const char *name)
+ __attribute__ ((warn_unused_result));
+
JobClass * job_class_new (const void *parent,
const char *name,
Session *session)
@@ -347,9 +356,6 @@
void job_class_prepare_reexec (void);
-char ** job_class_environment_get (const void *parent)
- __attribute__ ((warn_unused_result, malloc));
-
NIH_END_EXTERN
#endif /* INIT_JOB_CLASS_H */
=== modified file 'init/main.c'
--- init/main.c 2012-12-19 09:08:57 +0000
+++ init/main.c 2013-01-08 15:57:31 +0000
@@ -640,6 +640,7 @@
nih_debug ("Sessions disabled");
job_class_environment_init ();
+
/* Set us as the child subreaper.
* This ensures that even when init doesn't run as PID 1, it'll always be
* the ultimate parent of everything it spawns. */
--
upstart-devel mailing list
[email protected]
Modify settings or unsubscribe at:
https://lists.ubuntu.com/mailman/listinfo/upstart-devel