core: Make unprivileged case ignore ownership, add "_compose" context
I was in the process of trying to support `%post` scripts, and I wanted to use `rpm-ostree container` for convenient and safe testing. However the recent package layering changes broke it to error out on perms like `filesystem`'s `root:mail` on `/var/mail`. I decided to introduce a new `rpmostree_context_new_compose` which had the current behavior, switch `compose tree` to use it, and then change `_new_unprivileged` to *really* be unprivileged. Specifically we ignore file ownership (and fix dir owners) because we assume we'll be operating with `bare-user` repos. Closes: #327 Approved by: jlebon
This commit is contained in:
parent
5936b53812
commit
3c77c36999
@ -689,7 +689,7 @@ rpmostree_compose_builtin_tree (int argc,
|
||||
goto out;
|
||||
}
|
||||
|
||||
corectx = rpmostree_context_new_unprivileged (self->cachedir_dfd, cancellable, error);
|
||||
corectx = rpmostree_context_new_compose (self->cachedir_dfd, cancellable, error);
|
||||
if (!corectx)
|
||||
goto out;
|
||||
|
||||
|
@ -275,6 +275,7 @@ struct _RpmOstreeContext {
|
||||
RpmOstreeTreespec *spec;
|
||||
HifContext *hifctx;
|
||||
OstreeRepo *ostreerepo;
|
||||
gboolean unprivileged;
|
||||
char *dummy_instroot_path;
|
||||
OstreeSePolicy *sepolicy;
|
||||
};
|
||||
@ -356,10 +357,11 @@ rpmostree_context_new_system (GCancellable *cancellable,
|
||||
return self;
|
||||
}
|
||||
|
||||
RpmOstreeContext *
|
||||
rpmostree_context_new_unprivileged (int userroot_dfd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
static RpmOstreeContext *
|
||||
rpmostree_context_new_internal (int userroot_dfd,
|
||||
gboolean unprivileged,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(RpmOstreeContext) ret = rpmostree_context_new_system (cancellable, error);
|
||||
struct stat stbuf;
|
||||
@ -367,6 +369,8 @@ rpmostree_context_new_unprivileged (int userroot_dfd,
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
ret->unprivileged = unprivileged;
|
||||
|
||||
{ g_autofree char *reposdir = glnx_fdrel_abspath (userroot_dfd, "rpmmd.repos.d");
|
||||
hif_context_set_repo_dir (ret->hifctx, reposdir);
|
||||
}
|
||||
@ -408,6 +412,22 @@ rpmostree_context_new_unprivileged (int userroot_dfd,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RpmOstreeContext *
|
||||
rpmostree_context_new_compose (int basedir_dfd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return rpmostree_context_new_internal (basedir_dfd, FALSE, cancellable, error);
|
||||
}
|
||||
|
||||
RpmOstreeContext *
|
||||
rpmostree_context_new_unprivileged (int basedir_dfd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return rpmostree_context_new_internal (basedir_dfd, TRUE, cancellable, error);
|
||||
}
|
||||
|
||||
/* XXX: or put this in new_system() instead? */
|
||||
void
|
||||
rpmostree_context_set_repo (RpmOstreeContext *self,
|
||||
@ -1290,7 +1310,7 @@ rpmostree_context_download (RpmOstreeContext *ctx,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
import_one_package (OstreeRepo *ostreerepo,
|
||||
import_one_package (RpmOstreeContext *self,
|
||||
HifContext *hifctx,
|
||||
HifPackage *pkg,
|
||||
OstreeSePolicy *sepolicy,
|
||||
@ -1298,6 +1318,7 @@ import_one_package (OstreeRepo *ostreerepo,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
OstreeRepo *ostreerepo = self->ostreerepo;
|
||||
g_autofree char *ostree_commit = NULL;
|
||||
glnx_unref_object RpmOstreeUnpacker *unpacker = NULL;
|
||||
g_autofree char *pkg_path;
|
||||
@ -1314,6 +1335,8 @@ import_one_package (OstreeRepo *ostreerepo,
|
||||
}
|
||||
|
||||
flags = RPMOSTREE_UNPACKER_FLAGS_OSTREE_CONVENTION;
|
||||
if (self->unprivileged)
|
||||
flags |= RPMOSTREE_UNPACKER_FLAGS_UNPRIVILEGED;
|
||||
|
||||
/* TODO - tweak the unpacker flags for containers */
|
||||
unpacker = rpmostree_unpacker_new_at (AT_FDCWD, pkg_path, flags, error);
|
||||
@ -1369,7 +1392,7 @@ rpmostree_context_import (RpmOstreeContext *self,
|
||||
for (guint i = 0; i < install->packages_to_import->len; i++)
|
||||
{
|
||||
HifPackage *pkg = install->packages_to_import->pdata[i];
|
||||
if (!import_one_package (self->ostreerepo, hifctx, pkg,
|
||||
if (!import_one_package (self, hifctx, pkg,
|
||||
self->sepolicy, cancellable, error))
|
||||
goto out;
|
||||
hif_state_assert_done (hifstate);
|
||||
|
@ -38,6 +38,10 @@ G_DECLARE_FINAL_TYPE (RpmOstreeInstall, rpmostree_install, RPMOSTREE, INSTALL, G
|
||||
RpmOstreeContext *rpmostree_context_new_system (GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
RpmOstreeContext *rpmostree_context_new_compose (int basedir_dfd,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
RpmOstreeContext *rpmostree_context_new_unprivileged (int basedir_dfd,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
@ -503,15 +503,15 @@ typedef struct
|
||||
} cb_data;
|
||||
|
||||
static OstreeRepoCommitFilterResult
|
||||
filter_cb (OstreeRepo *repo,
|
||||
const char *path,
|
||||
GFileInfo *file_info,
|
||||
gpointer user_data)
|
||||
compose_filter_cb (OstreeRepo *repo,
|
||||
const char *path,
|
||||
GFileInfo *file_info,
|
||||
gpointer user_data)
|
||||
{
|
||||
RpmOstreeUnpacker *self = ((cb_data*)user_data)->self;
|
||||
GError **error = ((cb_data*)user_data)->error;
|
||||
|
||||
/* For now we fail if an RPM requires a file to be owned by non-root. The
|
||||
/* In the system case, fail if an RPM requires a file to be owned by non-root. The
|
||||
* problem is that RPM provides strings, but ostree records uids/gids. Any
|
||||
* mapping we choose would be specific to a certain userdb and thus not
|
||||
* portable. To properly support this will probably require switching over to
|
||||
@ -548,6 +548,23 @@ filter_cb (OstreeRepo *repo,
|
||||
return OSTREE_REPO_COMMIT_FILTER_ALLOW;
|
||||
}
|
||||
|
||||
static OstreeRepoCommitFilterResult
|
||||
unprivileged_filter_cb (OstreeRepo *repo,
|
||||
const char *path,
|
||||
GFileInfo *file_info,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint32 mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
||||
/* Fedora changed the directories to not be writable by root for bad
|
||||
* reasons, which isn't useful here since we expect people to slap a
|
||||
* ro bind mount on top, so let's just mark as writable by user.
|
||||
*/
|
||||
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
|
||||
mode |= S_IWUSR;
|
||||
g_file_info_set_attribute_uint32 (file_info, "unix::mode", mode);
|
||||
return OSTREE_REPO_COMMIT_FILTER_ALLOW;
|
||||
}
|
||||
|
||||
static GVariant*
|
||||
xattr_cb (OstreeRepo *repo,
|
||||
const char *path,
|
||||
@ -596,8 +613,14 @@ import_rpm_to_repo (RpmOstreeUnpacker *self,
|
||||
|
||||
GError *cb_error = NULL;
|
||||
cb_data fdata = { self, &cb_error };
|
||||
OstreeRepoCommitFilter filter;
|
||||
|
||||
modifier = ostree_repo_commit_modifier_new (0, filter_cb, &fdata, NULL);
|
||||
if ((self->flags & RPMOSTREE_UNPACKER_FLAGS_UNPRIVILEGED) > 0)
|
||||
filter = unprivileged_filter_cb;
|
||||
else
|
||||
filter = compose_filter_cb;
|
||||
|
||||
modifier = ostree_repo_commit_modifier_new (0, filter, &fdata, NULL);
|
||||
ostree_repo_commit_modifier_set_xattr_callback (modifier, xattr_cb,
|
||||
NULL, self);
|
||||
ostree_repo_commit_modifier_set_sepolicy (modifier, sepolicy);
|
||||
|
@ -36,9 +36,11 @@ GType rpmostree_unpacker_get_type (void);
|
||||
/**
|
||||
* RpmOstreeUnpackerFlags:
|
||||
* @RPMOSTREE_UNPACKER_FLAGS_OSTREE_CONVENTION: Move files to follow ostree convention
|
||||
* @RPMOSTREE_UNPACKER_FLAGS_UNPRIVILEGED: Ignore file ownership and setuid modes
|
||||
*/
|
||||
typedef enum {
|
||||
RPMOSTREE_UNPACKER_FLAGS_OSTREE_CONVENTION = (1 << 0)
|
||||
RPMOSTREE_UNPACKER_FLAGS_OSTREE_CONVENTION = (1 << 0),
|
||||
RPMOSTREE_UNPACKER_FLAGS_UNPRIVILEGED = (1 << 1)
|
||||
} RpmOstreeUnpackerFlags;
|
||||
|
||||
RpmOstreeUnpacker*
|
||||
|
Loading…
Reference in New Issue
Block a user