summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_unlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix/pvfs_unlink.c')
-rw-r--r--source4/ntvfs/posix/pvfs_unlink.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index 12ab583082..432481a88a 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -42,16 +42,23 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
}
/* make sure its matches the given attributes */
- if (!pvfs_match_attrib(pvfs, name, attrib, 0)) {
+ status = pvfs_match_attrib(pvfs, name, attrib, 0);
+ if (!NT_STATUS_IS_OK(status)) {
talloc_free(name);
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ return status;
}
status = pvfs_can_delete(pvfs, name);
if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(name);
return status;
}
+ if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
+ talloc_free(name);
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
+ }
+
/* finally try the actual unlink */
if (unlink(name->full_name) == -1) {
status = pvfs_map_errno(pvfs, errno);
@@ -85,6 +92,11 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
+ if (name->exists &&
+ (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
+ }
+
dir = talloc_p(req, struct pvfs_dir);
if (dir == NULL) {
return NT_STATUS_NO_MEMORY;
@@ -97,10 +109,18 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
}
if (dir->count == 0) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ return NT_STATUS_NO_SUCH_FILE;
}
for (i=0;i<dir->count;i++) {
+
+ /* this seems to be a special case */
+ if ((unl->in.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
+ (strcmp(dir->names[i], ".") == 0 ||
+ strcmp(dir->names[i], "..") == 0)) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
status = pvfs_unlink_one(pvfs, req, dir->unix_path,
dir->names[i], unl->in.attrib);
if (NT_STATUS_IS_OK(status)) {