Commit ca2e26ef authored by Yathindra Naik's avatar Yathindra Naik

Refactoring code.

parent 225e6ae1
......@@ -403,24 +403,11 @@ static struct node *read_node(struct connection *conn, const char *name)
/* Permissions are struct xs_permissions. */
node->perms = (void *)&p[4];
/* Capabilites are struct capability. */
node->caps = node->perms + node->num_perms;
node->caps = (struct capability *)(node->perms + node->num_perms);
/* Data is binary blob (usually ascii, no nul). */
node->data = node->caps + node->num_caps;
/* Children is strings, nul separated. */
node->children = node->data + node->datalen;
#else
/* Datalen, childlen, number of permissions */
p = (uint32_t *)dataptr;
node->num_perms = p[0];
node->datalen = p[1];
node->childlen = p[2];
/* Permissions are struct xs_permissions. */
node->perms = (void *)&p[3];
/* Data is binary blob (usually ascii, no nul). */
node->data = node->perms + node->num_perms;
/* Children is strings, nul separated. */
node->children = node->data + node->datalen;
#endif
return node;
}
......@@ -515,31 +502,35 @@ static int caps_for_conn(struct connection *conn,
switch(perm)
{
case XS_PERM_READ:
case XS_PERM_READ|XS_PERM_OWNER:
/* Read Capabilities */
/* Return true if we have read capabilities
* Or we have owner capabilities - But owner possese both.
//case XS_PERM_READ|XS_PERM_OWNER:
/* Read Capabilities
* Return true if we have read capabilities
* Or we have owner capabilities - But owner has both.
*/
if ( (xc_cap_check(xch, domid, 2, caps[0])) == 0 )
ret = 0;
if ( (xc_cap_check(xch, domid, 2, &caps[0])) == 0 )
ret = 0;
break;
case XS_PERM_WRITE:
case XS_PERM_WRITE|XS_PERM_OWNER:
/* Write Capabilities */
/* Return true if we have write capabilities
* Or we have owner capabilities - But owner possese both.
//case XS_PERM_WRITE|XS_PERM_OWNER:
/* Write Capabilities
* Return true if we have write capabilities
* Or we have owner capabilities - But owner has both.
*/
if ( (xc_cap_check(xch, domid, 2, caps[1])) == 0 )
ret = 0;
if ( (xc_cap_check(xch, domid, 2, &caps[1])) == 0 )
ret = 0;
break;
case XS_PERM_READ|XS_PERM_WRITE:
//case XS_PERM_READ|XS_PERM_WRITE:
case XS_PERM_OWNER:
/* Read | Write Capabilities */
/* Owner must have both. */
if ( (xc_cap_check(xch, domid, 2, caps[0])) == 0 ||
(xc_cap_check(xch, domid, 2, caps[1])) == 0 )
ret = 0;
if ( (xc_cap_check(xch, domid, 2, &caps[0])) == 0 ||
(xc_cap_check(xch, domid, 2, &caps[1])) == 0 )
ret = 0;
break;
case XS_PERM_NONE:
ret = 0;
default:
ret = 0;
}
xprintf("caps_for_conn: After xc_cap_check\n");
return ret;
......@@ -599,7 +590,7 @@ static enum xs_perm_type ask_parents(struct connection *conn, const char *name)
if (domain_is_cap(conn)) {
if (caps_for_conn(conn, node->caps, XS_PERM_READ))
xs_perms = XS_PERM_READ;
if (caps_for_conn(conn, node->caps, XS_PERM_READ))
if (caps_for_conn(conn, node->caps, XS_PERM_WRITE))
xs_perms |= XS_PERM_WRITE;
xprintf("ask_parents: Returning\n");
return xs_perms;
......@@ -804,17 +795,128 @@ static const char *onearg(struct buffered_data *in)
}
#ifdef CONFIG_XENCAP
static char *caps_to_strings(const void *ctx,
struct capability *caps)
/* Convert strings to capabilities. False if a problem.
* Permission scheme in xenstore is weird. Here are the rules -
1) Domain 0 may read or write anywhere in the store,
regardless of permissions, and permissions are set
up by the tools in domain 0, or by Xenstored when
it first starts up.
2) The first element in this list specifies the owner of the path.
3) The owner always has read and write access to their nodes.
4) The example below, therefore, sets the permissions in the path
to be such that domain 0 (being privileged), dom1 (being the owner),
and domains dom2 and dom3 (being explicitly specified) can _all_ write
to the node. Any other domain can only read, as specified by the first
pair of 'read' and 'write' flags.
Example:
xstransact.SetPermissions(path, { 'dom' : dom1,
'read' : True,
'write' : False },
{ 'dom' : dom2,
'read' : True,
'write' : True },
{ 'dom' : dom3,
'read' : True,
'write' : True })
*/
bool xs_strings_to_caps(unsigned int num, const char *strings)
{
const char *p;
char *end;
unsigned int i;
char *strings = NULL;
char buffer[MAX_STRLEN(unsigned int) + 1];
strings = talloc_realloc(ctx, strings, char, 2 + stelen(buffer
struct capability *caps = (struct capability *)malloc(2*sizeof(struct capability));
xc_interface *xch;
int owner_domid,to_domid;
int list[2] = {-1,-1};
int flag = 0;
/* I'm guessing we need to handle two cases here.
* The first domain id is the owner. Create 2 capabilities for it.
* Rest of the domain id's we can simply grant from the owner.
*/
xch = xc_interface_open(0,0,0);
if(xch == 0)
{
printf("\nxc_interface_open failed to get xc_handle!\n");
return false;
}
/* First, identify the owner domain and
create read and write capabilities. */
p = strings;
p++;
owner_domid = strtol(p, &end, 0);
if (!xc_cap_create(xch, owner_domid, &caps[0]))
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_create.\n");
return false;
}
if (!xc_cap_create(xch, owner_domid, &caps[1]))
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_create.\n");
return false;
}
for (p = end+1, i = 1; i < num; i++) {
/* "r", "w", or "b" for both. */
switch (*p) {
case 'r':
list[0] = 0;
flag = 1;
break;
case 'w':
list[0] = 1;
flag = 1;
break;
case 'b':
list[0] = 0;
list[1] = 1;
break;
case 'n':
break;
default:
errno = EINVAL;
return false;
}
p++;
to_domid = strtol(p, &end, 0);
if (*end || !*p) {
errno = EINVAL;
return false;
}
if (flag)
{
/* Read or Write Caps */
if ((xc_cap_grant(xch,owner_domid,to_domid,2,&list,1)) == 1)
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_grant.\n");
return false;
}
}
else
{
/* Both the flags */
if ((xc_cap_grant(xch,owner_domid,to_domid,2,&list,2)) == 1)
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_grant.\n");
return false;
}
}
}
p = end + 1;
}
return true;
}
#endif
static char *perms_to_strings(const void *ctx,
......@@ -949,8 +1051,6 @@ static struct node *construct_node(struct connection *conn, const char *name)
if (domain_is_unprivileged(conn))
node->perms[0].id = conn->id;
}
/* No children, no data */
node->children = node->data = NULL;
node->childlen = node->datalen = 0;
......@@ -974,8 +1074,8 @@ static int destroy_node(void *_node)
key.dsize = strlen(node->name);
#ifdef CONFIG_XENCAP
for ( i = 0; i < node->num_caps; ++i )
free(node->caps[i]);
for (i = 0; i < node->num_caps; ++i)
free(((void*)node->caps[i]));
#endif
tdb_delete(node->tdb, key);
return 0;
......@@ -1220,11 +1320,11 @@ static void do_get_perms(struct connection *conn, const char *name)
#ifdef CONFIG_XENCAP
if (domain_is_cap(conn))
{
strings = caps_to_strings(node, node->caps);
strings = caps_to_strings(node, &len);
}
#endif
strings = perms_to_strings(node, node->perms, node->num_perms, &len);
else
strings = perms_to_strings(node, node->perms, node->num_perms, &len);
#endif
if (!strings)
send_error(conn, errno);
else
......@@ -1273,9 +1373,12 @@ static void do_set_perms(struct connection *conn, struct buffered_data *in)
return NULL;
}
xprintf("construct_node: Before xc_cap_create\n");
xprintf("construct_node: Before xs_strings_to_caps\n");
if (!xs_strings_to_caps(num,strings)) {
send_error(conn,errno);
xs_interface_close(xch);
return;
}
xc_interface_close(xch);
return;
......
......@@ -281,7 +281,7 @@ bool domain_is_cap(struct connection *conn)
Find out which domains has the reqd capabilities
to access this node.
*/
static char *caps_to_strings(struct node *node, unsigned int *len)
char *caps_to_strings(struct node *node, unsigned int *len)
{
xc_dominfo_t dominfo;
struct domain *domain, *tmp;
......
......@@ -63,6 +63,9 @@ int get_domid(struct connection *conn);
/* Returns true if domain is in capability mode. */
bool domain_is_cap(struct connection *conn);
//char *caps_to_strings(struct node *node, unsigned int *len)
#endif
/* Quota manipulation */
......
......@@ -107,131 +107,6 @@ bool xs_write_all(int fd, const void *data, unsigned int len)
return true;
}
#ifdef CONFIG_XENCAP
/* Convert strings to capabilities. False if a problem.
* Permission scheme in xenstore is weird. Here are the rules -
1) Domain 0 may read or write anywhere in the store,
regardless of permissions, and permissions are set
up by the tools in domain 0, or by Xenstored when
it first starts up.
2) The first element in this list specifies the owner of the path.
3) The owner always has read and write access to their nodes.
4) The example below, therefore, sets the permissions in the path
to be such that domain 0 (being privileged), dom1 (being the owner),
and domains dom2 and dom3 (being explicitly specified) can _all_ write
to the node. Any other domain can only read, as specified by the first
pair of 'read' and 'write' flags.
Example:
xstransact.SetPermissions(path, { 'dom' : dom1,
'read' : True,
'write' : False },
{ 'dom' : dom2,
'read' : True,
'write' : True },
{ 'dom' : dom3,
'read' : True,
'write' : True })
*/
bool xs_strings_to_caps(unsigned int num, const char *strings)
{
const char *p;
char *end;
unsigned int i;
xc_interface *xch;
int owner_domid;
int list[2] = {-1,-1};
int flag = 0;
/* I'm guessing we need to handle two cases here.
* The first domain id is the owner. Create 2 capabilities for it.
* Rest of the domain id's we can simply grant from the owner.
*/
xc_interface *xch;
xch = xc_interface_open(0,0,0);
if(xch == 0)
{
printf("\nxc_interface_open failed to get xc_handle!\n");
return FALSE;
}
/* First, identify the owner domain and
create read and write capabilities. */
p = strings;
p++;
owner_domid = strtol(p, &end, 0);
if (!xc_cap_create(owner_domid, node->caps[0]))
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_create.\n");
return FALSE;
}
if (!xc_cap_create(owner_domid, node->caps[1]))
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_create.\n");
return FALSE;
}
for (p = end+1, i = 1; i < num; i++) {
/* "r", "w", or "b" for both. */
switch (*p) {
case 'r':
list[0] = 0;
flag = 1;
break;
case 'w':
list[0] = 1;
flag = 1;
break;
case 'b':
list[0] = 0;
list[1] = 1;
break;
case 'n':
break;
default:
errno = EINVAL;
return false;
}
p++;
to_domid = strtol(p, &end, 0);
if (*end || !*p) {
errno = EINVAL;
return false;
}
if (flag)
{
/* Read or Write Caps */
if ((xc_cap_grant(owner_domid,to_domid,2,list,1)) == 1)
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_grant.\n");
return FALSE;
}
}
else
{
/* Both the flags */
if ((xc_cap_grant(owner_domid,to_domid,2,list,2)) == 1)
{
xc_interface_close(xch);
printf("xs_strings_to_caps: Error in xc_cap_grant.\n");
return FALSE;
}
}
p = end + 1;
}
return true;
}
#endif
/* Convert strings to permissions. False if a problem. */
bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
const char *strings)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment