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 */
25NTSTATUS ntvfs_connect(struct ntvfs_request *req, union smb_tcon *tcon)
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, tcon);
32}
33
34NTSTATUS 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 */
49NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private_data)
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_data);
56}
57
58/* filesystem operations */
59NTSTATUS 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 */
69NTSTATUS 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
78NTSTATUS 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
87NTSTATUS 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
96NTSTATUS 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
105NTSTATUS 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
114NTSTATUS 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
123NTSTATUS 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
132NTSTATUS 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
141NTSTATUS 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 */
151NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private_data,
152				     bool ntvfs_callback(void *private_data, 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_data, ntvfs_callback);
159}
160
161NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private_data,
162				    bool ntvfs_callback(void *private_data, 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_data, ntvfs_callback);
169}
170
171NTSTATUS 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 */
181NTSTATUS 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
190NTSTATUS 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
199NTSTATUS 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
208NTSTATUS 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
217NTSTATUS 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
227NTSTATUS 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
236NTSTATUS 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
245NTSTATUS 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
254NTSTATUS 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 */
264NTSTATUS 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 */
274NTSTATUS 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 */
284NTSTATUS 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 */
294NTSTATUS 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
303NTSTATUS 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*/
315NTSTATUS 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*/
327NTSTATUS 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 */
337NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs,
338				     struct ntvfs_request *req,
339				     union smb_tcon *tcon)
340{
341	if (!ntvfs->next || !ntvfs->next->ops->connect) {
342		return NT_STATUS_NOT_IMPLEMENTED;
343	}
344	return ntvfs->next->ops->connect(ntvfs->next, req, tcon);
345}
346
347NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs)
348{
349	if (!ntvfs->next || !ntvfs->next->ops->disconnect) {
350		return NT_STATUS_NOT_IMPLEMENTED;
351	}
352	return ntvfs->next->ops->disconnect(ntvfs->next);
353}
354
355/* async_setup - called when setting up for a async request */
356NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs,
357					 struct ntvfs_request *req,
358					 void *private_data)
359{
360	if (!ntvfs->next || !ntvfs->next->ops->async_setup) {
361		return NT_STATUS_NOT_IMPLEMENTED;
362	}
363	return ntvfs->next->ops->async_setup(ntvfs->next, req, private_data);
364}
365
366/* filesystem operations */
367NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs,
368				    struct ntvfs_request *req,
369				    union smb_fsinfo *fs)
370{
371	if (!ntvfs->next || !ntvfs->next->ops->fsinfo) {
372		return NT_STATUS_NOT_IMPLEMENTED;
373	}
374	return ntvfs->next->ops->fsinfo(ntvfs->next, req, fs);
375}
376
377/* path operations */
378NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs,
379				    struct ntvfs_request *req,
380				    union smb_unlink *unl)
381{
382	if (!ntvfs->next || !ntvfs->next->ops->unlink) {
383		return NT_STATUS_NOT_IMPLEMENTED;
384	}
385	return ntvfs->next->ops->unlink(ntvfs->next, req, unl);
386}
387
388NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs,
389				     struct ntvfs_request *req,
390				     union smb_chkpath *cp)
391{
392	if (!ntvfs->next || !ntvfs->next->ops->chkpath) {
393		return NT_STATUS_NOT_IMPLEMENTED;
394	}
395	return ntvfs->next->ops->chkpath(ntvfs->next, req, cp);
396}
397
398NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs,
399				       struct ntvfs_request *req,
400				       union smb_fileinfo *st)
401{
402	if (!ntvfs->next || !ntvfs->next->ops->qpathinfo) {
403		return NT_STATUS_NOT_IMPLEMENTED;
404	}
405	return ntvfs->next->ops->qpathinfo(ntvfs->next, req, st);
406}
407
408NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs,
409					 struct ntvfs_request *req,
410					 union smb_setfileinfo *st)
411{
412	if (!ntvfs->next || !ntvfs->next->ops->setpathinfo) {
413		return NT_STATUS_NOT_IMPLEMENTED;
414	}
415	return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st);
416}
417
418NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs,
419				   struct ntvfs_request *req,
420				   union smb_mkdir *md)
421{
422	if (!ntvfs->next || !ntvfs->next->ops->mkdir) {
423		return NT_STATUS_NOT_IMPLEMENTED;
424	}
425	return ntvfs->next->ops->mkdir(ntvfs->next, req, md);
426}
427
428NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs,
429				   struct ntvfs_request *req,
430				   struct smb_rmdir *rd)
431{
432	if (!ntvfs->next || !ntvfs->next->ops->rmdir) {
433		return NT_STATUS_NOT_IMPLEMENTED;
434	}
435	return ntvfs->next->ops->rmdir(ntvfs->next, req, rd);
436}
437
438NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs,
439				    struct ntvfs_request *req,
440				    union smb_rename *ren)
441{
442	if (!ntvfs->next || !ntvfs->next->ops->rename) {
443		return NT_STATUS_NOT_IMPLEMENTED;
444	}
445	return ntvfs->next->ops->rename(ntvfs->next, req, ren);
446}
447
448NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs,
449				  struct ntvfs_request *req,
450				  struct smb_copy *cp)
451{
452	if (!ntvfs->next || !ntvfs->next->ops->copy) {
453		return NT_STATUS_NOT_IMPLEMENTED;
454	}
455	return ntvfs->next->ops->copy(ntvfs->next, req, cp);
456}
457
458NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs,
459				  struct ntvfs_request *req,
460				  union smb_open *oi)
461{
462	if (!ntvfs->next || !ntvfs->next->ops->open) {
463		return NT_STATUS_NOT_IMPLEMENTED;
464	}
465	return ntvfs->next->ops->open(ntvfs->next, req, oi);
466}
467
468
469/* directory search */
470NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs,
471					  struct ntvfs_request *req,
472					  union smb_search_first *io, void *private_data,
473					  bool (*callback)(void *private_data, const union smb_search_data *file))
474{
475	if (!ntvfs->next || !ntvfs->next->ops->search_first) {
476		return NT_STATUS_NOT_IMPLEMENTED;
477	}
478	return ntvfs->next->ops->search_first(ntvfs->next, req, io, private_data, callback);
479}
480
481NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs,
482					 struct ntvfs_request *req,
483					 union smb_search_next *io, void *private_data,
484					 bool (*callback)(void *private_data, const union smb_search_data *file))
485{
486	if (!ntvfs->next || !ntvfs->next->ops->search_next) {
487		return NT_STATUS_NOT_IMPLEMENTED;
488	}
489	return ntvfs->next->ops->search_next(ntvfs->next, req, io, private_data, callback);
490}
491
492NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs,
493					  struct ntvfs_request *req,
494					  union smb_search_close *io)
495{
496	if (!ntvfs->next || !ntvfs->next->ops->search_close) {
497		return NT_STATUS_NOT_IMPLEMENTED;
498	}
499	return ntvfs->next->ops->search_close(ntvfs->next, req, io);
500}
501
502/* operations on open files */
503NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs,
504				   struct ntvfs_request *req,
505				   union smb_ioctl *io)
506{
507	if (!ntvfs->next || !ntvfs->next->ops->ioctl) {
508		return NT_STATUS_NOT_IMPLEMENTED;
509	}
510	return ntvfs->next->ops->ioctl(ntvfs->next, req, io);
511}
512
513NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs,
514				  struct ntvfs_request *req,
515				  union smb_read *io)
516{
517	if (!ntvfs->next || !ntvfs->next->ops->read) {
518		return NT_STATUS_NOT_IMPLEMENTED;
519	}
520	return ntvfs->next->ops->read(ntvfs->next, req, io);
521}
522
523NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs,
524				   struct ntvfs_request *req,
525				   union smb_write *io)
526{
527	if (!ntvfs->next || !ntvfs->next->ops->write) {
528		return NT_STATUS_NOT_IMPLEMENTED;
529	}
530	return ntvfs->next->ops->write(ntvfs->next, req, io);
531}
532
533NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs,
534				  struct ntvfs_request *req,
535				  union smb_seek *io)
536{
537	if (!ntvfs->next || !ntvfs->next->ops->seek) {
538		return NT_STATUS_NOT_IMPLEMENTED;
539	}
540	return ntvfs->next->ops->seek(ntvfs->next, req, io);
541}
542
543NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs,
544				   struct ntvfs_request *req,
545				   union smb_flush *flush)
546{
547	if (!ntvfs->next || !ntvfs->next->ops->flush) {
548		return NT_STATUS_NOT_IMPLEMENTED;
549	}
550	return ntvfs->next->ops->flush(ntvfs->next, req, flush);
551}
552
553NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs,
554				  struct ntvfs_request *req,
555				  union smb_lock *lck)
556{
557	if (!ntvfs->next || !ntvfs->next->ops->lock) {
558		return NT_STATUS_NOT_IMPLEMENTED;
559	}
560	return ntvfs->next->ops->lock(ntvfs->next, req, lck);
561}
562
563NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs,
564				       struct ntvfs_request *req,
565				       union smb_fileinfo *info)
566{
567	if (!ntvfs->next || !ntvfs->next->ops->qfileinfo) {
568		return NT_STATUS_NOT_IMPLEMENTED;
569	}
570	return ntvfs->next->ops->qfileinfo(ntvfs->next, req, info);
571}
572
573NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs,
574					 struct ntvfs_request *req,
575					 union smb_setfileinfo *info)
576{
577	if (!ntvfs->next || !ntvfs->next->ops->setfileinfo) {
578		return NT_STATUS_NOT_IMPLEMENTED;
579	}
580	return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info);
581}
582
583NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs,
584				   struct ntvfs_request *req,
585				   union smb_close *io)
586{
587	if (!ntvfs->next || !ntvfs->next->ops->close) {
588		return NT_STATUS_NOT_IMPLEMENTED;
589	}
590	return ntvfs->next->ops->close(ntvfs->next, req, io);
591}
592
593/* trans interface - used by IPC backend for pipes and RAP calls */
594NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs,
595				   struct ntvfs_request *req,
596				   struct smb_trans2 *trans)
597{
598	if (!ntvfs->next || !ntvfs->next->ops->trans) {
599		return NT_STATUS_NOT_IMPLEMENTED;
600	}
601	return ntvfs->next->ops->trans(ntvfs->next, req, trans);
602}
603
604/* trans2 interface - only used by CIFS backend to prover complete passthru for testing */
605NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs,
606				    struct ntvfs_request *req,
607				    struct smb_trans2 *trans2)
608{
609	if (!ntvfs->next || !ntvfs->next->ops->trans2) {
610		return NT_STATUS_NOT_IMPLEMENTED;
611	}
612	return ntvfs->next->ops->trans2(ntvfs->next, req, trans2);
613}
614
615/*
616  change notify request
617*/
618NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs,
619				    struct ntvfs_request *req,
620				    union smb_notify *info)
621{
622	if (!ntvfs->next || !ntvfs->next->ops->notify) {
623		return NT_STATUS_NOT_IMPLEMENTED;
624	}
625	return ntvfs->next->ops->notify(ntvfs->next, req, info);
626}
627
628/* cancel - called to cancel an outstanding async request */
629NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs,
630				    struct ntvfs_request *req)
631{
632	if (!ntvfs->next || !ntvfs->next->ops->cancel) {
633		return NT_STATUS_NOT_IMPLEMENTED;
634	}
635	return ntvfs->next->ops->cancel(ntvfs->next, req);
636}
637
638/* printing specific operations */
639NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs,
640				 struct ntvfs_request *req,
641				 union smb_lpq *lpq)
642{
643	if (!ntvfs->next || !ntvfs->next->ops->lpq) {
644		return NT_STATUS_NOT_IMPLEMENTED;
645	}
646	return ntvfs->next->ops->lpq(ntvfs->next, req, lpq);
647}
648
649
650/* logoff - called when a vuid is closed */
651NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs,
652				    struct ntvfs_request *req)
653{
654	if (!ntvfs->next || !ntvfs->next->ops->logoff) {
655		return NT_STATUS_NOT_IMPLEMENTED;
656	}
657	return ntvfs->next->ops->logoff(ntvfs->next, req);
658}
659
660NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs,
661				  struct ntvfs_request *req)
662{
663	if (!ntvfs->next || !ntvfs->next->ops->exit) {
664		return NT_STATUS_NOT_IMPLEMENTED;
665	}
666	return ntvfs->next->ops->exit(ntvfs->next, req);
667}
668
669/* oplock helpers */
670NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs,
671					   NTSTATUS (*handler)(void *private_data, struct ntvfs_handle *handle, uint8_t level),
672					   void *private_data)
673{
674	ntvfs->oplock.handler		= handler;
675	ntvfs->oplock.private_data	= private_data;
676	return NT_STATUS_OK;
677}
678
679NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs,
680					  struct ntvfs_handle *handle, uint8_t level)
681{
682	if (!ntvfs->ctx->oplock.handler) {
683		return NT_STATUS_OK;
684	}
685
686	return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, handle, level);
687}
688
689/* client connection callback */
690NTSTATUS ntvfs_set_addr_callbacks(struct ntvfs_context *ntvfs,
691					   struct socket_address *(*my_addr)(void *private_data, TALLOC_CTX *mem_ctx),
692					   struct socket_address *(*peer_addr)(void *private_data, TALLOC_CTX *mem_ctx),
693					   void *private_data)
694{
695	ntvfs->client.get_peer_addr	= my_addr;
696	ntvfs->client.get_my_addr	= peer_addr;
697	ntvfs->client.private_data	= private_data;
698	return NT_STATUS_OK;
699}
700
701struct socket_address *ntvfs_get_my_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx)
702{
703	if (!ntvfs->ctx->client.get_my_addr) {
704		return NULL;
705	}
706
707	return ntvfs->ctx->client.get_my_addr(ntvfs->ctx->client.private_data, mem_ctx);
708}
709
710struct socket_address *ntvfs_get_peer_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx)
711{
712	if (!ntvfs->ctx->client.get_peer_addr) {
713		return NULL;
714	}
715
716	return ntvfs->ctx->client.get_peer_addr(ntvfs->ctx->client.private_data, mem_ctx);
717}
718