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 )