diff --git a/weed/filesys/dir.go b/weed/filesys/dir.go index be140e8df..96ca4fcac 100644 --- a/weed/filesys/dir.go +++ b/weed/filesys/dir.go @@ -424,31 +424,44 @@ func findFileType(mode uint16) fuse.DirentType { func (dir *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { - if err := checkPermission(dir.entry, req.Uid, req.Gid, true); err != nil { + parentHasPermission := false + parentEntry, err := dir.maybeLoadEntry() + if err != nil { return err } + if err := checkPermission(parentEntry, req.Uid, req.Gid, true); err == nil { + parentHasPermission = true + } + + dirFullPath := dir.FullPath() + filePath := util.NewFullPath(dirFullPath, req.Name) + entry, err := filer_pb.GetEntry(dir.wfs, filePath) + if err != nil { + return err + } + if !parentHasPermission { + if err := checkPermission(entry, req.Uid, req.Gid, true); err != nil { + return err + } + } if !req.Dir { - return dir.removeOneFile(req) + return dir.removeOneFile(entry, req) } - return dir.removeFolder(req) + return dir.removeFolder(entry, req) } -func (dir *Dir) removeOneFile(req *fuse.RemoveRequest) error { +func (dir *Dir) removeOneFile(entry *filer_pb.Entry, req *fuse.RemoveRequest) error { dirFullPath := dir.FullPath() filePath := util.NewFullPath(dirFullPath, req.Name) - entry, err := filer_pb.GetEntry(dir.wfs, filePath) - if err != nil { - return err - } // first, ensure the filer store can correctly delete glog.V(3).Infof("remove file: %v", req) isDeleteData := entry != nil && entry.HardLinkCounter <= 1 - err = filer_pb.Remove(dir.wfs, dirFullPath, req.Name, isDeleteData, false, false, false, []int32{dir.wfs.signature}) + err := filer_pb.Remove(dir.wfs, dirFullPath, req.Name, isDeleteData, false, false, false, []int32{dir.wfs.signature}) if err != nil { glog.V(3).Infof("not found remove file %s: %v", filePath, err) return fuse.ENOENT @@ -473,9 +486,10 @@ func (dir *Dir) removeOneFile(req *fuse.RemoveRequest) error { } -func (dir *Dir) removeFolder(req *fuse.RemoveRequest) error { +func (dir *Dir) removeFolder(entry *filer_pb.Entry, req *fuse.RemoveRequest) error { dirFullPath := dir.FullPath() + glog.V(3).Infof("remove directory entry: %v", req) ignoreRecursiveErr := false // ignore recursion error since the OS should manage it err := filer_pb.Remove(dir.wfs, dirFullPath, req.Name, true, false, ignoreRecursiveErr, false, []int32{dir.wfs.signature}) diff --git a/weed/filesys/permission.go b/weed/filesys/permission.go index a8c4cd891..2edfd49dd 100644 --- a/weed/filesys/permission.go +++ b/weed/filesys/permission.go @@ -6,6 +6,9 @@ import ( ) func checkPermission(entry *filer_pb.Entry, uid, gid uint32, isWrite bool) error { + if uid == 0 || gid == 0 { + return nil + } if entry == nil { return nil } @@ -15,13 +18,13 @@ func checkPermission(entry *filer_pb.Entry, uid, gid uint32, isWrite bool) error attr := entry.Attributes if attr.Uid == uid { if isWrite { - if attr.FileMode&0002 > 0 { + if attr.FileMode&0200 > 0 { return nil } else { return fuse.EPERM } } else { - if attr.FileMode&0004 > 0 { + if attr.FileMode&0400 > 0 { return nil } else { return fuse.EPERM @@ -43,13 +46,13 @@ func checkPermission(entry *filer_pb.Entry, uid, gid uint32, isWrite bool) error } } else { if isWrite { - if attr.FileMode&0200 > 0 { + if attr.FileMode&0002 > 0 { return nil } else { return fuse.EPERM } } else { - if attr.FileMode&0400 > 0 { + if attr.FileMode&0004 > 0 { return nil } else { return fuse.EPERM