diff options
author | Jeremy Allison <jra@samba.org> | 2007-02-09 02:03:39 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:17:51 -0500 |
commit | 2dab8928769938ab79da7b7ce2d165fc388f9b00 (patch) | |
tree | 60398b24d4799b13e49ecba5a7e93db90a10f1a0 | |
parent | 4c3a9135629415086698da28596f68f7a9db9133 (diff) | |
download | samba-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.c | 17 | ||||
-rw-r--r-- | source/locking/locking.c | 37 | ||||
-rw-r--r-- | source/smbd/dir.c | 39 |
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; +} |