summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-02-09 02:03:39 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:51 -0500
commit2dab8928769938ab79da7b7ce2d165fc388f9b00 (patch)
tree60398b24d4799b13e49ecba5a7e93db90a10f1a0
parent4c3a9135629415086698da28596f68f7a9db9133 (diff)
downloadsamba-2dab8928769938ab79da7b7ce2d165fc388f9b00.tar.gz
r21257: Better fix for bug #4188 :
Windows Vista RC1 and RC2 can't delete directory on Samba share based on work by Joe Meadows <jmeadows@webopolis.com>. Jeremy.
-rw-r--r--source/lib/dummysmbd.c17
-rw-r--r--source/locking/locking.c37
-rw-r--r--source/smbd/dir.c39
3 files changed, 44 insertions, 49 deletions
diff --git a/source/lib/dummysmbd.c b/source/lib/dummysmbd.c
index c97dec5ef3e..a291a5884d9 100644
--- a/source/lib/dummysmbd.c
+++ b/source/lib/dummysmbd.c
@@ -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)
-{
-}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 39cc991b5f2..ffac43aff59 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -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;
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 9f0350fe6df..2795b2a24b2 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -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;
+}