diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index acb8e16d..efbff120 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -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); @@ -1078,11 +1082,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; } @@ -1096,7 +1100,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); @@ -1105,10 +1109,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 */ @@ -1125,7 +1129,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); } } @@ -1168,7 +1172,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); @@ -1265,7 +1269,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;