r10878: Reply to some comments by tridge and metze:
[Samba/aatanasov.git] / source / ntvfs / cifs / vfs_cifs.c
blobcb6fbb38808c39687f4e43c9f7bb3e18df47cf87
1 /*
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.
28 #include "includes.h"
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 */
37 struct cvfs_private {
38 struct smbcli_tree *tree;
39 struct smbcli_transport *transport;
40 struct smbsrv_tcon *tcon;
41 BOOL map_generic;
45 /* a structure used to pass information to an async handler */
46 struct async_info {
47 struct smbsrv_request *req;
48 void *parms;
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
55 along to the client
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 */
76 talloc_free(tcon);
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;
87 NTSTATUS status;
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;
92 struct fd_event *fde;
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");
105 if (!remote_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);
115 if (!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;
130 io.in.port = 0;
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;
145 SETUP_PID;
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,
157 private,
158 socket_get_fd(private->transport->socket->sock),
159 EVENT_FD_READ | EVENT_FD_WRITE,
160 cifs_socket_handler,
161 private);
162 private->transport->socket->event.fde = fde;
165 private->map_generic = lp_parm_bool(req->tcon->service,
166 "cifs", "mapgeneric", False);
168 return NT_STATUS_OK;
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);
181 return NT_STATUS_OK;
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; \
205 async->parms = io; \
206 async->req = req; \
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; \
212 } while (0)
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;
226 SETUP_PID;
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);
236 SIMPLE_ASYNC_TAIL;
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);
251 ioctl interface
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;
259 SETUP_PID;
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;
281 SETUP_PID;
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);
289 SIMPLE_ASYNC_TAIL;
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;
312 SETUP_PID;
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;
343 SETUP_PID;
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;
364 SETUP_PID;
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);
372 SIMPLE_ASYNC_TAIL;
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);
388 open a file
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;
396 SETUP_PID;
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);
413 create a directory
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;
421 SETUP_PID;
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);
429 SIMPLE_ASYNC_TAIL;
433 remove a directory
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;
441 SETUP_PID;
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);
448 SIMPLE_ASYNC_TAIL;
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;
460 SETUP_PID;
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);
468 SIMPLE_ASYNC_TAIL;
472 copy a set of files
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);
492 read from a file
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;
500 SETUP_PID;
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);
528 write to a file
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;
536 SETUP_PID;
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);
564 seek in a file
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;
572 SETUP_PID;
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);
584 flush a file
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;
592 SETUP_PID;
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);
600 SIMPLE_ASYNC_TAIL;
604 close a file
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;
612 SETUP_PID;
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);
625 SIMPLE_ASYNC_TAIL;
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;
637 SETUP_PID;
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);
645 SIMPLE_ASYNC_TAIL;
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 .... */
655 return NT_STATUS_OK;
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,
663 void *private)
665 return NT_STATUS_OK;
669 cancel an async call
671 static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs,
672 struct smbsrv_request *req)
674 return NT_STATUS_NOT_IMPLEMENTED;
678 lock a byte range
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;
686 SETUP_PID;
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);
698 SIMPLE_ASYNC_TAIL;
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;
711 SETUP_PID;
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);
718 SIMPLE_ASYNC_TAIL;
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;
742 SETUP_PID;
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;
772 SETUP_PID;
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;
785 SETUP_PID;
787 return smb_raw_search_next(private->tree, req, io, search_private, callback);
790 /* close a search */
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;
796 SETUP_PID;
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);
812 /* raw trans2 */
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;
819 SETUP_PID;
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)
843 NTSTATUS ret;
844 struct ntvfs_ops ops;
846 ZERO_STRUCT(ops);
848 /* fill in the name and type */
849 ops.name = "cifs";
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;
875 ops.lpq = cvfs_lpq;
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"));
896 return ret;