#define MAX_BUFFER 4096
+#define NOT_SUPPORTED_ERROR "the requested function %s is not currently supported with unprivileged containers"
+
lxc_log_define(lxc_container, lxc);
+inline static bool am_unpriv() {
+ return geteuid() != 0;
+}
+
static bool file_exists(const char *f)
{
struct stat statbuf;
char **interfaces = NULL;
int old_netns = -1, new_netns = -1;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ goto out;
+ }
+
if (!enter_to_ns(c, &old_netns, &new_netns))
goto out;
char *address = NULL;
int old_netns = -1, new_netns = -1;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ goto out;
+ }
+
if (!enter_to_ns(c, &old_netns, &new_netns))
goto out;
static bool lxcapi_destroy(struct lxc_container *c)
{
struct bdev *r = NULL;
- bool bret = false, am_unpriv;
+ bool bret = false;
int ret;
if (!c || !lxcapi_is_defined(c))
goto out;
}
- am_unpriv = c->lxc_conf && geteuid() != 0 && !lxc_list_empty(&c->lxc_conf->id_map);
-
if (c->lxc_conf && has_snapshots(c)) {
ERROR("container %s has dependent snapshots", c->name);
goto out;
}
- if (!am_unpriv && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) {
+ if (!am_unpriv() && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) {
r = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
if (r) {
if (r->ops->destroy(r) < 0) {
const char *p1 = lxcapi_get_config_path(c);
char *path = alloca(strlen(p1) + strlen(c->name) + 2);
sprintf(path, "%s/%s", p1, c->name);
- if (am_unpriv)
+ if (am_unpriv())
ret = userns_exec_1(c->lxc_conf, lxc_rmdir_onedev_wrapper, path);
else
ret = lxc_rmdir_onedev(path);
if (!c || !c->is_defined(c))
return NULL;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return NULL;
+ }
+
if (container_mem_lock(c))
return NULL;
if (!c || !c->name || !c->config_path)
return false;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return false;
+ }
+
bdev = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
if (!bdev) {
ERROR("Failed to find original backing store type");
if (!c)
return -1;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return -1;
+ }
+
return lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process);
}
if (!c)
return -1;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return -1;
+ }
+
command.program = (char*)program;
command.argv = (char**)argv;
r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid);
struct lxc_container *c2;
char snappath[MAXPATHLEN], newname[20];
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return -1;
+ }
+
// /var/lib/lxc -> /var/lib/lxcsnaps \0
ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
if (ret < 0 || ret >= MAXPATHLEN)
if (!c || !lxcapi_is_defined(c))
return -1;
+
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return -1;
+ }
+
// snappath is ${lxcpath}snaps/${lxcname}/
dirlen = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
if (dirlen < 0 || dirlen >= MAXPATHLEN) {
if (!c || !c->name || !c->config_path)
return false;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return false;
+ }
+
bdev = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
if (!bdev) {
ERROR("Failed to find original backing store type");
if (!c || !c->name || !c->config_path)
return false;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return false;
+ }
+
ret = snprintf(clonelxcpath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
if (ret < 0 || ret >= MAXPATHLEN)
goto err;
static bool lxcapi_add_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
{
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return false;
+ }
return add_remove_device_node(c, src_path, dest_path, true);
}
static bool lxcapi_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
{
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return false;
+ }
return add_remove_device_node(c, src_path, dest_path, false);
}
if (!c)
return -1;
+ if (am_unpriv()) {
+ ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
+ return -1;
+ }
+
va_start(ap, arg);
argv = lxc_va_arg_list_to_argv_const(ap, 1);
va_end(ap);