Explorar o código

Preserve setgid bit on local directores (fixes #2012)

When setting the permissions on directories with ignore permissions off,
preserve the setgid bit to it's original value instead of setting it
off.
Daniel Bergmann %!s(int64=10) %!d(string=hai) anos
pai
achega
3fe1673ce9
Modificáronse 1 ficheiros con 14 adicións e 3 borrados
  1. 14 3
      internal/model/rwfolder.go

+ 14 - 3
internal/model/rwfolder.go

@@ -50,6 +50,9 @@ type copyBlocksState struct {
 	blocks []protocol.BlockInfo
 }
 
+// Which filemode bits to preserve
+const retainBits = os.ModeSetgid | os.ModeSetuid | os.ModeSticky
+
 var (
 	activity    = newDeviceActivity()
 	errNoDevice = errors.New("no available source device")
@@ -644,7 +647,16 @@ func (p *rwFolder) handleDir(file protocol.FileInfo) {
 			if err != nil || p.ignorePermissions(file) {
 				return err
 			}
-			return os.Chmod(path, mode)
+
+			// Stat the directory so we can check its permissions.
+			info, err := osutil.Lstat(path)
+			if err != nil {
+				return err
+			}
+
+			// Mask for the bits we want to preserve and add them in to the
+			// directories permissions.
+			return os.Chmod(path, mode|(info.Mode()&retainBits))
 		}
 
 		if err = osutil.InWritableDir(mkdir, realName); err == nil {
@@ -665,10 +677,9 @@ func (p *rwFolder) handleDir(file protocol.FileInfo) {
 	// The directory already exists, so we just correct the mode bits. (We
 	// don't handle modification times on directories, because that sucks...)
 	// It's OK to change mode bits on stuff within non-writable directories.
-
 	if p.ignorePermissions(file) {
 		p.dbUpdates <- dbUpdateJob{file, dbUpdateHandleDir}
-	} else if err := os.Chmod(realName, mode); err == nil {
+	} else if err := os.Chmod(realName, mode|(info.Mode()&retainBits)); err == nil {
 		p.dbUpdates <- dbUpdateJob{file, dbUpdateHandleDir}
 	} else {
 		l.Infof("Puller (folder %q, dir %q): %v", p.folder, file.Name, err)