The change a couple days ago to create files initially without group and
authorDavid Dykstra <dwd@samba.org>
Thu, 4 Mar 1999 21:48:52 +0000 (21:48 +0000)
committerDavid Dykstra <dwd@samba.org>
Thu, 4 Mar 1999 21:48:52 +0000 (21:48 +0000)
other access resulted in group and other access being left off when the
'-p' option was not used.  This fixes it by reintroducing the ACCESSPERMS
mask and setting permissions to (file->mode & ACCESSPERMS) if preserve_perms
is off.  I decided to change the mask INITPERMMASK to INITACCESSPERMS at
the same time.  When preserve_perms is off, rsync is restored to the
previous behavior of having the permissions of the original file with the
umask and setuid/setgid bits shut off.

Also, I decided that a check for "(updated && (file->mode & ~ACCESSPERMS))"
is no longer needed since as far as I can tell that would have only affected
permissions when not running as root and when a chgrp was done to a group
the user was not a member of, using system V chgrp semantics.  This is no
longer allowed.

receiver.c
rsync.c
rsync.h

index d941fa2..5882e60 100644 (file)
@@ -412,14 +412,15 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                   setuid/setgid bits to ensure that there is no race
                   condition. They are then correctly updated after
                   the lchown. Thanks to snabb@epipe.fi for pointing
-                  this out */
+                  this out.  We also set it initially without group
+                  access because of a similar race condition. */
                fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
-                             file->mode & INITPERMMASK);
+                             file->mode & INITACCESSPERMS);
 
                if (fd2 == -1 && relative_paths && errno == ENOENT && 
                    create_directory_path(fnametmp) == 0) {
                        fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
-                                     file->mode & INITPERMMASK);
+                                     file->mode & INITACCESSPERMS);
                }
                if (fd2 == -1) {
                        rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));
diff --git a/rsync.c b/rsync.c
index 02dd837..87a8056 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -200,14 +200,19 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
        }
 
 #ifdef HAVE_CHMOD
-       if (preserve_perms && !S_ISLNK(st->st_mode) &&
-           (st->st_mode != file->mode || 
-            (updated && (file->mode & ~INITPERMMASK)))) {
-               updated = 1;
-               if (do_chmod(fname,file->mode) != 0) {
-                       rprintf(FERROR,"failed to set permissions on %s : %s\n",
-                               fname,strerror(errno));
-                       return 0;
+       if (!S_ISLNK(st->st_mode)) {
+               int file_mode;
+               if (preserve_perms)
+                       file_mode = file->mode;
+               else
+                       file_mode = file->mode & ACCESSPERMS;
+               if (st->st_mode != file->mode) {
+                       updated = 1;
+                       if (do_chmod(fname,file_mode) != 0) {
+                               rprintf(FERROR,"failed to set permissions on %s : %s\n",
+                                       fname,strerror(errno));
+                               return 0;
+                       }
                }
        }
 #endif
@@ -260,7 +265,7 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
                if (errno == EXDEV) {
                        /* rename failed on cross-filesystem link.  
                           Copy the file instead. */
-                       if (copy_file(fnametmp,fname, file->mode & INITPERMMASK)) {
+                       if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) {
                                rprintf(FERROR,"copy %s -> %s : %s\n",
                                        fnametmp,fname,strerror(errno));
                        } else {
diff --git a/rsync.h b/rsync.h
index 92823bb..3e040d4 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -462,10 +462,13 @@ extern int errno;
 
 #define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
 
+#ifndef ACCESSPERMS
+#define ACCESSPERMS 0777
+#endif
 /* Initial mask on permissions given to temporary files.  Mask off setuid
      bits and group access because of potential race-condition security
      holes, and mask other access because mode 707 is bizarre */
-#define INITPERMMASK 0700
+#define INITACCESSPERMS 0700
 
 /* handler for null strings in printf format */
 #define NS(s) ((s)?(s):"<NULL>")