checksum_obj = ostree_object_to_string (checksum, objtype);
g_debug ("fetch of %s complete", checksum_obj);
- if (pull_data->is_mirror && pull_data->repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
+ /* If we're mirroring and writing into an archive repo, we can directly copy
+ * the content rather than paying the cost of exploding it, checksumming, and
+ * re-gzip.
+ */
+ if (pull_data->is_mirror && pull_data->repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
+ && !pull_data->is_bareuseronly_files)
{
gboolean have_object;
if (!ostree_repo_has_object (pull_data->repo, OSTREE_OBJECT_TYPE_FILE, checksum,
}
/* Also, delete it now that we've opened it, we'll hold
- * a reference to the fd. If we fail to write later, then
+ * a reference to the fd. If we fail to validate or write, then
* the temp space will be cleaned up.
*/
(void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
+ if (!validate_bareuseronly_mode (pull_data,
+ checksum,
+ g_file_info_get_attribute_uint32 (file_info, "unix::mode"),
+ error))
+ goto out;
+
if (!ostree_raw_file_to_content_stream (file_in, file_info, xattrs,
&object_input, &length,
cancellable, error))
goto out;
-
+
pull_data->n_outstanding_content_write_requests++;
ostree_repo_write_content_async (pull_data->repo, checksum,
object_input, length,
pull_data->disable_static_deltas = TRUE;
}
- else if (pull_data->is_bareuseronly_files)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't use bareuseronly-files with non-local origin repo");
- goto out;
- }
/* We can't use static deltas if pulling into an archive-z2 repo. */
if (self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
assert_file_has_content baz/cow '^moo$'
}
-echo "1..21"
+echo "1..23"
# Try both syntaxes
repo_init --no-gpg-verify
${CMD_PREFIX} ostree --repo=mirrorrepo fsck
echo "ok pull (refuses deltas)"
-if ${CMD_PREFIX} ostree --repo=mirrorrepo \
- pull origin main --bareuseronly-files 2>err.txt; then
- assert_not_reached "--bareuseronly-files unexpectedly succeeded"
-fi
-assert_file_has_content err.txt 'bareuseronly-files with non-local'
-echo "ok pull (refuses bareuseronly)"
+cd ${test_tmpdir}
+rm mirrorrepo/refs/remotes/* -rf
+${CMD_PREFIX} ostree --repo=mirrorrepo prune --refs-only
+${CMD_PREFIX} ostree --repo=mirrorrepo pull --bareuseronly-files origin main
+echo "ok pull (bareuseronly, safe)"
+
+rm checkout-origin-main -rf
+$OSTREE --repo=ostree-srv/gnomerepo checkout main checkout-origin-main
+cat > statoverride.txt <<EOF
+2048 /some-setuid
+EOF
+echo asetuid > checkout-origin-main/some-setuid
+${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo commit -b content-with-suid --statoverride=statoverride.txt --tree=dir=checkout-origin-main
+${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo summary -u
+# Verify we reject it both when unpacking and when mirroring
+for flag in "" "--mirror"; do
+ if ${CMD_PREFIX} ostree --repo=mirrorrepo pull ${flag} --bareuseronly-files origin content-with-suid 2>err.txt; then
+ assert_not_reached "pulled unsafe bareuseronly"
+ fi
+ assert_file_has_content err.txt 'object.*\.file: invalid mode.*with bits 040.*'
+done
+echo "ok pull (bareuseronly, unsafe)"
+
+cd ${test_tmpdir}
+rm mirrorrepo/refs/remotes/* -rf
+${CMD_PREFIX} ostree --repo=mirrorrepo prune --refs-only
+${CMD_PREFIX} ostree --repo=mirrorrepo pull --mirror --bareuseronly-files origin main
+echo "ok pull (bareuseronly mirror)"
cd ${test_tmpdir}
rm mirrorrepo/refs/remotes/* -rf