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>
This commit is contained in:
parent
692f7a2cfe
commit
a60bbf1a45
1 changed files with 14 additions and 10 deletions
|
@ -73,17 +73,21 @@ static mode_t _getumask(void)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int finalize_download_file(const char *filename)
|
static int finalize_download_file(const char *filename, const char *user)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
uid_t myuid = getuid();
|
uid_t myuid = getuid();
|
||||||
|
struct passwd const *pw = NULL;
|
||||||
|
|
||||||
ASSERT(filename != NULL, return -1);
|
ASSERT(filename != NULL, return -1);
|
||||||
ASSERT(stat(filename, &st) == 0, return -1);
|
ASSERT(stat(filename, &st) == 0, return -1);
|
||||||
|
ASSERT((pw = getpwuid(0)) != NULL, return -1);
|
||||||
|
|
||||||
if(st.st_size == 0) {
|
if(st.st_size == 0) {
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(myuid == 0) {
|
if(myuid == 0 && strcmp(user, pw->pw_name) != 0) {
|
||||||
ASSERT(chown(filename, 0, 0) != -1, return -1);
|
ASSERT(chown(filename, 0, 0) != -1, return -1);
|
||||||
}
|
}
|
||||||
ASSERT(chmod(filename, ~(_getumask()) & 0666) != -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;
|
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(filepath != NULL, return -1);
|
||||||
ASSERT(directory != NULL, return -1);
|
ASSERT(directory != NULL, return -1);
|
||||||
int ret = finalize_download_file(filepath);
|
int ret = finalize_download_file(filepath, user);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +1102,7 @@ static int move_file(const char *filepath, const char *directory)
|
||||||
return 0;
|
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(payloads != NULL, return -1);
|
||||||
ASSERT(localpath != 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) {
|
for(p = payloads; p; p = p->next) {
|
||||||
struct dload_payload *payload = p->data;
|
struct dload_payload *payload = p->data;
|
||||||
if(payload->tempfile_name) {
|
if(payload->tempfile_name) {
|
||||||
move_file(payload->tempfile_name, localpath);
|
move_file(payload->tempfile_name, localpath, user);
|
||||||
}
|
}
|
||||||
if(payload->destfile_name) {
|
if(payload->destfile_name) {
|
||||||
int ret = move_file(payload->destfile_name, localpath);
|
int ret = move_file(payload->destfile_name, localpath, user);
|
||||||
|
|
||||||
if(ret == -1) {
|
if(ret == -1) {
|
||||||
/* ignore error if the file already existed - only signature file was downloaded */
|
/* 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);
|
size_t sig_filename_len = strlen(payload->destfile_name) + sizeof(sig_suffix);
|
||||||
MALLOC(sig_filename, sig_filename_len, continue);
|
MALLOC(sig_filename, sig_filename_len, continue);
|
||||||
snprintf(sig_filename, sig_filename_len, "%s%s", payload->destfile_name, sig_suffix);
|
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);
|
FREE(sig_filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1170,7 +1174,7 @@ static void prepare_resumable_downloads(alpm_list_t *payloads, const char *local
|
||||||
FREE(src);
|
FREE(src);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(pw != NULL) {
|
if(pw != NULL && pw->pw_uid != 0) {
|
||||||
ASSERT(chown(payload->tempfile_name, pw->pw_uid, pw->pw_gid), return);
|
ASSERT(chown(payload->tempfile_name, pw->pw_uid, pw->pw_gid), return);
|
||||||
}
|
}
|
||||||
FREE(src);
|
FREE(src);
|
||||||
|
@ -1267,7 +1271,7 @@ download_signature:
|
||||||
ret = updated ? 0 : 1;
|
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);
|
RET_ERR(handle, ALPM_ERR_RETRIEVE, -1);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Reference in a new issue