summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Jacke <bj@sernet.de>2010-11-18 17:24:00 +0100
committerJeremy Allison <jra@samba.org>2010-12-17 21:11:04 +0100
commit192c4a145f22d5d08586476793980c21db7793fe (patch)
tree725dd526f0b408ff119707d0c0022102762bf951
parent2c10c3496876892eb4a89b57c909c3ca397a7440 (diff)
downloadsamba-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.
-rw-r--r--source3/smbd/nttrans.c48
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];