]> arthur.barton.de Git - netatalk.git/commitdiff
Ignore EAs on symlinks
authorFrank Lahm <franklahm@googlemail.com>
Tue, 6 Mar 2012 14:16:01 +0000 (15:16 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Tue, 6 Mar 2012 14:16:01 +0000 (15:16 +0100)
libatalk/adouble/ad_open.c
libatalk/vfs/ea_sys.c
libatalk/vfs/extattr.c

index 94549cd81769092d2a11aa40d5651ec5b8104384..d4e84fd21ce21c0b3cfc9bc2b5bbb6f1c3ab64dd 100644 (file)
@@ -1333,7 +1333,7 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble
         goto EC_CLEANUP;
     }
 #ifdef HAVE_EAFD
-    if (ad_meta_fileno(ad) == -1)
+    if (ad_meta_fileno(ad) < 0)
         EC_FAIL;
     if ((ad_reso_fileno(ad) = sys_getxattrfd(ad_meta_fileno(ad), AD_EA_RESO, oflags)) == -1) {
         if (!(adflags & ADFLAGS_CREATE)) {
index fc6a4044ae2b9e8d93dc74b8835e00d60eb60084..549aa6d11c24f6d03e63f4be6d7f87ab2b8f402f 100644 (file)
@@ -81,8 +81,8 @@ int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE)
         switch(errno) {
         case OPEN_NOFOLLOW_ERRNO:
             /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "sys_getextattr_size(%s): encountered symlink with kXAttrNoFollow", uname);
-            return AFP_OK;
+            LOG(log_debug, logtype_afpd, "sys_getextattr_size(%s): symlink with kXAttrNoFollow", uname);
+            return AFPERR_MISC;
 
         case ENOATTR:
         case ENOENT:
@@ -157,8 +157,8 @@ int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT)
         switch(errno) {
         case OPEN_NOFOLLOW_ERRNO:
             /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): encountered symlink with kXAttrNoFollow", uname);
-            return AFP_OK;
+            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): symlink with kXAttrNoFollow", uname);
+            return AFPERR_MISC;
 
         case ENOATTR:
             return AFPERR_MISC;
@@ -220,18 +220,13 @@ int sys_list_eas(VFS_FUNC_ARGS_EA_LIST)
 
     if (ret == -1) switch(errno) {
         case OPEN_NOFOLLOW_ERRNO:
-            /* its a symlink and client requested O_NOFOLLOW */
-            ret = AFPERR_BADTYPE;
-            goto exit;
-#ifdef HAVE_ATTROPEN            /* Solaris */
-        case ENOATTR:
-        case ENOENT:
+            /* its a symlink and client requested O_NOFOLLOW, we pretend 0 EAs */
+            LOG(log_debug, logtype_afpd, "sys_list_extattr(%s): symlink with kXAttrNoFollow", uname);
             ret = AFP_OK;
             goto exit;
-#endif
         default:
             LOG(log_debug, logtype_afpd, "sys_list_extattr(%s): error opening atttribute dir: %s", uname, strerror(errno));
-            ret= AFPERR_MISC;
+            ret = AFPERR_MISC;
             goto exit;
     }
     
@@ -311,8 +306,8 @@ int sys_set_ea(VFS_FUNC_ARGS_EA_SET)
         switch(errno) {
         case OPEN_NOFOLLOW_ERRNO:
             /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s'): encountered symlink with kXAttrNoFollow",
-                getcwdpath(), uname, attruname);
+            LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s\", ea:'%s'): symlink with kXAttrNoFollow",
+                uname, attruname);
             return AFP_OK;
         case EEXIST:
             LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s'): EA already exists",
@@ -365,7 +360,7 @@ int sys_remove_ea(VFS_FUNC_ARGS_EA_REMOVE)
         switch(errno) {
         case OPEN_NOFOLLOW_ERRNO:
             /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "sys_remove_ea(%s/%s): encountered symlink with kXAttrNoFollow", uname);
+            LOG(log_debug, logtype_afpd, "sys_remove_ea(%s/%s): symlink with kXAttrNoFollow", uname);
             return AFP_OK;
         case EACCES:
             LOG(log_debug, logtype_afpd, "sys_remove_ea(%s/%s): error: %s", uname, attruname, strerror(errno));
index db325328550c6a74d6f2e0905becd1d0ca5397ec..5130146170685d8b430b9ff3bd5160622cfe5848 100644 (file)
@@ -60,6 +60,7 @@
 #include <atalk/logger.h>
 #include <atalk/ea.h>
 #include <atalk/compat.h>
+#include <atalk/errchk.h>
 
 /******** Solaris EA helper function prototypes ********/
 #ifdef HAVE_ATTROPEN
@@ -263,7 +264,7 @@ ssize_t sys_lgetxattr (const char *path, const char *uname, void *value, size_t
        return retval ? retval : valuelength;
 #elif defined(HAVE_ATTROPEN)
        ssize_t ret = -1;
-       int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+       int attrfd = solaris_attropen(path, name, O_RDONLY | O_NOFOLLOW, 0);
        if (attrfd >= 0) {
                ret = solaris_read_xattr(attrfd, value, size);
                close(attrfd);
@@ -513,7 +514,7 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size)
        return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
 #elif defined(HAVE_ATTROPEN)
        ssize_t ret = -1;
-       int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+       int attrdirfd = solaris_attropen(path, ".", O_RDONLY | O_NOFOLLOW, 0);
        if (attrdirfd >= 0) {
                ret = solaris_list_xattr(attrdirfd, list, size);
                close(attrdirfd);
@@ -581,7 +582,7 @@ int sys_lremovexattr (const char *path, const char *uname)
        return attr_remove(path, attrname, flags);
 #elif defined(HAVE_ATTROPEN)
        int ret = -1;
-       int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+       int attrdirfd = solaris_attropen(path, ".", O_RDONLY | O_NOFOLLOW, 0);
        if (attrdirfd >= 0) {
                ret = solaris_unlinkat(attrdirfd, name);
                close(attrdirfd);
@@ -767,7 +768,7 @@ int sys_lsetxattr (const char *path, const char *uname, const void *value, size_
        return attr_set(path, attrname, (const char *)value, size, myflags);
 #elif defined(HAVE_ATTROPEN)
        int ret = -1;
-       int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
+       int myflags = O_RDWR | O_NOFOLLOW;
        int attrfd;
        if (flags & XATTR_CREATE) myflags |= O_EXCL;
        if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
@@ -866,21 +867,43 @@ static int solaris_unlinkat(int attrdirfd, const char *name)
 
 static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode)
 {
-       int filedes;
+    EC_INIT;
+       int filedes = -1, eafd = -1;
 
-       if ((filedes = attropen(path, attrpath, oflag, mode)) == -1) {
+    if ((filedes = open(path, O_RDONLY | (oflag & O_NOFOLLOW), mode)) == -1) {
         switch (errno) {
         case ENOENT:
         case EEXIST:
-            break;
+        case OPEN_NOFOLLOW_ERRNO:
+            EC_FAIL;
         default:
-            LOG(log_debug, logtype_default, "attropen(\"%s\", ea:'%s'): %s",
-                path, attrpath, strerror(errno));
+            LOG(log_debug, logtype_default, "open(\"%s\"): %s", fullpathname(path), strerror(errno));
             errno = ENOATTR;
-            break;
+            EC_FAIL;
         }
        }
-       return filedes;
+
+       if ((eafd = openat(filedes, attrpath, oflag | O_XATTR, mode)) == -1) {
+        switch (errno) {
+        case ENOENT:
+        case EEXIST:
+            EC_FAIL;
+        default:
+            LOG(log_debug, logtype_default, "openat(\"%s\"): %s", fullpathname(path), strerror(errno));
+            errno = ENOATTR;
+            EC_FAIL;
+        }
+       }
+    
+EC_CLEANUP:
+    if (filedes != -1)
+        close(filedes);
+    if (ret != 0) {
+        if (eafd != -1)
+            close(eafd);
+        eafd = -1;
+    }
+    return eafd;
 }
 
 static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)