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