]> sourceware.org Git - newlib-cygwin.git/commitdiff
* ntea.cc (read_ea): Try to open file first to have more sensible
authorCorinna Vinschen <corinna@vinschen.de>
Wed, 18 Nov 2009 11:57:41 +0000 (11:57 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Wed, 18 Nov 2009 11:57:41 +0000 (11:57 +0000)
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.

winsup/cygwin/ChangeLog
winsup/cygwin/ntea.cc

index c82b603e9c0133ec87c5ae21954bf283e260ef79..21ec0616901a7dc42470769720170bc71a5bc2e4 100644 (file)
@@ -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.
index 744076ef7a4e2b2294e078f9410e7ede34123779..7e3240abc3f6647cc62fe9cb6f226c699da83773 100644 (file)
@@ -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);
This page took 0.0337 seconds and 5 git commands to generate.