added support for returning the maximal access MXAC tag in SMB2 create
authorAndrew Tridgell <tridge@samba.org>
Thu, 29 May 2008 09:16:26 +0000 (19:16 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 29 May 2008 09:16:26 +0000 (19:16 +1000)
(This used to be commit 4eb49335d5f0319f9aa47ded5215a2977d3336bf)

source4/libcli/raw/interfaces.h
source4/ntvfs/ntvfs_generic.c
source4/ntvfs/posix/pvfs_acl.c
source4/ntvfs/posix/pvfs_open.c
source4/smb_server/smb2/fileio.c

index d170006d3b03a9d1897923e9197a620338b81a10..19d51893a616411c7f211bb3446cee38d91b9728 100644 (file)
@@ -1354,7 +1354,7 @@ union smb_open {
                break; \
        } \
 } while (0)
-       /* SMBNTCreateX interface */
+       /* SMBNTCreateX, nttrans and generic interface */
        struct {
                enum smb_open_level level;
                struct {
@@ -1377,6 +1377,9 @@ union smb_open {
                           NTTRANS varient of the call */
                        struct security_descriptor *sec_desc;
                        struct smb_ea_list *ea_list;
+                       
+                       /* some optional parameters from the SMB2 varient */
+                       bool query_maximal_access;
                } in;
                struct {
                        union smb_handle file;
@@ -1392,6 +1395,10 @@ union smb_open {
                        uint16_t file_type;
                        uint16_t ipc_state;
                        uint8_t  is_directory;
+
+                       /* optional return values matching SMB2 tagged
+                          values in the call */
+                       uint32_t maximal_access;
                } out;
        } ntcreatex, nttrans, generic;
 
index 9227295696bd3c3e1cef70636244178b551838cd..d70575847574f6a6ca361fdf2f32e99b6bb661bd 100644 (file)
@@ -233,6 +233,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
                io->smb2.out.size               = io2->generic.out.size;
                io->smb2.out.file_attr          = io2->generic.out.attrib;
                io->smb2.out.reserved2          = 0;
+               io->smb2.out.maximal_access     = io2->generic.out.maximal_access;
                break;
 
        default:
@@ -522,6 +523,7 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
                io2->generic.in.fname           = io->smb2.in.fname;
                io2->generic.in.sec_desc        = io->smb2.in.sec_desc;
                io2->generic.in.ea_list         = &io->smb2.in.eas;
+               io2->generic.in.query_maximal_access = io->smb2.in.query_maximal_access; 
 
                /* we don't support timewarp yet */
                if (io->smb2.in.timewarp != 0) {
index 089631a30738f1e516963f367fc05b7b544bd8d8..623b1ae5e9a5e7e3c6b0e2b25131946ca35e3f43 100644 (file)
@@ -807,3 +807,15 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
        
        return status;
 }
+
+/*
+  return the maximum allowed access mask
+*/
+NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs, 
+                                    struct ntvfs_request *req,
+                                    struct pvfs_filename *name,
+                                    uint32_t *maximal_access)
+{
+       *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
+       return pvfs_access_check(pvfs, req, name, maximal_access);
+}
index a1c5571258686368de53946d58baabe3be4d6f6d..dada9f503f5334ce9b2b1e86b34cc2120cbdbd84 100644 (file)
@@ -252,8 +252,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
        } else {
                status = pvfs_access_check_create(pvfs, req, name, &access_mask);
        }
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       if (io->generic.in.query_maximal_access) {
+               status = pvfs_access_maximal_allowed(pvfs, req, name, 
+                                                    &io->generic.out.maximal_access);
+               NT_STATUS_NOT_OK_RETURN(status);
        }
 
        f->ntvfs         = h;
@@ -578,6 +582,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        status = pvfs_access_check_create(pvfs, req, name, &access_mask);
        NT_STATUS_NOT_OK_RETURN(status);
 
+       if (io->generic.in.query_maximal_access) {
+               status = pvfs_access_maximal_allowed(pvfs, req, name, 
+                                                    &io->generic.out.maximal_access);
+               NT_STATUS_NOT_OK_RETURN(status);
+       }
+
        /* check that the parent isn't opened with delete on close set */
        status = pvfs_resolve_parent(pvfs, req, name, &parent);
        if (NT_STATUS_IS_OK(status)) {
@@ -1135,6 +1145,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                return ntvfs_map_open(ntvfs, req, io);
        }
 
+       ZERO_STRUCT(io->generic.out);
+
        create_options = io->generic.in.create_options;
        share_access   = io->generic.in.share_access;
        access_mask    = io->generic.in.access_mask;
@@ -1282,8 +1294,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 
        /* check the security descriptor */
        status = pvfs_access_check(pvfs, req, name, &access_mask);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       if (io->generic.in.query_maximal_access) {
+               status = pvfs_access_maximal_allowed(pvfs, req, name, 
+                                                    &io->generic.out.maximal_access);
+               NT_STATUS_NOT_OK_RETURN(status);
        }
 
        status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
index 086ddc690eb1947165b2eba8dcb12232cebdd20a..2c322ea58765e5763f0cd674c9509c9a9127bda9 100644 (file)
@@ -36,6 +36,18 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs)
        DATA_BLOB blob;
 
        SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open);
+
+       /* setup the blobs we should give in the reply */
+       if (io->smb2.out.maximal_access != 0) {
+               uint32_t data[2];
+               SIVAL(data, 0, 0);
+               SIVAL(data, 4, io->smb2.out.maximal_access);
+               SMB2SRV_CHECK(smb2_create_blob_add(req, &io->smb2.out.blobs,
+                                                  SMB2_CREATE_TAG_MXAC, 
+                                                  data_blob_const(data, 8)));
+       }
+       
+
        SMB2SRV_CHECK(smb2_create_blob_push(req, &blob, io->smb2.out.blobs));
        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, blob.length));