summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Gustafsson <fredrigu@axis.com>2019-11-20 11:48:48 +0100
committerTimo Teräs <timo.teras@iki.fi>2020-04-28 14:48:49 +0300
commitd61c009f7a7ba9c99797855d8cd4e0a503c2fda5 (patch)
tree891bff6bb4146e17ec94dbfbdcb909e048a0fb09
parentb67df9843dbdad15cb794fa26a7c216a14453690 (diff)
downloadapk-tools-d61c009f7a7ba9c99797855d8cd4e0a503c2fda5.tar.gz
apk-tools-d61c009f7a7ba9c99797855d8cd4e0a503c2fda5.tar.bz2
apk-tools-d61c009f7a7ba9c99797855d8cd4e0a503c2fda5.tar.xz
apk-tools-d61c009f7a7ba9c99797855d8cd4e0a503c2fda5.zip
apk: do not manage file ownership as non-root or when asked so
If apk is run as a non-root user, it's not possible to chown files. Maintainers note: minor wording changes on commit log and man page. Signed-off-by: Fredrik Gustafsson <fredrigu@axis.com>
-rw-r--r--doc/apk-add.8.scd6
-rw-r--r--src/apk_archive.h5
-rw-r--r--src/apk_database.h1
-rw-r--r--src/app_add.c8
-rw-r--r--src/database.c6
-rw-r--r--src/io_archive.c29
6 files changed, 40 insertions, 15 deletions
diff --git a/doc/apk-add.8.scd b/doc/apk-add.8.scd
index f7b52bd..7959a99 100644
--- a/doc/apk-add.8.scd
+++ b/doc/apk-add.8.scd
@@ -39,6 +39,12 @@ following options:
virtual package, and by deleting that package the *apk add* operation
may be easily reverted later.
+*--no-chown*
+ Do not change file owner or group. By default apk will manage the file
+ ownership when running as root. However, this option is turned on when
+ running as non-root user, as changing file ownership is not permitted
+ by the system then.
+
# AUTHORS
Natanael Copa <ncopa@alpinelinux.org>++
diff --git a/src/apk_archive.h b/src/apk_archive.h
index bb16c48..bd24733 100644
--- a/src/apk_archive.h
+++ b/src/apk_archive.h
@@ -16,6 +16,8 @@
#include "apk_blob.h"
#include "apk_io.h"
+#define APK_EXTRACTF_NO_CHOWN 0x0001
+
typedef int (*apk_archive_entry_parser)(void *ctx,
const struct apk_file_info *ae,
struct apk_istream *istream);
@@ -30,6 +32,7 @@ int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae);
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *extract_name, const char *hardlink_name,
struct apk_istream *is,
- apk_progress_cb cb, void *cb_ctx);
+ apk_progress_cb cb, void *cb_ctx,
+ unsigned int extract_flags);
#endif
diff --git a/src/apk_database.h b/src/apk_database.h
index 30684c3..bcd5719 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -155,6 +155,7 @@ struct apk_database {
unsigned int local_repos, available_repos, cache_max_age;
unsigned int repo_update_errors, repo_update_counter;
unsigned int pending_triggers;
+ unsigned int extract_flags;
int performing_self_upgrade : 1;
int permanent : 1;
int autoupdate : 1;
diff --git a/src/app_add.c b/src/app_add.c
index 8b0ed1a..f5edae0 100644
--- a/src/app_add.c
+++ b/src/app_add.c
@@ -20,6 +20,7 @@
struct add_ctx {
const char *virtpkg;
unsigned short solver_flags;
+ unsigned short extract_flags;
};
static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int optch, const char *optarg)
@@ -30,6 +31,9 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt
case 0x10000:
dbopts->open_flags |= APK_OPENF_CREATE;
break;
+ case 0x10001:
+ actx->extract_flags |= APK_EXTRACTF_NO_CHOWN;
+ break;
case 'u':
actx->solver_flags |= APK_SOLVERF_UPGRADE;
break;
@@ -47,6 +51,7 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt
static const struct apk_option options_applet[] = {
{ 0x10000, "initdb" },
+ { 0x10001, "no-chown" },
{ 'u', "upgrade" },
{ 'l', "latest" },
{ 't', "virtual", required_argument, "NAME" },
@@ -118,6 +123,9 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array
apk_dependency_array_copy(&world, db->world);
+ if (getuid() != 0 || (actx->extract_flags & APK_EXTRACTF_NO_CHOWN))
+ db->extract_flags |= APK_EXTRACTF_NO_CHOWN;
+
if (actx->virtpkg) {
apk_blob_t b = APK_BLOB_STR(actx->virtpkg);
apk_blob_pull_dep(&b, db, &virtdep);
diff --git a/src/database.c b/src/database.c
index cbc6667..dd27e2a 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1347,6 +1347,10 @@ static int apk_db_create(struct apk_database *db)
if (fd < 0)
return -errno;
close(fd);
+ fd = openat(db->root_fd, apk_installed_file, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0644);
+ if (fd < 0)
+ return -errno;
+ close(fd);
return 0;
}
@@ -2554,7 +2558,7 @@ static int apk_db_install_archive_entry(void *_ctx,
db->root_fd, ae,
format_tmpname(pkg, file, tmpname_file),
format_tmpname(pkg, link_target_file, tmpname_link_target),
- is, extract_cb, ctx);
+ is, extract_cb, ctx, db->extract_flags);
switch (r) {
case 0:
diff --git a/src/io_archive.c b/src/io_archive.c
index 22145ab..1d34927 100644
--- a/src/io_archive.c
+++ b/src/io_archive.c
@@ -337,7 +337,8 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *extract_name, const char *link_target,
struct apk_istream *is,
- apk_progress_cb cb, void *cb_ctx)
+ apk_progress_cb cb, void *cb_ctx,
+ unsigned int apk_extract_flags)
{
struct apk_xattr *xattr;
const char *fn = extract_name ?: ae->name;
@@ -385,22 +386,24 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
return ret;
}
- r = fchownat(atfd, fn, ae->uid, ae->gid, atflags);
- if (r < 0) {
- apk_error("Failed to set ownership on %s: %s",
- fn, strerror(errno));
- if (!ret) ret = -errno;
- }
-
- /* chown resets suid bit so we need set it again */
- if (ae->mode & 07000) {
- r = fchmodat(atfd, fn, ae->mode & 07777, atflags);
+ if (!(apk_extract_flags & APK_EXTRACTF_NO_CHOWN)) {
+ r = fchownat(atfd, fn, ae->uid, ae->gid, atflags);
if (r < 0) {
- apk_error("Failed to set file permissions "
- "on %s: %s",
+ apk_error("Failed to set ownership on %s: %s",
fn, strerror(errno));
if (!ret) ret = -errno;
}
+
+ /* chown resets suid bit so we need set it again */
+ if (ae->mode & 07000) {
+ r = fchmodat(atfd, fn, ae->mode & 07777, atflags);
+ if (r < 0) {
+ apk_error("Failed to set file permissions "
+ "on %s: %s",
+ fn, strerror(errno));
+ if (!ret) ret = -errno;
+ }
+ }
}
/* extract xattrs */