1/* 2 Unix SMB/CIFS implementation. 3 Wrap disk only vfs functions to sidestep dodgy compilers. 4 Copyright (C) Tim Potter 1998 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#include "includes.h" 22 23#undef DBGC_CLASS 24#define DBGC_CLASS DBGC_VFS 25 26 27/* Check for NULL pointer parameters in vfswrap_* functions */ 28 29/* We don't want to have NULL function pointers lying around. Someone 30 is sure to try and execute them. These stubs are used to prevent 31 this possibility. */ 32 33#ifdef MAX_USB_ACCESS 34extern CON_STATISTIC *con_st; 35extern int binary_semaphore_post (int semid); 36extern int binary_semaphore_wait (int semid); 37#endif 38 39int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user) 40{ 41 return 0; /* Return >= 0 for success */ 42} 43 44void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn) 45{ 46 47} 48 49/* Disk operations */ 50 51SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, 52 SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) 53{ 54 SMB_BIG_UINT result; 55 56 result = sys_disk_free(path, small_query, bsize, dfree, dsize); 57 return result; 58} 59 60int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) 61{ 62#ifdef HAVE_SYS_QUOTAS 63 int result; 64 65 START_PROFILE(syscall_get_quota); 66 result = sys_get_quota(conn->connectpath, qtype, id, qt); 67 END_PROFILE(syscall_get_quota); 68 return result; 69#else 70 errno = ENOSYS; 71 return -1; 72#endif 73} 74 75int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) 76{ 77#ifdef HAVE_SYS_QUOTAS 78 int result; 79 80 START_PROFILE(syscall_set_quota); 81 result = sys_set_quota(conn->connectpath, qtype, id, qt); 82 END_PROFILE(syscall_set_quota); 83 return result; 84#else 85 errno = ENOSYS; 86 return -1; 87#endif 88} 89 90int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels) 91{ 92 errno = ENOSYS; 93 return -1; /* Not implemented. */ 94} 95 96/* Directory operations */ 97 98DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) 99{ 100 DIR *result; 101 102 START_PROFILE(syscall_opendir); 103 result = sys_opendir(fname); 104 END_PROFILE(syscall_opendir); 105 return result; 106} 107 108SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) 109{ 110 SMB_STRUCT_DIRENT *result; 111 112 START_PROFILE(syscall_readdir); 113 result = sys_readdir(dirp); 114 END_PROFILE(syscall_readdir); 115 return result; 116} 117 118void vfswrap_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset) 119{ 120 START_PROFILE(syscall_seekdir); 121 sys_seekdir(dirp, offset); 122 END_PROFILE(syscall_seekdir); 123} 124 125long vfswrap_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) 126{ 127 long result; 128 START_PROFILE(syscall_telldir); 129 result = sys_telldir(dirp); 130 END_PROFILE(syscall_telldir); 131 return result; 132} 133 134void vfswrap_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) 135{ 136 START_PROFILE(syscall_rewinddir); 137 sys_rewinddir(dirp); 138 END_PROFILE(syscall_rewinddir); 139} 140 141int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) 142{ 143 int result; 144 BOOL has_dacl = False; 145 146 START_PROFILE(syscall_mkdir); 147 148 if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(conn, parent_dirname(path)))) 149 mode = 0777; 150 151 result = mkdir(path, mode); 152 153 if (result == 0 && !has_dacl) { 154 /* 155 * We need to do this as the default behavior of POSIX ACLs 156 * is to set the mask to be the requested group permission 157 * bits, not the group permission bits to be the requested 158 * group permission bits. This is not what we want, as it will 159 * mess up any inherited ACL bits that were set. JRA. 160 */ 161 int saved_errno = errno; /* We may get ENOSYS */ 162 if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS)) 163 errno = saved_errno; 164 } 165 166 END_PROFILE(syscall_mkdir); 167 return result; 168} 169 170int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) 171{ 172 int result; 173 174 START_PROFILE(syscall_rmdir); 175 result = rmdir(path); 176 END_PROFILE(syscall_rmdir); 177 return result; 178} 179 180int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) 181{ 182 int result; 183 184 START_PROFILE(syscall_closedir); 185 result = sys_closedir(dirp); 186 END_PROFILE(syscall_closedir); 187 return result; 188} 189 190/* File operations */ 191 192int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) 193{ 194 int result; 195 196 /* Foxconn added start pling 07/12/2012 */ 197 /* Do connection count check first */ 198#if 0 //def MAX_USB_ACCESS // pling removed 07/18/2012, In Win7, copy a folder with more than 15 files may have problems 199 if(con_st != NULL) 200 { 201 if ( ( con_st->num ) >= MAX_CON_NUM) 202 return -1; 203 } 204 //cprintf("*******%s(%d):con_st->num=%d\n", __FUNCTION__, __LINE__, con_st->num); 205#endif 206 /* Foxconn added end pling 07/12/2012 */ 207 208 START_PROFILE(syscall_open); 209 result = sys_open(fname, flags, mode); 210 END_PROFILE(syscall_open); 211 212 /* Foxconn modified start pling 07/12/2012 */ 213 /* Increment counter if open is successful */ 214#if 0 //def MAX_USB_ACCESS // pling removed 07/18/2012, In Win7, copy a folder with more than 15 files may have problems 215 if (result != -1 && con_st != NULL) 216 { 217 binary_semaphore_wait (con_st->sem_id); 218 ++(con_st->num); 219 binary_semaphore_post (con_st->sem_id); 220 } 221#endif 222 /* Foxconn modified end pling 07/12/2012 */ 223 224 return result; 225} 226 227int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd) 228{ 229 int result; 230 231 START_PROFILE(syscall_close); 232 233 result = close(fd); 234 END_PROFILE(syscall_close); 235 236#if 0 //def MAX_USB_ACCESS // pling removed 07/18/2012, In Win7, copy a folder with more than 15 files may have problems 237 /* Foxconn modified start pling 07/12/2012 */ 238 /* Increment counter if close is successful */ 239 //if(con_st != NULL) 240 if (result != -1 && con_st != NULL) 241 /* Foxconn modified end pling 07/12/2012 */ 242 { 243 binary_semaphore_wait (con_st->sem_id); 244 --(con_st->num); 245 binary_semaphore_post (con_st->sem_id); 246 } 247 //cprintf("*******%s(%d):con_st->num=%d\n", __FUNCTION__, __LINE__, con_st->num); 248#endif 249 250 return result; 251} 252 253ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n) 254{ 255 ssize_t result; 256 257 START_PROFILE_BYTES(syscall_read, n); 258 result = sys_read(fd, data, n); 259 END_PROFILE(syscall_read); 260 return result; 261} 262 263/* Foxconn modified start pling 11/18/2009 */ 264//ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, 265// size_t n, SMB_OFF_T offset) 266ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, 267 size_t n, SMB_BIG_UINT offset) 268/* Foxconn modified end pling 11/18/2009 */ 269{ 270 ssize_t result; 271 272#if defined(HAVE_PREAD) || defined(HAVE_PREAD64) 273 START_PROFILE_BYTES(syscall_pread, n); 274 result = sys_pread(fd, data, n, offset); 275 END_PROFILE(syscall_pread); 276 277 if (result == -1 && errno == ESPIPE) { 278 /* Maintain the fiction that pipes can be seeked (sought?) on. */ 279 result = SMB_VFS_READ(fsp, fd, data, n); 280 fsp->pos = 0; 281 } 282 283#else /* HAVE_PREAD */ 284 SMB_OFF_T curr; 285 int lerrno; 286 287 curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); 288 if (curr == -1 && errno == ESPIPE) { 289 /* Maintain the fiction that pipes can be seeked (sought?) on. */ 290 result = SMB_VFS_READ(fsp, fd, data, n); 291 fsp->pos = 0; 292 return result; 293 } 294 295 if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { 296 return -1; 297 } 298 299 errno = 0; 300 result = SMB_VFS_READ(fsp, fd, data, n); 301 lerrno = errno; 302 303 SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); 304 errno = lerrno; 305 306#endif /* HAVE_PREAD */ 307 308 return result; 309} 310 311ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) 312{ 313 ssize_t result; 314 315 START_PROFILE_BYTES(syscall_write, n); 316 result = sys_write(fd, data, n); 317 END_PROFILE(syscall_write); 318 return result; 319} 320 321/* Foxconn modified start pling 11/18/2009 */ 322//ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, 323// size_t n, SMB_OFF_T offset) 324ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, 325 size_t n, SMB_BIG_UINT offset) 326/* Foxconn modified end pling 11/18/2009 */ 327{ 328 ssize_t result; 329 330#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64) 331 START_PROFILE_BYTES(syscall_pwrite, n); 332 result = sys_pwrite(fd, data, n, offset); 333 END_PROFILE(syscall_pwrite); 334 335 if (result == -1 && errno == ESPIPE) { 336 /* Maintain the fiction that pipes can be sought on. */ 337 result = SMB_VFS_WRITE(fsp, fd, data, n); 338 } 339 340#else /* HAVE_PWRITE */ 341 SMB_OFF_T curr; 342 int lerrno; 343 344 curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); 345 if (curr == -1) { 346 return -1; 347 } 348 349 if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { 350 return -1; 351 } 352 353 result = SMB_VFS_WRITE(fsp, fd, data, n); 354 lerrno = errno; 355 356 SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); 357 errno = lerrno; 358 359#endif /* HAVE_PWRITE */ 360 361 return result; 362} 363 364/* Foxconn modified start pling 11/18/2009 */ 365//SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) 366SMB_BIG_UINT vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_BIG_UINT offset, int whence) 367/* Foxconn modified end pling 11/18/2009 */ 368{ 369 //SMB_OFF_T result = 0; 370 SMB_BIG_UINT result = 0; 371 372 START_PROFILE(syscall_lseek); 373 374 /* Cope with 'stat' file opens. */ 375 if (filedes != -1) 376 result = sys_lseek(filedes, offset, whence); 377 378 /* 379 * We want to maintain the fiction that we can seek 380 * on a fifo for file system purposes. This allows 381 * people to set up UNIX fifo's that feed data to Windows 382 * applications. JRA. 383 */ 384 385 if((result == -1) && (errno == ESPIPE)) { 386 result = 0; 387 errno = 0; 388 } 389 390 END_PROFILE(syscall_lseek); 391 return result; 392} 393 394ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr, 395 SMB_OFF_T offset, size_t n) 396{ 397 ssize_t result; 398 399 START_PROFILE_BYTES(syscall_sendfile, n); 400 result = sys_sendfile(tofd, fromfd, hdr, offset, n); 401 END_PROFILE(syscall_sendfile); 402 return result; 403} 404 405/********************************************************* 406 For rename across filesystems Patch from Warren Birnbaum 407 <warrenb@hpcvscdp.cv.hp.com> 408**********************************************************/ 409 410static int copy_reg(const char *source, const char *dest) 411{ 412 SMB_STRUCT_STAT source_stats; 413 int saved_errno; 414 int ifd = -1; 415 int ofd = -1; 416 417 if (sys_lstat (source, &source_stats) == -1) 418 return -1; 419 420 if (!S_ISREG (source_stats.st_mode)) 421 return -1; 422 423 if((ifd = sys_open (source, O_RDONLY, 0)) < 0) 424 return -1; 425 426 if (unlink (dest) && errno != ENOENT) 427 return -1; 428 429#ifdef O_NOFOLLOW 430 if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 ) 431#else 432 if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 ) 433#endif 434 goto err; 435 436 if (transfer_file(ifd, ofd, (size_t)-1) == -1) 437 goto err; 438 439 /* 440 * Try to preserve ownership. For non-root it might fail, but that's ok. 441 * But root probably wants to know, e.g. if NFS disallows it. 442 */ 443 444#ifdef HAVE_FCHOWN 445 if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) 446#else 447 if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) 448#endif 449 goto err; 450 451 /* 452 * fchown turns off set[ug]id bits for non-root, 453 * so do the chmod last. 454 */ 455 456#if defined(HAVE_FCHMOD) 457 if (fchmod (ofd, source_stats.st_mode & 07777)) 458#else 459 if (chmod (dest, source_stats.st_mode & 07777)) 460#endif 461 goto err; 462 463 if (close (ifd) == -1) 464 goto err; 465 466 if (close (ofd) == -1) 467 return -1; 468 469 /* Try to copy the old file's modtime and access time. */ 470 { 471 struct utimbuf tv; 472 473 tv.actime = source_stats.st_atime; 474 tv.modtime = source_stats.st_mtime; 475 utime(dest, &tv); 476 } 477 478 if (unlink (source) == -1) 479 return -1; 480 481 return 0; 482 483 err: 484 485 saved_errno = errno; 486 if (ifd != -1) 487 close(ifd); 488 if (ofd != -1) 489 close(ofd); 490 errno = saved_errno; 491 return -1; 492} 493 494int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new) 495{ 496 int result; 497 498 START_PROFILE(syscall_rename); 499 result = rename(old, new); 500 if (errno == EXDEV) { 501 /* Rename across filesystems needed. */ 502 result = copy_reg(old, new); 503 } 504 505 END_PROFILE(syscall_rename); 506 return result; 507} 508 509int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) 510{ 511#ifdef HAVE_FSYNC 512 int result; 513 514 START_PROFILE(syscall_fsync); 515 result = fsync(fd); 516 END_PROFILE(syscall_fsync); 517 return result; 518#else 519 return 0; 520#endif 521} 522 523int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) 524{ 525 int result; 526 527 START_PROFILE(syscall_stat); 528 result = sys_stat(fname, sbuf); 529 END_PROFILE(syscall_stat); 530 531 return result; 532} 533 534int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) 535{ 536 int result; 537 538 START_PROFILE(syscall_fstat); 539 result = sys_fstat(fd, sbuf); 540 END_PROFILE(syscall_fstat); 541 return result; 542} 543 544int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) 545{ 546 int result; 547 548 START_PROFILE(syscall_lstat); 549 result = sys_lstat(path, sbuf); 550 END_PROFILE(syscall_lstat); 551 return result; 552} 553 554int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) 555{ 556 int result; 557 558 START_PROFILE(syscall_unlink); 559 result = unlink(path); 560 END_PROFILE(syscall_unlink); 561 return result; 562} 563 564int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) 565{ 566 int result; 567 568 START_PROFILE(syscall_chmod); 569 570 /* 571 * We need to do this due to the fact that the default POSIX ACL 572 * chmod modifies the ACL *mask* for the group owner, not the 573 * group owner bits directly. JRA. 574 */ 575 576 577 { 578 int saved_errno = errno; /* We might get ENOSYS */ 579 if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) { 580 END_PROFILE(syscall_chmod); 581 return result; 582 } 583 /* Error - return the old errno. */ 584 errno = saved_errno; 585 } 586 587 result = chmod(path, mode); 588 END_PROFILE(syscall_chmod); 589 return result; 590} 591 592int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) 593{ 594 int result; 595 596 START_PROFILE(syscall_fchmod); 597 598 /* 599 * We need to do this due to the fact that the default POSIX ACL 600 * chmod modifies the ACL *mask* for the group owner, not the 601 * group owner bits directly. JRA. 602 */ 603 604 { 605 int saved_errno = errno; /* We might get ENOSYS */ 606 if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) { 607 END_PROFILE(syscall_chmod); 608 return result; 609 } 610 /* Error - return the old errno. */ 611 errno = saved_errno; 612 } 613 614#if defined(HAVE_FCHMOD) 615 result = fchmod(fd, mode); 616#else 617 result = -1; 618 errno = ENOSYS; 619#endif 620 621 END_PROFILE(syscall_fchmod); 622 return result; 623} 624 625int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid) 626{ 627 int result; 628 629 START_PROFILE(syscall_chown); 630 result = sys_chown(path, uid, gid); 631 END_PROFILE(syscall_chown); 632 return result; 633} 634 635int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid) 636{ 637#ifdef HAVE_FCHOWN 638 int result; 639 640 START_PROFILE(syscall_fchown); 641 result = fchown(fd, uid, gid); 642 END_PROFILE(syscall_fchown); 643 return result; 644#else 645 errno = ENOSYS; 646 return -1; 647#endif 648} 649 650int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) 651{ 652 int result; 653 654 START_PROFILE(syscall_chdir); 655 result = chdir(path); 656 END_PROFILE(syscall_chdir); 657 return result; 658} 659 660char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path) 661{ 662 char *result; 663 664 START_PROFILE(syscall_getwd); 665 result = sys_getwd(path); 666 END_PROFILE(syscall_getwd); 667 return result; 668} 669 670int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times) 671{ 672 int result; 673 674 START_PROFILE(syscall_utime); 675 result = utime(path, times); 676 END_PROFILE(syscall_utime); 677 return result; 678} 679 680/********************************************************************* 681 A version of ftruncate that will write the space on disk if strict 682 allocate is set. 683**********************************************************************/ 684 685static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) 686{ 687 SMB_STRUCT_STAT st; 688 SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); 689 unsigned char zero_space[4096]; 690 SMB_OFF_T space_to_write; 691 692 if (currpos == -1) 693 return -1; 694 695 if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) 696 return -1; 697 698 space_to_write = len - st.st_size; 699 700#ifdef S_ISFIFO 701 if (S_ISFIFO(st.st_mode)) 702 return 0; 703#endif 704 705 if (st.st_size == len) 706 return 0; 707 708 /* Shrink - just ftruncate. */ 709 if (st.st_size > len) 710 return sys_ftruncate(fd, len); 711 712 /* Write out the real space on disk. */ 713 if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size) 714 return -1; 715 716 space_to_write = len - st.st_size; 717 718 memset(zero_space, '\0', sizeof(zero_space)); 719 while ( space_to_write > 0) { 720 SMB_OFF_T retlen; 721 SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write); 722 723 retlen = SMB_VFS_WRITE(fsp,fsp->fd,(char *)zero_space,current_len_to_write); 724 if (retlen <= 0) 725 return -1; 726 727 space_to_write -= retlen; 728 } 729 730 /* Seek to where we were */ 731 if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) 732 return -1; 733 734 return 0; 735} 736 737int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len) 738{ 739 int result = -1; 740 SMB_STRUCT_STAT st; 741 char c = 0; 742 SMB_OFF_T currpos; 743 744 START_PROFILE(syscall_ftruncate); 745 746 if (lp_strict_allocate(SNUM(fsp->conn))) { 747 result = strict_allocate_ftruncate(handle, fsp, fd, len); 748 END_PROFILE(syscall_ftruncate); 749 return result; 750 } 751 752 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use 753 sys_ftruncate if the system supports it. Then I discovered that 754 you can have some filesystems that support ftruncate 755 expansion and some that don't! On Linux fat can't do 756 ftruncate extend but ext2 can. */ 757 758 result = sys_ftruncate(fd, len); 759 if (result == 0) 760 goto done; 761 762 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot 763 extend a file with ftruncate. Provide alternate implementation 764 for this */ 765 currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); 766 if (currpos == -1) { 767 goto done; 768 } 769 770 /* Do an fstat to see if the file is longer than the requested 771 size in which case the ftruncate above should have 772 succeeded or shorter, in which case seek to len - 1 and 773 write 1 byte of zero */ 774 if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) { 775 goto done; 776 } 777 778#ifdef S_ISFIFO 779 if (S_ISFIFO(st.st_mode)) { 780 result = 0; 781 goto done; 782 } 783#endif 784 785 if (st.st_size == len) { 786 result = 0; 787 goto done; 788 } 789 790 if (st.st_size > len) { 791 /* the sys_ftruncate should have worked */ 792 goto done; 793 } 794 795 if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1) 796 goto done; 797 798 if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1) 799 goto done; 800 801 /* Seek to where we were */ 802 if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos) 803 goto done; 804 result = 0; 805 806 done: 807 808 END_PROFILE(syscall_ftruncate); 809 return result; 810} 811 812BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) 813{ 814 BOOL result; 815 816 START_PROFILE(syscall_fcntl_lock); 817 result = fcntl_lock(fd, op, offset, count,type); 818 END_PROFILE(syscall_fcntl_lock); 819 return result; 820} 821 822int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) 823{ 824 int result; 825 826 START_PROFILE(syscall_symlink); 827 result = sys_symlink(oldpath, newpath); 828 END_PROFILE(syscall_symlink); 829 return result; 830} 831 832int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) 833{ 834 int result; 835 836 START_PROFILE(syscall_readlink); 837 result = sys_readlink(path, buf, bufsiz); 838 END_PROFILE(syscall_readlink); 839 return result; 840} 841 842int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) 843{ 844 int result; 845 846 START_PROFILE(syscall_link); 847 result = sys_link(oldpath, newpath); 848 END_PROFILE(syscall_link); 849 return result; 850} 851 852int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev) 853{ 854 int result; 855 856 START_PROFILE(syscall_mknod); 857 result = sys_mknod(pathname, mode, dev); 858 END_PROFILE(syscall_mknod); 859 return result; 860} 861 862char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path) 863{ 864 char *result; 865 866 START_PROFILE(syscall_realpath); 867 result = sys_realpath(path, resolved_path); 868 END_PROFILE(syscall_realpath); 869 return result; 870} 871 872size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) 873{ 874 size_t result; 875 876 START_PROFILE(fget_nt_acl); 877 result = get_nt_acl(fsp, security_info, ppdesc); 878 END_PROFILE(fget_nt_acl); 879 return result; 880} 881 882size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc) 883{ 884 size_t result; 885 886 START_PROFILE(get_nt_acl); 887 result = get_nt_acl(fsp, security_info, ppdesc); 888 END_PROFILE(get_nt_acl); 889 return result; 890} 891 892BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) 893{ 894 BOOL result; 895 896 START_PROFILE(fset_nt_acl); 897 result = set_nt_acl(fsp, security_info_sent, psd); 898 END_PROFILE(fset_nt_acl); 899 return result; 900} 901 902BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) 903{ 904 BOOL result; 905 906 START_PROFILE(set_nt_acl); 907 result = set_nt_acl(fsp, security_info_sent, psd); 908 END_PROFILE(set_nt_acl); 909 return result; 910} 911 912int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode) 913{ 914#ifdef HAVE_NO_ACL 915 errno = ENOSYS; 916 return -1; 917#else 918 int result; 919 920 START_PROFILE(chmod_acl); 921 result = chmod_acl(conn, name, mode); 922 END_PROFILE(chmod_acl); 923 return result; 924#endif 925} 926 927int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) 928{ 929#ifdef HAVE_NO_ACL 930 errno = ENOSYS; 931 return -1; 932#else 933 int result; 934 935 START_PROFILE(fchmod_acl); 936 result = fchmod_acl(fsp, fd, mode); 937 END_PROFILE(fchmod_acl); 938 return result; 939#endif 940} 941 942int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) 943{ 944 return sys_acl_get_entry(theacl, entry_id, entry_p); 945} 946 947int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) 948{ 949 return sys_acl_get_tag_type(entry_d, tag_type_p); 950} 951 952int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) 953{ 954 return sys_acl_get_permset(entry_d, permset_p); 955} 956 957void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d) 958{ 959 return sys_acl_get_qualifier(entry_d); 960} 961 962SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) 963{ 964 return sys_acl_get_file(path_p, type); 965} 966 967SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) 968{ 969 return sys_acl_get_fd(fd); 970} 971 972int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset) 973{ 974 return sys_acl_clear_perms(permset); 975} 976 977int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) 978{ 979 return sys_acl_add_perm(permset, perm); 980} 981 982char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen) 983{ 984 return sys_acl_to_text(theacl, plen); 985} 986 987SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count) 988{ 989 return sys_acl_init(count); 990} 991 992int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) 993{ 994 return sys_acl_create_entry(pacl, pentry); 995} 996 997int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) 998{ 999 return sys_acl_set_tag_type(entry, tagtype); 1000} 1001 1002int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual) 1003{ 1004 return sys_acl_set_qualifier(entry, qual); 1005} 1006 1007int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) 1008{ 1009 return sys_acl_set_permset(entry, permset); 1010} 1011 1012int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl ) 1013{ 1014 return sys_acl_valid(theacl ); 1015} 1016 1017int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) 1018{ 1019 return sys_acl_set_file(name, acltype, theacl); 1020} 1021 1022int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl) 1023{ 1024 return sys_acl_set_fd(fd, theacl); 1025} 1026 1027int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path) 1028{ 1029 return sys_acl_delete_def_file(path); 1030} 1031 1032int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) 1033{ 1034 return sys_acl_get_perm(permset, perm); 1035} 1036 1037int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text) 1038{ 1039 return sys_acl_free_text(text); 1040} 1041 1042int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl) 1043{ 1044 return sys_acl_free_acl(posix_acl); 1045} 1046 1047int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) 1048{ 1049 return sys_acl_free_qualifier(qualifier, tagtype); 1050} 1051 1052/**************************************************************** 1053 Extended attribute operations. 1054*****************************************************************/ 1055 1056ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) 1057{ 1058 return sys_getxattr(path, name, value, size); 1059} 1060 1061ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size) 1062{ 1063 return sys_lgetxattr(path, name, value, size); 1064} 1065 1066ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size) 1067{ 1068 return sys_fgetxattr(fd, name, value, size); 1069} 1070 1071ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) 1072{ 1073 return sys_listxattr(path, list, size); 1074} 1075 1076ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size) 1077{ 1078 return sys_llistxattr(path, list, size); 1079} 1080 1081ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size) 1082{ 1083 return sys_flistxattr(fd, list, size); 1084} 1085 1086int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) 1087{ 1088 return sys_removexattr(path, name); 1089} 1090 1091int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name) 1092{ 1093 return sys_lremovexattr(path, name); 1094} 1095 1096int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name) 1097{ 1098 return sys_fremovexattr(fd, name); 1099} 1100 1101int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) 1102{ 1103 return sys_setxattr(path, name, value, size, flags); 1104} 1105 1106int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags) 1107{ 1108 return sys_lsetxattr(path, name, value, size, flags); 1109} 1110 1111int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags) 1112{ 1113 return sys_fsetxattr(fd, name, value, size, flags); 1114} 1115