r3528: added support for the SMBntcancel() operation, which cancels any
[jelmer/samba4-debian.git] / source / ntvfs / ntvfs_interface.c
1 /* 
2    Unix SMB/CIFS implementation.
3    NTVFS interface functions
4
5    Copyright (C) Stefan (metze) Metzmacher 2004
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "smb_server/smb_server.h"
24
25
26 /* connect/disconnect */
27 NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename)
28 {
29         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
30         if (!ntvfs->ops->connect) {
31                 return NT_STATUS_NOT_IMPLEMENTED;
32         }
33         return ntvfs->ops->connect(ntvfs, req, sharename);
34 }
35
36 NTSTATUS ntvfs_disconnect(struct smbsrv_tcon *tcon)
37 {
38         struct ntvfs_module_context *ntvfs = tcon->ntvfs_ctx->modules;
39         if (!ntvfs->ops->disconnect) {
40                 return NT_STATUS_NOT_IMPLEMENTED;
41         }
42         return ntvfs->ops->disconnect(ntvfs, tcon);
43 }
44
45 /* path operations */
46 NTSTATUS ntvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl)
47 {
48         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
49         if (!ntvfs->ops->unlink) {
50                 return NT_STATUS_NOT_IMPLEMENTED;
51         }
52         return ntvfs->ops->unlink(ntvfs, req, unl);
53 }
54
55 NTSTATUS ntvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp)
56 {
57         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
58         if (!ntvfs->ops->chkpath) {
59                 return NT_STATUS_NOT_IMPLEMENTED;
60         }
61         return ntvfs->ops->chkpath(ntvfs, req, cp);
62 }
63
64 NTSTATUS ntvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *st)
65 {
66         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
67         if (!ntvfs->ops->qpathinfo) {
68                 return NT_STATUS_NOT_IMPLEMENTED;
69         }
70         return ntvfs->ops->qpathinfo(ntvfs, req, st);
71 }
72
73 NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st)
74 {
75         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
76         if (!ntvfs->ops->setpathinfo) {
77                 return NT_STATUS_NOT_IMPLEMENTED;
78         }
79         return ntvfs->ops->setpathinfo(ntvfs, req, st);
80 }
81
82 NTSTATUS ntvfs_openfile(struct smbsrv_request *req, union smb_open *oi)
83 {
84         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
85         if (!ntvfs->ops->openfile) {
86                 return NT_STATUS_NOT_IMPLEMENTED;
87         }
88         return ntvfs->ops->openfile(ntvfs, req, oi);
89 }
90
91 NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md)
92 {
93         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
94         if (!ntvfs->ops->mkdir) {
95                 return NT_STATUS_NOT_IMPLEMENTED;
96         }
97         return ntvfs->ops->mkdir(ntvfs, req, md);
98 }
99
100 NTSTATUS ntvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd)
101 {
102         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
103         if (!ntvfs->ops->rmdir) {
104                 return NT_STATUS_NOT_IMPLEMENTED;
105         }
106         return ntvfs->ops->rmdir(ntvfs, req, rd);
107 }
108
109 NTSTATUS ntvfs_rename(struct smbsrv_request *req, union smb_rename *ren)
110 {
111         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
112         if (!ntvfs->ops->rename) {
113                 return NT_STATUS_NOT_IMPLEMENTED;
114         }
115         return ntvfs->ops->rename(ntvfs, req, ren);
116 }
117
118 NTSTATUS ntvfs_copy(struct smbsrv_request *req, struct smb_copy *cp)
119 {
120         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
121         if (!ntvfs->ops->copy) {
122                 return NT_STATUS_NOT_IMPLEMENTED;
123         }
124         return ntvfs->ops->copy(ntvfs, req, cp);
125 }
126
127 /* directory search */
128 NTSTATUS ntvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *private,
129                                  BOOL ntvfs_callback(void *private, union smb_search_data *file))
130 {
131         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
132         if (!ntvfs->ops->search_first) {
133                 return NT_STATUS_NOT_IMPLEMENTED;
134         }
135         return ntvfs->ops->search_first(ntvfs, req, io, private, ntvfs_callback);
136 }
137
138 NTSTATUS ntvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *private,
139                                  BOOL ntvfs_callback(void *private, union smb_search_data *file))
140 {
141         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
142         if (!ntvfs->ops->search_next) {
143                 return NT_STATUS_NOT_IMPLEMENTED;
144         }
145         return ntvfs->ops->search_next(ntvfs, req, io, private, ntvfs_callback);
146 }
147
148 NTSTATUS ntvfs_search_close(struct smbsrv_request *req, union smb_search_close *io)
149 {
150         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
151         if (!ntvfs->ops->search_close) {
152                 return NT_STATUS_NOT_IMPLEMENTED;
153         }
154         return ntvfs->ops->search_close(ntvfs, req, io);
155 }
156
157 /* operations on open files */
158 NTSTATUS ntvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io)
159 {
160         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
161         if (!ntvfs->ops->ioctl) {
162                 return NT_STATUS_NOT_IMPLEMENTED;
163         }
164         return ntvfs->ops->ioctl(ntvfs, req, io);
165 }
166
167 NTSTATUS ntvfs_read(struct smbsrv_request *req, union smb_read *io)
168 {
169         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
170         if (!ntvfs->ops->read) {
171                 return NT_STATUS_NOT_IMPLEMENTED;
172         }
173         return ntvfs->ops->read(ntvfs, req, io);
174 }
175
176 NTSTATUS ntvfs_write(struct smbsrv_request *req, union smb_write *io)
177 {
178         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
179         if (!ntvfs->ops->write) {
180                 return NT_STATUS_NOT_IMPLEMENTED;
181         }
182         return ntvfs->ops->write(ntvfs, req, io);
183 }
184
185 NTSTATUS ntvfs_seek(struct smbsrv_request *req, struct smb_seek *io)
186 {
187         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
188         if (!ntvfs->ops->seek) {
189                 return NT_STATUS_NOT_IMPLEMENTED;
190         }
191         return ntvfs->ops->seek(ntvfs, req, io);
192 }
193
194 NTSTATUS ntvfs_flush(struct smbsrv_request *req, struct smb_flush *flush)
195 {
196         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
197         if (!ntvfs->ops->flush) {
198                 return NT_STATUS_NOT_IMPLEMENTED;
199         }
200         return ntvfs->ops->flush(ntvfs, req, flush);
201 }
202
203 NTSTATUS ntvfs_close(struct smbsrv_request *req, union smb_close *io)
204 {
205         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
206         if (!ntvfs->ops->close) {
207                 return NT_STATUS_NOT_IMPLEMENTED;
208         }
209         return ntvfs->ops->close(ntvfs, req, io);
210 }
211
212 NTSTATUS ntvfs_exit(struct smbsrv_request *req)
213 {
214         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
215         if (!ntvfs->ops->exit) {
216                 return NT_STATUS_NOT_IMPLEMENTED;
217         }
218         return ntvfs->ops->exit(ntvfs, req);
219 }
220
221 NTSTATUS ntvfs_lock(struct smbsrv_request *req, union smb_lock *lck)
222 {
223         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
224         if (!ntvfs->ops->lock) {
225                 return NT_STATUS_NOT_IMPLEMENTED;
226         }
227         return ntvfs->ops->lock(ntvfs, req, lck);
228 }
229
230 NTSTATUS ntvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info)
231 {
232         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
233         if (!ntvfs->ops->setfileinfo) {
234                 return NT_STATUS_NOT_IMPLEMENTED;
235         }
236         return ntvfs->ops->setfileinfo(ntvfs, req, info);
237 }
238
239 NTSTATUS ntvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
240 {
241         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
242         if (!ntvfs->ops->qfileinfo) {
243                 return NT_STATUS_NOT_IMPLEMENTED;
244         }
245         return ntvfs->ops->qfileinfo(ntvfs, req, info);
246 }
247
248 /* filesystem operations */
249 NTSTATUS ntvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
250 {
251         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
252         if (!ntvfs->ops->fsinfo) {
253                 return NT_STATUS_NOT_IMPLEMENTED;
254         }
255         return ntvfs->ops->fsinfo(ntvfs, req, fs);
256 }
257
258 /* printing specific operations */
259 NTSTATUS ntvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq)
260 {
261         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
262         if (!ntvfs->ops->lpq) {
263                 return NT_STATUS_NOT_IMPLEMENTED;
264         }
265         return ntvfs->ops->lpq(ntvfs, req, lpq);
266 }
267
268 /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */
269 NTSTATUS ntvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2)
270 {
271         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
272         if (!ntvfs->ops->trans2) {
273                 return NT_STATUS_NOT_IMPLEMENTED;
274         }
275         return ntvfs->ops->trans2(ntvfs, req, trans2);
276 }
277
278 /* trans interface - used by IPC backend for pipes and RAP calls */
279 NTSTATUS ntvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans)
280 {
281         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
282         if (!ntvfs->ops->trans) {
283                 return NT_STATUS_NOT_IMPLEMENTED;
284         }
285         return ntvfs->ops->trans(ntvfs, req, trans);
286 }
287
288 /* logoff - called when a vuid is closed */
289 NTSTATUS ntvfs_logoff(struct smbsrv_request *req)
290 {
291         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
292         if (!ntvfs->ops->logoff) {
293                 return NT_STATUS_NOT_IMPLEMENTED;
294         }
295         return ntvfs->ops->logoff(ntvfs, req);
296 }
297
298 /* async setup - called by a backend that wants to setup any state for
299    a async request */
300 NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private)
301 {
302         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
303         if (!ntvfs->ops->async_setup) {
304                 return NT_STATUS_NOT_IMPLEMENTED;
305         }
306         return ntvfs->ops->async_setup(ntvfs, req, private);
307 }
308
309
310 /*
311   cancel an outstanding async request
312 */
313 NTSTATUS ntvfs_cancel(struct smbsrv_request *req)
314 {
315         struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules;
316         if (!ntvfs->ops->cancel) {
317                 return NT_STATUS_NOT_IMPLEMENTED;
318         }
319         return ntvfs->ops->cancel(ntvfs, req);
320 }
321
322
323 /* initial setup */
324 NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, 
325                             struct smbsrv_request *req, const char *sharename)
326 {
327         if (!ntvfs->next || !ntvfs->next->ops->connect) {
328                 return NT_STATUS_NOT_IMPLEMENTED;
329         }
330         return ntvfs->next->ops->connect(ntvfs->next, req, sharename);
331 }
332
333 NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs, 
334                                struct smbsrv_tcon *tcon)
335 {
336         if (!ntvfs->next || !ntvfs->next->ops->disconnect) {
337                 return NT_STATUS_NOT_IMPLEMENTED;
338         }
339         return ntvfs->next->ops->disconnect(ntvfs->next, tcon);
340 }
341
342 /* path operations */
343 NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, 
344                            struct smbsrv_request *req, struct smb_unlink *unl)
345 {
346         if (!ntvfs->next || !ntvfs->next->ops->unlink) {
347                 return NT_STATUS_NOT_IMPLEMENTED;
348         }
349         return ntvfs->next->ops->unlink(ntvfs->next, req, unl);
350 }
351
352 NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, 
353                             struct smbsrv_request *req, struct smb_chkpath *cp)
354 {
355         if (!ntvfs->next || !ntvfs->next->ops->chkpath) {
356                 return NT_STATUS_NOT_IMPLEMENTED;
357         }
358         return ntvfs->next->ops->chkpath(ntvfs->next, req, cp);
359 }
360
361 NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, 
362                               struct smbsrv_request *req, union smb_fileinfo *st)
363 {
364         if (!ntvfs->next || !ntvfs->next->ops->qpathinfo) {
365                 return NT_STATUS_NOT_IMPLEMENTED;
366         }
367         return ntvfs->next->ops->qpathinfo(ntvfs->next, req, st);
368 }
369
370 NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, 
371                                 struct smbsrv_request *req, union smb_setfileinfo *st)
372 {
373         if (!ntvfs->next || !ntvfs->next->ops->setpathinfo) {
374                 return NT_STATUS_NOT_IMPLEMENTED;
375         }
376         return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st);
377 }
378
379 NTSTATUS ntvfs_next_openfile(struct ntvfs_module_context *ntvfs, 
380                          struct smbsrv_request *req, union smb_open *oi)
381 {
382         if (!ntvfs->next || !ntvfs->next->ops->openfile) {
383                 return NT_STATUS_NOT_IMPLEMENTED;
384         }
385         return ntvfs->next->ops->openfile(ntvfs->next, req, oi);
386 }
387
388 NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, 
389                           struct smbsrv_request *req, union smb_mkdir *md)
390 {
391         if (!ntvfs->next || !ntvfs->next->ops->mkdir) {
392                 return NT_STATUS_NOT_IMPLEMENTED;
393         }
394         return ntvfs->next->ops->mkdir(ntvfs->next, req, md);
395 }
396
397 NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, 
398                           struct smbsrv_request *req, struct smb_rmdir *rd)
399 {
400         if (!ntvfs->next || !ntvfs->next->ops->rmdir) {
401                 return NT_STATUS_NOT_IMPLEMENTED;
402         }
403         return ntvfs->next->ops->rmdir(ntvfs->next, req, rd);
404 }
405
406 NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, 
407                            struct smbsrv_request *req, union smb_rename *ren)
408 {
409         if (!ntvfs->next || !ntvfs->next->ops->rename) {
410                 return NT_STATUS_NOT_IMPLEMENTED;
411         }
412         return ntvfs->next->ops->rename(ntvfs->next, req, ren);
413 }
414
415 NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, 
416                          struct smbsrv_request *req, struct smb_copy *cp)
417 {
418         if (!ntvfs->next || !ntvfs->next->ops->copy) {
419                 return NT_STATUS_NOT_IMPLEMENTED;
420         }
421         return ntvfs->next->ops->copy(ntvfs->next, req, cp);
422 }
423
424 /* directory search */
425 NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, 
426                                  struct smbsrv_request *req, union smb_search_first *io, void *private,
427                                  BOOL (*callback)(void *private, union smb_search_data *file))
428 {
429         if (!ntvfs->next || !ntvfs->next->ops->search_first) {
430                 return NT_STATUS_NOT_IMPLEMENTED;
431         }
432         return ntvfs->next->ops->search_first(ntvfs->next, req, io, private, callback);
433 }
434
435 NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, 
436                                 struct smbsrv_request *req, union smb_search_next *io, void *private,
437                                 BOOL (*callback)(void *private, union smb_search_data *file))
438 {
439         if (!ntvfs->next || !ntvfs->next->ops->search_next) {
440                 return NT_STATUS_NOT_IMPLEMENTED;
441         }
442         return ntvfs->next->ops->search_next(ntvfs->next, req, io, private, callback);
443 }
444
445 NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, 
446                                  struct smbsrv_request *req, union smb_search_close *io)
447 {
448         if (!ntvfs->next || !ntvfs->next->ops->search_close) {
449                 return NT_STATUS_NOT_IMPLEMENTED;
450         }
451         return ntvfs->next->ops->search_close(ntvfs->next, req, io);
452 }
453
454 /* operations on open files */
455 NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, 
456                           struct smbsrv_request *req, union smb_ioctl *io)
457 {
458         if (!ntvfs->next || !ntvfs->next->ops->ioctl) {
459                 return NT_STATUS_NOT_IMPLEMENTED;
460         }
461         return ntvfs->next->ops->ioctl(ntvfs->next, req, io);
462 }
463
464 NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, 
465                          struct smbsrv_request *req, union smb_read *io)
466 {
467         if (!ntvfs->next || !ntvfs->next->ops->read) {
468                 return NT_STATUS_NOT_IMPLEMENTED;
469         }
470         return ntvfs->next->ops->read(ntvfs->next, req, io);
471 }
472
473 NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, 
474                           struct smbsrv_request *req, union smb_write *io)
475 {
476         if (!ntvfs->next || !ntvfs->next->ops->write) {
477                 return NT_STATUS_NOT_IMPLEMENTED;
478         }
479         return ntvfs->next->ops->write(ntvfs->next, req, io);
480 }
481
482 NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, 
483                          struct smbsrv_request *req, struct smb_seek *io)
484 {
485         if (!ntvfs->next || !ntvfs->next->ops->seek) {
486                 return NT_STATUS_NOT_IMPLEMENTED;
487         }
488         return ntvfs->next->ops->seek(ntvfs->next, req, io);
489 }
490
491 NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, 
492                           struct smbsrv_request *req, struct smb_flush *flush)
493 {
494         if (!ntvfs->next || !ntvfs->next->ops->flush) {
495                 return NT_STATUS_NOT_IMPLEMENTED;
496         }
497         return ntvfs->next->ops->flush(ntvfs->next, req, flush);
498 }
499
500 NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, 
501                           struct smbsrv_request *req, union smb_close *io)
502 {
503         if (!ntvfs->next || !ntvfs->next->ops->close) {
504                 return NT_STATUS_NOT_IMPLEMENTED;
505         }
506         return ntvfs->next->ops->close(ntvfs->next, req, io);
507 }
508
509 NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, 
510                          struct smbsrv_request *req)
511 {
512         if (!ntvfs->next || !ntvfs->next->ops->exit) {
513                 return NT_STATUS_NOT_IMPLEMENTED;
514         }
515         return ntvfs->next->ops->exit(ntvfs->next, req);
516 }
517
518 NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, 
519                          struct smbsrv_request *req, union smb_lock *lck)
520 {
521         if (!ntvfs->next || !ntvfs->next->ops->lock) {
522                 return NT_STATUS_NOT_IMPLEMENTED;
523         }
524         return ntvfs->next->ops->lock(ntvfs->next, req, lck);
525 }
526
527 NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, 
528                                 struct smbsrv_request *req, union smb_setfileinfo *info)
529 {
530         if (!ntvfs->next || !ntvfs->next->ops->setfileinfo) {
531                 return NT_STATUS_NOT_IMPLEMENTED;
532         }
533         return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info);
534 }
535
536 NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, 
537                               struct smbsrv_request *req, union smb_fileinfo *info)
538 {
539         if (!ntvfs->next || !ntvfs->next->ops->qfileinfo) {
540                 return NT_STATUS_NOT_IMPLEMENTED;
541         }
542         return ntvfs->next->ops->qfileinfo(ntvfs->next, req, info);
543 }
544
545 /* filesystem operations */
546 NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, 
547                            struct smbsrv_request *req, union smb_fsinfo *fs)
548 {
549         if (!ntvfs->next || !ntvfs->next->ops->fsinfo) {
550                 return NT_STATUS_NOT_IMPLEMENTED;
551         }
552         return ntvfs->next->ops->fsinfo(ntvfs->next, req, fs);
553 }
554
555 /* printing specific operations */
556 NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, 
557                         struct smbsrv_request *req, union smb_lpq *lpq)
558 {
559         if (!ntvfs->next || !ntvfs->next->ops->lpq) {
560                 return NT_STATUS_NOT_IMPLEMENTED;
561         }
562         return ntvfs->next->ops->lpq(ntvfs->next, req, lpq);
563 }
564
565 /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */
566 NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, 
567                            struct smbsrv_request *req, struct smb_trans2 *trans2)
568 {
569         if (!ntvfs->next || !ntvfs->next->ops->trans2) {
570                 return NT_STATUS_NOT_IMPLEMENTED;
571         }
572         return ntvfs->next->ops->trans2(ntvfs->next, req, trans2);
573 }
574
575 /* trans interface - used by IPC backend for pipes and RAP calls */
576 NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, 
577                           struct smbsrv_request *req, struct smb_trans2 *trans)
578 {
579         if (!ntvfs->next || !ntvfs->next->ops->trans) {
580                 return NT_STATUS_NOT_IMPLEMENTED;
581         }
582         return ntvfs->next->ops->trans(ntvfs->next, req, trans);
583 }
584
585 /* logoff - called when a vuid is closed */
586 NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, 
587                            struct smbsrv_request *req)
588 {
589         if (!ntvfs->next || !ntvfs->next->ops->logoff) {
590                 return NT_STATUS_NOT_IMPLEMENTED;
591         }
592         return ntvfs->next->ops->logoff(ntvfs->next, req);
593 }
594
595 /* async_setup - called when setting up for a async request */
596 NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, 
597                                 struct smbsrv_request *req, 
598                                 void *private)
599 {
600         if (!ntvfs->next || !ntvfs->next->ops->async_setup) {
601                 return NT_STATUS_NOT_IMPLEMENTED;
602         }
603         return ntvfs->next->ops->async_setup(ntvfs->next, req, private);
604 }
605
606 /* cancel - called to cancel an outstanding async request */
607 NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, 
608                            struct smbsrv_request *req)
609 {
610         if (!ntvfs->next || !ntvfs->next->ops->cancel) {
611                 return NT_STATUS_NOT_IMPLEMENTED;
612         }
613         return ntvfs->next->ops->cancel(ntvfs->next, req);
614 }