aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/xenstored_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xenstore/xenstored_core.c')
-rw-r--r--tools/xenstore/xenstored_core.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2511e4a5fc..5ac4dd3b0f 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -575,8 +575,10 @@ struct node *get_node(struct connection *conn,
/* If we don't have permission, we don't have node. */
if (node) {
if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
- != perm)
+ != perm) {
+ errno = EACCES;
node = NULL;
+ }
}
/* Clean up errno if they weren't supposed to know. */
if (!node)
@@ -789,7 +791,7 @@ static void delete_node_single(struct connection *conn, struct node *node)
corrupt(conn, "Could not delete '%s'", node->name);
return;
}
- domain_entry_dec(conn);
+ domain_entry_dec(conn, node);
}
/* Must not be / */
@@ -840,7 +842,7 @@ static struct node *construct_node(struct connection *conn, const char *name)
node->children = node->data = NULL;
node->childlen = node->datalen = 0;
node->parent = parent;
- domain_entry_inc(conn);
+ domain_entry_inc(conn, node);
return node;
}
@@ -876,7 +878,7 @@ static struct node *create_node(struct connection *conn,
* something goes wrong. */
for (i = node; i; i = i->parent) {
if (!write_node(conn, i)) {
- domain_entry_dec(conn);
+ domain_entry_dec(conn, i);
return NULL;
}
talloc_set_destructor(i, destroy_node);
@@ -1106,6 +1108,7 @@ static void do_get_perms(struct connection *conn, const char *name)
static void do_set_perms(struct connection *conn, struct buffered_data *in)
{
unsigned int num;
+ struct xs_permissions *perms;
char *name, *permstr;
struct node *node;
@@ -1127,12 +1130,24 @@ static void do_set_perms(struct connection *conn, struct buffered_data *in)
return;
}
- node->perms = talloc_array(node, struct xs_permissions, num);
- node->num_perms = num;
- if (!xs_strings_to_perms(node->perms, num, permstr)) {
+ perms = talloc_array(node, struct xs_permissions, num);
+ if (!xs_strings_to_perms(perms, num, permstr)) {
send_error(conn, errno);
return;
}
+
+ /* Unprivileged domains may not change the owner. */
+ if (domain_is_unprivileged(conn) &&
+ perms[0].id != node->perms[0].id) {
+ send_error(conn, EPERM);
+ return;
+ }
+
+ domain_entry_dec(conn, node);
+ node->perms = perms;
+ node->num_perms = num;
+ domain_entry_inc(conn, node);
+
if (!write_node(conn, node)) {
send_error(conn, errno);
return;
@@ -1688,7 +1703,7 @@ static void write_pidfile(const char *pidfile)
if (lockf(fd, F_TLOCK, 0) == -1)
exit(0);
- len = sprintf(buf, "%d\n", getpid());
+ len = sprintf(buf, "%ld\n", (long)getpid());
if (write(fd, buf, len) != len)
barf_perror("Writing pid file %s", pidfile);
}
@@ -1901,7 +1916,7 @@ int main(int argc, char *argv[])
restore_existing_connections();
if (outputpid) {
- printf("%i\n", getpid());
+ printf("%ld\n", (long)getpid());
fflush(stdout);
}
@@ -1924,6 +1939,9 @@ int main(int argc, char *argv[])
/* Get ready to listen to the tools. */
max = initialize_set(&inset, &outset, *sock, *ro_sock);
+ /* Tell the kernel we're up and running. */
+ xenbus_notify_running();
+
/* Main loop. */
/* FIXME: Rewrite so noone can starve. */
for (;;) {