Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/ntea.cc89
2 files changed, 65 insertions, 35 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c82b603e9..21ec06169 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,14 @@
+2009-11-18 Corinna Vinschen <corinna@vinschen.de>
+
+ * ntea.cc (read_ea): Try to open file first to have more sensible
+ error codes. Always refuse non "user." EAs for Linux compatibility
+ and return EOPNOTSUPP. Fix handling of empty (== non-existant) EAs.
+ Always prepend "user." prefix to EA names.
+ (write_ea): Try to open file first to have more sensible error codes.
+ Always refuse non "user." EAs for Linux compatibility and return
+ EOPNOTSUPP. Delay skipping "user." prefix until after potential call
+ to read_ea.
+
2009-11-17 Corinna Vinschen <corinna@vinschen.de>
Reintegrate socket duplication via WSADuplicateSocket/WSASocket.
diff --git a/winsup/cygwin/ntea.cc b/winsup/cygwin/ntea.cc
index 744076ef7..7e3240abc 100644
--- a/winsup/cygwin/ntea.cc
+++ b/winsup/cygwin/ntea.cc
@@ -56,22 +56,34 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
debug_printf ("read_ea (%S, %s, %p, %lu)",
attr.ObjectName, name, value, size);
+ /* Early open if handle is NULL. This allows to return error codes like
+ ENOENT before we actually check for the correctness of the EA name and
+ stuff like that. */
+ if (!hdl)
+ {
+ status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
+ FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
+ if (!NT_SUCCESS (status))
+ {
+ __seterrno_from_nt_status (status);
+ goto out;
+ }
+ hdl = NULL;
+ }
+
fea = (PFILE_FULL_EA_INFORMATION) alloca (EA_BUFSIZ);
if (name)
{
size_t nlen;
- /* Samba hides the user namespace from Windows clients. If we try to
- retrieve a user namespace item, we remove the leading namespace from
- the name, otherwise the search fails. */
- if (!pc.fs_is_samba ())
- /* nothing to do */;
- else if (ascii_strncasematch (name, "user.", 5))
+ /* For compatibility with Linux, we only allow user xattrs and
+ return EOPNOTSUPP otherwise. */
+ if (ascii_strncasematch (name, "user.", 5))
name += 5;
else
{
- set_errno (ENOATTR);
+ set_errno (EOPNOTSUPP);
goto out;
}
@@ -117,6 +129,16 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
}
if (name)
{
+ /* Another weird behaviour of ZwQueryEaFile. If you ask for a
+ specific EA which is not present in the file's EA list, you don't
+ get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
+ ZwQueryEaFile returns success with the entry's EaValueLength
+ set to 0. */
+ if (!fea->EaValueLength)
+ {
+ set_errno (ENOATTR);
+ goto out;
+ }
if (size > 0)
{
if (size < fea->EaValueLength)
@@ -124,19 +146,8 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
set_errno (ERANGE);
goto out;
}
- /* Another weird behaviour of ZwQueryEaFile. If you ask for a
- specific EA which is not present in the file's EA list, you don't
- get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
- ZwQueryEaFile returns success with the entry's EaValueLength
- set to 0. */
- if (!fea->EaValueLength)
- {
- set_errno (ENOATTR);
- goto out;
- }
- else
- memcpy (value, fea->EaName + fea->EaNameLength + 1,
- fea->EaValueLength);
+ memcpy (value, fea->EaName + fea->EaNameLength + 1,
+ fea->EaValueLength);
}
ret = fea->EaValueLength;
}
@@ -158,8 +169,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
it in EA listings to keep tools like attr/getfattr/setfattr
happy. */
char tmpbuf[MAX_EA_NAME_LEN * 2], *tp = tmpbuf;
- if (pc.fs_is_samba ())
- tp = stpcpy (tmpbuf, "user.");
+ tp = stpcpy (tmpbuf, "user.");
stpcpy (tp, fea->EaName);
/* NTFS stores all EA names in uppercase unfortunately. To keep
compatibility with ext/xfs EA namespaces and accompanying
@@ -210,20 +220,26 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
attr.ObjectName, name, value, size, flags);
- /* Samba hides the user namespace from Windows clients. If we get a
- user namespace item, we remove the leading namespace from the name.
- This keeps tools like attr/getfattr/setfattr happy. Otherwise
- setting the EA fails as if we don't have the permissions. */
- /* Samba hides the user namespace from Windows clients. If we try to
- retrieve a user namespace item, we remove the leading namespace from
- the name, otherwise the search fails. */
- if (!pc.fs_is_samba ())
- /* nothing to do */;
- else if (ascii_strncasematch (name, "user.", 5))
- name += 5;
- else
+ /* Early open if handle is NULL. This allows to return error codes like
+ ENOENT before we actually check for the correctness of the EA name and
+ stuff like that. */
+ if (!hdl)
+ {
+ status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
+ FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
+ if (!NT_SUCCESS (status))
+ {
+ __seterrno_from_nt_status (status);
+ goto out;
+ }
+ hdl = NULL;
+ }
+
+ /* For compatibility with Linux, we only allow user xattrs and
+ return EOPNOTSUPP otherwise. */
+ if (!ascii_strncasematch (name, "user.", 5))
{
- set_errno (ENOATTR);
+ set_errno (EOPNOTSUPP);
goto out;
}
@@ -249,6 +265,9 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
goto out;
}
+ /* Skip "user." prefix. */
+ name += 5;
+
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
{
set_errno (EINVAL);