diff -Naur ./js/webfm.js /home/xl666/Escritorio/webfm/js/webfm.js
--- ./js/webfm.js	2010-03-10 14:49:00.000000000 -0600
+++ /home/xl666/Escritorio/webfm/js/webfm.js	2010-03-14 12:12:36.092102502 -0600
@@ -383,12 +383,12 @@
   //global to allow external functions to push new menu elements into the menu array
   Webfm.menuHT = new Webfm.hht();
   try {
-    Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.menuAdmin));
+    Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.usCreateDir)); //xl666 modification
     Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg["search"], Webfm.menuSearch, ''));
 
-    Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.menuAdmin));
-    Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rmdir"], Webfm.menuRemove, Webfm.menuAdmin));
-    Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rendir"], Webfm.menuRename, Webfm.menuAdmin));
+    Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.usCreateDir));//xl666 modification
+    Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rmdir"], Webfm.menuRemove, Webfm.menuFileUid));//xl666 modification
+    Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rendir"], Webfm.menuRename, Webfm.menuRenFileUid)); // xl666 modification
     Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["search"], Webfm.menuSearch, ''));
 
     Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["rm"], Webfm.menuRemove, Webfm.menuFileUid));
@@ -868,7 +868,7 @@
 //maintain 4 column table
 Webfm.list.prototype.adminCtl = function(admin) {
   col_span = getWebfmOwnerColumn() ? 4 : 3
-  if(admin) {
+  if(Webfm.usCreateDir("")) { //xl666 modification
     if(Webfm.$('webfm-bcrumb-td').colSpan == col_span) {
       var wl = this;
       Webfm.$('webfm-bcrumb-td').colSpan = col_span - 1;
@@ -887,29 +887,30 @@
       var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true, 0); });
       var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false, 0); });
       elSpan.appendChild(elA);
-
-      var elA = Webfm.ce('a');
-      elA.title = Webfm.js_msg["add-2-db"];
-      var elImg = Webfm.ce('img');
-      elImg.setAttribute('alt', Webfm.js_msg["add-2-db"]);
-      elImg.setAttribute('src', this.iconDir + '/add_loc.gif');
-      elA.appendChild(elImg);
-      var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { Webfm.stopEvent(e);wl.enumLocal(); });
-      var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true); });
-      var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false); });
-      elSpan.appendChild(elA);
-
-      var elA = Webfm.ce('a');
-      elA.title = Webfm.js_msg["r-add-2-db"];
-      var elImg = Webfm.ce('img');
-      elImg.setAttribute('alt', Webfm.js_msg["r-add-2-db"]);
-      elImg.setAttribute('src', this.iconDir + '/add_recur.gif');
-      elA.appendChild(elImg);
-      var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { Webfm.stopEvent(e);wl.enumRecur(); });
-      var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true); });
-      var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false); });
-      elSpan.appendChild(elA);
-
+	if(admin)
+	{
+	    var elA = Webfm.ce('a');
+	    elA.title = Webfm.js_msg["add-2-db"];
+	    var elImg = Webfm.ce('img');
+	    elImg.setAttribute('alt', Webfm.js_msg["add-2-db"]);
+	    elImg.setAttribute('src', this.iconDir + '/add_loc.gif');
+	    elA.appendChild(elImg);
+	    var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { Webfm.stopEvent(e);wl.enumLocal(); });
+	    var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true); });
+	    var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false); });
+	    elSpan.appendChild(elA);
+
+	    var elA = Webfm.ce('a');
+	    elA.title = Webfm.js_msg["r-add-2-db"];
+	    var elImg = Webfm.ce('img');
+	    elImg.setAttribute('alt', Webfm.js_msg["r-add-2-db"]);
+	    elImg.setAttribute('src', this.iconDir + '/add_recur.gif');
+	    elA.appendChild(elImg);
+	    var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "click", function(e) { Webfm.stopEvent(e);wl.enumRecur(); });
+	    var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseover", function(e) { wl.hover(e, true); });
+	    var listener = Webfm.eventListenerAdd(Webfm.eventListeners, elA, "mouseout", function(e) { wl.hover(e, false); });
+	    elSpan.appendChild(elA);
+	}
       elTd.appendChild(elSpan);
 
       Webfm.$('webfm-top-tr').appendChild(elTd);
@@ -1032,6 +1033,7 @@
  */
 Webfm.dirrow = function(parent, dir, index, dd_enable, menu, eventListenerArr) {
   var dr = this;
+  this.uid = dir.u; //xl666 modification
   this.draggable = dd_enable;
   this.iconDir = getWebfmIconDir();
   //id used for drop container
@@ -1042,7 +1044,7 @@
 
   elTr.setAttribute('id', _id);
   elTr.setAttribute('title', dir.p);
-  if(dd_enable && Webfm.admin) {
+  if(dd_enable && (Webfm.admin || this.uid==getWebfmUid())) {//xl666 modification
     //Webfm.draggable must be created after title assigned to set current path
     this.dd = new Webfm.draggable(Webfm.dragCont, elTr, this.element.className);
   } else {
@@ -1085,8 +1087,8 @@
   if(getWebfmOwnerColumn()) {
     var elTd = Webfm.ce('td');
     elTd.className = 'txt';
-    if(dir.o) {
-      var owner = Webfm.ce(dir.o);
+    if(dir.u) { // xl666 modification
+      var owner = dir.un; //xl666 modification
       elTd.appendChild(Webfm.ctn(owner));
     }
     elTr.appendChild(elTd);
@@ -2086,6 +2088,13 @@
   //determine if we are the owner of this file
   return((Webfm.admin || obj.uid == getWebfmUid()) ? true : false);
 }
+
+Webfm.usCreateDir=function(obj){ //xl666 new function
+	if(canCreateDir() >= 1) return true;
+	else return false;
+}
+
+
 Webfm.menuRenFileUid =function(obj) {
   if(Webfm.menuFileUid(obj))
     // Determine if name is a metadata title
diff -Naur ./webfm_file.inc /home/xl666/Escritorio/webfm/webfm_file.inc
--- ./webfm_file.inc	2009-08-19 10:37:09.000000000 -0500
+++ /home/xl666/Escritorio/webfm/webfm_file.inc	2010-03-14 12:16:55.644102329 -0600
@@ -55,6 +55,7 @@
   $dest_temp = $dest.'~'; //handle possible case problem
   //File
   //if target is a file and new name isn't already used...
+  $res=db_fetch_object(db_query("SELECT uid FROM {webfm_directory} WHERE path='%s'",$source)); //xl666 modification
   if(is_file($source) && !is_file($dest)) {
     $file_o = webfm_get_file_record('', $source);
     //if we are admin or owner of target file...
@@ -91,8 +92,9 @@
 
   //Directory
   //if target is a directory, new name is a unique path and we are an admin...
-  else if(is_dir($source) && !is_dir($dest) && ($uid == 1)) {
+  else if(is_dir($source) && !is_dir($dest) && ($uid == 1 || $uid == $res->uid)) { //xl666 modification
     //if the target isn't read-only
+    changePathRecursively($source,$dest);// xl666 modification
     if(@rename($source, $dest_temp)) {
       //directory rename is OK, back out, rename db files and rename dir again
       @rename($dest_temp, $source);
@@ -271,4 +273,34 @@
   }
   return $result;
 }
+
+/*
+ * Added by xl666,  maintains the integrity of the directory owners when a
+ * directory that contains another directories is moved or renamed it
+ */
+function changePathRecursively($source,$dest)
+{
+  $que=db_query("SELECT path FROM {webfm_directory} WHERE path like '%s%'",$source);
+  while($res=db_fetch_object($que))
+    {
+      $arrPath=explode($source,$res->path);
+      $sub=$dest;
+      for($i=1;$i<count($arrPath);$i++)
+	{
+	  $sub.=$arrPath[$i];
+	}
+          db_query("UPDATE {webfm_directory} set path='%s' WHERE path='%s'",$sub,$res->path);
+    }
+}
+
+/* 
+ * added by xl666, maintains the consistency of directory owners when there are
+ * deletions 
+ */
+function xdeleteRecursively($source)
+{
+  db_query("DELETE FROM {webfm_directory} WHERE path like '%s%'",$source);
+}
+
+
 ?>
diff -Naur ./webfm.install /home/xl666/Escritorio/webfm/webfm.install
--- ./webfm.install	2010-03-10 15:19:24.000000000 -0600
+++ /home/xl666/Escritorio/webfm/webfm.install	2010-03-14 12:21:22.644102126 -0600
@@ -89,6 +89,15 @@
     ),
     'primary key' => array('nid', 'fid', 'cid' ),
   );
+$schema['webfm_directory'] = array( //xl666 new schema
+    'fields' => array(
+      'path' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE),
+      'uid' => array('type' => 'int', 'size' => 'normal', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+    ),
+    //doesn't have primary key, the logical it would be that path were the
+    //primary key but mysql doesn't support text/blob types as primary key 
+  );
+
   return $schema;
 }
 
@@ -105,3 +114,14 @@
   db_add_primary_key($ret, 'webfm_attach', array('nid', 'cid', 'fid'));
   return $ret;
 }
+function webfm_update_666() // added by xl666
+{
+   $schema['webfm_directory'] = array( 
+      'fields' => array(
+	 'path' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE),
+	 'uid' => array('type' => 'int', 'size' => 'normal', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+	 ));
+   $ret = array();
+   db_create_table($ret, 'webfm_directory', $schema['webfm_directory']);
+   return $ret;
+}
diff -Naur ./webfm.module /home/xl666/Escritorio/webfm/webfm.module
--- ./webfm.module	2010-03-11 21:24:56.000000000 -0600
+++ /home/xl666/Escritorio/webfm/webfm.module	2010-03-14 12:02:43.268102107 -0600
@@ -153,7 +153,7 @@
  * Implementation of hook_perm().
  */
 function webfm_perm() {
-  return array('access webfm', 'view webfm attachments', 'administer webfm', 'webfm upload');
+  return array('access webfm', 'view webfm attachments', 'administer webfm', 'webfm upload','create directory');
 }
 
 /**
@@ -1022,8 +1022,10 @@
 
             if(is_dir($source)) {
               //Only admins can delete directories (and contained files)
-              if($webfm_perm == WEBFM_ADMIN) {
+	      $res=db_fetch_object(db_query("SELECT uid FROM {webfm_directory} WHERE path='%s'",$source)); //xl666 modification
+              if($webfm_perm == WEBFM_ADMIN || ($res->uid==$user->uid)) {//xl666 modification
                 $err_arr[] = array();
+		xdeleteRecursively($source); //xl666 modification
                 $ret = webfm_delete_dir_recur($source, TRUE, $err_arr);
                 webfm_json(array('status' => $ret, 'data' => $err_arr));
                 exit();
@@ -1071,7 +1073,7 @@
       //Create new directory
       case "mkdir":
         //Only admins can create directories
-        if($webfm_perm == WEBFM_ADMIN) {
+        if($webfm_perm == WEBFM_ADMIN || user_access('create directory')) {// xl666 modification
           if(isset($_POST["param0"])) {
             $source = $root_dir.trim(rawurldecode($_POST["param0"]));
             $dest = t("New_Folder");
@@ -1079,8 +1081,9 @@
             // third param is right to rename if a dir of same name already
             // exixts in current folder
             if(($ret = webfm_mkdir($source, $dest, TRUE, $err_arr))!== FALSE) {
-              $ret = ltrim($ret, $root_dir);
+              $ret = ltrim($ret, $root_dir);	      
               webfm_json(array('status' => TRUE, 'data' => $ret));
+	      db_query("INSERT INTO {webfm_directory} (path,uid) VALUES ('%s',%d)",$source.'/'.$dest,$user->uid); // xl666 modification           
             } else {
               webfm_json(array('status' => FALSE, 'data' => $err_arr));
             }
@@ -1100,7 +1103,8 @@
         if(isset($_POST["param0"]) && isset($_POST["param1"])) {
           $source = $root_dir.trim(rawurldecode($_POST["param0"]));
           $dest = $root_dir.trim(rawurldecode($_POST["param1"]));
-          if(is_dir($source) && ($webfm_perm != WEBFM_ADMIN)) {
+	  $res=db_fetch_object(db_query("SELECT uid FROM {webfm_directory} WHERE path='%s'",$source)); //xl666 modification
+          if(is_dir($source) && (($webfm_perm != WEBFM_ADMIN) && ($res->uid != $user->uid))) { //xl666 modification
             //Only admins can manipulate directories
             webfm_json(array('status' => FALSE, 'data' => t('permission denied')));
             exit();
@@ -1736,7 +1740,7 @@
  * Function to pass base_url, icon directory, debug and cleanurl flags
  */
 function webfm_inline_js($base_url, $base_path, $clean_url, $uid) {
-  $js = 'function getBaseUrl(){return '. drupal_to_js($base_url) .';} function getBasePath(){return '. drupal_to_js($base_path) .';} function getWebfmIconDir(){return '. drupal_to_js($base_url .'/'. variable_get('webfm_icon_dir', drupal_get_path('module', 'webfm') .'/image/icon')) .';} function getWebfmCleanUrl(){return '.drupal_to_js($clean_url).'; }function getWebfmIETreeOffset(){return '.drupal_to_js(variable_get('webfm_ie_dd_tree_offset', '')).';}function getWebfmIEListOffset(){return '.drupal_to_js(variable_get('webfm_ie_dd_list_offset', '')).';} function getWebfmUid(){return '.drupal_to_js($uid).';} function getWebfmDateFormat(){return '.drupal_to_js(variable_get('webfm_date_format', WEBFM_DATE_FORMAT_DAY)).';} function getWebfmMetaName(){return '.drupal_to_js(variable_get('webfm_display_title', '')).';} function getWebfmOwnerColumn(){return '.drupal_to_js(variable_get('webfm_display_owner', '')).';}' ;
+  $js = 'function getBaseUrl(){return '. drupal_to_js($base_url) .';} function getBasePath(){return '. drupal_to_js($base_path) .';} function getWebfmIconDir(){return '. drupal_to_js($base_url .'/'. variable_get('webfm_icon_dir', drupal_get_path('module', 'webfm') .'/image/icon')) .';} function getWebfmCleanUrl(){return '.drupal_to_js($clean_url).'; }function getWebfmIETreeOffset(){return '.drupal_to_js(variable_get('webfm_ie_dd_tree_offset', '')).';}function getWebfmIEListOffset(){return '.drupal_to_js(variable_get('webfm_ie_dd_list_offset', '')).';} function getWebfmUid(){return '.drupal_to_js($uid).';} function canCreateDir(){if('.drupal_to_js(user_access('create directory')).') return 1; else return 0;} function getWebfmDateFormat(){return '.drupal_to_js(variable_get('webfm_date_format', WEBFM_DATE_FORMAT_DAY)).';} function getWebfmMetaName(){return '.drupal_to_js(variable_get('webfm_display_title', '')).';} function getWebfmOwnerColumn(){return '.drupal_to_js(variable_get('webfm_display_owner', '')).';}' ;
   drupal_add_js($js, 'inline');
 }
 
@@ -2015,7 +2019,11 @@
         foreach($_dirs as $dir) {
           $dd = new stdClass();
           $dd->n = $dir;
+	  $temp=db_fetch_object(db_query("SELECT name FROM {webfm_directory} as t1 natural join {users} as t2  WHERE t1.uid=t2.uid AND t1.path='%s'",$root.$path."/".$dir)); //xl666 modification
+          $dd->un= $temp->name; // xl666 modification
           $dd->p = $path."/".$dir;
+	  $temp=db_fetch_object(db_query("SELECT uid FROM {webfm_directory} WHERE path='%s'",$root.$path."/".$dir)); //xl666 modification
+          $dd->u=$temp->uid;
           $dd->m = (filemtime($full_path.'/'.$dir)) ? @filemtime($full_path.'/'.$dir) : "";
           $this->dirs[] = $dd;
         }
