2 Unix SMB/CIFS implementation.
4 CIFS-on-CIFS NTVFS filesystem backend
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) James J Myers 2003 <myersjj@samba.org>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 this implements a CIFS->CIFS NTVFS filesystem backend.
29 #include "lib/events/events.h"
30 #include "libcli/raw/libcliraw.h"
31 #include "libcli/composite/composite.h"
32 #include "libcli/smb_composite/smb_composite.h"
33 #include "smb_server/smb_server.h"
34 #include "smbd/service_stream.h"
36 /* this is stored in ntvfs_private */
38 struct smbcli_tree
*tree
;
39 struct smbcli_transport
*transport
;
40 struct smbsrv_tcon
*tcon
;
45 /* a structure used to pass information to an async handler */
47 struct smbsrv_request
*req
;
51 #define SETUP_PID private->tree->session->pid = SVAL(req->in.hdr, HDR_PID)
54 a handler for oplock break events from the server - these need to be passed
57 static BOOL
oplock_handler(struct smbcli_transport
*transport
, uint16_t tid
, uint16_t fnum
, uint8_t level
, void *p_private
)
59 struct cvfs_private
*private = p_private
;
61 DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level
, fnum
));
62 return req_send_oplock_break(private->tcon
, fnum
, level
);
66 a handler for read events on a connection to a backend server
68 static void cifs_socket_handler(struct event_context
*ev
, struct fd_event
*fde
,
69 uint16_t flags
, void *private)
71 struct cvfs_private
*cvfs
= talloc_get_type(private, struct cvfs_private
);
72 struct smbsrv_tcon
*tcon
= cvfs
->tcon
;
74 if (!smbcli_transport_process(cvfs
->transport
)) {
75 /* the connection to our server is dead */
81 connect to a share - used when a tree_connect operation comes in.
83 static NTSTATUS
cvfs_connect(struct ntvfs_module_context
*ntvfs
,
84 struct smbsrv_request
*req
, const char *sharename
)
86 struct smbsrv_tcon
*tcon
= req
->tcon
;
88 struct cvfs_private
*private;
89 const char *host
, *user
, *pass
, *domain
, *remote_share
;
90 struct smb_composite_connect io
;
91 struct composite_context
*creq
;
94 struct cli_credentials
*credentials
;
96 /* Here we need to determine which server to connect to.
97 * For now we use parametric options, type cifs.
98 * Later we will use security=server and auth_server.c.
100 host
= lp_parm_string(req
->tcon
->service
, "cifs", "server");
101 user
= lp_parm_string(req
->tcon
->service
, "cifs", "user");
102 pass
= lp_parm_string(req
->tcon
->service
, "cifs", "password");
103 domain
= lp_parm_string(req
->tcon
->service
, "cifs", "domain");
104 remote_share
= lp_parm_string(req
->tcon
->service
, "cifs", "share");
106 remote_share
= sharename
;
109 if (!host
|| !user
|| !pass
|| !domain
) {
110 DEBUG(1,("CIFS backend: You must supply server, user, password and domain\n"));
111 return NT_STATUS_INVALID_PARAMETER
;
114 private = talloc(req
->tcon
, struct cvfs_private
);
116 return NT_STATUS_NO_MEMORY
;
118 ZERO_STRUCTP(private);
120 ntvfs
->private_data
= private;
122 credentials
= cli_credentials_init(private);
123 cli_credentials_set_username(credentials
, user
, CRED_SPECIFIED
);
124 cli_credentials_set_domain(credentials
, domain
, CRED_SPECIFIED
);
125 cli_credentials_set_password(credentials
, pass
, CRED_SPECIFIED
);
126 cli_credentials_set_workstation(credentials
, "vfs_cifs", CRED_SPECIFIED
);
128 /* connect to the server, using the smbd event context */
129 io
.in
.dest_host
= host
;
131 io
.in
.called_name
= host
;
132 io
.in
.credentials
= credentials
;
133 io
.in
.fallback_to_anonymous
= False
;
134 io
.in
.workgroup
= lp_workgroup();
135 io
.in
.service
= remote_share
;
136 io
.in
.service_type
= "?????";
138 creq
= smb_composite_connect_send(&io
, private, tcon
->smb_conn
->connection
->event
.ctx
);
139 status
= smb_composite_connect_recv(creq
, private);
140 NT_STATUS_NOT_OK_RETURN(status
);
142 private->tree
= io
.out
.tree
;
144 private->transport
= private->tree
->session
->transport
;
146 private->tcon
= req
->tcon
;
148 tcon
->fs_type
= talloc_strdup(tcon
, "NTFS");
149 tcon
->dev_type
= talloc_strdup(tcon
, "A:");
151 /* we need to receive oplock break requests from the server */
152 smbcli_oplock_handler(private->transport
, oplock_handler
, private);
154 /* take over event handling for this socket */
155 talloc_free(private->transport
->socket
->event
.fde
);
156 fde
= event_add_fd(private->transport
->socket
->event
.ctx
,
158 socket_get_fd(private->transport
->socket
->sock
),
159 EVENT_FD_READ
| EVENT_FD_WRITE
,
162 private->transport
->socket
->event
.fde
= fde
;
165 private->map_generic
= lp_parm_bool(req
->tcon
->service
,
166 "cifs", "mapgeneric", False
);
172 disconnect from a share
174 static NTSTATUS
cvfs_disconnect(struct ntvfs_module_context
*ntvfs
,
175 struct smbsrv_tcon
*tcon
)
177 struct cvfs_private
*private = ntvfs
->private_data
;
179 talloc_free(private);
185 a handler for simple async replies
186 this handler can only be used for functions that don't return any
187 parameters (those that just return a status code)
189 static void async_simple(struct smbcli_request
*c_req
)
191 struct async_info
*async
= c_req
->async
.private;
192 struct smbsrv_request
*req
= async
->req
;
193 req
->async_states
->status
= smbcli_request_simple_recv(c_req
);
194 req
->async_states
->send_fn(req
);
198 /* save some typing for the simple functions */
199 #define ASYNC_RECV_TAIL(io, async_fn) do { \
200 if (!c_req) return NT_STATUS_UNSUCCESSFUL; \
202 struct async_info *async; \
203 async = talloc(req, struct async_info); \
204 if (!async) return NT_STATUS_NO_MEMORY; \
207 c_req->async.private = async; \
209 c_req->async.fn = async_fn; \
210 req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \
211 return NT_STATUS_OK; \
214 #define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple)
217 delete a file - the dirtype specifies the file types to include in the search.
218 The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
220 static NTSTATUS
cvfs_unlink(struct ntvfs_module_context
*ntvfs
,
221 struct smbsrv_request
*req
, struct smb_unlink
*unl
)
223 struct cvfs_private
*private = ntvfs
->private_data
;
224 struct smbcli_request
*c_req
;
228 /* see if the front end will allow us to perform this
229 function asynchronously. */
230 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
231 return smb_raw_unlink(private->tree
, unl
);
234 c_req
= smb_raw_unlink_send(private->tree
, unl
);
240 a handler for async ioctl replies
242 static void async_ioctl(struct smbcli_request
*c_req
)
244 struct async_info
*async
= c_req
->async
.private;
245 struct smbsrv_request
*req
= async
->req
;
246 req
->async_states
->status
= smb_raw_ioctl_recv(c_req
, req
, async
->parms
);
247 req
->async_states
->send_fn(req
);
253 static NTSTATUS
cvfs_ioctl(struct ntvfs_module_context
*ntvfs
,
254 struct smbsrv_request
*req
, union smb_ioctl
*io
)
256 struct cvfs_private
*private = ntvfs
->private_data
;
257 struct smbcli_request
*c_req
;
261 /* see if the front end will allow us to perform this
262 function asynchronously. */
263 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
264 return smb_raw_ioctl(private->tree
, req
, io
);
267 c_req
= smb_raw_ioctl_send(private->tree
, io
);
269 ASYNC_RECV_TAIL(io
, async_ioctl
);
273 check if a directory exists
275 static NTSTATUS
cvfs_chkpath(struct ntvfs_module_context
*ntvfs
,
276 struct smbsrv_request
*req
, struct smb_chkpath
*cp
)
278 struct cvfs_private
*private = ntvfs
->private_data
;
279 struct smbcli_request
*c_req
;
283 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
284 return smb_raw_chkpath(private->tree
, cp
);
287 c_req
= smb_raw_chkpath_send(private->tree
, cp
);
293 a handler for async qpathinfo replies
295 static void async_qpathinfo(struct smbcli_request
*c_req
)
297 struct async_info
*async
= c_req
->async
.private;
298 struct smbsrv_request
*req
= async
->req
;
299 req
->async_states
->status
= smb_raw_pathinfo_recv(c_req
, req
, async
->parms
);
300 req
->async_states
->send_fn(req
);
304 return info on a pathname
306 static NTSTATUS
cvfs_qpathinfo(struct ntvfs_module_context
*ntvfs
,
307 struct smbsrv_request
*req
, union smb_fileinfo
*info
)
309 struct cvfs_private
*private = ntvfs
->private_data
;
310 struct smbcli_request
*c_req
;
314 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
315 return smb_raw_pathinfo(private->tree
, req
, info
);
318 c_req
= smb_raw_pathinfo_send(private->tree
, info
);
320 ASYNC_RECV_TAIL(info
, async_qpathinfo
);
324 a handler for async qfileinfo replies
326 static void async_qfileinfo(struct smbcli_request
*c_req
)
328 struct async_info
*async
= c_req
->async
.private;
329 struct smbsrv_request
*req
= async
->req
;
330 req
->async_states
->status
= smb_raw_fileinfo_recv(c_req
, req
, async
->parms
);
331 req
->async_states
->send_fn(req
);
335 query info on a open file
337 static NTSTATUS
cvfs_qfileinfo(struct ntvfs_module_context
*ntvfs
,
338 struct smbsrv_request
*req
, union smb_fileinfo
*info
)
340 struct cvfs_private
*private = ntvfs
->private_data
;
341 struct smbcli_request
*c_req
;
345 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
346 return smb_raw_fileinfo(private->tree
, req
, info
);
349 c_req
= smb_raw_fileinfo_send(private->tree
, info
);
351 ASYNC_RECV_TAIL(info
, async_qfileinfo
);
356 set info on a pathname
358 static NTSTATUS
cvfs_setpathinfo(struct ntvfs_module_context
*ntvfs
,
359 struct smbsrv_request
*req
, union smb_setfileinfo
*st
)
361 struct cvfs_private
*private = ntvfs
->private_data
;
362 struct smbcli_request
*c_req
;
366 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
367 return smb_raw_setpathinfo(private->tree
, st
);
370 c_req
= smb_raw_setpathinfo_send(private->tree
, st
);
377 a handler for async open replies
379 static void async_open(struct smbcli_request
*c_req
)
381 struct async_info
*async
= c_req
->async
.private;
382 struct smbsrv_request
*req
= async
->req
;
383 req
->async_states
->status
= smb_raw_open_recv(c_req
, req
, async
->parms
);
384 req
->async_states
->send_fn(req
);
390 static NTSTATUS
cvfs_open(struct ntvfs_module_context
*ntvfs
,
391 struct smbsrv_request
*req
, union smb_open
*io
)
393 struct cvfs_private
*private = ntvfs
->private_data
;
394 struct smbcli_request
*c_req
;
398 if (io
->generic
.level
!= RAW_OPEN_GENERIC
&&
399 private->map_generic
) {
400 return ntvfs_map_open(req
, io
, ntvfs
);
403 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
404 return smb_raw_open(private->tree
, req
, io
);
407 c_req
= smb_raw_open_send(private->tree
, io
);
409 ASYNC_RECV_TAIL(io
, async_open
);
415 static NTSTATUS
cvfs_mkdir(struct ntvfs_module_context
*ntvfs
,
416 struct smbsrv_request
*req
, union smb_mkdir
*md
)
418 struct cvfs_private
*private = ntvfs
->private_data
;
419 struct smbcli_request
*c_req
;
423 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
424 return smb_raw_mkdir(private->tree
, md
);
427 c_req
= smb_raw_mkdir_send(private->tree
, md
);
435 static NTSTATUS
cvfs_rmdir(struct ntvfs_module_context
*ntvfs
,
436 struct smbsrv_request
*req
, struct smb_rmdir
*rd
)
438 struct cvfs_private
*private = ntvfs
->private_data
;
439 struct smbcli_request
*c_req
;
443 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
444 return smb_raw_rmdir(private->tree
, rd
);
446 c_req
= smb_raw_rmdir_send(private->tree
, rd
);
452 rename a set of files
454 static NTSTATUS
cvfs_rename(struct ntvfs_module_context
*ntvfs
,
455 struct smbsrv_request
*req
, union smb_rename
*ren
)
457 struct cvfs_private
*private = ntvfs
->private_data
;
458 struct smbcli_request
*c_req
;
462 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
463 return smb_raw_rename(private->tree
, ren
);
466 c_req
= smb_raw_rename_send(private->tree
, ren
);
474 static NTSTATUS
cvfs_copy(struct ntvfs_module_context
*ntvfs
,
475 struct smbsrv_request
*req
, struct smb_copy
*cp
)
477 return NT_STATUS_NOT_SUPPORTED
;
481 a handler for async read replies
483 static void async_read(struct smbcli_request
*c_req
)
485 struct async_info
*async
= c_req
->async
.private;
486 struct smbsrv_request
*req
= async
->req
;
487 req
->async_states
->status
= smb_raw_read_recv(c_req
, async
->parms
);
488 req
->async_states
->send_fn(req
);
494 static NTSTATUS
cvfs_read(struct ntvfs_module_context
*ntvfs
,
495 struct smbsrv_request
*req
, union smb_read
*rd
)
497 struct cvfs_private
*private = ntvfs
->private_data
;
498 struct smbcli_request
*c_req
;
502 if (rd
->generic
.level
!= RAW_READ_GENERIC
&&
503 private->map_generic
) {
504 return ntvfs_map_read(req
, rd
, ntvfs
);
507 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
508 return smb_raw_read(private->tree
, rd
);
511 c_req
= smb_raw_read_send(private->tree
, rd
);
513 ASYNC_RECV_TAIL(rd
, async_read
);
517 a handler for async write replies
519 static void async_write(struct smbcli_request
*c_req
)
521 struct async_info
*async
= c_req
->async
.private;
522 struct smbsrv_request
*req
= async
->req
;
523 req
->async_states
->status
= smb_raw_write_recv(c_req
, async
->parms
);
524 req
->async_states
->send_fn(req
);
530 static NTSTATUS
cvfs_write(struct ntvfs_module_context
*ntvfs
,
531 struct smbsrv_request
*req
, union smb_write
*wr
)
533 struct cvfs_private
*private = ntvfs
->private_data
;
534 struct smbcli_request
*c_req
;
538 if (wr
->generic
.level
!= RAW_WRITE_GENERIC
&&
539 private->map_generic
) {
540 return ntvfs_map_write(req
, wr
, ntvfs
);
543 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
544 return smb_raw_write(private->tree
, wr
);
547 c_req
= smb_raw_write_send(private->tree
, wr
);
549 ASYNC_RECV_TAIL(wr
, async_write
);
553 a handler for async seek replies
555 static void async_seek(struct smbcli_request
*c_req
)
557 struct async_info
*async
= c_req
->async
.private;
558 struct smbsrv_request
*req
= async
->req
;
559 req
->async_states
->status
= smb_raw_seek_recv(c_req
, async
->parms
);
560 req
->async_states
->send_fn(req
);
566 static NTSTATUS
cvfs_seek(struct ntvfs_module_context
*ntvfs
,
567 struct smbsrv_request
*req
, struct smb_seek
*io
)
569 struct cvfs_private
*private = ntvfs
->private_data
;
570 struct smbcli_request
*c_req
;
574 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
575 return smb_raw_seek(private->tree
, io
);
578 c_req
= smb_raw_seek_send(private->tree
, io
);
580 ASYNC_RECV_TAIL(io
, async_seek
);
586 static NTSTATUS
cvfs_flush(struct ntvfs_module_context
*ntvfs
,
587 struct smbsrv_request
*req
, struct smb_flush
*io
)
589 struct cvfs_private
*private = ntvfs
->private_data
;
590 struct smbcli_request
*c_req
;
594 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
595 return smb_raw_flush(private->tree
, io
);
598 c_req
= smb_raw_flush_send(private->tree
, io
);
606 static NTSTATUS
cvfs_close(struct ntvfs_module_context
*ntvfs
,
607 struct smbsrv_request
*req
, union smb_close
*io
)
609 struct cvfs_private
*private = ntvfs
->private_data
;
610 struct smbcli_request
*c_req
;
614 if (io
->generic
.level
!= RAW_CLOSE_GENERIC
&&
615 private->map_generic
) {
616 return ntvfs_map_close(req
, io
, ntvfs
);
619 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
620 return smb_raw_close(private->tree
, io
);
623 c_req
= smb_raw_close_send(private->tree
, io
);
629 exit - closing files open by the pid
631 static NTSTATUS
cvfs_exit(struct ntvfs_module_context
*ntvfs
,
632 struct smbsrv_request
*req
)
634 struct cvfs_private
*private = ntvfs
->private_data
;
635 struct smbcli_request
*c_req
;
639 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
640 return smb_raw_exit(private->tree
->session
);
643 c_req
= smb_raw_exit_send(private->tree
->session
);
649 logoff - closing files open by the user
651 static NTSTATUS
cvfs_logoff(struct ntvfs_module_context
*ntvfs
,
652 struct smbsrv_request
*req
)
654 /* we can't do this right in the cifs backend .... */
659 setup for an async call - nothing to do yet
661 static NTSTATUS
cvfs_async_setup(struct ntvfs_module_context
*ntvfs
,
662 struct smbsrv_request
*req
,
671 static NTSTATUS
cvfs_cancel(struct ntvfs_module_context
*ntvfs
,
672 struct smbsrv_request
*req
)
674 return NT_STATUS_NOT_IMPLEMENTED
;
680 static NTSTATUS
cvfs_lock(struct ntvfs_module_context
*ntvfs
,
681 struct smbsrv_request
*req
, union smb_lock
*lck
)
683 struct cvfs_private
*private = ntvfs
->private_data
;
684 struct smbcli_request
*c_req
;
688 if (lck
->generic
.level
!= RAW_LOCK_GENERIC
&&
689 private->map_generic
) {
690 return ntvfs_map_lock(req
, lck
, ntvfs
);
693 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
694 return smb_raw_lock(private->tree
, lck
);
697 c_req
= smb_raw_lock_send(private->tree
, lck
);
702 set info on a open file
704 static NTSTATUS
cvfs_setfileinfo(struct ntvfs_module_context
*ntvfs
,
705 struct smbsrv_request
*req
,
706 union smb_setfileinfo
*info
)
708 struct cvfs_private
*private = ntvfs
->private_data
;
709 struct smbcli_request
*c_req
;
713 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
714 return smb_raw_setfileinfo(private->tree
, info
);
716 c_req
= smb_raw_setfileinfo_send(private->tree
, info
);
723 a handler for async fsinfo replies
725 static void async_fsinfo(struct smbcli_request
*c_req
)
727 struct async_info
*async
= c_req
->async
.private;
728 struct smbsrv_request
*req
= async
->req
;
729 req
->async_states
->status
= smb_raw_fsinfo_recv(c_req
, req
, async
->parms
);
730 req
->async_states
->send_fn(req
);
734 return filesystem space info
736 static NTSTATUS
cvfs_fsinfo(struct ntvfs_module_context
*ntvfs
,
737 struct smbsrv_request
*req
, union smb_fsinfo
*fs
)
739 struct cvfs_private
*private = ntvfs
->private_data
;
740 struct smbcli_request
*c_req
;
744 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
745 return smb_raw_fsinfo(private->tree
, req
, fs
);
748 c_req
= smb_raw_fsinfo_send(private->tree
, req
, fs
);
750 ASYNC_RECV_TAIL(fs
, async_fsinfo
);
754 return print queue info
756 static NTSTATUS
cvfs_lpq(struct ntvfs_module_context
*ntvfs
,
757 struct smbsrv_request
*req
, union smb_lpq
*lpq
)
759 return NT_STATUS_NOT_SUPPORTED
;
763 list files in a directory matching a wildcard pattern
765 static NTSTATUS
cvfs_search_first(struct ntvfs_module_context
*ntvfs
,
766 struct smbsrv_request
*req
, union smb_search_first
*io
,
767 void *search_private
,
768 BOOL (*callback
)(void *, union smb_search_data
*))
770 struct cvfs_private
*private = ntvfs
->private_data
;
774 return smb_raw_search_first(private->tree
, req
, io
, search_private
, callback
);
777 /* continue a search */
778 static NTSTATUS
cvfs_search_next(struct ntvfs_module_context
*ntvfs
,
779 struct smbsrv_request
*req
, union smb_search_next
*io
,
780 void *search_private
,
781 BOOL (*callback
)(void *, union smb_search_data
*))
783 struct cvfs_private
*private = ntvfs
->private_data
;
787 return smb_raw_search_next(private->tree
, req
, io
, search_private
, callback
);
791 static NTSTATUS
cvfs_search_close(struct ntvfs_module_context
*ntvfs
,
792 struct smbsrv_request
*req
, union smb_search_close
*io
)
794 struct cvfs_private
*private = ntvfs
->private_data
;
798 return smb_raw_search_close(private->tree
, io
);
802 a handler for async trans2 replies
804 static void async_trans2(struct smbcli_request
*c_req
)
806 struct async_info
*async
= c_req
->async
.private;
807 struct smbsrv_request
*req
= async
->req
;
808 req
->async_states
->status
= smb_raw_trans2_recv(c_req
, req
, async
->parms
);
809 req
->async_states
->send_fn(req
);
813 static NTSTATUS
cvfs_trans2(struct ntvfs_module_context
*ntvfs
,
814 struct smbsrv_request
*req
, struct smb_trans2
*trans2
)
816 struct cvfs_private
*private = ntvfs
->private_data
;
817 struct smbcli_request
*c_req
;
821 if (!(req
->async_states
->state
& NTVFS_ASYNC_STATE_MAY_ASYNC
)) {
822 return smb_raw_trans2(private->tree
, req
, trans2
);
825 c_req
= smb_raw_trans2_send(private->tree
, trans2
);
827 ASYNC_RECV_TAIL(trans2
, async_trans2
);
831 /* SMBtrans - not used on file shares */
832 static NTSTATUS
cvfs_trans(struct ntvfs_module_context
*ntvfs
,
833 struct smbsrv_request
*req
, struct smb_trans2
*trans2
)
835 return NT_STATUS_ACCESS_DENIED
;
839 initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem
841 NTSTATUS
ntvfs_cifs_init(void)
844 struct ntvfs_ops ops
;
848 /* fill in the name and type */
850 ops
.type
= NTVFS_DISK
;
852 /* fill in all the operations */
853 ops
.connect
= cvfs_connect
;
854 ops
.disconnect
= cvfs_disconnect
;
855 ops
.unlink
= cvfs_unlink
;
856 ops
.chkpath
= cvfs_chkpath
;
857 ops
.qpathinfo
= cvfs_qpathinfo
;
858 ops
.setpathinfo
= cvfs_setpathinfo
;
859 ops
.openfile
= cvfs_open
;
860 ops
.mkdir
= cvfs_mkdir
;
861 ops
.rmdir
= cvfs_rmdir
;
862 ops
.rename
= cvfs_rename
;
863 ops
.copy
= cvfs_copy
;
864 ops
.ioctl
= cvfs_ioctl
;
865 ops
.read
= cvfs_read
;
866 ops
.write
= cvfs_write
;
867 ops
.seek
= cvfs_seek
;
868 ops
.flush
= cvfs_flush
;
869 ops
.close
= cvfs_close
;
870 ops
.exit
= cvfs_exit
;
871 ops
.lock
= cvfs_lock
;
872 ops
.setfileinfo
= cvfs_setfileinfo
;
873 ops
.qfileinfo
= cvfs_qfileinfo
;
874 ops
.fsinfo
= cvfs_fsinfo
;
876 ops
.search_first
= cvfs_search_first
;
877 ops
.search_next
= cvfs_search_next
;
878 ops
.search_close
= cvfs_search_close
;
879 ops
.trans
= cvfs_trans
;
880 ops
.logoff
= cvfs_logoff
;
881 ops
.async_setup
= cvfs_async_setup
;
882 ops
.cancel
= cvfs_cancel
;
884 if (lp_parm_bool(-1, "cifs", "maptrans2", False
)) {
885 ops
.trans2
= cvfs_trans2
;
888 /* register ourselves with the NTVFS subsystem. We register
889 under the name 'cifs'. */
890 ret
= ntvfs_register(&ops
);
892 if (!NT_STATUS_IS_OK(ret
)) {
893 DEBUG(0,("Failed to register CIFS backend!\n"));