r21257: Better fix for bug #4188 :
authorJeremy Allison <jra@samba.org>
Fri, 9 Feb 2007 02:03:39 +0000 (02:03 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:17:51 +0000 (12:17 -0500)
Windows Vista RC1 and RC2 can't delete directory on Samba share
based on work by Joe Meadows <jmeadows@webopolis.com>.
Jeremy.
(This used to be commit 2dab8928769938ab79da7b7ce2d165fc388f9b00)

source3/lib/dummysmbd.c
source3/locking/locking.c
source3/smbd/dir.c

index c97dec5ef3ebceefb1ba67a1534d021ebe94e7f6..a291a5884d9d546f170cbe0ce975a401e440c971 100644 (file)
@@ -38,22 +38,13 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo
 {
 }
 
-NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid,
-                               const char *wcard, BOOL wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret)
-{
-       return NT_STATUS_OK;
-}
-
-int dptr_CloseDir(struct dptr_struct *dptr)
+void send_stat_cache_delete_message(const char *name)
 {
-       return 0;
 }
 
-const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst)
+NTSTATUS can_delete_directory(struct connection_struct *conn,
+                               const char *dirname)
 {
-       return NULL;
+       return NT_STATUS_OK;
 }
 
-void send_stat_cache_delete_message(const char *name)
-{
-}
index 39cc991b5f297b6b997ffb60bbf4ed0369acf9fe..ffac43aff5933b18c13aeba05ea9a6758c65e39f 100644 (file)
@@ -1151,42 +1151,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
 
        /* Don't allow delete on close for non-empty directories. */
        if (fsp->is_directory) {
-               long offset = 0;
-               NTSTATUS status;
-               SMB_STRUCT_STAT st;
-               struct dptr_struct *dirptr;
-               const char *name;
-
-               status = dptr_create(fsp->conn,
-                                       fsp->fsp_name,
-                                       False,
-                                       True,
-                                       0,
-                                       "*",
-                                       True,
-                                       0,
-                                       &dirptr);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-
-               /* Read 3 entries. Ignore first 2 (they're . and .. ) */
-               name = dptr_ReadDirName(dirptr, &offset, &st);
-               if (!name) {
-                       dptr_CloseDir(dirptr);
-                       return NT_STATUS_ACCESS_DENIED;
-               }
-               name = dptr_ReadDirName(dirptr, &offset, &st);
-               if (!name) {
-                       dptr_CloseDir(dirptr);
-                       return NT_STATUS_ACCESS_DENIED;
-               }
-               name = dptr_ReadDirName(dirptr, &offset, &st);
-               dptr_CloseDir(dirptr);
-               if (name) {
-                       DEBUG(10,("can_set_delete_on_close: got name %s - can't delete\n", name ));
-                       return NT_STATUS_DIRECTORY_NOT_EMPTY;
-               }
+               return can_delete_directory(fsp->conn, fsp->fsp_name);
        }
 
        return NT_STATUS_OK;
index 9f0350fe6dfa0bb6bd6f968466164e9569f4ec1e..2795b2a24b29fa10e1fdf1ec19a75f0f8bd98135 100644 (file)
@@ -1279,3 +1279,42 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
        }
        return False;
 }
+
+/*****************************************************************
+ Is this directory empty ?
+*****************************************************************/
+
+NTSTATUS can_delete_directory(struct connection_struct *conn,
+                               const char *dirname)
+{
+       NTSTATUS status = NT_STATUS_OK;
+       long dirpos = 0;
+       const char *dname;
+       struct smb_Dir *dir_hnd = OpenDir(conn, dirname, NULL, 0);
+
+       if (!dir_hnd) {
+               return map_nt_error_from_unix(errno);
+       }
+
+       while ((dname = ReadDirName(dir_hnd,&dirpos))) {
+               SMB_STRUCT_STAT st;
+
+               /* Quick check for "." and ".." */
+               if (dname[0] == '.') {
+                       if (!dname[1] || (dname[1] == '.' && !dname[2])) {
+                               continue;
+                       }
+               }
+
+               if (!is_visible_file(conn, dirname, dname, &st, True)) {
+                       continue;
+               }
+
+               DEBUG(10,("can_delete_directory: got name %s - can't delete\n", dname ));
+               status = NT_STATUS_DIRECTORY_NOT_EMPTY;
+               break;
+       }
+       CloseDir(dir_hnd);
+
+       return status;
+}