security: require delete permission for HTTP rename overwrite
This commit is contained in:
@@ -263,6 +263,30 @@ func (s *Server) newdir(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.logOp(r, fmt.Sprintf("created directory '%s'", p))
|
s.logOp(r, fmt.Sprintf("created directory '%s'", p))
|
||||||
writeCreated(w)
|
writeCreated(w)
|
||||||
}
|
}
|
||||||
|
func checkDeleteTree(store storage.Storage, a *auth.Account, root string) error {
|
||||||
|
info, err := store.Stat(root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !a.MaskFor(root).HasDelete() {
|
||||||
|
return fmt.Errorf("delete permission denied")
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
items, err := store.List(root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, item := range items {
|
||||||
|
p := path.Join(root, item.Name())
|
||||||
|
if err := checkDeleteTree(store, a, p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
|
||||||
a := account(r, s)
|
a := account(r, s)
|
||||||
rawOld, rawNew := r.FormValue("old"), r.FormValue("new")
|
rawOld, rawNew := r.FormValue("old"), r.FormValue("new")
|
||||||
@@ -276,6 +300,17 @@ func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
|
|||||||
writeJSONError(w, http.StatusForbidden, "has no privilege")
|
writeJSONError(w, http.StatusForbidden, "has no privilege")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if old != neu {
|
||||||
|
if _, e := s.Store.Stat(neu); e == nil {
|
||||||
|
if e := checkDeleteTree(s.Store, a, neu); e != nil {
|
||||||
|
writeJSONError(w, http.StatusForbidden, "has no privilege")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if !os.IsNotExist(e) {
|
||||||
|
http.Error(w, e.Error(), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
if e := s.Store.Rename(old, neu); e != nil {
|
if e := s.Store.Rename(old, neu); e != nil {
|
||||||
http.Error(w, e.Error(), 500)
|
http.Error(w, e.Error(), 500)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user