Index: source/lib/dummysmbd.c =================================================================== --- source/lib/dummysmbd.c (revision 21254) +++ source/lib/dummysmbd.c (working copy) @@ -38,3 +38,9 @@ { return False; } + +NTSTATUS can_delete_directory(struct connection_struct *conn, + const char *dirname) +{ + return NT_STATUS_OK; +} Index: source/smbd/dir.c =================================================================== --- source/smbd/dir.c (revision 21254) +++ source/smbd/dir.c (working copy) @@ -1255,3 +1255,42 @@ } 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; +} Index: source/locking/locking.c =================================================================== --- source/locking/locking.c (revision 21254) +++ source/locking/locking.c (working copy) @@ -1166,6 +1166,11 @@ return NT_STATUS_ACCESS_DENIED; } + /* Don't allow delete on close for non-empty directories. */ + if (fsp->is_directory) { + return can_delete_directory(fsp->conn, fsp->fsp_name); + } + return NT_STATUS_OK; }