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/dosmode.c

    r597 r740  
    2020
    2121#include "includes.h"
     22#include "system/filesys.h"
    2223#include "librpc/gen_ndr/ndr_xattr.h"
     24#include "../libcli/security/security.h"
     25#include "smbd/smbd.h"
    2326
    2427static uint32_t filter_mode_by_protocol(uint32_t mode)
     
    3437}
    3538
    36 static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf)
    37 {
    38 #if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
    39         if (sbuf->st_ex_size > sbuf->st_ex_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) {
    40                 return FILE_ATTRIBUTE_SPARSE;
    41         }
    42 #endif
    43         return 0;
    44 }
    45 
    4639static int set_link_read_only_flag(const SMB_STRUCT_STAT *const sbuf)
    4740{
     
    4942#if LINKS_READ_ONLY
    5043        if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
    51                 return aRONLY;
     44                return FILE_ATTRIBUTE_READONLY;
    5245#endif
    5346#endif
     
    181174                /* Original Samba method - map inverse of user "w" bit. */
    182175                if ((smb_fname->st.st_ex_mode & S_IWUSR) == 0) {
    183                         result |= aRONLY;
     176                        result |= FILE_ATTRIBUTE_READONLY;
    184177                }
    185178        } else if (ro_opts == MAP_READONLY_PERMISSIONS) {
    186179                /* Check actual permissions for read-only. */
    187180                if (!can_write_to_file(conn, smb_fname)) {
    188                         result |= aRONLY;
     181                        result |= FILE_ATTRIBUTE_READONLY;
    189182                }
    190183        } /* Else never set the readonly bit. */
    191184
    192185        if (MAP_ARCHIVE(conn) && ((smb_fname->st.st_ex_mode & S_IXUSR) != 0))
    193                 result |= aARCH;
     186                result |= FILE_ATTRIBUTE_ARCHIVE;
    194187
    195188        if (MAP_SYSTEM(conn) && ((smb_fname->st.st_ex_mode & S_IXGRP) != 0))
    196                 result |= aSYSTEM;
     189                result |= FILE_ATTRIBUTE_SYSTEM;
    197190
    198191        if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0))
    199                 result |= aHIDDEN;   
     192                result |= FILE_ATTRIBUTE_HIDDEN;
    200193
    201194        if (S_ISDIR(smb_fname->st.st_ex_mode))
    202                 result = aDIR | (result & aRONLY);
    203 
    204         result |= set_sparse_flag(&smb_fname->st);
     195                result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY);
     196
    205197        result |= set_link_read_only_flag(&smb_fname->st);
    206198
    207199        DEBUG(8,("dos_mode_from_sbuf returning "));
    208200
    209         if (result & aHIDDEN) DEBUG(8, ("h"));
    210         if (result & aRONLY ) DEBUG(8, ("r"));
    211         if (result & aSYSTEM) DEBUG(8, ("s"));
    212         if (result & aDIR   ) DEBUG(8, ("d"));
    213         if (result & aARCH  ) DEBUG(8, ("a"));
     201        if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     202        if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     203        if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     204        if (result & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     205        if (result & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    214206
    215207        DEBUG(8,("\n"));
     
    250242                                ) {
    251243#endif
    252                         DEBUG(1,("get_ea_dos_attributes: Cannot get attribute "
     244                        DEBUG(1,("get_ea_dos_attribute: Cannot get attribute "
    253245                                 "from EA on file %s: Error = %s\n",
    254246                                 smb_fname_str_dbg(smb_fname),
     
    262254        blob.length = sizeret;
    263255
    264         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &dosattrib,
     256        ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib,
    265257                        (ndr_pull_flags_fn_t)ndr_pull_xattr_DOSATTRIB);
     258
     259        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     260                DEBUG(1,("get_ea_dos_attribute: bad ndr decode "
     261                         "from EA on file %s: Error = %s\n",
     262                         smb_fname_str_dbg(smb_fname),
     263                         ndr_errstr(ndr_err)));
     264                return false;
     265        }
    266266
    267267        DEBUG(10,("get_ea_dos_attribute: %s attr = %s\n",
     
    282282                                                        create_time);
    283283
    284                                 DEBUG(10,("get_ea_dos_attributes: file %s case 1 "
     284                                DEBUG(10,("get_ea_dos_attribute: file %s case 1 "
    285285                                        "set btime %s\n",
    286286                                        smb_fname_str_dbg(smb_fname),
     
    304304                                                        create_time);
    305305
    306                                 DEBUG(10,("get_ea_dos_attributes: file %s case 3 "
     306                                DEBUG(10,("get_ea_dos_attribute: file %s case 3 "
    307307                                        "set btime %s\n",
    308308                                        smb_fname_str_dbg(smb_fname),
     
    311311                        }
    312312                        break;
    313                         default:
    314                                 DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on "
    315                                         "file %s - %s\n", smb_fname_str_dbg(smb_fname),
    316                                         attrstr));
     313                default:
     314                        DEBUG(1,("get_ea_dos_attribute: Badly formed DOSATTRIB on "
     315                                "file %s - %s\n", smb_fname_str_dbg(smb_fname),
     316                                attrstr));
    317317                        return false;
    318318        }
    319319
    320320        if (S_ISDIR(smb_fname->st.st_ex_mode)) {
    321                 dosattr |= aDIR;
    322         }
    323         *pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
     321                dosattr |= FILE_ATTRIBUTE_DIRECTORY;
     322        }
     323        /* FILE_ATTRIBUTE_SPARSE is valid on get but not on set. */
     324        *pattr = (uint32)(dosattr & (SAMBA_ATTRIBUTES_MASK|FILE_ATTRIBUTE_SPARSE));
    324325
    325326        DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr));
    326327
    327         if (dosattr & aHIDDEN) DEBUG(8, ("h"));
    328         if (dosattr & aRONLY ) DEBUG(8, ("r"));
    329         if (dosattr & aSYSTEM) DEBUG(8, ("s"));
    330         if (dosattr & aDIR   ) DEBUG(8, ("d"));
    331         if (dosattr & aARCH  ) DEBUG(8, ("a"));
     328        if (dosattr & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     329        if (dosattr & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     330        if (dosattr & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     331        if (dosattr & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     332        if (dosattr & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    332333
    333334        DEBUG(8,("\n"));
     
    348349        enum ndr_err_code ndr_err;
    349350        DATA_BLOB blob;
    350         files_struct *fsp = NULL;
    351         bool ret = false;
    352351
    353352        if (!lp_store_dos_attributes(SNUM(conn))) {
     
    365364                                smb_fname->st.st_ex_btime);
    366365
     366        DEBUG(10,("set_ea_dos_attributes: set attribute 0x%x, btime = %s on file %s\n",
     367                (unsigned int)dosmode,
     368                time_to_asc(convert_timespec_to_time_t(smb_fname->st.st_ex_btime)),
     369                smb_fname_str_dbg(smb_fname) ));
     370
    367371        ndr_err = ndr_push_struct_blob(
    368                         &blob, talloc_tos(), NULL, &dosattrib,
     372                        &blob, talloc_tos(), &dosattrib,
    369373                        (ndr_push_flags_fn_t)ndr_push_xattr_DOSATTRIB);
    370374
     
    382386                             SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length,
    383387                             0) == -1) {
     388                bool ret = false;
     389                files_struct *fsp = NULL;
     390
    384391                if((errno != EPERM) && (errno != EACCES)) {
    385392                        if (errno == ENOSYS
     
    414421                if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname,
    415422                                                      &fsp)))
    416                         return ret;
     423                        return false;
    417424                become_root();
    418                 if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
     425                if (SMB_VFS_FSETXATTR(fsp,
    419426                                     SAMBA_XATTR_DOS_ATTRIB, blob.data,
    420427                                     blob.length, 0) == 0) {
     
    459466                if (p[0] == '.' && !((p[1] == '\0') ||
    460467                                (p[1] == '.' && p[2] == '\0'))) {
    461                         result |= aHIDDEN;
     468                        result |= FILE_ATTRIBUTE_HIDDEN;
    462469                }
    463470        }
     
    467474        /* Optimization : Only call is_hidden_path if it's not already
    468475           hidden. */
    469         if (!(result & aHIDDEN) &&
     476        if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
    470477            IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
    471                 result |= aHIDDEN;
     478                result |= FILE_ATTRIBUTE_HIDDEN;
    472479        }
    473480
     
    480487        DEBUG(8,("dos_mode_msdfs returning "));
    481488
    482         if (result & aHIDDEN) DEBUG(8, ("h"));
    483         if (result & aRONLY ) DEBUG(8, ("r"));
    484         if (result & aSYSTEM) DEBUG(8, ("s"));
    485         if (result & aDIR   ) DEBUG(8, ("d"));
    486         if (result & aARCH  ) DEBUG(8, ("a"));
     489        if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     490        if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     491        if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     492        if (result & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     493        if (result & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    487494        if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
    488495
     
    501508        uint32_t dos_stat_flags = 0;
    502509
    503         if (dosmode & aARCH)
     510        if (dosmode & FILE_ATTRIBUTE_ARCHIVE)
    504511                dos_stat_flags |= UF_DOS_ARCHIVE;
    505         if (dosmode & aHIDDEN)
     512        if (dosmode & FILE_ATTRIBUTE_HIDDEN)
    506513                dos_stat_flags |= UF_DOS_HIDDEN;
    507         if (dosmode & aRONLY)
     514        if (dosmode & FILE_ATTRIBUTE_READONLY)
    508515                dos_stat_flags |= UF_DOS_RO;
    509         if (dosmode & aSYSTEM)
     516        if (dosmode & FILE_ATTRIBUTE_SYSTEM)
    510517                dos_stat_flags |= UF_DOS_SYSTEM;
    511518        if (dosmode & FILE_ATTRIBUTE_NONINDEXED)
     
    534541
    535542        if (smb_fname->st.st_ex_flags & UF_DOS_ARCHIVE)
    536                 *dosmode |= aARCH;
     543                *dosmode |= FILE_ATTRIBUTE_ARCHIVE;
    537544        if (smb_fname->st.st_ex_flags & UF_DOS_HIDDEN)
    538                 *dosmode |= aHIDDEN;
     545                *dosmode |= FILE_ATTRIBUTE_HIDDEN;
    539546        if (smb_fname->st.st_ex_flags & UF_DOS_RO)
    540                 *dosmode |= aRONLY;
     547                *dosmode |= FILE_ATTRIBUTE_READONLY;
    541548        if (smb_fname->st.st_ex_flags & UF_DOS_SYSTEM)
    542                 *dosmode |= aSYSTEM;
     549                *dosmode |= FILE_ATTRIBUTE_SYSTEM;
    543550        if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX)
    544551                *dosmode |= FILE_ATTRIBUTE_NONINDEXED;
     552        if (smb_fname->st.st_ex_flags & FILE_ATTRIBUTE_SPARSE)
     553                *dosmode |= FILE_ATTRIBUTE_SPARSE;
    545554        if (S_ISDIR(smb_fname->st.st_ex_mode))
    546                 *dosmode |= aDIR;
    547 
    548         *dosmode |= set_sparse_flag(&smb_fname->st);
     555                *dosmode |= FILE_ATTRIBUTE_DIRECTORY;
     556
    549557        *dosmode |= set_link_read_only_flag(&smb_fname->st);
    550558
     
    630638                if (p[0] == '.' && !((p[1] == '\0') ||
    631639                                (p[1] == '.' && p[2] == '\0'))) {
    632                         result |= aHIDDEN;
     640                        result |= FILE_ATTRIBUTE_HIDDEN;
    633641                }
    634642        }
     
    639647        if (!used_stat_dos_flags) {
    640648                /* Get the DOS attributes from an EA by preference. */
    641                 if (get_ea_dos_attribute(conn, smb_fname, &result)) {
    642                         result |= set_sparse_flag(&smb_fname->st);
    643                 } else {
     649                if (!get_ea_dos_attribute(conn, smb_fname, &result)) {
    644650                        result |= dos_mode_from_sbuf(conn, smb_fname);
    645651                }
    646652        }
    647653
    648         offline = SMB_VFS_IS_OFFLINE(conn, smb_fname->base_name, &smb_fname->st);
     654        offline = SMB_VFS_IS_OFFLINE(conn, smb_fname, &smb_fname->st);
    649655        if (S_ISREG(smb_fname->st.st_ex_mode) && offline) {
    650656                result |= FILE_ATTRIBUTE_OFFLINE;
     
    653659        /* Optimization : Only call is_hidden_path if it's not already
    654660           hidden. */
    655         if (!(result & aHIDDEN) &&
     661        if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
    656662            IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
    657                 result |= aHIDDEN;
     663                result |= FILE_ATTRIBUTE_HIDDEN;
    658664        }
    659665
     
    666672        DEBUG(8,("dos_mode returning "));
    667673
    668         if (result & aHIDDEN) DEBUG(8, ("h"));
    669         if (result & aRONLY ) DEBUG(8, ("r"));
    670         if (result & aSYSTEM) DEBUG(8, ("s"));
    671         if (result & aDIR   ) DEBUG(8, ("d"));
    672         if (result & aARCH  ) DEBUG(8, ("a"));
     674        if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     675        if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     676        if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     677        if (result & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     678        if (result & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    673679        if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
    674680
     
    707713
    708714        if (S_ISDIR(smb_fname->st.st_ex_mode))
    709                 dosmode |= aDIR;
     715                dosmode |= FILE_ATTRIBUTE_DIRECTORY;
    710716        else
    711                 dosmode &= ~aDIR;
     717                dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
    712718
    713719        new_create_timespec = smb_fname->st.st_ex_btime;
     
    717723        if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
    718724                if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
    719                         lret = SMB_VFS_SET_OFFLINE(conn, smb_fname->base_name);
     725                        lret = SMB_VFS_SET_OFFLINE(conn, smb_fname);
    720726                        if (lret == -1) {
    721727                                DEBUG(0, ("set_dos_mode: client has asked to "
     
    807813        if (S_ISDIR(smb_fname->st.st_ex_mode) && (unixmode & S_ISGID) &&
    808814                        geteuid() != sec_initial_uid() &&
    809                         !current_user_in_group(smb_fname->st.st_ex_gid)) {
     815                        !current_user_in_group(conn, smb_fname->st.st_ex_gid)) {
    810816                DEBUG(3,("file_set_dosmode: setgid bit cannot be "
    811817                        "set for directory %s\n",
     
    814820                return -1;
    815821        }
    816 
    817822
    818823        ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
     
    865870}
    866871
     872
     873NTSTATUS file_set_sparse(connection_struct *conn,
     874                         files_struct *fsp,
     875                         bool sparse)
     876{
     877        uint32_t old_dosmode;
     878        uint32_t new_dosmode;
     879        NTSTATUS status;
     880
     881        if (!CAN_WRITE(conn)) {
     882                DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
     883                        "on readonly share[%s]\n",
     884                        smb_fname_str_dbg(fsp->fsp_name),
     885                        sparse,
     886                        lp_servicename(SNUM(conn))));
     887                return NT_STATUS_MEDIA_WRITE_PROTECTED;
     888        }
     889
     890        if (!(fsp->access_mask & FILE_WRITE_DATA) &&
     891                        !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
     892                DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
     893                        "access_mask[0x%08X] - access denied\n",
     894                        smb_fname_str_dbg(fsp->fsp_name),
     895                        sparse,
     896                        fsp->access_mask));
     897                return NT_STATUS_ACCESS_DENIED;
     898        }
     899
     900        DEBUG(10,("file_set_sparse: setting sparse bit %u on file %s\n",
     901                  sparse, smb_fname_str_dbg(fsp->fsp_name)));
     902
     903        if (!lp_store_dos_attributes(SNUM(conn))) {
     904                return NT_STATUS_INVALID_DEVICE_REQUEST;
     905        }
     906
     907        status = vfs_stat_fsp(fsp);
     908        if (!NT_STATUS_IS_OK(status)) {
     909                return status;
     910        }
     911
     912        old_dosmode = dos_mode(conn, fsp->fsp_name);
     913
     914        if (sparse && !(old_dosmode & FILE_ATTRIBUTE_SPARSE)) {
     915                new_dosmode = old_dosmode | FILE_ATTRIBUTE_SPARSE;
     916        } else if (!sparse && (old_dosmode & FILE_ATTRIBUTE_SPARSE)) {
     917                new_dosmode = old_dosmode & ~FILE_ATTRIBUTE_SPARSE;
     918        } else {
     919                return NT_STATUS_OK;
     920        }
     921
     922        /* Store the DOS attributes in an EA. */
     923        if (!set_ea_dos_attribute(conn, fsp->fsp_name,
     924                                  new_dosmode)) {
     925                if (errno == 0) {
     926                        errno = EIO;
     927                }
     928                return map_nt_error_from_unix(errno);
     929        }
     930
     931        notify_fname(conn, NOTIFY_ACTION_MODIFIED,
     932                     FILE_NOTIFY_CHANGE_ATTRIBUTES,
     933                     fsp->fsp_name->base_name);
     934
     935        fsp->is_sparse = sparse;
     936
     937        return NT_STATUS_OK;
     938}
     939
    867940/*******************************************************************
    868941 Wrapper around the VFS ntimes that possibly allows DOS semantics rather
Note: See TracChangeset for help on using the changeset viewer.