pvfs_open: add pvfs_can_update_file_size()
[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 3 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, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "ntvfs/ntvfs.h"
23
24 /* connect/disconnect */
25 _PUBLIC_ NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename)
26 {
27         struct ntvfs_module_context *ntvfs = req->ctx->modules;
28         if (!ntvfs->ops->connect) {
29                 return NT_STATUS_NOT_IMPLEMENTED;
30         }
31         return ntvfs->ops->connect(ntvfs, req, sharename);
32 }
33
34 _PUBLIC_ NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx)
35 {
36         struct ntvfs_module_context *ntvfs;
37         if (ntvfs_ctx == NULL) {
38                 return NT_STATUS_INVALID_CONNECTION;
39         }
40         ntvfs = ntvfs_ctx->modules;
41         if (!ntvfs->ops->disconnect) {
42                 return NT_STATUS_NOT_IMPLEMENTED;
43         }
44         return ntvfs->ops->disconnect(ntvfs);
45 }
46
47 /* async setup - called by a backend that wants to setup any state for
48    a async request */
49 _PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private)
50 {
51         struct ntvfs_module_context *ntvfs = req->ctx->modules;
52         if (!ntvfs->ops->async_setup) {
53                 return NT_STATUS_NOT_IMPLEMENTED;
54         }
55         return ntvfs->ops->async_setup(ntvfs, req, private);
56 }
57
58 /* filesystem operations */
59 _PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs)
60 {
61         struct ntvfs_module_context *ntvfs = req->ctx->modules;
62         if (!ntvfs->ops->fsinfo) {
63                 return NT_STATUS_NOT_IMPLEMENTED;
64         }
65         return ntvfs->ops->fsinfo(ntvfs, req, fs);
66 }
67
68 /* path operations */
69 _PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl)
70 {
71         struct ntvfs_module_context *ntvfs = req->ctx->modules;
72         if (!ntvfs->ops->unlink) {
73                 return NT_STATUS_NOT_IMPLEMENTED;
74         }
75         return ntvfs->ops->unlink(ntvfs, req, unl);
76 }
77
78 _PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp)
79 {
80         struct ntvfs_module_context *ntvfs = req->ctx->modules;
81         if (!ntvfs->ops->chkpath) {
82                 return NT_STATUS_NOT_IMPLEMENTED;
83         }
84         return ntvfs->ops->chkpath(ntvfs, req, cp);
85 }
86
87 _PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo *st)
88 {
89         struct ntvfs_module_context *ntvfs = req->ctx->modules;
90         if (!ntvfs->ops->qpathinfo) {
91                 return NT_STATUS_NOT_IMPLEMENTED;
92         }
93         return ntvfs->ops->qpathinfo(ntvfs, req, st);
94 }
95
96 _PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfileinfo *st)
97 {
98         struct ntvfs_module_context *ntvfs = req->ctx->modules;
99         if (!ntvfs->ops->setpathinfo) {
100                 return NT_STATUS_NOT_IMPLEMENTED;
101         }
102         return ntvfs->ops->setpathinfo(ntvfs, req, st);
103 }
104
105 _PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi)
106 {
107         struct ntvfs_module_context *ntvfs = req->ctx->modules;
108         if (!ntvfs->ops->open) {
109                 return NT_STATUS_NOT_IMPLEMENTED;
110         }
111         return ntvfs->ops->open(ntvfs, req, oi);
112 }
113
114 _PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md)
115 {
116         struct ntvfs_module_context *ntvfs = req->ctx->modules;
117         if (!ntvfs->ops->mkdir) {
118                 return NT_STATUS_NOT_IMPLEMENTED;
119         }
120         return ntvfs->ops->mkdir(ntvfs, req, md);
121 }
122
123 _PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd)
124 {
125         struct ntvfs_module_context *ntvfs = req->ctx->modules;
126         if (!ntvfs->ops->rmdir) {
127                 return NT_STATUS_NOT_IMPLEMENTED;
128         }
129         return ntvfs->ops->rmdir(ntvfs, req, rd);
130 }
131
132 _PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren)
133 {
134         struct ntvfs_module_context *ntvfs = req->ctx->modules;
135         if (!ntvfs->ops->rename) {
136                 return NT_STATUS_NOT_IMPLEMENTED;
137         }
138         return ntvfs->ops->rename(ntvfs, req, ren);
139 }
140
141 _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp)
142 {
143         struct ntvfs_module_context *ntvfs = req->ctx->modules;
144         if (!ntvfs->ops->copy) {
145                 return NT_STATUS_NOT_IMPLEMENTED;
146         }
147         return ntvfs->ops->copy(ntvfs, req, cp);
148 }
149
150 /* directory search */
151 _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private,
152                                      bool ntvfs_callback(void *private, const union smb_search_data *file))
153 {
154         struct ntvfs_module_context *ntvfs = req->ctx->modules;
155         if (!ntvfs->ops->search_first) {
156                 return NT_STATUS_NOT_IMPLEMENTED;
157         }
158         return ntvfs->ops->search_first(ntvfs, req, io, private, ntvfs_callback);
159 }
160
161 _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private,
162                                     bool ntvfs_callback(void *private, const union smb_search_data *file))
163 {
164         struct ntvfs_module_context *ntvfs = req->ctx->modules;
165         if (!ntvfs->ops->search_next) {
166                 return NT_STATUS_NOT_IMPLEMENTED;
167         }
168         return ntvfs->ops->search_next(ntvfs, req, io, private, ntvfs_callback);
169 }
170
171 _PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search_close *io)
172 {
173         struct ntvfs_module_context *ntvfs = req->ctx->modules;
174         if (!ntvfs->ops->search_close) {
175                 return NT_STATUS_NOT_IMPLEMENTED;
176         }
177         return ntvfs->ops->search_close(ntvfs, req, io);
178 }
179
180 /* operations on open files */
181 _PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io)
182 {
183         struct ntvfs_module_context *ntvfs = req->ctx->modules;
184         if (!ntvfs->ops->ioctl) {
185                 return NT_STATUS_NOT_IMPLEMENTED;
186         }
187         return ntvfs->ops->ioctl(ntvfs, req, io);
188 }
189
190 _PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io)
191 {
192         struct ntvfs_module_context *ntvfs = req->ctx->modules;
193         if (!ntvfs->ops->read) {
194                 return NT_STATUS_NOT_IMPLEMENTED;
195         }
196         return ntvfs->ops->read(ntvfs, req, io);
197 }
198
199 _PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io)
200 {
201         struct ntvfs_module_context *ntvfs = req->ctx->modules;
202         if (!ntvfs->ops->write) {
203                 return NT_STATUS_NOT_IMPLEMENTED;
204         }
205         return ntvfs->ops->write(ntvfs, req, io);
206 }
207
208 _PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io)
209 {
210         struct ntvfs_module_context *ntvfs = req->ctx->modules;
211         if (!ntvfs->ops->seek) {
212                 return NT_STATUS_NOT_IMPLEMENTED;
213         }
214         return ntvfs->ops->seek(ntvfs, req, io);
215 }
216
217 _PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req,
218                               union smb_flush *flush)
219 {
220         struct ntvfs_module_context *ntvfs = req->ctx->modules;
221         if (!ntvfs->ops->flush) {
222                 return NT_STATUS_NOT_IMPLEMENTED;
223         }
224         return ntvfs->ops->flush(ntvfs, req, flush);
225 }
226
227 _PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck)
228 {
229         struct ntvfs_module_context *ntvfs = req->ctx->modules;
230         if (!ntvfs->ops->lock) {
231                 return NT_STATUS_NOT_IMPLEMENTED;
232         }
233         return ntvfs->ops->lock(ntvfs, req, lck);
234 }
235
236 _PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo *info)
237 {
238         struct ntvfs_module_context *ntvfs = req->ctx->modules;
239         if (!ntvfs->ops->qfileinfo) {
240                 return NT_STATUS_NOT_IMPLEMENTED;
241         }
242         return ntvfs->ops->qfileinfo(ntvfs, req, info);
243 }
244
245 _PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfileinfo *info)
246 {
247         struct ntvfs_module_context *ntvfs = req->ctx->modules;
248         if (!ntvfs->ops->setfileinfo) {
249                 return NT_STATUS_NOT_IMPLEMENTED;
250         }
251         return ntvfs->ops->setfileinfo(ntvfs, req, info);
252 }
253
254 _PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io)
255 {
256         struct ntvfs_module_context *ntvfs = req->ctx->modules;
257         if (!ntvfs->ops->close) {
258                 return NT_STATUS_NOT_IMPLEMENTED;
259         }
260         return ntvfs->ops->close(ntvfs, req, io);
261 }
262
263 /* trans interface - used by IPC backend for pipes and RAP calls */
264 _PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *trans)
265 {
266         struct ntvfs_module_context *ntvfs = req->ctx->modules;
267         if (!ntvfs->ops->trans) {
268                 return NT_STATUS_NOT_IMPLEMENTED;
269         }
270         return ntvfs->ops->trans(ntvfs, req, trans);
271 }
272
273 /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */
274 _PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *trans2)
275 {
276         struct ntvfs_module_context *ntvfs = req->ctx->modules;
277         if (!ntvfs->ops->trans2) {
278                 return NT_STATUS_NOT_IMPLEMENTED;
279         }
280         return ntvfs->ops->trans2(ntvfs, req, trans2);
281 }
282
283 /* printing specific operations */
284 _PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq)
285 {
286         struct ntvfs_module_context *ntvfs = req->ctx->modules;
287         if (!ntvfs->ops->lpq) {
288                 return NT_STATUS_NOT_IMPLEMENTED;
289         }
290         return ntvfs->ops->lpq(ntvfs, req, lpq);
291 }
292
293 /* logoff - called when a vuid is closed */
294 _PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req)
295 {
296         struct ntvfs_module_context *ntvfs = req->ctx->modules;
297         if (!ntvfs->ops->logoff) {
298                 return NT_STATUS_NOT_IMPLEMENTED;
299         }
300         return ntvfs->ops->logoff(ntvfs, req);
301 }
302
303 _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req)
304 {
305         struct ntvfs_module_context *ntvfs = req->ctx->modules;
306         if (!ntvfs->ops->exit) {
307                 return NT_STATUS_NOT_IMPLEMENTED;
308         }
309         return ntvfs->ops->exit(ntvfs, req);
310 }
311
312 /*
313   change notify request
314 */
315 _PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info)
316 {
317         struct ntvfs_module_context *ntvfs = req->ctx->modules;
318         if (!ntvfs->ops->notify) {
319                 return NT_STATUS_NOT_IMPLEMENTED;
320         }
321         return ntvfs->ops->notify(ntvfs, req, info);
322 }
323
324 /*
325   cancel an outstanding async request
326 */
327 _PUBLIC_ NTSTATUS ntvfs_cancel(struct ntvfs_request *req)
328 {
329         struct ntvfs_module_context *ntvfs = req->ctx->modules;
330         if (!ntvfs->ops->cancel) {
331                 return NT_STATUS_NOT_IMPLEMENTED;
332         }
333         return ntvfs->ops->cancel(ntvfs, req);
334 }
335
336 /* initial setup */
337 _PUBLIC_ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, 
338                                      struct ntvfs_request *req, const char *sharename)
339 {
340         if (!ntvfs->next || !ntvfs->next->ops->connect) {
341                 return NT_STATUS_NOT_IMPLEMENTED;
342         }
343         return ntvfs->next->ops->connect(ntvfs->next, req, sharename);
344 }
345
346 _PUBLIC_ NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs)
347 {
348         if (!ntvfs->next || !ntvfs->next->ops->disconnect) {
349                 return NT_STATUS_NOT_IMPLEMENTED;
350         }
351         return ntvfs->next->ops->disconnect(ntvfs->next);
352 }
353
354 /* async_setup - called when setting up for a async request */
355 _PUBLIC_ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, 
356                                          struct ntvfs_request *req, 
357                                          void *private)
358 {
359         if (!ntvfs->next || !ntvfs->next->ops->async_setup) {
360                 return NT_STATUS_NOT_IMPLEMENTED;
361         }
362         return ntvfs->next->ops->async_setup(ntvfs->next, req, private);
363 }
364
365 /* filesystem operations */
366 _PUBLIC_ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, 
367                                     struct ntvfs_request *req,
368                                     union smb_fsinfo *fs)
369 {
370         if (!ntvfs->next || !ntvfs->next->ops->fsinfo) {
371                 return NT_STATUS_NOT_IMPLEMENTED;
372         }
373         return ntvfs->next->ops->fsinfo(ntvfs->next, req, fs);
374 }
375
376 /* path operations */
377 _PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, 
378                                     struct ntvfs_request *req,
379                                     union smb_unlink *unl)
380 {
381         if (!ntvfs->next || !ntvfs->next->ops->unlink) {
382                 return NT_STATUS_NOT_IMPLEMENTED;
383         }
384         return ntvfs->next->ops->unlink(ntvfs->next, req, unl);
385 }
386
387 _PUBLIC_ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, 
388                                      struct ntvfs_request *req,
389                                      union smb_chkpath *cp)
390 {
391         if (!ntvfs->next || !ntvfs->next->ops->chkpath) {
392                 return NT_STATUS_NOT_IMPLEMENTED;
393         }
394         return ntvfs->next->ops->chkpath(ntvfs->next, req, cp);
395 }
396
397 _PUBLIC_ NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, 
398                                        struct ntvfs_request *req,
399                                        union smb_fileinfo *st)
400 {
401         if (!ntvfs->next || !ntvfs->next->ops->qpathinfo) {
402                 return NT_STATUS_NOT_IMPLEMENTED;
403         }
404         return ntvfs->next->ops->qpathinfo(ntvfs->next, req, st);
405 }
406
407 _PUBLIC_ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, 
408                                          struct ntvfs_request *req,
409                                          union smb_setfileinfo *st)
410 {
411         if (!ntvfs->next || !ntvfs->next->ops->setpathinfo) {
412                 return NT_STATUS_NOT_IMPLEMENTED;
413         }
414         return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st);
415 }
416
417 _PUBLIC_ NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, 
418                                    struct ntvfs_request *req,
419                                    union smb_mkdir *md)
420 {
421         if (!ntvfs->next || !ntvfs->next->ops->mkdir) {
422                 return NT_STATUS_NOT_IMPLEMENTED;
423         }
424         return ntvfs->next->ops->mkdir(ntvfs->next, req, md);
425 }
426
427 _PUBLIC_ NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, 
428                                    struct ntvfs_request *req,
429                                    struct smb_rmdir *rd)
430 {
431         if (!ntvfs->next || !ntvfs->next->ops->rmdir) {
432                 return NT_STATUS_NOT_IMPLEMENTED;
433         }
434         return ntvfs->next->ops->rmdir(ntvfs->next, req, rd);
435 }
436
437 _PUBLIC_ NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, 
438                                     struct ntvfs_request *req,
439                                     union smb_rename *ren)
440 {
441         if (!ntvfs->next || !ntvfs->next->ops->rename) {
442                 return NT_STATUS_NOT_IMPLEMENTED;
443         }
444         return ntvfs->next->ops->rename(ntvfs->next, req, ren);
445 }
446
447 _PUBLIC_ NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, 
448                                   struct ntvfs_request *req,
449                                   struct smb_copy *cp)
450 {
451         if (!ntvfs->next || !ntvfs->next->ops->copy) {
452                 return NT_STATUS_NOT_IMPLEMENTED;
453         }
454         return ntvfs->next->ops->copy(ntvfs->next, req, cp);
455 }
456
457 _PUBLIC_ NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, 
458                                   struct ntvfs_request *req,
459                                   union smb_open *oi)
460 {
461         if (!ntvfs->next || !ntvfs->next->ops->open) {
462                 return NT_STATUS_NOT_IMPLEMENTED;
463         }
464         return ntvfs->next->ops->open(ntvfs->next, req, oi);
465 }
466
467
468 /* directory search */
469 _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, 
470                                           struct ntvfs_request *req,
471                                           union smb_search_first *io, void *private,
472                                           bool (*callback)(void *private, const union smb_search_data *file))
473 {
474         if (!ntvfs->next || !ntvfs->next->ops->search_first) {
475                 return NT_STATUS_NOT_IMPLEMENTED;
476         }
477         return ntvfs->next->ops->search_first(ntvfs->next, req, io, private, callback);
478 }
479
480 _PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, 
481                                          struct ntvfs_request *req,
482                                          union smb_search_next *io, void *private,
483                                          bool (*callback)(void *private, const union smb_search_data *file))
484 {
485         if (!ntvfs->next || !ntvfs->next->ops->search_next) {
486                 return NT_STATUS_NOT_IMPLEMENTED;
487         }
488         return ntvfs->next->ops->search_next(ntvfs->next, req, io, private, callback);
489 }
490
491 _PUBLIC_ NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, 
492                                           struct ntvfs_request *req,
493                                           union smb_search_close *io)
494 {
495         if (!ntvfs->next || !ntvfs->next->ops->search_close) {
496                 return NT_STATUS_NOT_IMPLEMENTED;
497         }
498         return ntvfs->next->ops->search_close(ntvfs->next, req, io);
499 }
500
501 /* operations on open files */
502 _PUBLIC_ NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, 
503                                    struct ntvfs_request *req,
504                                    union smb_ioctl *io)
505 {
506         if (!ntvfs->next || !ntvfs->next->ops->ioctl) {
507                 return NT_STATUS_NOT_IMPLEMENTED;
508         }
509         return ntvfs->next->ops->ioctl(ntvfs->next, req, io);
510 }
511
512 _PUBLIC_ NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, 
513                                   struct ntvfs_request *req,
514                                   union smb_read *io)
515 {
516         if (!ntvfs->next || !ntvfs->next->ops->read) {
517                 return NT_STATUS_NOT_IMPLEMENTED;
518         }
519         return ntvfs->next->ops->read(ntvfs->next, req, io);
520 }
521
522 _PUBLIC_ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, 
523                                    struct ntvfs_request *req,
524                                    union smb_write *io)
525 {
526         if (!ntvfs->next || !ntvfs->next->ops->write) {
527                 return NT_STATUS_NOT_IMPLEMENTED;
528         }
529         return ntvfs->next->ops->write(ntvfs->next, req, io);
530 }
531
532 _PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, 
533                                   struct ntvfs_request *req,
534                                   union smb_seek *io)
535 {
536         if (!ntvfs->next || !ntvfs->next->ops->seek) {
537                 return NT_STATUS_NOT_IMPLEMENTED;
538         }
539         return ntvfs->next->ops->seek(ntvfs->next, req, io);
540 }
541
542 _PUBLIC_ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, 
543                                    struct ntvfs_request *req,
544                                    union smb_flush *flush)
545 {
546         if (!ntvfs->next || !ntvfs->next->ops->flush) {
547                 return NT_STATUS_NOT_IMPLEMENTED;
548         }
549         return ntvfs->next->ops->flush(ntvfs->next, req, flush);
550 }
551
552 _PUBLIC_ NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, 
553                                   struct ntvfs_request *req,
554                                   union smb_lock *lck)
555 {
556         if (!ntvfs->next || !ntvfs->next->ops->lock) {
557                 return NT_STATUS_NOT_IMPLEMENTED;
558         }
559         return ntvfs->next->ops->lock(ntvfs->next, req, lck);
560 }
561
562 _PUBLIC_ NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, 
563                                        struct ntvfs_request *req,
564                                        union smb_fileinfo *info)
565 {
566         if (!ntvfs->next || !ntvfs->next->ops->qfileinfo) {
567                 return NT_STATUS_NOT_IMPLEMENTED;
568         }
569         return ntvfs->next->ops->qfileinfo(ntvfs->next, req, info);
570 }
571
572 _PUBLIC_ NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, 
573                                          struct ntvfs_request *req,
574                                          union smb_setfileinfo *info)
575 {
576         if (!ntvfs->next || !ntvfs->next->ops->setfileinfo) {
577                 return NT_STATUS_NOT_IMPLEMENTED;
578         }
579         return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info);
580 }
581
582 _PUBLIC_ NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, 
583                                    struct ntvfs_request *req,
584                                    union smb_close *io)
585 {
586         if (!ntvfs->next || !ntvfs->next->ops->close) {
587                 return NT_STATUS_NOT_IMPLEMENTED;
588         }
589         return ntvfs->next->ops->close(ntvfs->next, req, io);
590 }
591
592 /* trans interface - used by IPC backend for pipes and RAP calls */
593 _PUBLIC_ NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, 
594                                    struct ntvfs_request *req,
595                                    struct smb_trans2 *trans)
596 {
597         if (!ntvfs->next || !ntvfs->next->ops->trans) {
598                 return NT_STATUS_NOT_IMPLEMENTED;
599         }
600         return ntvfs->next->ops->trans(ntvfs->next, req, trans);
601 }
602
603 /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */
604 _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, 
605                                     struct ntvfs_request *req,
606                                     struct smb_trans2 *trans2)
607 {
608         if (!ntvfs->next || !ntvfs->next->ops->trans2) {
609                 return NT_STATUS_NOT_IMPLEMENTED;
610         }
611         return ntvfs->next->ops->trans2(ntvfs->next, req, trans2);
612 }
613
614 /*
615   change notify request
616 */
617 _PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs,
618                                     struct ntvfs_request *req,
619                                     union smb_notify *info)
620 {
621         if (!ntvfs->next || !ntvfs->next->ops->notify) {
622                 return NT_STATUS_NOT_IMPLEMENTED;
623         }
624         return ntvfs->next->ops->notify(ntvfs->next, req, info);
625 }
626
627 /* cancel - called to cancel an outstanding async request */
628 _PUBLIC_ NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, 
629                                     struct ntvfs_request *req)
630 {
631         if (!ntvfs->next || !ntvfs->next->ops->cancel) {
632                 return NT_STATUS_NOT_IMPLEMENTED;
633         }
634         return ntvfs->next->ops->cancel(ntvfs->next, req);
635 }
636
637 /* printing specific operations */
638 _PUBLIC_ NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, 
639                                  struct ntvfs_request *req,
640                                  union smb_lpq *lpq)
641 {
642         if (!ntvfs->next || !ntvfs->next->ops->lpq) {
643                 return NT_STATUS_NOT_IMPLEMENTED;
644         }
645         return ntvfs->next->ops->lpq(ntvfs->next, req, lpq);
646 }
647
648
649 /* logoff - called when a vuid is closed */
650 _PUBLIC_ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, 
651                                     struct ntvfs_request *req)
652 {
653         if (!ntvfs->next || !ntvfs->next->ops->logoff) {
654                 return NT_STATUS_NOT_IMPLEMENTED;
655         }
656         return ntvfs->next->ops->logoff(ntvfs->next, req);
657 }
658
659 _PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, 
660                                   struct ntvfs_request *req)
661 {
662         if (!ntvfs->next || !ntvfs->next->ops->exit) {
663                 return NT_STATUS_NOT_IMPLEMENTED;
664         }
665         return ntvfs->next->ops->exit(ntvfs->next, req);
666 }
667
668 /* oplock helpers */
669 _PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs,
670                                            NTSTATUS (*handler)(void *private_data, struct ntvfs_handle *handle, uint8_t level),
671                                            void *private_data)
672 {
673         ntvfs->oplock.handler           = handler;
674         ntvfs->oplock.private_data      = private_data;
675         return NT_STATUS_OK;
676 }
677
678 _PUBLIC_ NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs,
679                                           struct ntvfs_handle *handle, uint8_t level)
680 {
681         if (!ntvfs->ctx->oplock.handler) {
682                 return NT_STATUS_OK;
683         }
684
685         return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, handle, level);
686 }
687
688 /* client connection callback */
689 _PUBLIC_ NTSTATUS ntvfs_set_addr_callbacks(struct ntvfs_context *ntvfs,
690                                            struct socket_address *(*my_addr)(void *private_data, TALLOC_CTX *mem_ctx),
691                                            struct socket_address *(*peer_addr)(void *private_data, TALLOC_CTX *mem_ctx),
692                                            void *private_data)
693 {
694         ntvfs->client.get_peer_addr     = my_addr;
695         ntvfs->client.get_my_addr       = peer_addr;
696         ntvfs->client.private_data      = private_data;
697         return NT_STATUS_OK;
698 }
699
700 _PUBLIC_ struct socket_address *ntvfs_get_my_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx)
701 {
702         if (!ntvfs->ctx->client.get_my_addr) {
703                 return NULL;
704         }
705
706         return ntvfs->ctx->client.get_my_addr(ntvfs->ctx->client.private_data, mem_ctx);
707 }
708
709 _PUBLIC_ struct socket_address *ntvfs_get_peer_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx)
710 {
711         if (!ntvfs->ctx->client.get_peer_addr) {
712                 return NULL;
713         }
714
715         return ntvfs->ctx->client.get_peer_addr(ntvfs->ctx->client.private_data, mem_ctx);
716 }