diff --git a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
index 467a0eee12c51877db3d1db08e87427a419386e6..b4b3356276876caf282bb4b0136ff723789a342f 100644
--- a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
+++ b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
@@ -12,8 +12,11 @@ import java.sql.SQLException;
 import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import javax.sql.DataSource;
@@ -147,6 +150,9 @@ public class NodeDAO {
             return ps;
         });
         
+        if (recursive == true)
+            updatePermissionsRecursively(newNode, vosPath);
+        
         return newNode;
     }
 
@@ -366,6 +372,79 @@ public class NodeDAO {
         }
         
     }
+    
+    /*
+    Map contains:
+    Key             column
+    column name     value
+    column name     value
+    and value is a String containing comma separated groups having permissions
+    */
+    private Map getPermissionsFromDB(String vosPath) {
+        
+        String sql = "SELECT group_read, group_write "
+                + "FROM node n JOIN node_vos_path p ON n.node_id = p.node_id "
+                + "WHERE p.vos_path = ?";
+        
+        Map<String, Object> result =  (Map<String, Object>) jdbcTemplate
+                              .queryForMap(sql, new Object[] {vosPath});
+        
+        return result;
+        
+    }
+    
+    private void updatePermissionsRecursively(Node newNode, String vosPath) {
+        
+        Map permissions = getPermissionsFromDB(vosPath);
+        String existingGroupReadStr = (String)permissions.get("group_read");
+        String existingGroupWriteStr = (String)permissions.get("group_write");
+        
+        List<String> existingGroupReadList = NodeProperties.parsePropertyStringToList(existingGroupReadStr);
+        List<String> existingGroupWriteList = NodeProperties.parsePropertyStringToList(existingGroupWriteStr);
+        
+        List<String> newGroupReadList = NodeProperties.getNodePropertyAsListByURI(newNode, NodeProperties.GROUP_READ_URI);
+        List<String> newGroupWriteList = NodeProperties.getNodePropertyAsListByURI(newNode, NodeProperties.GROUP_WRITE_URI);
+        
+        Set<String> existingGroupRead = new HashSet<>(existingGroupReadList);
+        Set<String> existingGroupWrite = new HashSet<>(existingGroupWriteList);
+        
+        Set<String> newGroupRead = new HashSet<>(newGroupReadList);
+        Set<String> newGroupWrite = new HashSet<>(newGroupWriteList);
+        
+        Set<String> groupReadToAdd = differenceBetweenSets(newGroupRead, existingGroupRead) ;                
+        Set<String> groupReadToRemove = differenceBetweenSets(existingGroupRead, newGroupRead) ;
+        
+        Set<String> groupWriteToAdd = differenceBetweenSets(newGroupWrite, existingGroupWrite) ;                
+        Set<String> groupWriteToRemove = differenceBetweenSets(existingGroupWrite, newGroupWrite) ;
+        
+        String sql = "UPDATE node SET " +
+                       "group_read = update_array(group_read, " +  groupReadToAdd + ", " + groupReadToRemove + "), " +
+                       "group_write = update_array(group_write, " + groupWriteToAdd + ", " + groupWriteToRemove + "), " + 
+                       "is_public = ? " +
+                       "WHERE path <@ (SELECT path FROM node n " +
+                       "JOIN node_vos_path p ON n.node_id = p.node_id " +
+                       "AND p.vos_path = ?)";
+        
+
+        jdbcTemplate.update(conn -> {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            int i = 0;
+            ps.setBoolean(++i, Boolean.valueOf(NodeProperties.getNodePropertyByURI(newNode, NodeProperties.PUBLIC_READ_URI)));
+            ps.setString(++i, vosPath);
+            return ps;
+        });
+        
+    }
+
+    // Returns the difference a minus b
+    private Set<String> differenceBetweenSets(Set<String> a, Set<String> b) {
+        
+        Set<String> diff = new HashSet<>(a);
+        diff.removeAll(b);
+        
+        return diff;
+        
+    }
           
     private List<NodePaths> getNodePathsFromDB(String nodeURI) {        
 
@@ -411,5 +490,6 @@ public class NodeDAO {
             return this.relativePath;
         } 
         
-    }
+    }    
+    
 }