]> arthur.barton.de Git - netatalk.git/commitdiff
adouble:ea symlink handling
authorFrank Lahm <franklahm@googlemail.com>
Fri, 27 Jan 2012 11:37:28 +0000 (12:37 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Fri, 27 Jan 2012 11:37:28 +0000 (12:37 +0100)
etc/afpd/file.c
include/atalk/adouble.h
libatalk/adouble/ad_open.c

index 78c7a5fb3f154f485a40bff58b68d9ce57bbbc0d..e28345d057faa618f8f3afde9ff711645f912a04 100644 (file)
@@ -821,9 +821,7 @@ int setfilparams(struct vol *vol,
     uint32_t           aint;
     uint32_t           upriv;
     uint16_t           upriv_bit = 0;
-    
-    struct utimbuf     ut;
-
+        struct utimbuf ut;
     int                 change_mdate = 0;
     int                 change_parent_mdate = 0;
     int                 newdate = 0;
@@ -833,6 +831,7 @@ int setfilparams(struct vol *vol,
     uint16_t           bitmap = f_bitmap;
     uint32_t           cdate,bdate;
     u_char              finder_buf[32];
+    int symlinked = 0;
 
 #ifdef DEBUG
     LOG(log_debug9, logtype_afpd, "begin setfilparams:");
@@ -875,16 +874,15 @@ int setfilparams(struct vol *vol,
         case FILPBIT_FINFO :
             change_mdate = 1;
             memcpy(finder_buf, buf, 32 );
-            if (memcmp(buf,"slnkrhap",8)==0 && !S_ISLNK(path->st.st_mode)){
-            // SLFINFO
+            if (memcmp(buf, "slnkrhap", 8) == 0 && !S_ISLNK(path->st.st_mode)) {
                 int fp;
                 ssize_t len;
                 int erc=1;
                 char buf[PATH_MAX+1];
-                if ((fp=open(path->u_name,O_RDONLY))>=0){
-                    if ((len=read(fp,buf,PATH_MAX+1))){
-                        if (unlink(path->u_name)==0){
-                            buf[len]=0;
+                if ((fp = open(path->u_name, O_RDONLY)) >= 0) {
+                    if ((len = read(fp, buf, PATH_MAX+1))) {
+                        if (unlink(path->u_name) == 0) {
+                            buf[len] = 0;
                             erc = symlink(buf, path->u_name);
                             if (!erc)
                                 of_stat(path);
@@ -892,10 +890,11 @@ int setfilparams(struct vol *vol,
                     }
                     close(fp);
                 }
-                if (erc!=0){
+                if (erc != 0) {
                     err=AFPERR_BITMAP;
                     goto setfilparam_done;
                 }
+                symlinked = 1;
             }
             buf += 32;
             break;
@@ -966,7 +965,7 @@ int setfilparams(struct vol *vol,
          * - change of modification date
          * - UNIX privs (Bug-ID #2863424)
          */
-        if (f_bitmap & ~(1<<FILPBIT_MDATE | 1<<FILPBIT_UNIXPR)) {
+        if (!symlinked && f_bitmap & ~(1<<FILPBIT_MDATE | 1<<FILPBIT_UNIXPR)) {
             LOG(log_debug, logtype_afpd, "setfilparams: need adouble access");
             return AFPERR_ACCESS;
         }
index 78b6fa6f8301b245d46bc15e94d71adaca570eeb..a4a508bb8c2b2b74ed54a3cb4c4f1231fb07697e 100644 (file)
@@ -349,9 +349,10 @@ struct adouble {
 #define ad_reso_fileno(ad)  ((ad)->ad_rfp->adf_fd)
 #define ad_meta_fileno(ad)  ((ad)->ad_mdp->adf_fd)
 
-#define AD_DATA_OPEN(ad) ((ad)->ad_data_fork.adf_fd != -1)
-#define AD_META_OPEN(ad) ((ad)->ad_mdp->adf_fd != -1)
-#define AD_RSRC_OPEN(ad) ((ad)->ad_rfp->adf_fd != -1)
+/* -1 means not open, -2 is a symlink */
+#define AD_DATA_OPEN(ad) ((ad)->ad_data_fork.adf_fd >= 0)
+#define AD_META_OPEN(ad) ((ad)->ad_mdp->adf_fd >= 0)
+#define AD_RSRC_OPEN(ad) ((ad)->ad_rfp->adf_fd >= 0)
 
 #define ad_getversion(ad)   ((ad)->ad_version)
 
index aeb34c29c4c5a8bdef22fcb1bf101eff5b885a4e..2e2d686c358df16d7420ba5081617f97575fab1d 100644 (file)
@@ -938,6 +938,10 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
 
     oflags = O_NOFOLLOW | (ad2openflags(adflags) & ~(O_CREAT | O_TRUNC));
 
+    if (ad_meta_fileno(ad) == -2)
+        /* symlink */
+        EC_EXIT;
+
     if (ad_meta_fileno(ad) != -1) {
         /* the file is already open, but we want write access: */
         if ((oflags & O_RDWR) &&
@@ -957,7 +961,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
                 /* For directories we open the directory RDONYL so we can later fchdir()  */
                 oflags = (oflags & ~O_RDWR) | O_RDONLY;
             LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): opening base file for meta adouble EA", path);
-            EC_NEG1(ad_meta_fileno(ad) = open(path, oflags));
+            EC_NEG1_LOG(ad_meta_fileno(ad) = open(path, oflags));
             opened = 1;
             ad->ad_mdp->adf_flags = oflags;
         }
@@ -966,6 +970,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
     /* Read the adouble header in and parse it.*/
     if (ad->ad_ops->ad_header_read(path, ad, NULL) != 0) {
         if (!(adflags & ADFLAGS_CREATE)) {
+            LOG(log_error, logtype_default, "ad_open_hf_ea(\"%s\"): can't read metadata EA", path);
             errno = ENOENT;
             EC_FAIL;
         }