]> arthur.barton.de Git - netatalk.git/commitdiff
Fix for filesystem without NFSv4 ACL support on Solaris, Bug ID #3428389
authorFrank Lahm <franklahm@googlemail.com>
Thu, 3 Nov 2011 12:51:13 +0000 (13:51 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Thu, 3 Nov 2011 12:51:13 +0000 (13:51 +0100)
NEWS
etc/afpd/acls.c
etc/afpd/acls.h
etc/afpd/afs.c
etc/afpd/directory.c
etc/afpd/file.c
etc/afpd/unix.c
etc/afpd/unix.h
etc/afpd/volume.c
libatalk/acl/unix.c

diff --git a/NEWS b/NEWS
index 326f35b98ce455294674563849a037823c7859aa..6e8aaa2a7f4bed83091bd7485fd6a97ff4ea3446 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Changes in 2.2.2
 * FIX: afpd: Fix an error when duplicating files that lacked an AppleDouble file
        which lead to a possible Finder crash
 * FIX: afpd: Read-only filesystems lead to afpd processes running as root
+* FIX: afpd: Fix for filesystem without NFSv4 ACL support on Solaris
 * FIX: dbd: Better checking for duplicated or bogus CNIDs from AppleDouble files
 * FIX: Fix compilation error when AppleTalk support is disabled
 
index d46f3605b89fe8d2a7f98c204eca989a834e944d..1f4be0674aaa730b1e318a71d26da8e84a5b5c9b 100644 (file)
@@ -1715,14 +1715,13 @@ int afp_setacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
  * This is the magic function that makes ACLs usable by calculating
  * the access granted by ACEs to the logged in user.
  */
-int acltoownermode(char *path, struct stat *st, struct maccess *ma)
+int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct maccess *ma)
 {
     EC_INIT;
     uint32_t rights = 0;
 
     if ( ! (AFPobj->options.flags & OPTION_ACL2MACCESS)
-         || (current_vol == NULL)
-         || ! (current_vol->v_flags & AFPVOL_ACLS))
+         || ! (vol->v_flags & AFPVOL_ACLS))
          return 0;
 
     LOG(log_maxdebug, logtype_afpd, "acltoownermode(\"%s/%s\", 0x%02x)",
index c89fe9c8f3c5fe0ee8df275a5e9d8c8b3dd9d9f6..273a9f13e1cca3cdd31cfc659e1c4cafba6454ed 100644 (file)
@@ -113,6 +113,6 @@ int afp_setacl (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf,  size_t *rb
 extern int acl_ldap_readconfig(char *name);
 
 /* Misc funcs */
-extern int acltoownermode(char *path, struct stat *st, struct maccess *ma);
+extern int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct maccess *ma);
 extern int check_vol_acl_support(const struct vol *vol);
 #endif
index d045cd4ee83abb334bec306b698f164105df0fb5..377d5fb5a6389c2d99a3faf0f0b220f8dc71a741 100644 (file)
@@ -129,7 +129,8 @@ int afp_getdiracl(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r
     #undef accessmode
 #endif
 
-void afsmode( path, ma, dir, st )
+void afsmode( vol, path, ma, dir, st )
+const struct volume *vol;
 char           *path;
 struct maccess *ma;
 struct dir      *dir;
@@ -153,7 +154,7 @@ struct stat     *st;
         return;
     }
 
-    accessmode( path, ma, dir, st );
+    accessmode(vol, path, ma, dir, st );
 
     return;
 }
index be52d36d1350d833f53c5c1a8448f7d1e400865d..da7eb6c4eae973c2d2bc2811eea9a4dc3117f550 100644 (file)
@@ -1410,7 +1410,7 @@ int check_access(char *path, int mode)
     if (!p)
         return -1;
 
-    accessmode(p, &ma, curdir, NULL);
+    accessmode(current_vol, p, &ma, curdir, NULL);
     if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
         return -1;
     if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
@@ -1424,7 +1424,7 @@ int file_access(struct path *path, int mode)
 {
     struct maccess ma;
 
-    accessmode(path->u_name, &ma, curdir, &path->st);
+    accessmode(current_vol, path->u_name, &ma, curdir, &path->st);
 
     LOG(log_debug, logtype_afpd, "file_access(\"%s\"): mapped user mode: 0x%02x",
         path->u_name, ma.ma_user);
@@ -1629,7 +1629,7 @@ int getdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_ACCESS :
-            accessmode( upath, &ma, dir , st);
+            accessmode(vol, upath, &ma, dir , st);
 
             *data++ = ma.ma_user;
             *data++ = ma.ma_world;
@@ -1665,7 +1665,7 @@ int getdirparams(const struct vol *vol,
 
         case DIRPBIT_UNIXPR :
             /* accessmode may change st_mode with ACLs */
-            accessmode( upath, &ma, dir, st);
+            accessmode(vol, upath, &ma, dir, st);
 
             aint = htonl(st->st_uid);
             memcpy( data, &aint, sizeof( aint ));
index 8402ebf164dcb81611b38402181eabdfc34d8088..36798904ad0802b9d5d89ca25d17432f456be6af 100644 (file)
@@ -394,9 +394,9 @@ int getmetadata(struct vol *vol,
             /* FIXME do we want a visual clue if the file is read only
              */
             struct maccess     ma;
-            accessmode( ".", &ma, dir , NULL);
+            accessmode(vol, ".", &ma, dir , NULL);
             if ((ma.ma_user & AR_UWRITE)) {
-               accessmode( upath, &ma, dir , st);
+               accessmode(vol, upath, &ma, dir , st);
                if (!(ma.ma_user & AR_UWRITE)) {
                        ashort |= htons(ATTRBIT_NOWRITE);
                 }
@@ -563,7 +563,7 @@ int getmetadata(struct vol *vol,
             break;
         case FILPBIT_UNIXPR :
             /* accessmode may change st_mode with ACLs */
-            accessmode( upath, &ma, dir , st);
+            accessmode(vol, upath, &ma, dir , st);
 
             aint = htonl(st->st_uid);
             memcpy( data, &aint, sizeof( aint ));
index 0e444bcfffe36d712c7a6a9de7887a8cda497b05..53a59b35e7c0e6aa3d4a5a43e501d250affae794 100644 (file)
@@ -169,7 +169,7 @@ mode_t mode;
  *
  * dir parameter is used by AFS
  */
-void accessmode(char *path, struct maccess *ma, struct dir *dir _U_, struct stat *st)
+void accessmode(const struct vol *vol, char *path, struct maccess *ma, struct dir *dir _U_, struct stat *st)
 {
     struct stat     sb;
 
@@ -181,7 +181,7 @@ void accessmode(char *path, struct maccess *ma, struct dir *dir _U_, struct stat
     }
     utommode( st, ma );
 #ifdef HAVE_ACLS
-    acltoownermode(path, st, ma);
+    acltoownermode(vol, path, st, ma);
 #endif
 }
 
index be7b7bfb4aa5bd3f8848f9ce4c31be1f80306c0e..54ebf3d69bfac079b576a6eae4f00edaf757181f 100644 (file)
@@ -227,7 +227,7 @@ extern int setdeskowner     (const uid_t, const gid_t);
 extern int setdirowner      (const struct vol *, const char *, const uid_t, const gid_t);
 extern int setfilunixmode   (const struct vol *, struct path*, const mode_t);
 extern int setfilowner      (const struct vol *, const uid_t, const gid_t, struct path*);
-extern void accessmode      (char *, struct maccess *, struct dir *, struct stat *);
+extern void accessmode      (const struct vol *, char *, struct maccess *, struct dir *, struct stat *);
 
 #ifdef AFS     
     #define accessmode afsmode
index dd580cb80747bd4bfffff97829fd1b5e7817aa4c..9b9672ab3c9887076d9068b40028bd2cb588ca90 100644 (file)
@@ -1939,7 +1939,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
             if (!S_ISDIR(st.st_mode)) {
                 continue;       /* not a dir */
             }
-            accessmode(volume->v_path, &ma, NULL, &st);
+            accessmode(volume, volume->v_path, &ma, NULL, &st);
             if ((ma.ma_user & (AR_UREAD | AR_USEARCH)) != (AR_UREAD | AR_USEARCH)) {
                 continue;   /* no r-x access */
             }
index 31027abe581da133c0de503b479c2ccb301142ff..9bad9c94ea277ec4d1a7be192ab539aa6c71977d 100644 (file)
@@ -56,17 +56,17 @@ int get_nfsv4_acl(const char *name, ace_t **retAces)
         return 0;
 
     if ( ! (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) {
-        LOG(log_warning, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): special", getcwdpath(), name);
+        LOG(log_debug, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): special", getcwdpath(), name);
         return 0;
     }
 
     if ((ace_count = acl(name, ACE_GETACLCNT, 0, NULL)) == 0) {
-        LOG(log_warning, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): 0 ACEs", getcwdpath(), name);
+        LOG(log_debug, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): 0 ACEs", getcwdpath(), name);
         return 0;
     }
 
     if (ace_count == -1) {
-        LOG(log_error, logtype_afpd, "get_nfsv4_acl: acl('%s/%s', ACE_GETACLCNT): ace_count %i, error: %s",
+        LOG(log_debug, logtype_afpd, "get_nfsv4_acl: acl('%s/%s', ACE_GETACLCNT): ace_count %i, error: %s",
             getcwdpath(), name, ace_count, strerror(errno));
         return -1;
     }
@@ -205,10 +205,10 @@ int strip_nontrivial_aces(ace_t **saces, int sacecount)
  * Change mode of file preserving existing explicit ACEs
  *
  * nfsv4_chmod
- * (1) reads objects ACL (acl1)
+ * (1) reads objects ACL (acl1), may return 0 or -1 NFSv4 ACEs on eg UFS fs
  * (2) removes all trivial ACEs from the ACL by calling strip_trivial_aces(), possibly
  *     leaving 0 ACEs in the ACL if there were only trivial ACEs as mapped from the mode
- * (3) calls chmod() with mode
+ * (3) calls chmod() with mode, we're done if step (1) returned 0 for noaces
  * (4) reads the changed ACL (acl2) which
  *     a) might still contain explicit ACEs (up to onnv132)
  *     b) will have any explicit ACE removed (starting with onnv145/Openindiana)
@@ -225,8 +225,9 @@ int nfsv4_chmod(char *name, mode_t mode)
     LOG(log_debug, logtype_afpd, "nfsv4_chmod(\"%s/%s\", %04o)",
         getcwdpath(), name, mode);
 
-    if ((noaces = get_nfsv4_acl(name, &oacl)) == -1) /* (1) */
-        goto exit;
+    if ((noaces = get_nfsv4_acl(name, &oacl)) < 1) /* (1) */
+        return chmod(name, mode);
+
     if ((noaces = strip_trivial_aces(&oacl, noaces)) == -1) /* (2) */
         goto exit;