]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/filedir.c
Warning fixes.
[netatalk.git] / etc / afpd / filedir.c
index f342b78bc2ea55439ab6852ead9fe2da7aa2463f..6f9877719e6f45ccd3e8c683ef0b09ddc280a9a6 100644 (file)
@@ -3,6 +3,10 @@
  * All Rights Reserved.  See COPYRIGHT.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <errno.h>
 #include <sys/syslog.h>
 #include <sys/types.h>
@@ -18,6 +22,7 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "directory.h"
 #include "desktop.h"
 #include "globals.h"
 #include "filedir.h"
 
+int matchfile2dirperms(upath, vol, did)
+                              /* Since it's kinda' big; I decided against an
+                              inline function */
+    char       *upath;
+    struct vol  *vol;
+    int                did;
+  /* The below code changes the way file ownership is determined in the name of
+  fixing dropboxes.  It has known security problem.  See the netatalk FAQ for
+  more information */
+{
+    struct stat        st, sb;
+    struct dir *dir;
+    char       adpath[50];
+    int                uid;
+
+#ifdef DEBUG
+    syslog (LOG_INFO, "begin matchfile2dirperms:");
+#endif DEBUG
+
+    if (stat(upath, &st ) < 0)
+      syslog(LOG_ERR, "Could not stat %s: %m", upath);
+    strcpy (adpath, "./.AppleDouble/");
+    strcat (adpath, upath);
+    if (( dir = dirsearch( vol, did )) == NULL ) {
+      syslog (LOG_ERR, "matchfile2dirperms: Unable to get directory info.");
+      return( AFPERR_NOOBJ );
+    }
+    else if (stat(".", &sb) < 0) {
+        syslog (LOG_ERR, 
+          "matchfile2dirperms: Error checking directory \"%s\": %m", 
+          dir->d_name);
+        return(AFPERR_NOOBJ );
+      }
+    else {
+       uid=geteuid();
+       if ( uid != sb.st_uid )
+        {
+         seteuid(0);
+         if (lchown(upath, sb.st_uid, sb.st_gid) < 0)
+          {
+            syslog (LOG_ERR, 
+             "matchfile2dirperms: Error changing owner/gid of %s: %m", upath);
+            return (AFPERR_ACCESS);
+          }
+          if (chmod(upath,(st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0)
+          {
+            syslog (LOG_ERR, 
+             "matchfile2dirperms:  Error adding file read permissions: %m");
+            return (AFPERR_ACCESS);
+          }
+#ifdef DEBUG
+          else 
+           syslog (LOG_INFO, 
+             "matchfile2dirperms:  Added S_IRGRP and S_IROTH: %m");
+#endif DEBUG
+          if (lchown(adpath, sb.st_uid, sb.st_gid) < 0)
+          {
+           syslog (LOG_ERR, 
+             "matchfile2dirperms: Error changing AppleDouble owner/gid %s: %m",
+             adpath);
+            return (AFPERR_ACCESS);
+         }
+          if (chmod(adpath, (st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0)
+          {
+            syslog (LOG_ERR, 
+             "matchfile2dirperms:  Error adding AD file read permissions: %m");
+            return (AFPERR_ACCESS);
+          }
+#ifdef DEBUG
+          else 
+           syslog (LOG_INFO, 
+             "matchfile2dirperms:  Added S_IRGRP and S_IROTH to AD: %m");
+#endif DEBUG
+       }
+#ifdef DEBUG
+        else
+         syslog (LOG_INFO, 
+           "matchfile2dirperms: No ownership change necessary.");
+#endif DEBUG
+    } /* end else if stat success */
+    seteuid(uid); /* Restore process ownership to normal */
+#ifdef DEBUG
+    syslog (LOG_INFO, "end matchfile2dirperms:");
+#endif DEBUG
+
+    return (AFP_OK);
+
+}
+    
+
 int afp_getfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
     AFPObj      *obj;
     char       *ibuf, *rbuf;
@@ -40,6 +135,10 @@ int afp_getfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
     char               *path;
     u_int16_t          fbitmap, dbitmap, vid;
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_getfildirparams:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -96,6 +195,10 @@ int afp_getfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
     rbuf += sizeof( dbitmap ) + sizeof( u_char );
     *rbuf = 0;
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_getfildirparams:");
+#endif DEBUG
+
     return( AFP_OK );
 }
 
@@ -111,6 +214,10 @@ int afp_setfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
     u_int16_t  vid, bitmap;
     int                did, rc;
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_setfildirparams:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
     memcpy( &vid, ibuf, sizeof(vid));
@@ -157,6 +264,11 @@ int afp_setfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
     if ( rc == AFP_OK ) {
        setvoltime(obj, vol );
     }
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_setfildirparams:");
+#endif DEBUG
+
     return( rc );
 }
 
@@ -178,6 +290,10 @@ int afp_rename(obj, ibuf, ibuflen, rbuf, rbuflen )
     cnid_t              id;
 #endif
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_rename:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -328,6 +444,10 @@ out:
     if (of_rename(vol, curdir, path, curdir, ibuf) < 0)
        return AFPERR_MISC;
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_rename:");
+#endif DEBUG
+
     return( AFP_OK );
 }
 
@@ -343,6 +463,10 @@ int afp_delete(obj, ibuf, ibuflen, rbuf, rbuflen )
     int                        did, rc;
     u_int16_t          vid;
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_delete:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -378,6 +502,11 @@ int afp_delete(obj, ibuf, ibuflen, rbuf, rbuflen )
     if ( rc == AFP_OK ) {
        setvoltime(obj, vol );
     }
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_delete:");
+#endif DEBUG
+
     return( rc );
 }
 
@@ -430,6 +559,10 @@ int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen )
     cnid_t      id;
 #endif
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_moveandrename:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -540,6 +673,14 @@ int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen )
        rc = renamedir(p, upath, odir, curdir, newname, vol_noadouble(vol));
     }
 
+#ifdef DROPKLUDGE
+    if (vol->v_flags & AFPVOL_DROPBOX) {
+        if (retvalue=matchfile2dirperms (newname, vol, did) != AFP_OK) {
+           return retvalue;
+        }
+    }
+#endif DROPKLUDGE
+
     if ( rc == AFP_OK ) {
 #if AD_VERSION > AD_VERSION1
         /* renaming may have moved the file/dir across a filesystem */
@@ -551,6 +692,11 @@ int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen )
 #endif      
        setvoltime(obj, vol );
     }
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_moveandrename:");
+#endif DEBUG
+
     return( rc );
 }