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