From: itlm019 Date: Thu, 19 Oct 2000 23:42:49 +0000 (+0000) Subject: Added DROPKLUDGE file copying support, modularized DROPKLUDGE operations, X-Git-Tag: netatalk-1-5-rc1~626 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=c85292898a115867f9fce8473b9eaf25d1b0aabb Added DROPKLUDGE file copying support, modularized DROPKLUDGE operations, and improved error handling. That means we have DROPKLUDGE support for creating files, moving files, and copying files now. As far as I'm aware, that covers all the ways of adding a file to a directory via AppleShare. --- diff --git a/etc/afpd/file.c b/etc/afpd/file.c index fd1a980b..a5529df7 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -81,6 +81,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 +312,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,19 +326,18 @@ 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 DEBUG + syslog(LOG_INFO, "begin afp_createfile:"); +#endif DEBUG + *rbuflen = 0; ibuf++; creatf = (unsigned char) *ibuf++; @@ -408,56 +416,16 @@ int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen ) createfile_done: #ifdef DROPKLUDGE - -/* 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 */ - if (stat(".", &sb) < 0) { - syslog (LOG_ERR, "afp_createfile: Error checking directory \"%s\": %m", dir->d_name); - return(-1); - } - else { - uid=geteuid(); - if ( uid != sb.st_uid ) - { - strcpy (adpath, "./.AppleDouble/"); - strcat (adpath, upath); - seteuid(0); /* Become root to change the owner of the file */ - if (lchown(upath, sb.st_uid, sb.st_gid) < 0) - { - syslog (LOG_ERR, "afp_createfile: Error changing owner/gid: %m"); - return (-1); - } - /* 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 */ - stat(upath, &st); - if (chmod(upath,(st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0) - { - syslog (LOG_ERR, "afp_createfile: Error adding file read permissions: %m"); - return (-1); - } - else syslog (LOG_DEBUG, "afp_createfile: Added S_IRGRP and S_IROTH: %m"); - if (lchown(adpath, sb.st_uid, sb.st_gid) < 0) - { - syslog (LOG_ERR, "afp_createfile: Error changing AppleDouble owner/gid: %m"); - return (-1); - } - if (chmod(adpath, (st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0) - { - syslog (LOG_ERR, "afp_createfile: Error adding AD file read permissions: %m"); - return (-1); - } - else syslog (LOG_DEBUG, "afp_createfile: Added S_IRGRP and S_IROTH to AD: %m"); - syslog (LOG_DEBUG, "afp_createfile: Changing afpd owner back to %d", uid); - seteuid(uid); /* Restore process ownership to normal */ - } - } - + retvalue=matchfile2dirperms(upath, vol, did); #endif DROPKLUDGE setvoltime(obj, vol ); - return AFP_OK; + +#ifdef DEBUG + syslog(LOG_INFO, "end afp_createfile"); +#endif DEBUG + + return (retvalue); } int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen ) @@ -471,6 +439,10 @@ int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen ) int did, rc; u_int16_t vid, bitmap; +#ifdef DEBUG + syslog(LOG_INFO, "begin afp_setfilparams:"); +#endif DEBUG + *rbuflen = 0; ibuf += 2; @@ -505,6 +477,10 @@ int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen ) setvoltime(obj, vol ); } +#ifdef DEBUG + syslog(LOG_INFO, "end afp_setfilparams:"); +#endif DEBUG + return( rc ); } @@ -524,6 +500,10 @@ int setfilparams(vol, path, bitmap, buf ) u_int32_t aint; struct utimbuf ut; +#ifdef DEBUG + syslog(LOG_INFO, "begin setfilparams:"); +#endif DEBUG + upath = mtoupath(vol, path); if ((of = of_findname(vol, curdir, path))) { adp = of->of_ad; @@ -653,6 +633,11 @@ setfilparam_done: ad_flush( adp, ADFLAGS_HF ); ad_close( adp, ADFLAGS_HF ); } + +#ifdef DEBUG + syslog(LOG_INFO, "end setfilparams:"); +#endif DEBUG + return err; } @@ -679,6 +664,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 : @@ -746,6 +735,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 ); } @@ -758,9 +751,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; +#ifdef DEBUG + syslog (LOG_INFO, "begin afp_copyfile:"); +#endif DEBUG + *rbuflen = 0; ibuf += 2; @@ -834,7 +831,16 @@ int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen ) } setvoltime(obj, vol ); - return( AFP_OK ); + +#ifdef DROPKLUDGE + retvalue=matchfile2dirperms(newname, vol, sdid); +#endif DROPKLUDGE + +#ifdef DEBUG + syslog (LOG_INFO, "end afp_copyfile:"); +#endif DEBUG + + return( retvalue ); } @@ -843,6 +849,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) { @@ -861,7 +871,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 @@ -876,6 +890,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 ) { @@ -1034,6 +1051,10 @@ copydata_done: ad_close( &ad, ADFLAGS_HF ); } +#ifdef DEBUG + syslog(LOG_INFO, "end copyfile:"); +#endif DEBUG + return( AFP_OK ); } @@ -1044,6 +1065,10 @@ 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)); @@ -1124,6 +1149,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; } @@ -1143,6 +1173,10 @@ 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 *rbuflen = 0; ibuf += 2; @@ -1205,6 +1239,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; @@ -1232,6 +1270,10 @@ 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 *rbuflen = 0; ibuf += 2; @@ -1279,6 +1321,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; } @@ -1294,7 +1341,11 @@ int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen ) int err; cnid_t id; u_short vid; - + +#ifdef DEBUG + syslog(LOG_INFO, "begin afp_deleteid:"); +#endif DEBUG + *rbuflen = 0; ibuf += 2; @@ -1350,6 +1401,10 @@ int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen ) } } +#ifdef DEBUG + syslog(LOG_INFO, "end afp_deleteid:"); +#endif DEBUG + return err; } #endif @@ -1371,7 +1426,11 @@ int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen ) #endif cnid_t sid, did; u_int16_t vid; - + +#ifdef DEBUG + syslog(LOG_INFO, "begin afp_exchangefiles:"); +#endif DEBUG + *rbuflen = 0; ibuf += 2; @@ -1519,6 +1578,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; diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index 1a475f7c..367e94b4 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -22,9 +22,7 @@ #include #include #include -#ifdef DROPKLUDGE #include -#endif DROPKLUDGE #include "directory.h" #include "desktop.h" @@ -34,6 +32,96 @@ #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; @@ -47,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; @@ -103,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 ); } @@ -118,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)); @@ -164,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 ); } @@ -185,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; @@ -335,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 ); } @@ -350,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; @@ -385,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 ); } @@ -431,17 +553,15 @@ int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen ) char *oldname, *newname; char *path, *p, *upath; int did, rc; - int plen; + int plen, retvalue; u_int16_t vid; #if AD_VERSION > AD_VERSION1 cnid_t id; #endif -#ifdef DROPKLUDGE - struct stat sb; - struct dir *dir; - char adpath[50]; - int uid; -#endif DROPKLUDGE + +#ifdef DEBUG + syslog(LOG_INFO, "begin afp_moveandrename:"); +#endif DEBUG *rbuflen = 0; ibuf += 2; @@ -552,38 +672,10 @@ int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen ) } else { rc = renamedir(p, upath, odir, curdir, newname, vol_noadouble(vol)); } + #ifdef DROPKLUDGE - strcpy (adpath, "./.AppleDouble/"); - strcat (adpath, newname); - if (( dir = dirsearch( vol, did )) == NULL ) { - syslog (LOG_ERR, "afp_moveandrename: Unable to get directory info."); - return( AFPERR_NOOBJ ); - } - else - if (stat(".", &sb) < 0) { - syslog (LOG_ERR, "afp_moveandrename: Error checking directory \"%s\": %m", dir->d_name); - return(-1); - } - else { - uid=geteuid(); - if ( uid != sb.st_uid ) - { - seteuid(0); - if (lchown(newname, sb.st_uid, sb.st_gid) < 0) - { - syslog (LOG_ERR, "afp_moveandrename: Error changing owner/gid of %s: %m", p); - return (-1); - } - if (lchown(adpath, sb.st_uid, sb.st_gid) < 0) - { - syslog (LOG_ERR, "afp_moveandrename: Error changing AppleDouble owner/gid %s: %m", adpath); - return (-1); - } - } - else - syslog (LOG_DEBUG, "No ownership change necessary."); - } - seteuid(uid); /* Restore process ownership to normal */ + if (retvalue=matchfile2dirperms (newname, vol, did) != AFP_OK) + return retvalue; #endif DROPKLUDGE if ( rc == AFP_OK ) { @@ -597,6 +689,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 ); } diff --git a/etc/afpd/filedir.h b/etc/afpd/filedir.h index c20bc61c..23dcf2bf 100644 --- a/etc/afpd/filedir.h +++ b/etc/afpd/filedir.h @@ -2,6 +2,7 @@ #define AFPD_FILEDIR_H 1 #include +#include #include "globals.h" #include "volume.h" @@ -9,6 +10,7 @@ extern char *ctoupath __P((const struct vol *, struct dir *, char *)); /* FP functions */ +extern int matchfile2dirperms __P((char *, struct vol *, int)); extern int afp_moveandrename __P((AFPObj *, char *, int, char *, int *)); extern int afp_rename __P((AFPObj *, char *, int, char *, int *)); extern int afp_delete __P((AFPObj *, char *, int, char *, int *)); diff --git a/etc/afpd/unix.c b/etc/afpd/unix.c index 3bef4fcc..bd7be335 100644 --- a/etc/afpd/unix.c +++ b/etc/afpd/unix.c @@ -184,19 +184,19 @@ const mode_t mode; seteuid(0); if ( retval=chmod( name, (DIRBITS | mode | S_ISVTX)) < 0) { - syslog( LOG_ERR, "stickydirmode::setdirmode error: chmod %s: %m", name ); - return(-1); + syslog( LOG_ERR, "stickydirmode: chmod %s: %m", name ); + return(AFP_ACCESS); } else { - syslog( LOG_DEBUG, "stickydirmode::setdirmode: chmod %s: %m", name ); + syslog( LOG_DEBUG, "stickydirmode: chmod \"%s\": %m", name ); seteuid(uid); } } else #endif DROPKLUDGE if ( retval=chmod( name, DIRBITS | mode ) < 0 ) - syslog( LOG_DEBUG, "stickydirmode::setdirmode: chmod %s: %m", name ); + syslog( LOG_DEBUG, "stickydirmode: chmod \"%s\": %m", name ); return retval; } @@ -299,9 +299,10 @@ int setdirmode( mode, noadouble ) if (S_ISREG(st.st_mode)) { /* XXX: need to preserve special modes */ if (S_ISDIR(st.st_mode)) { - stickydirmode(dirp->d_name, DIRBITS | mode); - } else - stickydirmode(dirp->d_name, mode); + if (stickydirmode(dirp->d_name, DIRBITS | mode) < 0) + return (-1); + } else if (stickydirmode(dirp->d_name, mode) < 0) + return (-1); } } closedir( dir );