Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/smbd/vfs.c

    r594 r740  
    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;
     
    870899NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
    871900{
    872 #ifdef REALPATH_TAKES_NULL
    873         bool free_resolved_name = True;
    874 #else
    875         char resolved_name_buf[PATH_MAX+1];
    876         bool free_resolved_name = False;
    877 #endif
    878901        char *resolved_name = NULL;
    879         char *p = NULL;
     902        bool allow_symlinks = true;
     903        bool allow_widelinks = false;
    880904
    881905        DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
    882906
    883 #ifdef REALPATH_TAKES_NULL
    884         resolved_name = SMB_VFS_REALPATH(conn,fname,NULL);
    885 #else
    886         resolved_name = SMB_VFS_REALPATH(conn,fname,resolved_name_buf);
    887 #endif
     907        resolved_name = SMB_VFS_REALPATH(conn,fname);
    888908
    889909        if (!resolved_name) {
     
    897917                        {
    898918                                TALLOC_CTX *ctx = talloc_tos();
    899                                 char *tmp_fname = NULL;
    900                                 char *last_component = NULL;
    901                                 /* Last component didn't exist. Remove it and try and canonicalise the directory. */
    902 
    903                                 tmp_fname = talloc_strdup(ctx, fname);
    904                                 if (!tmp_fname) {
     919                                char *dir_name = NULL;
     920                                const char *last_component = NULL;
     921                                char *new_name = NULL;
     922
     923                                /* Last component didn't exist.
     924                                   Remove it and try and canonicalise
     925                                   the directory name. */
     926                                if (!parent_dirname(ctx, fname,
     927                                                &dir_name,
     928                                                &last_component)) {
    905929                                        return NT_STATUS_NO_MEMORY;
    906930                                }
    907                                 p = strrchr_m(tmp_fname, '/');
    908                                 if (p) {
    909                                         *p++ = '\0';
    910                                         last_component = p;
    911                                 } else {
    912                                         last_component = tmp_fname;
    913                                         tmp_fname = talloc_strdup(ctx,
    914                                                         ".");
    915                                         if (!tmp_fname) {
    916                                                 return NT_STATUS_NO_MEMORY;
    917                                         }
    918                                 }
    919 
    920 #ifdef REALPATH_TAKES_NULL
    921                                 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,NULL);
    922 #else
    923                                 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,resolved_name_buf);
    924 #endif
     931
     932                                resolved_name = SMB_VFS_REALPATH(conn,dir_name);
    925933                                if (!resolved_name) {
    926934                                        NTSTATUS status = map_nt_error_from_unix(errno);
     
    930938                                        }
    931939
    932                                         DEBUG(3,("check_reduce_named: "
     940                                        DEBUG(3,("check_reduce_name: "
    933941                                                 "couldn't get realpath for "
    934942                                                 "%s (%s)\n",
     
    937945                                        return status;
    938946                                }
    939                                 tmp_fname = talloc_asprintf(ctx,
     947                                new_name = talloc_asprintf(ctx,
    940948                                                "%s/%s",
    941949                                                resolved_name,
    942950                                                last_component);
    943                                 if (!tmp_fname) {
     951                                if (!new_name) {
    944952                                        return NT_STATUS_NO_MEMORY;
    945953                                }
    946 #ifdef REALPATH_TAKES_NULL
    947954                                SAFE_FREE(resolved_name);
    948                                 resolved_name = SMB_STRDUP(tmp_fname);
     955                                resolved_name = SMB_STRDUP(new_name);
    949956                                if (!resolved_name) {
    950                                         DEBUG(0, ("check_reduced_name: malloc "
    951                                                   "fail for %s\n", tmp_fname));
    952957                                        return NT_STATUS_NO_MEMORY;
    953958                                }
    954 #else
    955                                 safe_strcpy(resolved_name_buf, tmp_fname, PATH_MAX);
    956                                 resolved_name = resolved_name_buf;
    957 #endif
    958959                                break;
    959960                        }
     
    971972                DEBUG(0,("check_reduced_name: realpath doesn't return "
    972973                         "absolute paths !\n"));
    973                 if (free_resolved_name) {
     974                SAFE_FREE(resolved_name);
     975                return NT_STATUS_OBJECT_NAME_INVALID;
     976        }
     977
     978        allow_widelinks = lp_widelinks(SNUM(conn));
     979        allow_symlinks = lp_symlinks(SNUM(conn));
     980
     981        /* Common widelinks and symlinks checks. */
     982        if (!allow_widelinks || !allow_symlinks) {
     983                const char *conn_rootdir;
     984                size_t rootdir_len;
     985
     986                conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
     987                if (conn_rootdir == NULL) {
     988                        DEBUG(2, ("check_reduced_name: Could not get "
     989                                "conn_rootdir\n"));
    974990                        SAFE_FREE(resolved_name);
    975                 }
    976                 return NT_STATUS_OBJECT_NAME_INVALID;
    977         }
    978 
    979         /* Check for widelinks allowed. */
    980         if (!lp_widelinks(SNUM(conn))) {
    981                     const char *conn_rootdir;
    982 
    983                     conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
    984                     if (conn_rootdir == NULL) {
    985                             DEBUG(2, ("check_reduced_name: Could not get "
    986                                       "conn_rootdir\n"));
    987                             if (free_resolved_name) {
    988                                     SAFE_FREE(resolved_name);
    989                             }
    990                             return NT_STATUS_ACCESS_DENIED;
    991                     }
    992 
    993                     if (strncmp(conn_rootdir, resolved_name,
    994                                 strlen(conn_rootdir)) != 0) {
    995                             DEBUG(2, ("check_reduced_name: Bad access "
    996                                       "attempt: %s is a symlink outside the "
    997                                       "share path\n", fname));
    998                             if (free_resolved_name) {
    999                                     SAFE_FREE(resolved_name);
    1000                             }
    1001                             return NT_STATUS_ACCESS_DENIED;
    1002                     }
    1003         }
    1004 
    1005         /* Check if we are allowing users to follow symlinks */
    1006         /* Patch from David Clerc <David.Clerc@cui.unige.ch>
    1007                 University of Geneva */
    1008 
    1009 #ifdef S_ISLNK
    1010         if (!lp_symlinks(SNUM(conn))) {
    1011                 struct smb_filename *smb_fname = NULL;
    1012                 NTSTATUS status;
    1013 
    1014                 status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
    1015                                                     NULL, &smb_fname);
    1016                 if (!NT_STATUS_IS_OK(status)) {
    1017                         if (free_resolved_name) {
     991                        return NT_STATUS_ACCESS_DENIED;
     992                }
     993
     994                rootdir_len = strlen(conn_rootdir);
     995                if (strncmp(conn_rootdir, resolved_name,
     996                                rootdir_len) != 0) {
     997                        DEBUG(2, ("check_reduced_name: Bad access "
     998                                "attempt: %s is a symlink outside the "
     999                                "share path\n", fname));
     1000                        DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
     1001                        DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
     1002                        SAFE_FREE(resolved_name);
     1003                        return NT_STATUS_ACCESS_DENIED;
     1004                }
     1005
     1006                /* Extra checks if all symlinks are disallowed. */
     1007                if (!allow_symlinks) {
     1008                        /* fname can't have changed in resolved_path. */
     1009                        const char *p = &resolved_name[rootdir_len];
     1010
     1011                        /* *p can be '\0' if fname was "." */
     1012                        if (*p == '\0' && ISDOT(fname)) {
     1013                                goto out;
     1014                        }
     1015
     1016                        if (*p != '/') {
     1017                                DEBUG(2, ("check_reduced_name: logic error (%c) "
     1018                                        "in resolved_name: %s\n",
     1019                                        *p,
     1020                                        fname));
    10181021                                SAFE_FREE(resolved_name);
     1022                                return NT_STATUS_ACCESS_DENIED;
    10191023                        }
    1020                         return status;
    1021                 }
    1022 
    1023                 if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) &&
    1024                                 (S_ISLNK(smb_fname->st.st_ex_mode)) ) {
    1025                         if (free_resolved_name) {
     1024
     1025                        p++;
     1026                        if (strcmp(fname, p)!=0) {
     1027                                DEBUG(2, ("check_reduced_name: Bad access "
     1028                                        "attempt: %s is a symlink\n",
     1029                                        fname));
    10261030                                SAFE_FREE(resolved_name);
     1031                                return NT_STATUS_ACCESS_DENIED;
    10271032                        }
    1028                         DEBUG(3,("check_reduced_name: denied: file path name "
    1029                                  "%s is a symlink\n",resolved_name));
    1030                         TALLOC_FREE(smb_fname);
    1031                         return NT_STATUS_ACCESS_DENIED;
    1032                 }
    1033                 TALLOC_FREE(smb_fname);
    1034         }
    1035 #endif
     1033                }
     1034        }
     1035
     1036  out:
    10361037
    10371038        DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
    10381039                 resolved_name));
    1039         if (free_resolved_name) {
    1040                 SAFE_FREE(resolved_name);
    1041         }
     1040        SAFE_FREE(resolved_name);
    10421041        return NT_STATUS_OK;
    10431042}
     
    11101109        int ret;
    11111110
    1112         if(fsp->is_directory || fsp->fh->fd == -1) {
     1111        if(fsp->fh->fd == -1) {
    11131112                if (fsp->posix_open) {
    11141113                        ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
     
    11761175int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
    11771176                                      struct files_struct *fsp,
    1178                                       SHADOW_COPY_DATA *shadow_copy_data,
     1177                                      struct shadow_copy_data *shadow_copy_data,
    11791178                                      bool labels)
    11801179{
     
    12051204}
    12061205
     1206SMB_STRUCT_DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
     1207                                        struct files_struct *fsp,
     1208                                        const char *mask,
     1209                                        uint32 attributes)
     1210{
     1211        VFS_FIND(fdopendir);
     1212        return handle->fns->fdopendir(handle, fsp, mask, attributes);
     1213}
     1214
    12071215SMB_STRUCT_DIRENT *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
    12081216                                              SMB_STRUCT_DIR *dirp,
     
    12651273                      int flags, mode_t mode)
    12661274{
    1267         VFS_FIND(open);
    1268         return handle->fns->open(handle, smb_fname, fsp, flags, mode);
     1275        VFS_FIND(open_fn);
     1276        return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
    12691277}
    12701278
     
    12801288                                  uint32_t oplock_request,
    12811289                                  uint64_t allocation_size,
     1290                                  uint32_t private_flags,
    12821291                                  struct security_descriptor *sd,
    12831292                                  struct ea_list *ea_list,
     
    12891298                handle, req, root_dir_fid, smb_fname, access_mask,
    12901299                share_access, create_disposition, create_options,
    1291                 file_attributes, oplock_request, allocation_size, sd, ea_list,
     1300                file_attributes, oplock_request, allocation_size,
     1301                private_flags, sd, ea_list,
    12921302                result, pinfo);
    12931303}
     
    14421452}
    14431453
     1454NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
     1455{
     1456        int ret;
     1457        bool as_root = false;
     1458        const char *path;
     1459        char *saved_dir = NULL;
     1460        char *parent_dir = NULL;
     1461        NTSTATUS status;
     1462
     1463        if (fsp->fh->fd != -1) {
     1464                /* Try fchown. */
     1465                ret = SMB_VFS_FCHOWN(fsp, uid, gid);
     1466                if (ret == 0) {
     1467                        return NT_STATUS_OK;
     1468                }
     1469                if (ret == -1 && errno != ENOSYS) {
     1470                        return map_nt_error_from_unix(errno);
     1471                }
     1472        }
     1473
     1474        as_root = (geteuid() == 0);
     1475
     1476        if (as_root) {
     1477                /*
     1478                 * We are being asked to chown as root. Make
     1479                 * sure we chdir() into the path to pin it,
     1480                 * and always act using lchown to ensure we
     1481                 * don't deref any symbolic links.
     1482                 */
     1483                const char *final_component = NULL;
     1484                struct smb_filename local_fname;
     1485
     1486                saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
     1487                if (!saved_dir) {
     1488                        status = map_nt_error_from_unix(errno);
     1489                        DEBUG(0,("vfs_chown_fsp: failed to get "
     1490                                "current working directory. Error was %s\n",
     1491                                strerror(errno)));
     1492                        return status;
     1493                }
     1494
     1495                if (!parent_dirname(talloc_tos(),
     1496                                fsp->fsp_name->base_name,
     1497                                &parent_dir,
     1498                                &final_component)) {
     1499                        return NT_STATUS_NO_MEMORY;
     1500                }
     1501
     1502                /* cd into the parent dir to pin it. */
     1503                ret = SMB_VFS_CHDIR(fsp->conn, parent_dir);
     1504                if (ret == -1) {
     1505                        return map_nt_error_from_unix(errno);
     1506                }
     1507
     1508                ZERO_STRUCT(local_fname);
     1509                local_fname.base_name = CONST_DISCARD(char *,final_component);
     1510
     1511                /* Must use lstat here. */
     1512                ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
     1513                if (ret == -1) {
     1514                        return map_nt_error_from_unix(errno);
     1515                }
     1516
     1517                /* Ensure it matches the fsp stat. */
     1518                if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
     1519                        return NT_STATUS_ACCESS_DENIED;
     1520                }
     1521                path = final_component;
     1522        } else {
     1523                path = fsp->fsp_name->base_name;
     1524        }
     1525
     1526        if (fsp->posix_open || as_root) {
     1527                ret = SMB_VFS_LCHOWN(fsp->conn,
     1528                        path,
     1529                        uid, gid);
     1530        } else {
     1531                ret = SMB_VFS_CHOWN(fsp->conn,
     1532                        path,
     1533                        uid, gid);
     1534        }
     1535
     1536        if (ret == 0) {
     1537                status = NT_STATUS_OK;
     1538        } else {
     1539                status = map_nt_error_from_unix(errno);
     1540        }
     1541
     1542        if (as_root) {
     1543                vfs_ChDir(fsp->conn,saved_dir);
     1544                TALLOC_FREE(saved_dir);
     1545                TALLOC_FREE(parent_dir);
     1546        }
     1547        return status;
     1548}
     1549
    14441550int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
    14451551{
     
    14691575}
    14701576
     1577int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
     1578                                struct files_struct *fsp,
     1579                                enum vfs_fallocate_mode mode,
     1580                                SMB_OFF_T offset,
     1581                                SMB_OFF_T len)
     1582{
     1583        VFS_FIND(fallocate);
     1584        return handle->fns->fallocate(handle, fsp, mode, offset, len);
     1585}
     1586
    14711587int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
    14721588                              struct files_struct *fsp, uint32 share_mode,
     
    15131629}
    15141630
    1515 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
    1516                             const char *path, char *resolved_path)
     1631char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
    15171632{
    15181633        VFS_FIND(realpath);
    1519         return handle->fns->realpath(handle, path, resolved_path);
     1634        return handle->fns->realpath(handle, path);
    15201635}
    15211636
     
    19612076
    19622077bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
    1963                              const char *path, SMB_STRUCT_STAT *sbuf)
     2078                             const struct smb_filename *fname,
     2079                             SMB_STRUCT_STAT *sbuf)
    19642080{
    19652081        VFS_FIND(is_offline);
    1966         return handle->fns->is_offline(handle, path, sbuf);
     2082        return handle->fns->is_offline(handle, fname, sbuf);
    19672083}
    19682084
    19692085int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
    1970                              const char *path)
     2086                             const struct smb_filename *fname)
    19712087{
    19722088        VFS_FIND(set_offline);
    1973         return handle->fns->set_offline(handle, path);
    1974 }
     2089        return handle->fns->set_offline(handle, fname);
     2090}
Note: See TracChangeset for help on using the changeset viewer.