Set file owner to calling user

This fixes cache problems when running programs utilizing efreet with
sudo.

SVN revision: 56787
This commit is contained in:
Sebastian Dransfeld 2011-02-07 21:33:33 +00:00
parent 886a338b94
commit c49d6dd5c4
7 changed files with 81 additions and 3 deletions

View File

@ -54,3 +54,4 @@
* Don't create cache dir several times
* Do efreet_init before using efreet_*() functions
* Move lock creation to own function for desktop cache
* Set file owner to calling user

View File

@ -198,6 +198,7 @@ cache_lock_file(void)
snprintf(file, sizeof(file), "%s/efreet/desktop_data.lock", efreet_cache_home_get());
lockfd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (lockfd < 0) return -1;
efreet_fsetowner(lockfd);
memset(&fl, 0, sizeof(struct flock));
fl.l_type = F_WRLCK;
@ -258,7 +259,11 @@ main(int argc, char **argv)
/* create homedir */
snprintf(file, sizeof(file), "%s/efreet", efreet_cache_home_get());
if (!ecore_file_mkpath(file)) goto efreet_error;
if (!ecore_file_exists(file))
{
if (!ecore_file_mkpath(file)) goto efreet_error;
efreet_setowner(file);
}
/* lock process, so that we only run one copy of this program */
lockfd = cache_lock_file();
@ -350,6 +355,7 @@ main(int argc, char **argv)
{
dirsfd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
if (dirsfd < 0) goto error;
efreet_fsetowner(dirsfd);
EINA_LIST_FREE(user_dirs, dir)
{
unsigned int size = strlen(dir) + 1;
@ -428,7 +434,9 @@ main(int argc, char **argv)
}
/* cleanup */
eet_sync(util_ef);
eet_close(util_ef);
eet_sync(ef);
eet_close(ef);
/* unlink old cache files */
@ -444,7 +452,9 @@ main(int argc, char **argv)
}
/* rename tmp files to real files */
if (rename(util_file, efreet_desktop_util_cache_file()) < 0) goto error;
efreet_setowner(efreet_desktop_util_cache_file());
if (rename(file, efreet_desktop_cache_file()) < 0) goto error;
efreet_setowner(efreet_desktop_cache_file());
}
else
{
@ -458,6 +468,7 @@ main(int argc, char **argv)
tmpfd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
if (tmpfd >= 0)
{
efreet_fsetowner(tmpfd);
if (write(tmpfd, "a", 1) != 1) perror("write");
close(tmpfd);
}

View File

@ -617,6 +617,7 @@ cache_lock_file(void)
snprintf(file, sizeof(file), "%s/efreet/icon_data.lock", efreet_cache_home_get());
lockfd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (lockfd < 0) return -1;
efreet_fsetowner(lockfd);
memset(&fl, 0, sizeof(struct flock));
fl.l_type = F_WRLCK;
@ -724,7 +725,11 @@ main(int argc, char **argv)
/* create homedir */
snprintf(file, sizeof(file), "%s/efreet", efreet_cache_home_get());
if (!ecore_file_mkpath(file)) goto on_error;
if (!ecore_file_exists(file))
{
if (!ecore_file_mkpath(file)) return -1;
efreet_setowner(file);
}
/* lock process, so that we only run one copy of this program */
lockfd = cache_lock_file();
@ -883,7 +888,9 @@ main(int argc, char **argv)
}
eet_data_write(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION, icon_version, 1);
eet_sync(icon_ef);
eet_close(icon_ef);
efreet_setowner(efreet_icon_cache_file(theme->theme.name.internal));
free(icon_version);
}
eina_iterator_free(it);
@ -958,14 +965,18 @@ main(int argc, char **argv)
icon_theme_free(theme);
eet_data_write(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION, icon_version, 1);
eet_sync(icon_ef);
eet_close(icon_ef);
efreet_setowner(efreet_icon_cache_file(EFREET_CACHE_ICON_FALLBACK));
free(icon_version);
eina_hash_free(icon_themes);
/* save data */
eet_data_write(theme_ef, efreet_version_edd(), EFREET_CACHE_VERSION, theme_version, 1);
eet_sync(theme_ef);
eet_close(theme_ef);
efreet_setowner(efreet_icon_theme_cache_file());
free(theme_version);
/* touch update file */
@ -973,6 +984,7 @@ main(int argc, char **argv)
tmpfd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
if (tmpfd >= 0)
{
efreet_fsetowner(tmpfd);
write(tmpfd, "a", 1);
close(tmpfd);
}

View File

@ -24,6 +24,9 @@ void *alloca (size_t);
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <Eet.h>
#include <Ecore.h>
@ -49,6 +52,9 @@ static const char *efreet_lang_modifier = NULL;
static void efreet_parse_locale(void);
static int efreet_parse_locale_setting(const char *env);
static uid_t ruid;
static uid_t rgid;
/**
* @return Returns > 0 if the initialization was successful, 0 otherwise
* @brief Initializes the Efreet system
@ -56,9 +62,24 @@ static int efreet_parse_locale_setting(const char *env);
EAPI int
efreet_init(void)
{
char *tmp;
if (++_efreet_init_count != 1)
return _efreet_init_count;
/* Find users real uid and gid */
tmp = getenv("SUDO_UID");
if (tmp)
ruid = strtoul(tmp, NULL, 10);
else
ruid = getuid();
tmp = getenv("SUDO_GID");
if (tmp)
rgid = strtoul(tmp, NULL, 10);
else
rgid = getgid();
if (!eina_init())
return --_efreet_init_count;
if (!eet_init())
@ -289,3 +310,26 @@ efreet_array_cat(char *buffer, size_t size, const char *strs[])
}
return n;
}
EAPI void
efreet_fsetowner(int fd)
{
struct stat st;
if (fd < 0) return;
if (fstat(fd, &st) < 0) return;
if (st.st_uid == ruid) return;
fchown(fd, ruid, rgid);
}
EAPI void
efreet_setowner(const char *path)
{
int fd;
fd = open(path, O_RDONLY);
if (fd < 0) return;
efreet_fsetowner(fd);
close(fd);
}

View File

@ -110,7 +110,11 @@ efreet_cache_init(void)
fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
if (!ecore_file_mkpath(buf)) goto error;
if (!ecore_file_exists(buf))
{
if (!ecore_file_mkpath(buf)) goto error;
efreet_setowner(buf);
}
if (efreet_cache_update)
{
@ -899,6 +903,7 @@ desktop_cache_update_cache_job(void *data __UNUSED__)
desktop_cache_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (desktop_cache_exe_lock < 0) return;
efreet_fsetowner(desktop_cache_exe_lock);
memset(&fl, 0, sizeof(struct flock));
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
@ -936,6 +941,7 @@ icon_cache_update_cache_job(void *data __UNUSED__)
icon_cache_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (icon_cache_exe_lock < 0) return;
efreet_fsetowner(icon_cache_exe_lock);
memset(&fl, 0, sizeof(struct flock));
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;

View File

@ -792,6 +792,7 @@ efreet_desktop_write_cache_dirs_file(void)
snprintf(file, sizeof(file), "%s/desktop_data.lock", efreet_cache_home_get());
fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) return 0;
efreet_fsetowner(fd);
/* TODO: Retry update cache later */
memset(&fl, 0, sizeof(struct flock));
fl.l_type = F_WRLCK;
@ -800,6 +801,7 @@ efreet_desktop_write_cache_dirs_file(void)
cachefd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR);
if (cachefd < 0) goto error;
efreet_fsetowner(cachefd);
if (fstat(cachefd, &st) < 0) goto error;
if (st.st_size > 0)
{

View File

@ -224,6 +224,8 @@ char **efreet_cache_icon_theme_name_list(int *num);
EAPI void efreet_cache_array_string_free(Efreet_Cache_Array_String *array);
EAPI void efreet_hash_free(Eina_Hash *hash, Eina_Free_Cb free_cb);
EAPI void efreet_setowner(const char *path);
EAPI void efreet_fsetowner(int fd);
#define NON_EXISTING (void *)-1