]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/file.c
added dropbox as a volume option when DROPKLUDGE is compiled in
[netatalk.git] / etc / afpd / file.c
index 63a4ce16595763e9e1c39aa178e44d24578e576b..b96bc2f224aea639b59b961d810ecc4d9ee97fba 100644 (file)
 #include "filedir.h"
 #include "globals.h"
 
+#ifdef FORCE_UIDGID
+#include "uid.h"
+#endif /* FORCE_UIDGID */
+
 /* the format for the finderinfo fields (from IM: Toolbox Essentials):
  * field         bytes        subfield    bytes
  * 
@@ -81,6 +85,10 @@ int getfilparams(vol, bitmap, path, dir, st, buf, buflen )
     u_int16_t          ashort;
     u_char              achar, fdType[4];
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin getfilparams:");
+#endif DEBUG
+
     upath = mtoupath(vol, path);
     if ((of = of_findname(vol, curdir, path))) {
       adp = of->of_ad;
@@ -308,6 +316,11 @@ int getfilparams(vol, bitmap, path, dir, st, buf, buflen )
         ad_close( adp, ADFLAGS_HF );
     }
     *buflen = data - buf;
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end getfilparams:");
+#endif DEBUG
+
     return( AFP_OK );
 }
 
@@ -317,20 +330,21 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
     int                ibuflen, *rbuflen;
 {
     struct stat         st;
-#ifdef DROPKLUDGE
-    struct stat                sb;
-    char               adpath[50];
-    int                        uid;
-#endif DROPKLUDGE
     struct adouble     ad, *adp;
     struct vol         *vol;
     struct dir         *dir;
     struct ofork        *of;
     char               *path, *upath;
-    int                        creatf, did, openf;
+    int                        creatf, did, openf, retvalue = AFP_OK;
     u_int16_t          vid;
+#ifdef FORCE_UIDGID
+       uidgidset               *uidgid;
+#endif FORCE_UIDGID
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_createfile:");
+#endif DEBUG
 
-    syslog(LOG_INFO, "afp_createfile");
     *rbuflen = 0;
     ibuf++;
     creatf = (unsigned char) *ibuf++;
@@ -383,12 +397,30 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
        openf = O_RDWR|O_CREAT|O_EXCL;
     }
 
+#ifdef FORCE_UIDGID
+
+       /* preserve current euid, egid */
+       save_uidgid ( uidgid );
+
+       /* perform all switching of users */
+       set_uidgid ( vol );
+
+#endif FORCE_UIDGID
+
     if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF,
                  openf, 0666, adp) < 0 ) {
       switch ( errno ) {
        case EEXIST :
+#ifdef FORCE_UIDGID
+               /* bring everything back to old euid, egid */
+               restore_uidgid ( uidgid );
+#endif FORCE_UIDGID
            return( AFPERR_EXIST );
        case EACCES :
+#ifdef FORCE_UIDGID
+               /* bring everything back to old euid, egid */
+               restore_uidgid ( uidgid );
+#endif FORCE_UIDGID
            return( AFPERR_ACCESS );
         case ENOENT:
            /* on noadouble volumes, just creating the data fork is ok */
@@ -396,6 +428,10 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
              goto createfile_done;
            /* fallthrough */
        default :
+#ifdef FORCE_UIDGID
+               /* bring everything back to old euid, egid */
+               restore_uidgid ( uidgid );
+#endif FORCE_UIDGID
            return( AFPERR_PARAM );
        }
     }
@@ -409,37 +445,23 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
 createfile_done:
 
 #ifdef DROPKLUDGE
-
-/* The below code is an experimental, untested, incomplete kludge which 
-provides better dropbox support.  It should NOT be turned on yet unless
-you are a developer who wants to try it out and fix it. */
-    if (stat(".", &sb) == -1) 
-      syslog (LOG_ERR, "Error checking directory %s: %m", dir->d_name);
-    else {
-      uid=geteuid();
-      if ( uid != sb.st_uid )
-      {
-       strcpy (adpath, "./.AppleDouble/");
-       strcat (adpath, path);
-       seteuid(0); /* Become root to change the owner of the file */
-       syslog (LOG_INFO, "Changing %s to uid=%d gid=%d", path, sb.st_uid, sb.st_gid);
-       if (chown(path, sb.st_uid, sb.st_gid)==-1)
-         syslog (LOG_ERR, "Error changing permissions: %m");
-        /* In order to write information to the file, the Mac client needs
-        to be able to read from it too, so read bits have to be turned on.
-        Directory permissions remain unchanged */
-        chmod(path,(sb.st_mode&0x0FFFF)| S_IRGRP| S_IROTH);
-       if (chown(adpath, sb.st_uid, sb.st_gid)==-1)
-         syslog (LOG_ERR, "Error changing AppleDouble permissions: %m");
-       syslog (LOG_INFO, "Changing afpd owner back to %d", uid);
-       seteuid(uid); /* Restore process ownership to normal */
-      }
+    if (vol->v_flags & AFPVOL_DROPBOX) {
+         retvalue=matchfile2dirperms(upath, vol, did);
     }
-
 #endif DROPKLUDGE
 
     setvoltime(obj, vol );
-    return AFP_OK;
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_createfile");
+#endif DEBUG
+
+#ifdef FORCE_UIDGID
+       /* bring everything back to old euid, egid */
+       restore_uidgid ( uidgid );
+#endif FORCE_UIDGID
+
+    return (retvalue);
 }
 
 int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen )
@@ -453,7 +475,10 @@ int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen )
     int                did, rc;
     u_int16_t  vid, bitmap;
 
-    syslog (LOG_INFO, "afp_setfilparams");
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_setfilparams:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -488,6 +513,10 @@ int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen )
        setvoltime(obj, vol );
     }
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_setfilparams:");
+#endif DEBUG
+
     return( rc );
 }
 
@@ -507,6 +536,14 @@ int setfilparams(vol, path, bitmap, buf )
     u_int32_t          aint;
     struct utimbuf     ut;
 
+#ifdef FORCE_UIDGID
+       uidgidset               *uidgid;
+#endif FORCE_UIDGID
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin setfilparams:");
+#endif DEBUG
+
     upath = mtoupath(vol, path);
     if ((of = of_findname(vol, curdir, path))) {
       adp = of->of_ad;
@@ -514,10 +551,19 @@ int setfilparams(vol, path, bitmap, buf )
       memset(&ad, 0, sizeof(ad));
       adp = &ad;
     }
+
+#ifdef FORCE_UIDGID
+       save_uidgid ( uidgid );
+       set_uidgid ( vol );
+#endif FORCE_UIDGID
+
     if (ad_open( upath, vol_noadouble(vol) | ADFLAGS_HF, 
                 O_RDWR|O_CREAT, 0666, adp) < 0) {
       /* for some things, we don't need an adouble header */
       if (bitmap & ~(1<<FILPBIT_MDATE)) {
+#ifdef FORCE_UIDGID
+       restore_uidgid ( uidgid );
+#endif FORCE_UIDGID
        return vol_noadouble(vol) ? AFP_OK : AFPERR_ACCESS;
       }
       isad = 0;
@@ -635,7 +681,17 @@ setfilparam_done:
     if (isad) {
       ad_flush( adp, ADFLAGS_HF );
       ad_close( adp, ADFLAGS_HF );
+
+#ifdef FORCE_UIDGID
+       restore_uidgid ( uidgid );
+#endif FORCE_UIDGID
+
     }
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end setfilparams:");
+#endif DEBUG
+
     return err;
 }
 
@@ -662,6 +718,10 @@ int renamefile(src, dst, newname, noadouble )
 
     /* existence check moved to afp_moveandrename */
 
+#ifdef DEBUG
+    syslog (LOG_INFO, "begin renamefile:");
+#endif DEBUG
+
     if ( rename( src, dst ) < 0 ) {
        switch ( errno ) {
        case ENOENT :
@@ -729,6 +789,10 @@ rename_retry:
     ad_flush( &ad, ADFLAGS_HF );
     ad_close( &ad, ADFLAGS_HF );
 
+#ifdef DEBUG
+    syslog (LOG_INFO, "end renamefile:");
+#endif DEBUG
+
     return( AFP_OK );
 }
 
@@ -741,10 +805,13 @@ int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
     struct dir *dir;
     char       *newname, *path, *p;
     u_int32_t  sdid, ddid;
-    int                plen, err;
+    int                plen, err, did, retvalue = AFP_OK;
     u_int16_t  svid, dvid;
 
-    syslog(LOG_INFO, "afp_copyfile");
+#ifdef DEBUG
+    syslog (LOG_INFO, "begin afp_copyfile:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -818,7 +885,18 @@ int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
     }
 
     setvoltime(obj, vol );
-    return( AFP_OK );
+
+#ifdef DROPKLUDGE
+    if (vol->v_flags & AFPVOL_DROPBOX) {
+         retvalue=matchfile2dirperms(newname, vol, sdid);
+    }
+#endif DROPKLUDGE
+
+#ifdef DEBUG
+    syslog (LOG_INFO, "end afp_copyfile:");
+#endif DEBUG
+
+    return( retvalue );
 }
 
 
@@ -827,6 +905,10 @@ static __inline__ int copy_all(const int dfd, const void *buf,
 {
   ssize_t cc;
 
+#ifdef DEBUG
+  syslog(LOG_INFO, "begin copy_all:");
+#endif DEBUG
+
   while (buflen > 0) {
     if ((cc = write(dfd, buf, buflen)) < 0) {
       switch (errno) {
@@ -845,7 +927,11 @@ static __inline__ int copy_all(const int dfd, const void *buf,
     buflen -= cc;
   }
 
-  return 0;
+#ifdef DEBUG
+  syslog(LOG_INFO, "end copy_all:");
+#endif DEBUG
+
+  return AFP_OK;
 }
 
 /* XXX: this needs to use ad_open and ad_lock. so, we need to
@@ -860,6 +946,9 @@ int copyfile(src, dst, newname, noadouble )
     int                        sfd, dfd, len, err = AFP_OK;
     ssize_t             cc;
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin copyfile:");
+#endif DEBUG
 
     if (newname) { 
       if ((sfd = open( ad_path( src, ADFLAGS_HF ), O_RDONLY, 0 )) < 0 ) {
@@ -1018,6 +1107,10 @@ copydata_done:
       ad_close( &ad, ADFLAGS_HF );
     }
     
+#ifdef DEBUG
+    syslog(LOG_INFO, "end copyfile:");
+#endif DEBUG
+
     return( AFP_OK );
 }
 
@@ -1028,16 +1121,20 @@ int deletefile( file )
     struct adouble     ad;
     int                        adflags, err = AFP_OK;
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin deletefile:");
+#endif DEBUG
+
     /* try to open both at once */
     adflags = ADFLAGS_DF|ADFLAGS_HF;
     memset(&ad, 0, sizeof(ad));
-    if ( ad_open( file, adflags, O_RDWR, 0, &ad ) < 0 ) {
+    if ( ad_open( file, adflags, O_RDONLY, 0, &ad ) < 0 ) {
          switch (errno) {
          case ENOENT:
            adflags = ADFLAGS_DF;
            /* that failed. now try to open just the data fork */
            memset(&ad, 0, sizeof(ad));
-           if ( ad_open( file, adflags, O_RDWR, 0, &ad ) < 0 ) {
+           if ( ad_open( file, adflags, O_RDONLY, 0, &ad ) < 0 ) {
              switch (errno) {
              case ENOENT:
                return AFPERR_NOOBJ;
@@ -1108,6 +1205,11 @@ delete_unlock:
       ad_tmplock(&ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
     ad_tmplock(&ad, ADEID_DFORK, ADLOCK_CLR, 0, 0);
     ad_close( &ad, adflags );
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end deletefile:");
+#endif DEBUG
+
     return err;
 }
 
@@ -1127,8 +1229,11 @@ int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
     int                 len;
     cnid_t             did, id;
     u_short            vid;
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_createid:");
+#endif DEBUG
     
-    syslog(LOG_INFO, "afp_createid");
     *rbuflen = 0;
     ibuf += 2;
 
@@ -1190,6 +1295,10 @@ int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
       return AFP_OK;
     }
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "ending afp_createid...:");
+#endif DEBUG
+
     switch (errno) {
     case EROFS:
       return AFPERR_VLOCK;
@@ -1217,8 +1326,11 @@ int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen )
     int                 err, buflen;
     cnid_t             id;
     u_int16_t          vid, bitmap;
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_resolveid:");
+#endif DEBUG
     
-    syslog(LOG_INFO, "afp_resolveid");
     *rbuflen = 0;
     ibuf += 2;
 
@@ -1265,6 +1377,11 @@ int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen )
 
     *rbuflen = buflen + sizeof(bitmap);
     memcpy(rbuf, ibuf, sizeof(bitmap));
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_resolveid:");
+#endif DEBUG
+    
     return AFP_OK;
 }
 
@@ -1280,8 +1397,11 @@ int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen )
     int                 err;
     cnid_t             id;
     u_short            vid;
-    
-    syslog(LOG_INFO, "afp_deleteid");
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_deleteid:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -1337,6 +1457,10 @@ int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen )
       }
     }
 
+#ifdef DEBUG
+    syslog(LOG_INFO, "end afp_deleteid:");
+#endif DEBUG
+
     return err;
 }
 #endif
@@ -1358,8 +1482,11 @@ int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
 #endif
     cnid_t             sid, did;
     u_int16_t          vid;
-    
-    syslog(LOG_INFO, "afp_exchangefiles");
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "begin afp_exchangefiles:");
+#endif DEBUG
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -1507,6 +1634,11 @@ int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
       goto err_temp_to_dest;
     }
 #endif
+
+#ifdef DEBUG
+    syslog(LOG_INFO, "ending afp_exchangefiles:");
+#endif DEBUG
+
     return AFP_OK;