*/
static void ntvfs_map_async_send(struct ntvfs_request *req)
{
- struct ntvfs_map_async *m = req->async_states->private_data;
+ struct ntvfs_map_async *m = talloc_get_type(req->async_states->private_data,
+ struct ntvfs_map_async);
ntvfs_async_state_pop(req);
/* the backend is replying immediately. call the 2nd stage function after popping our local
async state */
- m = req->async_states->private_data;
+ m = talloc_get_type(req->async_states->private_data,
+ struct ntvfs_map_async);
ntvfs_async_state_pop(req);
time_t write_time = 0;
uint32_t set_size = 0;
union smb_setfileinfo *sf;
- uint_t state;
+ unsigned int state;
if (!NT_STATUS_IS_OK(status)) {
return status;
sf->standard.in.create_time = 0;
sf->standard.in.write_time = write_time;
sf->standard.in.access_time = 0;
- status = ntvfs->ops->setfileinfo(ntvfs, req, sf);
+ status = ntvfs->ops->setfileinfo_fn(ntvfs, req, sf);
}
if (set_size != 0) {
sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
sf->generic.in.file.ntvfs = io2->generic.out.file.ntvfs;
sf->end_of_file_info.in.size = set_size;
- status = ntvfs->ops->setfileinfo(ntvfs, req, sf);
+ status = ntvfs->ops->setfileinfo_fn(ntvfs, req, sf);
if (NT_STATUS_IS_OK(status)) {
io->openx.out.size = io->openx.in.size;
}
union smb_open *io2)
{
io2->generic.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
+ io2->generic.in.private_flags = 0;
if (flags & OPENX_FLAGS_REQUEST_OPLOCK) {
io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK;
break;
case OPENX_MODE_DENY_DOS:
/* DENY_DOS is quite strange - it depends on the filename! */
- io2->generic.in.create_options |=
+ io2->generic.in.private_flags |=
NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
if (is_exe_filename(fname)) {
io2->generic.in.share_access =
}
break;
case OPENX_MODE_DENY_FCB:
- io2->generic.in.create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
+ io2->generic.in.private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
break;
default:
io2->generic.in.file_attr = io->openx.in.file_attrs;
io2->generic.in.fname = io->openx.in.fname;
- status = ntvfs->ops->open(ntvfs, req, io2);
+ status = ntvfs->ops->open_fn(ntvfs, req, io2);
break;
io2->generic.in.file_attr = io->openold.in.search_attrs;
io2->generic.in.fname = io->openold.in.fname;
- status = ntvfs->ops->open(ntvfs, req, io2);
+ status = ntvfs->ops->open_fn(ntvfs, req, io2);
break;
case RAW_OPEN_T2OPEN:
io2->generic.in.ea_list->num_eas = io->t2open.in.num_eas;
io2->generic.in.ea_list->eas = io->t2open.in.eas;
- status = ntvfs->ops->open(ntvfs, req, io2);
+ status = ntvfs->ops->open_fn(ntvfs, req, io2);
break;
case RAW_OPEN_MKNEW:
io2->generic.in.share_access =
NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE;
- status = ntvfs->ops->open(ntvfs, req, io2);
+ status = ntvfs->ops->open_fn(ntvfs, req, io2);
break;
case RAW_OPEN_CREATE:
io2->generic.in.share_access =
NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE;
- status = ntvfs->ops->open(ntvfs, req, io2);
+ status = ntvfs->ops->open_fn(ntvfs, req, io2);
break;
case RAW_OPEN_CTEMP:
io2->generic.in.share_access =
NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE;
- status = ntvfs->ops->open(ntvfs, req, io2);
+ status = ntvfs->ops->open_fn(ntvfs, req, io2);
break;
case RAW_OPEN_SMB2:
switch (io->smb2.in.oplock_level) {
io2->generic.in.flags = 0;
break;
}
- io2->generic.in.root_fid = 0;
+ io2->generic.in.root_fid.fnum = 0;
io2->generic.in.access_mask = io->smb2.in.desired_access;
io2->generic.in.alloc_size = io->smb2.in.alloc_size;
io2->generic.in.file_attr = io->smb2.in.file_attributes;
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;
+ io2->generic.in.private_flags = 0;
/* we don't support timewarp yet */
if (io->smb2.in.timewarp != 0) {
io2->generic.in.create_options &= ~NTCREATEX_OPTIONS_SYNC_ALERT;
io2->generic.in.create_options &= ~NTCREATEX_OPTIONS_ASYNC_ALERT;
- status = ntvfs->ops->open(ntvfs, req, io2);
+ status = ntvfs->ops->open_fn(ntvfs, req, io2);
break;
default:
/*
- NTVFS fsinfo generic to any mapper
+ NTVFS any to fsinfo mapper
*/
-NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req,
- union smb_fsinfo *fs)
+static NTSTATUS ntvfs_map_fsinfo_finish(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_fsinfo *fs,
+ union smb_fsinfo *fs2,
+ NTSTATUS status)
{
- NTSTATUS status;
- union smb_fsinfo *fs2;
-
- fs2 = talloc(req, union smb_fsinfo);
- if (fs2 == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (fs->generic.level == RAW_QFS_GENERIC) {
- return NT_STATUS_INVALID_LEVEL;
- }
-
- /* only used by the simple backend, which doesn't do async */
- req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
-
- /* ask the backend for the generic info */
- fs2->generic.level = RAW_QFS_GENERIC;
-
- status = ntvfs->ops->fsinfo(ntvfs, req, fs2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* and convert it to the required level */
switch (fs->generic.level) {
- case RAW_QFS_GENERIC:
- return NT_STATUS_INVALID_LEVEL;
-
case RAW_QFS_DSKATTR: {
/* map from generic to DSKATTR */
- uint_t bpunit = 64;
+ unsigned int bpunit = 64;
/* we need to scale the sizes to fit */
for (bpunit=64; bpunit<0x10000; bpunit *= 2) {
fs->objectid_information.out.guid = fs2->generic.out.guid;
ZERO_STRUCT(fs->objectid_information.out.unknown);
return NT_STATUS_OK;
- }
+ case RAW_QFS_GENERIC:
+ case RAW_QFS_UNIX_INFO:
+ return NT_STATUS_INVALID_LEVEL;
+ }
return NT_STATUS_INVALID_LEVEL;
}
+/*
+ NTVFS fsinfo any to generic mapper
+*/
+NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_fsinfo *fs)
+{
+ NTSTATUS status;
+ union smb_fsinfo *fs2;
+
+ fs2 = talloc(req, union smb_fsinfo);
+ if (fs2 == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (fs->generic.level == RAW_QFS_GENERIC) {
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ status = ntvfs_map_async_setup(ntvfs, req, fs, fs2,
+ (second_stage_t)ntvfs_map_fsinfo_finish);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* ask the backend for the generic info */
+ fs2->generic.level = RAW_QFS_GENERIC;
+
+ status = ntvfs->ops->fsinfo_fn(ntvfs, req, fs2);
+ return ntvfs_map_async_finish(req, status);
+}
+
/*
NTVFS fileinfo generic to any mapper
int i;
/* and convert it to the required level using results in info2 */
switch (info->generic.level) {
- case RAW_FILEINFO_GENERIC:
- return NT_STATUS_INVALID_LEVEL;
case RAW_FILEINFO_GETATTR:
info->getattr.out.attrib = info2->generic.out.attrib & 0xff;
info->getattr.out.size = info2->generic.out.size;
return NT_STATUS_NO_MEMORY;
}
info->all_eas.out.eas[i].value.data =
- talloc_memdup(info->all_eas.out.eas,
+ (uint8_t *)talloc_memdup(info->all_eas.out.eas,
info2->generic.out.eas[i].value.data,
info2->generic.out.eas[i].value.length);
if (!info->all_eas.out.eas[i].value.data) {
info->unix_link_info.out.link_dest = info2->generic.out.link_dest;
return NT_STATUS_OK;
#endif
+ case RAW_FILEINFO_GENERIC:
+ case RAW_FILEINFO_SEC_DESC:
+ case RAW_FILEINFO_EA_LIST:
+ case RAW_FILEINFO_UNIX_INFO2:
+ case RAW_FILEINFO_SMB2_ALL_EAS:
+ case RAW_FILEINFO_SMB2_ALL_INFORMATION:
+ return NT_STATUS_INVALID_LEVEL;
}
return NT_STATUS_INVALID_LEVEL;
}
/*
+ NTVFS any to fileinfo mapper
+*/
+static NTSTATUS ntvfs_map_qfileinfo_finish(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_fileinfo *info,
+ union smb_fileinfo *info2,
+ NTSTATUS status)
+{
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return ntvfs_map_fileinfo(req, info, info2);
+}
+
+/*
NTVFS fileinfo generic to any mapper
*/
NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_LEVEL;
}
+ status = ntvfs_map_async_setup(ntvfs, req, info, info2,
+ (second_stage_t)ntvfs_map_qfileinfo_finish);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* ask the backend for the generic info */
info2->generic.level = RAW_FILEINFO_GENERIC;
info2->generic.in.file.ntvfs= info->generic.in.file.ntvfs;
- /* only used by the simple backend, which doesn't do async */
- req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
+ status = ntvfs->ops->qfileinfo_fn(ntvfs, req, info2);
+ return ntvfs_map_async_finish(req, status);
+}
- status = ntvfs->ops->qfileinfo(ntvfs, req, info2);
+/*
+ NTVFS any to fileinfo mapper
+*/
+static NTSTATUS ntvfs_map_qpathinfo_finish(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_fileinfo *info,
+ union smb_fileinfo *info2,
+ NTSTATUS status)
+{
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+
return ntvfs_map_fileinfo(req, info, info2);
}
return NT_STATUS_INVALID_LEVEL;
}
+ status = ntvfs_map_async_setup(ntvfs, req, info, info2,
+ (second_stage_t)ntvfs_map_qpathinfo_finish);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* ask the backend for the generic info */
info2->generic.level = RAW_FILEINFO_GENERIC;
info2->generic.in.file.path = info->generic.in.file.path;
- /* only used by the simple backend, which doesn't do async */
- req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
-
- status = ntvfs->ops->qpathinfo(ntvfs, req, info2);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- return ntvfs_map_fileinfo(req, info, info2);
+ status = ntvfs->ops->qpathinfo_fn(ntvfs, req, info2);
+ return ntvfs_map_async_finish(req, status);
}
/* only the first lock gives the UNLOCK bit - see
MS-SMB2 3.3.5.14 */
if (lck->smb2.in.locks[0].flags & SMB2_LOCK_FLAG_UNLOCK) {
+ if (lck->smb2.in.locks[0].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
lck2->generic.in.ulock_cnt = lck->smb2.in.lock_count;
isunlock = true;
} else {
isunlock = false;
}
for (i=0;i<lck->smb2.in.lock_count;i++) {
+ if (!isunlock &&
+ lck->smb2.in.locks[i].flags == SMB2_LOCK_FLAG_NONE) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (lck->smb2.in.locks[i].flags & ~SMB2_LOCK_FLAG_ALL_MASK) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
if (isunlock &&
(lck->smb2.in.locks[i].flags &
(SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE))) {
* as lock() doesn't have any output fields
*/
- return ntvfs->ops->lock(ntvfs, req, lck2);
+ return ntvfs->ops->lock_fn(ntvfs, req, lck2);
}
{
union smb_lock *lck;
union smb_close *cl;
- uint_t state;
+ unsigned int state;
if (NT_STATUS_IS_ERR(status)) {
return status;
/* do the lock sync for now */
state = req->async_states->state;
req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
- status = ntvfs->ops->lock(ntvfs, req, lck);
+ status = ntvfs->ops->lock_fn(ntvfs, req, lck);
req->async_states->state = state;
}
break;
/* do the close sync for now */
state = req->async_states->state;
req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
- status = ntvfs->ops->close(ntvfs, req, cl);
+ status = ntvfs->ops->close_fn(ntvfs, req, cl);
req->async_states->state = state;
}
break;
wr2->writex.in.remaining = wr->write.in.remaining;
wr2->writex.in.count = wr->write.in.count;
wr2->writex.in.data = wr->write.in.data;
- status = ntvfs->ops->write(ntvfs, req, wr2);
+ status = ntvfs->ops->write_fn(ntvfs, req, wr2);
break;
case RAW_WRITE_WRITEUNLOCK:
wr2->writex.in.remaining = wr->writeunlock.in.remaining;
wr2->writex.in.count = wr->writeunlock.in.count;
wr2->writex.in.data = wr->writeunlock.in.data;
- status = ntvfs->ops->write(ntvfs, req, wr2);
+ status = ntvfs->ops->write_fn(ntvfs, req, wr2);
break;
case RAW_WRITE_WRITECLOSE:
wr2->writex.in.remaining = 0;
wr2->writex.in.count = wr->writeclose.in.count;
wr2->writex.in.data = wr->writeclose.in.data;
- status = ntvfs->ops->write(ntvfs, req, wr2);
+ status = ntvfs->ops->write_fn(ntvfs, req, wr2);
break;
case RAW_WRITE_SPLWRITE:
wr2->writex.in.remaining = 0;
wr2->writex.in.count = wr->splwrite.in.count;
wr2->writex.in.data = wr->splwrite.in.data;
- status = ntvfs->ops->write(ntvfs, req, wr2);
+ status = ntvfs->ops->write_fn(ntvfs, req, wr2);
break;
case RAW_WRITE_SMB2:
wr2->writex.in.remaining = 0;
wr2->writex.in.count = wr->smb2.in.data.length;
wr2->writex.in.data = wr->smb2.in.data.data;
- status = ntvfs->ops->write(ntvfs, req, wr2);
+ status = ntvfs->ops->write_fn(ntvfs, req, wr2);
}
return ntvfs_map_async_finish(req, status);
union smb_read *rd2;
union smb_lock *lck;
NTSTATUS status;
- uint_t state;
+ unsigned int state;
rd2 = talloc(req, union smb_read);
if (rd2 == NULL) {
rd2->readx.in.maxcnt = rd->read.in.count;
rd2->readx.in.remaining = rd->read.in.remaining;
rd2->readx.out.data = rd->read.out.data;
- status = ntvfs->ops->read(ntvfs, req, rd2);
+ status = ntvfs->ops->read_fn(ntvfs, req, rd2);
break;
case RAW_READ_READBRAW:
rd2->readx.in.maxcnt = rd->readbraw.in.maxcnt;
rd2->readx.in.remaining = 0;
rd2->readx.out.data = rd->readbraw.out.data;
- status = ntvfs->ops->read(ntvfs, req, rd2);
+ status = ntvfs->ops->read_fn(ntvfs, req, rd2);
break;
case RAW_READ_LOCKREAD:
lck->lock.in.file.ntvfs = rd->lockread.in.file.ntvfs;
lck->lock.in.count = rd->lockread.in.count;
lck->lock.in.offset = rd->lockread.in.offset;
- status = ntvfs->ops->lock(ntvfs, req, lck);
+ status = ntvfs->ops->lock_fn(ntvfs, req, lck);
req->async_states->state = state;
rd2->readx.in.file.ntvfs= rd->lockread.in.file.ntvfs;
rd2->readx.out.data = rd->lockread.out.data;
if (NT_STATUS_IS_OK(status)) {
- status = ntvfs->ops->read(ntvfs, req, rd2);
+ status = ntvfs->ops->read_fn(ntvfs, req, rd2);
}
break;
rd2->readx.in.maxcnt = rd->smb2.in.length;
rd2->readx.in.remaining = 0;
rd2->readx.out.data = rd->smb2.out.data.data;
- status = ntvfs->ops->read(ntvfs, req, rd2);
+ status = ntvfs->ops->read_fn(ntvfs, req, rd2);
break;
}
(second_stage_t)ntvfs_map_close_finish);
NT_STATUS_NOT_OK_RETURN(status);
- status = ntvfs->ops->close(ntvfs, req, cl2);
+ status = ntvfs->ops->close_fn(ntvfs, req, cl2);
return ntvfs_map_async_finish(req, status);
}
nt2->nttrans.in.buffer_size = nt->smb2.in.buffer_size;
nt2->nttrans.in.completion_filter = nt->smb2.in.completion_filter;
nt2->nttrans.in.recursive = nt->smb2.in.recursive;
- status = ntvfs->ops->notify(ntvfs, req, nt2);
+ status = ntvfs->ops->notify_fn(ntvfs, req, nt2);
break;
}