Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Allan McRae
a60bbf1a45 Do not chown downloads when DownloadUser is unset
On NFS caches, using chown to change file permissions to the UID 0 user
will fail due to root_squash.  When DownloadUser is unset, or set to
the UID 0 user (root), avoid the unneeded chown calls providing a
workaround.

Fixes #194

Signed-off-by: Allan McRae <allan@archlinux.org>
2025-05-09 09:08:09 +10:00

View file

@ -73,17 +73,21 @@ static mode_t _getumask(void)
return mask;
}
static int finalize_download_file(const char *filename)
static int finalize_download_file(const char *filename, const char *user)
{
struct stat st;
uid_t myuid = getuid();
struct passwd const *pw = NULL;
ASSERT(filename != NULL, return -1);
ASSERT(stat(filename, &st) == 0, return -1);
ASSERT((pw = getpwuid(0)) != NULL, return -1);
if(st.st_size == 0) {
unlink(filename);
return 1;
}
if(myuid == 0) {
if(myuid == 0 && strcmp(user, pw->pw_name) != 0) {
ASSERT(chown(filename, 0, 0) != -1, return -1);
}
ASSERT(chmod(filename, ~(_getumask()) & 0666) != -1, return -1);
@ -1080,11 +1084,11 @@ static int payload_download_fetchcb(struct dload_payload *payload,
return ret;
}
static int move_file(const char *filepath, const char *directory)
static int move_file(const char *filepath, const char *directory, const char *user)
{
ASSERT(filepath != NULL, return -1);
ASSERT(directory != NULL, return -1);
int ret = finalize_download_file(filepath);
int ret = finalize_download_file(filepath, user);
if(ret != 0) {
return ret;
}
@ -1098,7 +1102,7 @@ static int move_file(const char *filepath, const char *directory)
return 0;
}
static int finalize_download_locations(alpm_list_t *payloads, const char *localpath)
static int finalize_download_locations(alpm_list_t *payloads, const char *localpath, const char *user)
{
ASSERT(payloads != NULL, return -1);
ASSERT(localpath != NULL, return -1);
@ -1107,10 +1111,10 @@ static int finalize_download_locations(alpm_list_t *payloads, const char *localp
for(p = payloads; p; p = p->next) {
struct dload_payload *payload = p->data;
if(payload->tempfile_name) {
move_file(payload->tempfile_name, localpath);
move_file(payload->tempfile_name, localpath, user);
}
if(payload->destfile_name) {
int ret = move_file(payload->destfile_name, localpath);
int ret = move_file(payload->destfile_name, localpath, user);
if(ret == -1) {
/* ignore error if the file already existed - only signature file was downloaded */
@ -1127,7 +1131,7 @@ static int finalize_download_locations(alpm_list_t *payloads, const char *localp
size_t sig_filename_len = strlen(payload->destfile_name) + sizeof(sig_suffix);
MALLOC(sig_filename, sig_filename_len, continue);
snprintf(sig_filename, sig_filename_len, "%s%s", payload->destfile_name, sig_suffix);
move_file(sig_filename, localpath);
move_file(sig_filename, localpath, user);
FREE(sig_filename);
}
}
@ -1170,7 +1174,7 @@ static void prepare_resumable_downloads(alpm_list_t *payloads, const char *local
FREE(src);
continue;
}
if(pw != NULL) {
if(pw != NULL && pw->pw_uid != 0) {
ASSERT(chown(payload->tempfile_name, pw->pw_uid, pw->pw_gid), return);
}
FREE(src);
@ -1267,7 +1271,7 @@ download_signature:
ret = updated ? 0 : 1;
}
if (finalize_download_locations(payloads, localpath) != 0 && ret == 0) {
if (finalize_download_locations(payloads, localpath, handle->sandboxuser) != 0 && ret == 0) {
RET_ERR(handle, ALPM_ERR_RETRIEVE, -1);
}
return ret;