]> arthur.barton.de Git - netatalk.git/commitdiff
Added DROPKLUDGE file copying support, modularized DROPKLUDGE operations,
authoritlm019 <itlm019>
Thu, 19 Oct 2000 23:42:49 +0000 (23:42 +0000)
committeritlm019 <itlm019>
Thu, 19 Oct 2000 23:42:49 +0000 (23:42 +0000)
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.

etc/afpd/file.c
etc/afpd/filedir.c
etc/afpd/filedir.h
etc/afpd/unix.c

index fd1a980bab7662a739dbe0db0f96d7b2d0f91a1a..a5529df7c96b7a5fbbf4fe1f0ddccc9c752c1206 100644 (file)
@@ -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;
 
 
index 1a475f7c6bf850ef77df02bc9564cc5cfc83eec2..367e94b47fbaae4cef35ff9c1815073671a7e815 100644 (file)
@@ -22,9 +22,7 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <string.h>
-#ifdef DROPKLUDGE
 #include <unistd.h>
-#endif DROPKLUDGE
 
 #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;
@@ -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 );
 }
 
index c20bc61cfafcd2e6b938db1e025e3595c55b5ed0..23dcf2bf2a42d4eece708e22e2595264be71e1ad 100644 (file)
@@ -2,6 +2,7 @@
 #define AFPD_FILEDIR_H 1
 
 #include <sys/cdefs.h>
+#include <sys/stat.h>
 #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 *));
index 3bef4fcc3075c71d31a60ccd5ac9855719f51e3e..bd7be335e6723d6451235c13a1fad2609da0185b 100644 (file)
@@ -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 );