Просмотр исходного кода

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 10 лет назад
Родитель
Сommit
3fe1673ce9
1 измененных файлов с 14 добавлено и 3 удалено
  1. 14 3
      internal/model/rwfolder.go

+ 14 - 3
internal/model/rwfolder.go

@@ -50,6 +50,9 @@ type copyBlocksState struct {
 	blocks []protocol.BlockInfo
 	blocks []protocol.BlockInfo
 }
 }
 
 
+// Which filemode bits to preserve
+const retainBits = os.ModeSetgid | os.ModeSetuid | os.ModeSticky
+
 var (
 var (
 	activity    = newDeviceActivity()
 	activity    = newDeviceActivity()
 	errNoDevice = errors.New("no available source device")
 	errNoDevice = errors.New("no available source device")
@@ -644,7 +647,16 @@ func (p *rwFolder) handleDir(file protocol.FileInfo) {
 			if err != nil || p.ignorePermissions(file) {
 			if err != nil || p.ignorePermissions(file) {
 				return err
 				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 {
 		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
 	// The directory already exists, so we just correct the mode bits. (We
 	// don't handle modification times on directories, because that sucks...)
 	// don't handle modification times on directories, because that sucks...)
 	// It's OK to change mode bits on stuff within non-writable directories.
 	// It's OK to change mode bits on stuff within non-writable directories.
-
 	if p.ignorePermissions(file) {
 	if p.ignorePermissions(file) {
 		p.dbUpdates <- dbUpdateJob{file, dbUpdateHandleDir}
 		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}
 		p.dbUpdates <- dbUpdateJob{file, dbUpdateHandleDir}
 	} else {
 	} else {
 		l.Infof("Puller (folder %q, dir %q): %v", p.folder, file.Name, err)
 		l.Infof("Puller (folder %q, dir %q): %v", p.folder, file.Name, err)