diff --git a/share/doc/xsd/opennebula_configuration.xsd b/share/doc/xsd/opennebula_configuration.xsd
index 5029aca650..027fcd6003 100644
--- a/share/doc/xsd/opennebula_configuration.xsd
+++ b/share/doc/xsd/opennebula_configuration.xsd
@@ -27,6 +27,8 @@
+
+
diff --git a/src/datastore_mad/remotes/fs/cp b/src/datastore_mad/remotes/fs/cp
index ddc4277eb1..7df73ad252 100755
--- a/src/datastore_mad/remotes/fs/cp
+++ b/src/datastore_mad/remotes/fs/cp
@@ -152,6 +152,13 @@ if [ -n "$BRIDGE_LIST" ]; then
ssh_exec_and_log "$DST_HOST" "$CONVERT_CMD" \
"Error converting $DST in $DST_HOST"
fi
+
+ FORMAT=$(ssh_monitor_and_log $DST_HOST "set -e -o pipefail; $QEMU_IMG info $DST | grep \"^file format:\" | awk '{print \$3}'")
+
+ # if ssh_monitor_and_log fails RC is returned
+ if [[ $FORMAT =~ '^[0-9]+$' ]]; then
+ exit -1
+ fi
else
mkdir -p "$BASE_PATH"
multiline_exec_and_log "set -e -o pipefail; $COPY_COMMAND" "Error copying $SRC to $DST"
@@ -159,6 +166,14 @@ else
if [ "x$CONVERT" = 'xyes' ] && [ -n "$DRIVER" ]; then
multiline_exec_and_log "$CONVERT_CMD" "Error converting $DST"
fi
+
+ FORMAT=$($QEMU_IMG info $DST | grep "^file format:" | awk '{print $3}' || :)
+
+ if [ -z $FORMAT ]; then
+ rm -rf $DST
+ log_error "Unknown image format src=$SRC"
+ exit -1
+ fi
fi
echo "$DST"
diff --git a/src/datastore_mad/remotes/fs/rm b/src/datastore_mad/remotes/fs/rm
index a49176cd82..bc6c44c5c4 100755
--- a/src/datastore_mad/remotes/fs/rm
+++ b/src/datastore_mad/remotes/fs/rm
@@ -59,11 +59,11 @@ BASE_PATH="${XPATH_ELEMENTS[i++]}"
if [ -n "$BRIDGE_LIST" ]; then
DST_HOST=`get_destination_host $ID`
- ssh_exec_and_log "$DST_HOST" "[ -f $SRC ] && rm -rf $SRC $SRC.snap" \
+ ssh_exec_and_log "$DST_HOST" "[ -e $SRC ] && rm -rf $SRC $SRC.snap" \
"Error deleting $SRC in $DST_HOST"
else
BASENAME_SRC=`basename "${SRC##$REMOTE_RM_CMD}"`
- if [ -f "$SRC" -a `dirname "$SRC"` = "$BASE_PATH" -a -n "$BASENAME_SRC" ]
+ if [ -e "$SRC" -a `dirname "$SRC"` = "$BASE_PATH" -a -n "$BASENAME_SRC" ]
then
log "Removing $SRC from the image repository"
diff --git a/src/template/OpenNebulaTemplate.cc b/src/template/OpenNebulaTemplate.cc
index b011b4d252..d04d93d15e 100644
--- a/src/template/OpenNebulaTemplate.cc
+++ b/src/template/OpenNebulaTemplate.cc
@@ -384,6 +384,8 @@ void OpenNebulaTemplate::set_conf_default()
set_conf_single("HOST_ENCRYPTED_ATTR", "NSX_PASSWORD");
set_conf_single("HOST_ENCRYPTED_ATTR", "ONE_PASSWORD");
set_conf_single("SHOWBACK_ONLY_RUNNING", "NO");
+ set_conf_single("CONTEXT_RESTRICTED_DIRS", "/etc");
+ set_conf_single("CONTEXT_SAFE_DIRS", "");
//DB CONFIGURATION
vvalue.insert(make_pair("BACKEND","sqlite"));
diff --git a/src/vm/VirtualMachineContext.cc b/src/vm/VirtualMachineContext.cc
index 6594c9fc9c..2edbd0442b 100644
--- a/src/vm/VirtualMachineContext.cc
+++ b/src/vm/VirtualMachineContext.cc
@@ -67,6 +67,39 @@ const std::vector NETWORK6_CONTEXT = {
{"EXTERNAL", "EXTERNAL", "", false},
};
+bool is_restricted(const string& path,
+ const set& restricted,
+ const set& safe)
+{
+ auto canonical_c = realpath(path.c_str(), nullptr);
+
+ if (canonical_c == nullptr)
+ {
+ return false;
+ }
+
+ string canonical_str(canonical_c);
+ free(canonical_c);
+
+ for (auto& s : safe)
+ {
+ if (canonical_str.find(s) == 0)
+ {
+ return false;
+ }
+ }
+
+ for (auto& r : restricted)
+ {
+ if (canonical_str.find(r) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* CONTEXT - Public Interface */
@@ -128,6 +161,33 @@ int VirtualMachine::generate_context(string &files, int &disk_id,
}
files = context->vector_value("FILES");
+
+ auto& nd = Nebula::instance();
+ string restricted_dirs, safe_dirs;
+ nd.get_configuration_attribute("CONTEXT_RESTRICTED_DIRS", restricted_dirs);
+ nd.get_configuration_attribute("CONTEXT_SAFE_DIRS", safe_dirs);
+
+ set restricted, safe;
+
+ one_util::split_unique(restricted_dirs, ' ', restricted);
+ one_util::split_unique(safe_dirs, ' ', safe);
+
+ set files_set;
+ one_util::split_unique(files, ' ', files_set);
+ for (auto& f : files_set)
+ {
+ if (is_restricted(f, restricted, safe))
+ {
+ string error = "CONTEXT/FILES cannot use " + f
+ + ", it's in restricted directories";
+
+ log("VM", Log::ERROR, error);
+ set_template_error_message(error);
+
+ return -1;
+ }
+ }
+
files_ds = context->vector_value("FILES_DS");
if (!files_ds.empty())
diff --git a/src/vmm/VirtualMachineManager.cc b/src/vmm/VirtualMachineManager.cc
index 383a898fd5..e44d3a7802 100644
--- a/src/vmm/VirtualMachineManager.cc
+++ b/src/vmm/VirtualMachineManager.cc
@@ -347,6 +347,9 @@ static int do_context_command(VirtualMachine * vm, const string& password,
if ( rc == -1 )
{
+ auto vmpool = Nebula::instance().get_vmpool();
+ vmpool->update(vm);
+
return -1;
}
else if ( rc == 1 )