diff options
author | Björn Jacke <bj@sernet.de> | 2010-11-18 17:24:00 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2010-12-17 21:11:04 +0100 |
commit | 192c4a145f22d5d08586476793980c21db7793fe (patch) | |
tree | 725dd526f0b408ff119707d0c0022102762bf951 /source3/smbd | |
parent | 2c10c3496876892eb4a89b57c909c3ca397a7440 (diff) | |
download | samba-192c4a145f22d5d08586476793980c21db7793fe.tar.gz samba-192c4a145f22d5d08586476793980c21db7793fe.tar.bz2 samba-192c4a145f22d5d08586476793980c21db7793fe.zip |
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.
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | 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 ad585337b8..8d92d60642 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]; |