From 6e8391cfdfe56ecebadf3f9a95828246305e8ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= Date: Thu, 18 Nov 2010 17:24:00 +0100 Subject: [PATCH 6/8] s3:smbd: implement FSCTL_SET_SPARSE more correctly this is a port of a patch from metze for 3.3: We don't do the "strict allocation" when the sparse bit isn't set, but that shouldn't matter. We now allow windows applications to set and unset the sparse bit. Note that in order to implement this 100% like described in [MS-FSA], we'd have to change our data model and support the sparse flag per stream. --- source3/smbd/nttrans.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 43 insertions(+), 5 deletions(-) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index ad58533..8d92d60 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -2107,14 +2107,52 @@ static void call_nt_transact_ioctl(connection_struct *conn, switch (function) { case FSCTL_SET_SPARSE: - /* pretend this succeeded - tho strictly we should - mark the file sparse (if the local fs supports it) - so we can know if we need to pre-allocate or not */ + { + bool set_sparse = true; + NTSTATUS status; + + if (data_count >= 1 && pdata[0] == 0) { + set_sparse = false; + } + + DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X]set[%u]\n", + fidnum, set_sparse)); + + if (!check_fsp_open(conn, req, fsp)) { + return; + } + + if (!CAN_WRITE(conn)) { + DEBUG(9,("FSCTL_SET_SPARSE: fname[%s] set[%u] " + "on readonly share[%s]\n", + smb_fname_str_dbg(fsp->fsp_name), set_sparse, + lp_servicename(SNUM(conn)))); + reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED); + return; + } + + if (!(fsp->access_mask & FILE_WRITE_DATA) && + !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) { + DEBUG(9,("FSCTL_SET_SPARSE: fname[%s] set[%u] " + "access_mask[0x%08X] - access denied\n", + smb_fname_str_dbg(fsp->fsp_name), set_sparse, fsp->access_mask)); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); + return; + } - DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum)); + status = file_set_sparse(conn, fsp->fsp_name, set_sparse); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(9,("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n", + smb_fname_str_dbg(fsp->fsp_name), set_sparse, nt_errstr(status))); + reply_nterror(req, status); + return; + } + + DEBUG(10,("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n", + smb_fname_str_dbg(fsp->fsp_name), set_sparse, nt_errstr(status))); send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0); return; - + } case FSCTL_CREATE_OR_GET_OBJECT_ID: { unsigned char objid[16]; -- 1.7.3.1