Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/vfs.c

    r596 r745  
    2525
    2626#include "includes.h"
     27#include "system/filesys.h"
     28#include "smbd/smbd.h"
    2729#include "smbd/globals.h"
     30#include "memcache.h"
     31#include "transfer_file.h"
     32#include "ntioctl.h"
    2833
    2934#undef DBGC_CLASS
     
    112117
    113118        if (!conn||!vfs_object||!vfs_object[0]) {
    114                 DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n"));
     119                DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
     120                          "empty vfs_object!\n"));
    115121                return False;
    116122        }
     
    393399                 * before returning. */
    394400                req->unread_bytes = 0;
    395                 return SMB_VFS_RECVFILE(smbd_server_fd(),
     401                return SMB_VFS_RECVFILE(req->sconn->sock,
    396402                                        fsp,
    397403                                        (SMB_OFF_T)-1,
     
    426432                 * before returning. */
    427433                req->unread_bytes = 0;
    428                 return SMB_VFS_RECVFILE(smbd_server_fd(),
     434                return SMB_VFS_RECVFILE(req->sconn->sock,
    429435                                        fsp,
    430436                                        offset,
     
    454460{
    455461        int ret;
    456         SMB_STRUCT_STAT st;
    457462        connection_struct *conn = fsp->conn;
    458463        uint64_t space_avail;
    459464        uint64_t bsize,dfree,dsize;
     465        NTSTATUS status;
    460466
    461467        /*
     
    473479        }
    474480
    475         ret = SMB_VFS_FSTAT(fsp, &st);
    476         if (ret == -1)
    477                 return ret;
    478 
    479         if (len == (uint64_t)st.st_ex_size)
     481        status = vfs_stat_fsp(fsp);
     482        if (!NT_STATUS_IS_OK(status)) {
     483                return -1;
     484        }
     485
     486        if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
    480487                return 0;
    481488
    482         if (len < (uint64_t)st.st_ex_size) {
     489        if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
    483490                /* Shrink - use ftruncate. */
    484491
    485492                DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
    486493                          "size %.0f\n", fsp_str_dbg(fsp),
    487                           (double)st.st_ex_size));
     494                          (double)fsp->fsp_name->st.st_ex_size));
    488495
    489496                contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
     
    499506        }
    500507
    501         /* Grow - we need to test if we have enough space. */
    502 
    503         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
    504         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
    505 
    506508        if (!lp_strict_allocate(SNUM(fsp->conn)))
    507509                return 0;
    508510
    509         len -= st.st_ex_size;
     511        /* Grow - we need to test if we have enough space. */
     512
     513        contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
     514
     515        /* See if we have a syscall that will allocate beyond end-of-file
     516           without changing EOF. */
     517        ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
     518
     519        contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
     520
     521        if (ret == 0) {
     522                /* We changed the allocation size on disk, but not
     523                   EOF - exactly as required. We're done ! */
     524                return 0;
     525        }
     526
     527        len -= fsp->fsp_name->st.st_ex_size;
    510528        len /= 1024; /* Len is now number of 1k blocks needed. */
    511529        space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
     
    517535        DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
    518536                  "needed blocks = %.0f, space avail = %.0f\n",
    519                   fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len,
     537                  fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
    520538                  (double)space_avail));
    521539
     
    557575
    558576/****************************************************************************
     577 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
     578 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
     579 as this is also called from the default SMB_VFS_FTRUNCATE code.
     580 Always extends the file size.
     581 Returns 0 on success, errno on failure.
     582****************************************************************************/
     583
     584#define SPARSE_BUF_WRITE_SIZE (32*1024)
     585
     586int vfs_slow_fallocate(files_struct *fsp, SMB_OFF_T offset, SMB_OFF_T len)
     587{
     588        ssize_t pwrite_ret;
     589        size_t total = 0;
     590
     591        if (!sparse_buf) {
     592                sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
     593                if (!sparse_buf) {
     594                        errno = ENOMEM;
     595                        return ENOMEM;
     596                }
     597        }
     598
     599        while (total < len) {
     600                size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
     601
     602                pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
     603                if (pwrite_ret == -1) {
     604                        DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
     605                                  "%s failed with error %s\n",
     606                                  fsp_str_dbg(fsp), strerror(errno)));
     607                        return errno;
     608                }
     609                total += pwrite_ret;
     610        }
     611
     612        return 0;
     613}
     614
     615/****************************************************************************
    559616 A vfs fill sparse call.
    560617 Writes zeros from the end of file to len, if len is greater than EOF.
     
    563620****************************************************************************/
    564621
    565 #define SPARSE_BUF_WRITE_SIZE (32*1024)
    566 
    567622int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
    568623{
    569624        int ret;
    570         SMB_STRUCT_STAT st;
     625        NTSTATUS status;
    571626        SMB_OFF_T offset;
    572         size_t total;
    573627        size_t num_to_write;
    574         ssize_t pwrite_ret;
    575 
    576         ret = SMB_VFS_FSTAT(fsp, &st);
    577         if (ret == -1) {
    578                 return ret;
    579         }
    580 
    581         if (len <= st.st_ex_size) {
     628
     629        status = vfs_stat_fsp(fsp);
     630        if (!NT_STATUS_IS_OK(status)) {
     631                return -1;
     632        }
     633
     634        if (len <= fsp->fsp_name->st.st_ex_size) {
    582635                return 0;
    583636        }
    584637
    585638#ifdef S_ISFIFO
    586         if (S_ISFIFO(st.st_ex_mode)) {
     639        if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
    587640                return 0;
    588641        }
     
    591644        DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
    592645                  "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
    593                   (double)st.st_ex_size, (double)len,
    594                   (double)(len - st.st_ex_size)));
     646                  (double)fsp->fsp_name->st.st_ex_size, (double)len,
     647                  (double)(len - fsp->fsp_name->st.st_ex_size)));
    595648
    596649        contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
     
    598651        flush_write_cache(fsp, SIZECHANGE_FLUSH);
    599652
    600 
    601         offset = st.st_ex_size;
    602         num_to_write = len - st.st_ex_size;
     653        offset = fsp->fsp_name->st.st_ex_size;
     654        num_to_write = len - fsp->fsp_name->st.st_ex_size;
    603655
    604656        /* Only do this on non-stream file handles. */
    605657        if (fsp->base_fsp == NULL) {
    606                 /* for allocation try posix_fallocate first. This can fail on some
     658                /* for allocation try fallocate first. This can fail on some
    607659                 * platforms e.g. when the filesystem doesn't support it and no
    608660                 * emulation is being done by the libc (like on AIX with JFS1). In that
    609                  * case we do our own emulation. posix_fallocate implementations can
     661                 * case we do our own emulation. fallocate implementations can
    610662                 * return ENOTSUP or EINVAL in cases like that. */
    611                 ret = sys_posix_fallocate(fsp->fh->fd, offset, num_to_write);
     663                ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
     664                                offset, num_to_write);
    612665                if (ret == ENOSPC) {
    613666                        errno = ENOSPC;
     
    616669                }
    617670                if (ret == 0) {
    618                         set_filelen_write_cache(fsp, len);
    619671                        goto out;
    620672                }
    621 
    622                 DEBUG(10,("vfs_fill_sparse: sys_posix_fallocate failed with "
     673                DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
    623674                        "error %d. Falling back to slow manual allocation\n", ret));
    624675        }
    625676
    626         if (!sparse_buf) {
    627                 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
    628                 if (!sparse_buf) {
    629                         errno = ENOMEM;
    630                         ret = -1;
    631                         goto out;
    632                 }
    633         }
    634 
    635         total = 0;
    636 
    637         while (total < num_to_write) {
    638                 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total));
    639 
    640                 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
    641                 if (pwrite_ret == -1) {
    642                         DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file "
    643                                   "%s failed with error %s\n",
    644                                   fsp_str_dbg(fsp), strerror(errno)));
    645                         ret = -1;
    646                         goto out;
    647                 }
    648                 if (pwrite_ret == 0) {
    649                         ret = 0;
    650                         goto out;
    651                 }
    652 
    653                 total += pwrite_ret;
    654         }
    655 
    656         set_filelen_write_cache(fsp, len);
    657 
    658         ret = 0;
     677        ret = vfs_slow_fallocate(fsp, offset, num_to_write);
     678        if (ret != 0) {
     679                errno = ret;
     680                ret = -1;
     681        }
     682
    659683 out:
     684
     685        if (ret == 0) {
     686                set_filelen_write_cache(fsp, len);
     687        }
     688
    660689        contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
    661690        return ret;
     
    874903NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
    875904{
    876 #ifdef REALPATH_TAKES_NULL
    877         bool free_resolved_name = True;
    878 #else
    879         char resolved_name_buf[PATH_MAX+1];
    880         bool free_resolved_name = False;
    881 #endif
    882905        char *resolved_name = NULL;
    883         char *p = NULL;
     906        bool allow_symlinks = true;
     907        bool allow_widelinks = false;
    884908
    885909        DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
    886910
    887 #ifdef REALPATH_TAKES_NULL
    888         resolved_name = SMB_VFS_REALPATH(conn,fname,NULL);
    889 #else
    890         resolved_name = SMB_VFS_REALPATH(conn,fname,resolved_name_buf);
    891 #endif
     911        resolved_name = SMB_VFS_REALPATH(conn,fname);
    892912
    893913        if (!resolved_name) {
     
    901921                        {
    902922                                TALLOC_CTX *ctx = talloc_tos();
    903                                 char *tmp_fname = NULL;
    904                                 char *last_component = NULL;
    905                                 /* Last component didn't exist. Remove it and try and canonicalise the directory. */
    906 
    907                                 tmp_fname = talloc_strdup(ctx, fname);
    908                                 if (!tmp_fname) {
     923                                char *dir_name = NULL;
     924                                const char *last_component = NULL;
     925                                char *new_name = NULL;
     926
     927                                /* Last component didn't exist.
     928                                   Remove it and try and canonicalise
     929                                   the directory name. */
     930                                if (!parent_dirname(ctx, fname,
     931                                                &dir_name,
     932                                                &last_component)) {
    909933                                        return NT_STATUS_NO_MEMORY;
    910934                                }
    911                                 p = strrchr_m(tmp_fname, '/');
    912                                 if (p) {
    913                                         *p++ = '\0';
    914                                         last_component = p;
    915                                 } else {
    916                                         last_component = tmp_fname;
    917                                         tmp_fname = talloc_strdup(ctx,
    918                                                         ".");
    919                                         if (!tmp_fname) {
    920                                                 return NT_STATUS_NO_MEMORY;
    921                                         }
    922                                 }
    923 
    924 #ifdef REALPATH_TAKES_NULL
    925                                 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,NULL);
    926 #else
    927                                 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,resolved_name_buf);
    928 #endif
     935
     936                                resolved_name = SMB_VFS_REALPATH(conn,dir_name);
    929937                                if (!resolved_name) {
    930938                                        NTSTATUS status = map_nt_error_from_unix(errno);
     
    934942                                        }
    935943
    936                                         DEBUG(3,("check_reduce_named: "
     944                                        DEBUG(3,("check_reduce_name: "
    937945                                                 "couldn't get realpath for "
    938946                                                 "%s (%s)\n",
     
    941949                                        return status;
    942950                                }
    943                                 tmp_fname = talloc_asprintf(ctx,
     951                                new_name = talloc_asprintf(ctx,
    944952                                                "%s/%s",
    945953                                                resolved_name,
    946954                                                last_component);
    947                                 if (!tmp_fname) {
     955                                if (!new_name) {
    948956                                        return NT_STATUS_NO_MEMORY;
    949957                                }
    950 #ifdef REALPATH_TAKES_NULL
    951958                                SAFE_FREE(resolved_name);
    952                                 resolved_name = SMB_STRDUP(tmp_fname);
     959                                resolved_name = SMB_STRDUP(new_name);
    953960                                if (!resolved_name) {
    954                                         DEBUG(0, ("check_reduced_name: malloc "
    955                                                   "fail for %s\n", tmp_fname));
    956961                                        return NT_STATUS_NO_MEMORY;
    957962                                }
    958 #else
    959                                 safe_strcpy(resolved_name_buf, tmp_fname, PATH_MAX);
    960                                 resolved_name = resolved_name_buf;
    961 #endif
    962963                                break;
    963964                        }
     
    979980                DEBUG(0,("check_reduced_name: realpath doesn't return "
    980981                         "absolute paths !\n"));
    981                 if (free_resolved_name) {
     982                SAFE_FREE(resolved_name);
     983                return NT_STATUS_OBJECT_NAME_INVALID;
     984        }
     985
     986        allow_widelinks = lp_widelinks(SNUM(conn));
     987        allow_symlinks = lp_symlinks(SNUM(conn));
     988
     989        /* Common widelinks and symlinks checks. */
     990        if (!allow_widelinks || !allow_symlinks) {
     991                const char *conn_rootdir;
     992                size_t rootdir_len;
     993
     994                conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
     995                if (conn_rootdir == NULL) {
     996                        DEBUG(2, ("check_reduced_name: Could not get "
     997                                "conn_rootdir\n"));
    982998                        SAFE_FREE(resolved_name);
    983                 }
    984                 return NT_STATUS_OBJECT_NAME_INVALID;
    985         }
    986 
    987         /* Check for widelinks allowed. */
    988         if (!lp_widelinks(SNUM(conn))) {
    989                     const char *conn_rootdir;
    990 
    991                     conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
    992                     if (conn_rootdir == NULL) {
    993                             DEBUG(2, ("check_reduced_name: Could not get "
    994                                       "conn_rootdir\n"));
    995                             if (free_resolved_name) {
    996                                     SAFE_FREE(resolved_name);
    997                             }
    998                             return NT_STATUS_ACCESS_DENIED;
    999                     }
    1000 
    1001                     if (strncmp(conn_rootdir, resolved_name,
    1002                                 strlen(conn_rootdir)) != 0) {
    1003                             DEBUG(2, ("check_reduced_name: Bad access "
    1004                                       "attempt: %s is a symlink outside the "
    1005                                       "share path\n", fname));
    1006                             if (free_resolved_name) {
    1007                                     SAFE_FREE(resolved_name);
    1008                             }
    1009                             return NT_STATUS_ACCESS_DENIED;
    1010                     }
    1011         }
    1012 
    1013         /* Check if we are allowing users to follow symlinks */
    1014         /* Patch from David Clerc <David.Clerc@cui.unige.ch>
    1015                 University of Geneva */
    1016 
    1017 #ifdef S_ISLNK
    1018         if (!lp_symlinks(SNUM(conn))) {
    1019                 struct smb_filename *smb_fname = NULL;
    1020                 NTSTATUS status;
    1021 
    1022                 status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
    1023                                                     NULL, &smb_fname);
    1024                 if (!NT_STATUS_IS_OK(status)) {
    1025                         if (free_resolved_name) {
     999                        return NT_STATUS_ACCESS_DENIED;
     1000                }
     1001
     1002                rootdir_len = strlen(conn_rootdir);
     1003                if (strncmp(conn_rootdir, resolved_name,
     1004                                rootdir_len) != 0) {
     1005                        DEBUG(2, ("check_reduced_name: Bad access "
     1006                                "attempt: %s is a symlink outside the "
     1007                                "share path\n", fname));
     1008                        DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
     1009                        DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
     1010                        SAFE_FREE(resolved_name);
     1011                        return NT_STATUS_ACCESS_DENIED;
     1012                }
     1013
     1014                /* Extra checks if all symlinks are disallowed. */
     1015                if (!allow_symlinks) {
     1016                        /* fname can't have changed in resolved_path. */
     1017                        const char *p = &resolved_name[rootdir_len];
     1018
     1019                        /* *p can be '\0' if fname was "." */
     1020                        if (*p == '\0' && ISDOT(fname)) {
     1021                                goto out;
     1022                        }
     1023
     1024                        if (*p != '/') {
     1025                                DEBUG(2, ("check_reduced_name: logic error (%c) "
     1026                                        "in resolved_name: %s\n",
     1027                                        *p,
     1028                                        fname));
    10261029                                SAFE_FREE(resolved_name);
     1030                                return NT_STATUS_ACCESS_DENIED;
    10271031                        }
    1028                         return status;
    1029                 }
    1030 
    1031                 if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) &&
    1032                                 (S_ISLNK(smb_fname->st.st_ex_mode)) ) {
    1033                         if (free_resolved_name) {
     1032
     1033                        p++;
     1034                        if (strcmp(fname, p)!=0) {
     1035                                DEBUG(2, ("check_reduced_name: Bad access "
     1036                                        "attempt: %s is a symlink\n",
     1037                                        fname));
    10341038                                SAFE_FREE(resolved_name);
     1039                                return NT_STATUS_ACCESS_DENIED;
    10351040                        }
    1036                         DEBUG(3,("check_reduced_name: denied: file path name "
    1037                                  "%s is a symlink\n",resolved_name));
    1038                         TALLOC_FREE(smb_fname);
    1039                         return NT_STATUS_ACCESS_DENIED;
    1040                 }
    1041                 TALLOC_FREE(smb_fname);
    1042         }
    1043 #endif
     1041                }
     1042        }
     1043
     1044  out:
    10441045
    10451046        DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
    10461047                 resolved_name));
    1047         if (free_resolved_name) {
    1048                 SAFE_FREE(resolved_name);
    1049         }
     1048        SAFE_FREE(resolved_name);
    10501049        return NT_STATUS_OK;
    10511050}
     
    11181117        int ret;
    11191118
    1120         if(fsp->is_directory || fsp->fh->fd == -1) {
     1119        if(fsp->fh->fd == -1) {
    11211120                if (fsp->posix_open) {
    11221121                        ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
     
    11841183int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
    11851184                                      struct files_struct *fsp,
    1186                                       SHADOW_COPY_DATA *shadow_copy_data,
     1185                                      struct shadow_copy_data *shadow_copy_data,
    11871186                                      bool labels)
    11881187{
     
    12131212}
    12141213
     1214SMB_STRUCT_DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
     1215                                        struct files_struct *fsp,
     1216                                        const char *mask,
     1217                                        uint32 attributes)
     1218{
     1219        VFS_FIND(fdopendir);
     1220        return handle->fns->fdopendir(handle, fsp, mask, attributes);
     1221}
     1222
    12151223SMB_STRUCT_DIRENT *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
    12161224                                              SMB_STRUCT_DIR *dirp,
     
    12731281                      int flags, mode_t mode)
    12741282{
    1275         VFS_FIND(open);
    1276         return handle->fns->open(handle, smb_fname, fsp, flags, mode);
     1283        VFS_FIND(open_fn);
     1284        return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
    12771285}
    12781286
     
    12881296                                  uint32_t oplock_request,
    12891297                                  uint64_t allocation_size,
     1298                                  uint32_t private_flags,
    12901299                                  struct security_descriptor *sd,
    12911300                                  struct ea_list *ea_list,
     
    12971306                handle, req, root_dir_fid, smb_fname, access_mask,
    12981307                share_access, create_disposition, create_options,
    1299                 file_attributes, oplock_request, allocation_size, sd, ea_list,
     1308                file_attributes, oplock_request, allocation_size,
     1309                private_flags, sd, ea_list,
    13001310                result, pinfo);
    13011311}
     
    14501460}
    14511461
     1462NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
     1463{
     1464        int ret;
     1465        bool as_root = false;
     1466        const char *path;
     1467        char *saved_dir = NULL;
     1468        char *parent_dir = NULL;
     1469        NTSTATUS status;
     1470
     1471        if (fsp->fh->fd != -1) {
     1472                /* Try fchown. */
     1473                ret = SMB_VFS_FCHOWN(fsp, uid, gid);
     1474                if (ret == 0) {
     1475                        return NT_STATUS_OK;
     1476                }
     1477                if (ret == -1 && errno != ENOSYS) {
     1478                        return map_nt_error_from_unix(errno);
     1479                }
     1480        }
     1481
     1482        as_root = (geteuid() == 0);
     1483
     1484        if (as_root) {
     1485                /*
     1486                 * We are being asked to chown as root. Make
     1487                 * sure we chdir() into the path to pin it,
     1488                 * and always act using lchown to ensure we
     1489                 * don't deref any symbolic links.
     1490                 */
     1491                const char *final_component = NULL;
     1492                struct smb_filename local_fname;
     1493
     1494                saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
     1495                if (!saved_dir) {
     1496                        status = map_nt_error_from_unix(errno);
     1497                        DEBUG(0,("vfs_chown_fsp: failed to get "
     1498                                "current working directory. Error was %s\n",
     1499                                strerror(errno)));
     1500                        return status;
     1501                }
     1502
     1503                if (!parent_dirname(talloc_tos(),
     1504                                fsp->fsp_name->base_name,
     1505                                &parent_dir,
     1506                                &final_component)) {
     1507                        return NT_STATUS_NO_MEMORY;
     1508                }
     1509
     1510                /* cd into the parent dir to pin it. */
     1511                ret = SMB_VFS_CHDIR(fsp->conn, parent_dir);
     1512                if (ret == -1) {
     1513                        return map_nt_error_from_unix(errno);
     1514                }
     1515
     1516                ZERO_STRUCT(local_fname);
     1517                local_fname.base_name = CONST_DISCARD(char *,final_component);
     1518
     1519                /* Must use lstat here. */
     1520                ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
     1521                if (ret == -1) {
     1522                        return map_nt_error_from_unix(errno);
     1523                }
     1524
     1525                /* Ensure it matches the fsp stat. */
     1526                if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
     1527                        return NT_STATUS_ACCESS_DENIED;
     1528                }
     1529                path = final_component;
     1530        } else {
     1531                path = fsp->fsp_name->base_name;
     1532        }
     1533
     1534        if (fsp->posix_open || as_root) {
     1535                ret = SMB_VFS_LCHOWN(fsp->conn,
     1536                        path,
     1537                        uid, gid);
     1538        } else {
     1539                ret = SMB_VFS_CHOWN(fsp->conn,
     1540                        path,
     1541                        uid, gid);
     1542        }
     1543
     1544        if (ret == 0) {
     1545                status = NT_STATUS_OK;
     1546        } else {
     1547                status = map_nt_error_from_unix(errno);
     1548        }
     1549
     1550        if (as_root) {
     1551                vfs_ChDir(fsp->conn,saved_dir);
     1552                TALLOC_FREE(saved_dir);
     1553                TALLOC_FREE(parent_dir);
     1554        }
     1555        return status;
     1556}
     1557
    14521558int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
    14531559{
     
    14771583}
    14781584
     1585int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
     1586                                struct files_struct *fsp,
     1587                                enum vfs_fallocate_mode mode,
     1588                                SMB_OFF_T offset,
     1589                                SMB_OFF_T len)
     1590{
     1591        VFS_FIND(fallocate);
     1592        return handle->fns->fallocate(handle, fsp, mode, offset, len);
     1593}
     1594
    14791595int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
    14801596                              struct files_struct *fsp, uint32 share_mode,
     
    15211637}
    15221638
    1523 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
    1524                             const char *path, char *resolved_path)
     1639char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
    15251640{
    15261641        VFS_FIND(realpath);
    1527         return handle->fns->realpath(handle, path, resolved_path);
     1642        return handle->fns->realpath(handle, path);
    15281643}
    15291644
     
    19692084
    19702085bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
    1971                              const char *path, SMB_STRUCT_STAT *sbuf)
     2086                             const struct smb_filename *fname,
     2087                             SMB_STRUCT_STAT *sbuf)
    19722088{
    19732089        VFS_FIND(is_offline);
    1974         return handle->fns->is_offline(handle, path, sbuf);
     2090        return handle->fns->is_offline(handle, fname, sbuf);
    19752091}
    19762092
    19772093int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
    1978                              const char *path)
     2094                             const struct smb_filename *fname)
    19792095{
    19802096        VFS_FIND(set_offline);
    1981         return handle->fns->set_offline(handle, path);
    1982 }
     2097        return handle->fns->set_offline(handle, fname);
     2098}
Note: See TracChangeset for help on using the changeset viewer.