mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
Handle MLS selinux policy better
Following the behaviour of ls here, we should return at least the file name, if we can't get any other information about a file. To do this, handle EACCESS on stat() calls. Patch by Tomas Bzatek, see bug 623692
This commit is contained in:
parent
1e8656fe24
commit
71e7b5800a
@ -1215,19 +1215,19 @@ get_content_type (const char *basename,
|
||||
{
|
||||
if (is_symlink &&
|
||||
(symlink_broken || (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)))
|
||||
return g_strdup ("inode/symlink");
|
||||
else if (S_ISDIR(statbuf->st_mode))
|
||||
return g_strdup ("inode/symlink");
|
||||
else if (statbuf != NULL && S_ISDIR(statbuf->st_mode))
|
||||
return g_strdup ("inode/directory");
|
||||
#ifndef G_OS_WIN32
|
||||
else if (S_ISCHR(statbuf->st_mode))
|
||||
else if (statbuf != NULL && S_ISCHR(statbuf->st_mode))
|
||||
return g_strdup ("inode/chardevice");
|
||||
else if (S_ISBLK(statbuf->st_mode))
|
||||
else if (statbuf != NULL && S_ISBLK(statbuf->st_mode))
|
||||
return g_strdup ("inode/blockdevice");
|
||||
else if (S_ISFIFO(statbuf->st_mode))
|
||||
else if (statbuf != NULL && S_ISFIFO(statbuf->st_mode))
|
||||
return g_strdup ("inode/fifo");
|
||||
#endif
|
||||
#ifdef S_ISSOCK
|
||||
else if (S_ISSOCK(statbuf->st_mode))
|
||||
else if (statbuf != NULL && S_ISSOCK(statbuf->st_mode))
|
||||
return g_strdup ("inode/socket");
|
||||
#endif
|
||||
else
|
||||
@ -1421,6 +1421,7 @@ _g_local_file_info_get (const char *basename,
|
||||
struct stat statbuf2;
|
||||
#endif
|
||||
int res;
|
||||
gboolean stat_ok;
|
||||
gboolean is_symlink, symlink_broken;
|
||||
#ifdef G_OS_WIN32
|
||||
DWORD dos_attributes;
|
||||
@ -1471,20 +1472,31 @@ _g_local_file_info_get (const char *basename,
|
||||
if (res == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
char *display_name = g_filename_display_name (path);
|
||||
g_object_unref (info);
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error stating file '%s': %s"),
|
||||
display_name, g_strerror (errsv));
|
||||
g_free (display_name);
|
||||
return NULL;
|
||||
|
||||
/* Don't bail out if we get Permission denied (SELinux?) */
|
||||
if (errsv != EACCES)
|
||||
{
|
||||
char *display_name = g_filename_display_name (path);
|
||||
g_object_unref (info);
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
_("Error stating file '%s': %s"),
|
||||
display_name, g_strerror (errsv));
|
||||
g_free (display_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
device = statbuf.st_dev;
|
||||
/* Even if stat() fails, try to get as much as other attributes possible */
|
||||
stat_ok = res != -1;
|
||||
|
||||
if (stat_ok)
|
||||
device = statbuf.st_dev;
|
||||
else
|
||||
device = 0;
|
||||
|
||||
#ifdef S_ISLNK
|
||||
is_symlink = S_ISLNK (statbuf.st_mode);
|
||||
is_symlink = stat_ok && S_ISLNK (statbuf.st_mode);
|
||||
#else
|
||||
is_symlink = FALSE;
|
||||
#endif
|
||||
@ -1499,23 +1511,27 @@ _g_local_file_info_get (const char *basename,
|
||||
{
|
||||
res = stat (path, &statbuf2);
|
||||
|
||||
/* Report broken links as symlinks */
|
||||
/* Report broken links as symlinks */
|
||||
if (res != -1)
|
||||
statbuf = statbuf2;
|
||||
{
|
||||
statbuf = statbuf2;
|
||||
stat_ok = TRUE;
|
||||
}
|
||||
else
|
||||
symlink_broken = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
set_info_from_stat (info, &statbuf, attribute_matcher);
|
||||
|
||||
if (stat_ok)
|
||||
set_info_from_stat (info, &statbuf, attribute_matcher);
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
if (basename != NULL && basename[0] == '.')
|
||||
g_file_info_set_is_hidden (info, TRUE);
|
||||
|
||||
if (basename != NULL && basename[strlen (basename) -1] == '~' &&
|
||||
S_ISREG (statbuf.st_mode))
|
||||
(stat_ok && S_ISREG (statbuf.st_mode)))
|
||||
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_IS_BACKUP, TRUE);
|
||||
#else
|
||||
if (dos_attributes & FILE_ATTRIBUTE_HIDDEN)
|
||||
@ -1578,7 +1594,7 @@ _g_local_file_info_get (const char *basename,
|
||||
_g_file_attribute_matcher_matches_id (attribute_matcher,
|
||||
G_FILE_ATTRIBUTE_ID_STANDARD_ICON))
|
||||
{
|
||||
char *content_type = get_content_type (basename, path, &statbuf, is_symlink, symlink_broken, flags, FALSE);
|
||||
char *content_type = get_content_type (basename, path, stat_ok ? &statbuf : NULL, is_symlink, symlink_broken, flags, FALSE);
|
||||
|
||||
if (content_type)
|
||||
{
|
||||
@ -1635,7 +1651,7 @@ _g_local_file_info_get (const char *basename,
|
||||
if (_g_file_attribute_matcher_matches_id (attribute_matcher,
|
||||
G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE))
|
||||
{
|
||||
char *content_type = get_content_type (basename, path, &statbuf, is_symlink, symlink_broken, flags, TRUE);
|
||||
char *content_type = get_content_type (basename, path, stat_ok ? &statbuf : NULL, is_symlink, symlink_broken, flags, TRUE);
|
||||
|
||||
if (content_type)
|
||||
{
|
||||
@ -1652,7 +1668,8 @@ _g_local_file_info_get (const char *basename,
|
||||
#ifdef G_OS_WIN32
|
||||
win32_get_file_user_info (path, NULL, &name, NULL);
|
||||
#else
|
||||
name = get_username_from_uid (statbuf.st_uid);
|
||||
if (stat_ok)
|
||||
name = get_username_from_uid (statbuf.st_uid);
|
||||
#endif
|
||||
if (name)
|
||||
_g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_OWNER_USER, name);
|
||||
@ -1666,7 +1683,8 @@ _g_local_file_info_get (const char *basename,
|
||||
#ifdef G_OS_WIN32
|
||||
win32_get_file_user_info (path, NULL, NULL, &name);
|
||||
#else
|
||||
name = get_realname_from_uid (statbuf.st_uid);
|
||||
if (stat_ok)
|
||||
name = get_realname_from_uid (statbuf.st_uid);
|
||||
#endif
|
||||
if (name)
|
||||
_g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_OWNER_USER_REAL, name);
|
||||
@ -1680,19 +1698,21 @@ _g_local_file_info_get (const char *basename,
|
||||
#ifdef G_OS_WIN32
|
||||
win32_get_file_user_info (path, &name, NULL, NULL);
|
||||
#else
|
||||
name = get_groupname_from_gid (statbuf.st_gid);
|
||||
if (stat_ok)
|
||||
name = get_groupname_from_gid (statbuf.st_gid);
|
||||
#endif
|
||||
if (name)
|
||||
_g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_OWNER_GROUP, name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
if (parent_info && parent_info->device != 0 &&
|
||||
if (stat_ok && parent_info && parent_info->device != 0 &&
|
||||
_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT) &&
|
||||
statbuf.st_dev != parent_info->device)
|
||||
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT, TRUE);
|
||||
|
||||
get_access_rights (attribute_matcher, info, path, &statbuf, parent_info);
|
||||
if (stat_ok)
|
||||
get_access_rights (attribute_matcher, info, path, &statbuf, parent_info);
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
get_selinux_context (path, info, attribute_matcher, (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user