make the SEC_STD_SYNCHRONIZE test more specific
[kai/samba.git] / source4 / ntvfs / posix / pvfs_open.c
index 926c99d37ed0c807fc20aa6eea5996e69d625a95..cfa88b6baad40e8dbb511fa7a343f7cd4bf2efc4 100644 (file)
@@ -203,6 +203,13 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
                return NT_STATUS_NOT_A_DIRECTORY;
        }
 
+       /* found with gentest */
+       if (io->ntcreatex.in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED &&
+           (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) &&
+           (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       
        switch (io->generic.in.open_disposition) {
        case NTCREATEX_DISP_OPEN_IF:
                break;
@@ -558,12 +565,16 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) {
                return NT_STATUS_INVALID_PARAMETER;
        }
+
+       if (io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_ENCRYPTED) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
            
        if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) &&
            (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
                return NT_STATUS_CANNOT_DELETE;
        }
-       
+
        status = pvfs_access_check_create(pvfs, req, name, &access_mask);
        NT_STATUS_NOT_OK_RETURN(status);
 
@@ -1121,6 +1132,42 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                return ntvfs_map_open(ntvfs, req, io);
        }
 
+       create_options = io->generic.in.create_options;
+       share_access   = io->generic.in.share_access;
+       access_mask    = io->generic.in.access_mask;
+
+       if (share_access & ~NTCREATEX_SHARE_ACCESS_MASK) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* some create options are not supported */
+       if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
+               return NT_STATUS_NOT_SUPPORTED;
+       }
+
+       /* other create options are not allowed */
+       if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
+           !(access_mask & SEC_STD_DELETE)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (access_mask & SEC_MASK_INVALID) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       /* what does this bit really mean?? */
+       if (req->ctx->protocol == PROTOCOL_SMB2 &&
+           (access_mask & SEC_STD_SYNCHRONIZE) &&
+           !(access_mask & SEC_STD_READ_CONTROL)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE|
+                                         FILE_ATTRIBUTE_VOLUME| 
+                                         (~FILE_ATTRIBUTE_ALL_MASK))) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
        /* resolve the cifs name to a posix name */
        status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 
                                   PVFS_RESOLVE_STREAMS, &name);
@@ -1152,16 +1199,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
           open doesn't match */
        io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY;
 
-       create_options = io->generic.in.create_options;
-       share_access   = io->generic.in.share_access;
-       access_mask    = io->generic.in.access_mask;
-
-       /* certain create options are not allowed */
-       if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
-           !(access_mask & SEC_STD_DELETE)) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
        flags = 0;
 
        switch (io->generic.in.open_disposition) {