]> arthur.barton.de Git - netatalk.git/commitdiff
Merge remote-tracking branch 'origin/spotlight' into develop
authorRalph Boehme <sloowfranklin@gmail.com>
Tue, 9 Apr 2013 12:57:03 +0000 (14:57 +0200)
committerRalph Boehme <sloowfranklin@gmail.com>
Tue, 9 Apr 2013 12:57:03 +0000 (14:57 +0200)
NEWS
etc/afpd/acls.c
etc/afpd/fork.c
include/atalk/adouble.h
include/atalk/globals.h
libatalk/adouble/ad_write.c
libatalk/util/netatalk_conf.c

diff --git a/NEWS b/NEWS
index 5d6ff9cf8240f415c9d3abb4560c2ff40baed9ec..a1c3cedf5d7b73d5066872aad4ad72459138c69a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,18 @@ Changes in 3.0.4
 * FIX: Opening files without metadata EA may result in an invalid
        metadata EA. Check for malformed metadata EAs and delete them.
        Fixes bug #510.
-
+* FIX: Fix an issue with filenames containing non-ASCII characters that
+       lead to a failure setting the size of a files ressource fork.
+       This affected application like Adobe Photoshop where saving
+       files may fail. Fixes bug #511.
+* UPD: Enhance ACL mapping, change global ACL option 'map acl' to take
+       the following options: "none", "rights" (default), "mode".
+       none   = no mapping, this resembles the previous false/no setting
+       rights = map ACLs to Finder UARights, this resembles the previous
+                true/yes setting. This is the default.
+       mode   = map ACLs to Finder UARights and UNIX mode
+       From FR #73.
+    
 Changes in 3.0.3
 ================
 * UPD: afpd: Increase default DSI server quantum to 1 MB
index 6f2abdf30f43b4c22f7d26a0c7ed7f38d54df9cf..d162b994e7af71d09436f0b937d80a2cd2b3bffa 100644 (file)
  *
  * @param obj            (r) handle
  * @param path           (r) path to filesystem object
- * @param sb             (r) struct stat of path
- * @param result         (w) resulting Darwin allow ACE
+ * @param sb             (rw) struct stat of path
+ * @param ma             (rw) UARights struct
+ * @param rights_out     (w) mapped Darwin ACL rights
  *
  * @returns                  0 or -1 on error
  */
 static int solaris_acl_rights(const AFPObj *obj,
                               const char *path,
-                              const struct stat *sb,
-                              uint32_t *result)
+                              struct stat *sb,
+                              struct maccess *ma,
+                              uint32_t *rights_out)
 {
     EC_INIT;
     int      i, ace_count, checkgroup;
@@ -168,7 +170,28 @@ static int solaris_acl_rights(const AFPObj *obj,
             darwin_rights |= nfsv4_to_darwin_rights[i].to;
     }
 
-    *result |= darwin_rights;
+    LOG(log_maxdebug, logtype_afpd, "rights: 0x%08x", darwin_rights);
+
+    if (rights_out)
+        *rights_out = darwin_rights;
+
+    if (ma && obj->options.flags & OPTION_ACL2MACCESS) {
+        if (darwin_rights & DARWIN_ACE_READ_DATA)
+            ma->ma_user |= AR_UREAD;
+        if (darwin_rights & DARWIN_ACE_WRITE_DATA)
+            ma->ma_user |= AR_UWRITE;
+        if (darwin_rights & (DARWIN_ACE_EXECUTE | DARWIN_ACE_SEARCH))
+            ma->ma_user |= AR_USEARCH;
+    }
+
+    if (sb && obj->options.flags & OPTION_ACL2MODE) {
+        if (darwin_rights & DARWIN_ACE_READ_DATA)
+            sb->st_mode |= S_IRUSR;
+        if (darwin_rights & DARWIN_ACE_WRITE_DATA)
+            sb->st_mode |= S_IWUSR;
+        if (darwin_rights & (DARWIN_ACE_EXECUTE | DARWIN_ACE_SEARCH))
+            sb->st_mode |= S_IXUSR;
+    }
 
 EC_CLEANUP:
     if (aces) free(aces);
@@ -607,21 +630,23 @@ static int posix_acls_to_uaperms(const AFPObj *obj, const char *path, struct sta
                 break;
         }
     }
-    /* apply the mask and adjust user and group permissions */
-    ma->ma_user |= (acl_rights & mask);
-    ma->ma_group = (group_rights & mask);
 
-    /* update st_mode to properly reflect group permissions */
-    sb->st_mode &= ~S_IRWXG;
-
-    if (ma->ma_group & AR_USEARCH)
-        sb->st_mode |= S_IXGRP;
-
-    if (ma->ma_group & AR_UWRITE)
-        sb->st_mode |= S_IWGRP;
+    if (obj->options.flags & OPTION_ACL2MACCESS) {
+        /* apply the mask and adjust user and group permissions */
+        ma->ma_user |= (acl_rights & mask);
+        ma->ma_group = (group_rights & mask);
+    }
 
-    if (ma->ma_group & AR_UREAD)
-        sb->st_mode |= S_IRGRP;
+    if (obj->options.flags & OPTION_ACL2MODE) {
+        /* update st_mode to properly reflect group permissions */
+        sb->st_mode &= ~S_IRWXG;
+        if (ma->ma_group & AR_USEARCH)
+            sb->st_mode |= S_IXGRP;
+        if (ma->ma_group & AR_UWRITE)
+            sb->st_mode |= S_IWGRP;
+        if (ma->ma_group & AR_UREAD)
+            sb->st_mode |= S_IRGRP;
+    }
 
 EC_CLEANUP:
     if (acl) acl_free(acl);
@@ -1396,7 +1421,7 @@ static int check_acl_access(const AFPObj *obj,
         LOG(log_debug, logtype_afpd, "check_access: allowed rights from dircache: 0x%08x", allowed_rights);
     } else {
 #ifdef HAVE_SOLARIS_ACLS
-        EC_ZERO_LOG(solaris_acl_rights(obj, path, &st, &allowed_rights));
+        EC_ZERO_LOG(solaris_acl_rights(obj, path, &st, NULL, &allowed_rights));
 #endif
 #ifdef HAVE_POSIX_ACLS
         EC_ZERO_LOG(posix_acl_rights(obj, path, &st, &allowed_rights));
@@ -1429,7 +1454,7 @@ static int check_acl_access(const AFPObj *obj,
             EC_ZERO_LOG_ERR(lstat(cfrombstr(parent), &st), AFPERR_MISC);
 
 #ifdef HAVE_SOLARIS_ACLS
-            EC_ZERO_LOG(solaris_acl_rights(obj, cfrombstr(parent), &st, &parent_rights));
+            EC_ZERO_LOG(solaris_acl_rights(obj, cfrombstr(parent), &st, NULL, &parent_rights));
 #endif
 #ifdef HAVE_POSIX_ACLS
             EC_ZERO_LOG(posix_acl_rights(obj, path, &st, &parent_rights));
@@ -1734,7 +1759,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct
 {
     EC_INIT;
 
-    if ( ! (obj->options.flags & OPTION_ACL2MACCESS)
+    if ( ! (obj->options.flags & (OPTION_ACL2MACCESS | OPTION_ACL2MODE))
          || ! (vol->v_flags & AFPVOL_ACLS))
          return 0;
 
@@ -1742,17 +1767,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct
         getcwdpath(), path, ma->ma_user);
 
 #ifdef HAVE_SOLARIS_ACLS
-    uint32_t rights = 0;
-    EC_ZERO_LOG(solaris_acl_rights(obj, path, st, &rights));
-
-    LOG(log_maxdebug, logtype_afpd, "rights: 0x%08x", rights);
-
-    if (rights & DARWIN_ACE_READ_DATA)
-        ma->ma_user |= AR_UREAD;
-    if (rights & DARWIN_ACE_WRITE_DATA)
-        ma->ma_user |= AR_UWRITE;
-    if (rights & (DARWIN_ACE_EXECUTE | DARWIN_ACE_SEARCH))
-        ma->ma_user |= AR_USEARCH;
+    EC_ZERO_LOG(solaris_acl_rights(obj, path, st, ma, NULL));
 #endif
 
 #ifdef HAVE_POSIX_ACLS
index 0d050b3259e30f8a5e818cdcfc972210f1f9a688..0c988828d609660bc096c8cf01c944f6f8e633dc 100644 (file)
@@ -583,7 +583,7 @@ int afp_setforkparams(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf _U_, s
             goto afp_setfork_err;
         }
 
-        err = ad_rtruncate(ofork->of_ad, size);
+        err = ad_rtruncate(ofork->of_ad, mtoupath(ofork->of_vol, of_name(ofork), ofork->of_did, utf8_encoding(obj)), size);
         if (st_size > size)
             ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, size, st_size -size, ofork->of_refnum);
         if (err < 0)
index de0598b5a9f2b279eedb71dd01cc24700d20a495..73688b41a6d1f837bd7909a2dbaed167ed9766a2 100644 (file)
@@ -219,7 +219,7 @@ struct adouble {
     int                 ad_reso_refcount;
     off_t               ad_rlen;           /* ressource fork len with AFP 3.0         *
                                             * the header parameter size is too small. */
-    char                *ad_name;          /* name in server encoding (usually UTF8)  */
+    char                *ad_name;          /* name (UTF8-MAC)                         */
     struct adouble_fops *ad_ops;
     uint16_t            ad_open_forks;     /* open forks (by others)                  */
     char                ad_data[AD_DATASZ_MAX];
@@ -423,7 +423,7 @@ extern ssize_t ad_write(struct adouble *, uint32_t, off_t, int, const char *, si
 extern ssize_t adf_pread(struct ad_fd *, void *, size_t, off_t);
 extern ssize_t adf_pwrite(struct ad_fd *, const void *, size_t, off_t);
 extern int     ad_dtruncate(struct adouble *, off_t);
-extern int     ad_rtruncate(struct adouble *, off_t);
+extern int     ad_rtruncate(struct adouble *, const char *, off_t);
 extern int     copy_fork(int eid, struct adouble *add, struct adouble *ads);
 
 /* ad_size.c */
index 6f8ff68f7c79f0b10990120380f5abb4738705f3..faadc71333d4ef2fcd5f4d4ec51128859b889743 100644 (file)
@@ -54,6 +54,7 @@
 #define OPTION_UUID          (1 << 7)
 #define OPTION_ACL2MACCESS   (1 << 8)
 #define OPTION_NOZEROCONF    (1 << 9)
+#define OPTION_ACL2MODE      (1 << 10)
 #define OPTION_SHARE_RESERV  (1 << 11) /* whether to use Solaris fcntl F_SHARE locks */
 #define OPTION_DBUS_AFPSTATS (1 << 12) /* whether to run dbus thread for afpstats */
 #define OPTION_SPOTLIGHT     (1 << 13) /* whether to enable Spotlight support */
index a807c1de748e7ae0da06f93f9643654cee0dbbac..5cd3742d69f9890f3fa01a5148fc23fda7ae1e6f 100644 (file)
@@ -157,13 +157,13 @@ char            c = 0;
 }
 
 /* ------------------------ */
-int ad_rtruncate( struct adouble *ad, const off_t size)
+int ad_rtruncate(struct adouble *ad, const char *uname, const off_t size)
 {
     EC_INIT;
 
 #ifndef HAVE_EAFD
     if (ad->ad_vers == AD_VERSION_EA && size == 0)
-        EC_NEG1( unlink(ad->ad_ops->ad_path(ad->ad_name, 0)) );
+        EC_NEG1( unlink(ad->ad_ops->ad_path(uname, 0)) );
     else
 #endif
         EC_NEG1( sys_ftruncate(ad_reso_fileno(ad), size + ad->ad_eid[ ADEID_RFORK ].ade_off) );
@@ -173,7 +173,7 @@ EC_CLEANUP:
         ad->ad_rlen = size;    
     else
         LOG(log_error, logtype_ad, "ad_rtruncate(\"%s\"): %s",
-            fullpathname(ad->ad_name), strerror(errno));
+            fullpathname(uname), strerror(errno));
     EC_EXIT;
 }
 
index 5b1100a3548956583ae6b89da3c181a52ef3082c..ce06b9d8a9fd7e28fd063ca74adda7caf0fce03f 100644 (file)
@@ -1717,8 +1717,6 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
         options->flags |= OPTION_NOZEROCONF;
     if (iniparser_getboolean(config, INISEC_GLOBAL, "advertise ssh", 0))
         options->flags |= OPTION_ANNOUNCESSH;
-    if (iniparser_getboolean(config, INISEC_GLOBAL, "map acls", 1))
-        options->flags |= OPTION_ACL2MACCESS;
     if (iniparser_getboolean(config, INISEC_GLOBAL, "close vol", 0))
         options->flags |= OPTION_CLOSEVOL;
     if (!iniparser_getboolean(config, INISEC_GLOBAL, "client polling", 0))
@@ -1770,6 +1768,18 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
     options->disconnected   = iniparser_getint   (config, INISEC_GLOBAL, "disconnect time",24);
     options->tracker_loglevel = iniparser_getint (config, INISEC_GLOBAL, "tracker loglevel", 1);
 
+    p = iniparser_getstring(config, INISEC_GLOBAL, "map acls", "rights");
+    if (STRCMP(p, ==, "rights"))
+        options->flags |= OPTION_ACL2MACCESS;
+    else if (STRCMP(p, ==, "mode"))
+        options->flags |= OPTION_ACL2MODE | OPTION_ACL2MACCESS;
+    else {
+        if (STRCMP(p, !=, "none")) {
+            LOG(log_error, logtype_afpd, "bad ACL mapping option: %s, defaulting to 'rights'", p);
+            options->flags |= OPTION_ACL2MACCESS;
+        }
+    }
+
     if ((p = iniparser_getstring(config, INISEC_GLOBAL, "hostname", NULL))) {
         EC_NULL_LOG( options->hostname = strdup(p) );
     } else {