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

    r599 r745  
    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
     
    183176                if ((smb_fname->st.st_ex_mode & S_IWUSR) == 0) {
    184177#else
    185                 if (os2_isattribute(smb_fname->base_name, aRONLY) == 0) {
     178                if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_READONLY) == 0) {
    186179#endif
    187                         result |= aRONLY;
     180                        result |= FILE_ATTRIBUTE_READONLY;
    188181                }
    189182        } else if (ro_opts == MAP_READONLY_PERMISSIONS) {
    190183                /* Check actual permissions for read-only. */
    191184                if (!can_write_to_file(conn, smb_fname)) {
    192                         result |= aRONLY;
     185                        result |= FILE_ATTRIBUTE_READONLY;
    193186                }
    194187        } /* Else never set the readonly bit. */
     
    197190        if (MAP_ARCHIVE(conn) && ((smb_fname->st.st_ex_mode & S_IXUSR) != 0))
    198191#else
    199         if (os2_isattribute(smb_fname->base_name, aARCH) == 0)
     192        if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_ARCHIVE) == 0)
    200193#endif
    201                 result |= aARCH;
     194                result |= FILE_ATTRIBUTE_ARCHIVE;
    202195
    203196#ifndef __OS2__
    204197        if (MAP_SYSTEM(conn) && ((smb_fname->st.st_ex_mode & S_IXGRP) != 0))
    205198#else
    206         if (os2_isattribute(smb_fname->base_name, aSYSTEM) == 0)
     199        if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_SYSTEM) == 0)
    207200#endif
    208                 result |= aSYSTEM;
     201                result |= FILE_ATTRIBUTE_SYSTEM;
    209202
    210203#ifndef __OS2__
    211204        if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0))
    212205#else
    213         if (os2_isattribute(smb_fname->base_name, aHIDDEN) == 0)
     206        if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_HIDDEN) == 0)
    214207#endif
    215                 result |= aHIDDEN;   
     208                result |= FILE_ATTRIBUTE_HIDDEN;
    216209
    217210        if (S_ISDIR(smb_fname->st.st_ex_mode))
    218                 result = aDIR | (result & aRONLY);
    219 
    220         result |= set_sparse_flag(&smb_fname->st);
     211                result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY);
     212
    221213        result |= set_link_read_only_flag(&smb_fname->st);
    222214
    223215        DEBUG(8,("dos_mode_from_sbuf returning "));
    224216
    225         if (result & aHIDDEN) DEBUG(8, ("h"));
    226         if (result & aRONLY ) DEBUG(8, ("r"));
    227         if (result & aSYSTEM) DEBUG(8, ("s"));
    228         if (result & aDIR   ) DEBUG(8, ("d"));
    229         if (result & aARCH  ) DEBUG(8, ("a"));
     217        if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     218        if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     219        if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     220        if (result & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     221        if (result & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    230222
    231223        DEBUG(8,("\n"));
     
    266258                                ) {
    267259#endif
    268 
    269260#ifdef __OS2__ //on os2 no error in case of ./.. and errno 2
    270261        if ((strncmp(smb_fname->base_name, "./..", 4) !=0) || (errno !=2))
    271262#endif
    272                         DEBUG(1,("get_ea_dos_attributes: Cannot get attribute "
     263                        DEBUG(1,("get_ea_dos_attribute: Cannot get attribute "
    273264                                 "from EA on file %s: Error = %s\n",
    274265                                 smb_fname_str_dbg(smb_fname),
     
    282273        blob.length = sizeret;
    283274
    284         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &dosattrib,
     275        ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib,
    285276                        (ndr_pull_flags_fn_t)ndr_pull_xattr_DOSATTRIB);
     277
     278        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     279                DEBUG(1,("get_ea_dos_attribute: bad ndr decode "
     280                         "from EA on file %s: Error = %s\n",
     281                         smb_fname_str_dbg(smb_fname),
     282                         ndr_errstr(ndr_err)));
     283                return false;
     284        }
    286285
    287286        DEBUG(10,("get_ea_dos_attribute: %s attr = %s\n",
     
    302301                                                        create_time);
    303302
    304                                 DEBUG(10,("get_ea_dos_attributes: file %s case 1 "
     303                                DEBUG(10,("get_ea_dos_attribute: file %s case 1 "
    305304                                        "set btime %s\n",
    306305                                        smb_fname_str_dbg(smb_fname),
     
    324323                                                        create_time);
    325324
    326                                 DEBUG(10,("get_ea_dos_attributes: file %s case 3 "
     325                                DEBUG(10,("get_ea_dos_attribute: file %s case 3 "
    327326                                        "set btime %s\n",
    328327                                        smb_fname_str_dbg(smb_fname),
     
    331330                        }
    332331                        break;
    333                         default:
    334                                 DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on "
    335                                         "file %s - %s\n", smb_fname_str_dbg(smb_fname),
    336                                         attrstr));
     332                default:
     333                        DEBUG(1,("get_ea_dos_attribute: Badly formed DOSATTRIB on "
     334                                "file %s - %s\n", smb_fname_str_dbg(smb_fname),
     335                                attrstr));
    337336                        return false;
    338337        }
    339338
    340339        if (S_ISDIR(smb_fname->st.st_ex_mode)) {
    341                 dosattr |= aDIR;
    342         }
    343         *pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
     340                dosattr |= FILE_ATTRIBUTE_DIRECTORY;
     341        }
     342        /* FILE_ATTRIBUTE_SPARSE is valid on get but not on set. */
     343        *pattr = (uint32)(dosattr & (SAMBA_ATTRIBUTES_MASK|FILE_ATTRIBUTE_SPARSE));
    344344
    345345        DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr));
    346346
    347         if (dosattr & aHIDDEN) DEBUG(8, ("h"));
    348         if (dosattr & aRONLY ) DEBUG(8, ("r"));
    349         if (dosattr & aSYSTEM) DEBUG(8, ("s"));
    350         if (dosattr & aDIR   ) DEBUG(8, ("d"));
    351         if (dosattr & aARCH  ) DEBUG(8, ("a"));
     347        if (dosattr & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     348        if (dosattr & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     349        if (dosattr & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     350        if (dosattr & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     351        if (dosattr & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    352352
    353353        DEBUG(8,("\n"));
     
    368368        enum ndr_err_code ndr_err;
    369369        DATA_BLOB blob;
    370         files_struct *fsp = NULL;
    371         bool ret = false;
    372370
    373371        if (!lp_store_dos_attributes(SNUM(conn))) {
     
    385383                                smb_fname->st.st_ex_btime);
    386384
     385        DEBUG(10,("set_ea_dos_attributes: set attribute 0x%x, btime = %s on file %s\n",
     386                (unsigned int)dosmode,
     387                time_to_asc(convert_timespec_to_time_t(smb_fname->st.st_ex_btime)),
     388                smb_fname_str_dbg(smb_fname) ));
     389
    387390        ndr_err = ndr_push_struct_blob(
    388                         &blob, talloc_tos(), NULL, &dosattrib,
     391                        &blob, talloc_tos(), &dosattrib,
    389392                        (ndr_push_flags_fn_t)ndr_push_xattr_DOSATTRIB);
    390393
     
    402405                             SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length,
    403406                             0) == -1) {
     407                bool ret = false;
     408                files_struct *fsp = NULL;
     409
    404410                if((errno != EPERM) && (errno != EACCES)) {
    405411                        if (errno == ENOSYS
     
    434440                if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname,
    435441                                                      &fsp)))
    436                         return ret;
     442                        return false;
    437443                become_root();
    438                 if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
     444                if (SMB_VFS_FSETXATTR(fsp,
    439445                                     SAMBA_XATTR_DOS_ATTRIB, blob.data,
    440446                                     blob.length, 0) == 0) {
     
    479485                if (p[0] == '.' && !((p[1] == '\0') ||
    480486                                (p[1] == '.' && p[2] == '\0'))) {
    481                         result |= aHIDDEN;
     487                        result |= FILE_ATTRIBUTE_HIDDEN;
    482488                }
    483489        }
     
    487493        /* Optimization : Only call is_hidden_path if it's not already
    488494           hidden. */
    489         if (!(result & aHIDDEN) &&
     495        if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
    490496            IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
    491                 result |= aHIDDEN;
     497                result |= FILE_ATTRIBUTE_HIDDEN;
    492498        }
    493499
     
    500506        DEBUG(8,("dos_mode_msdfs returning "));
    501507
    502         if (result & aHIDDEN) DEBUG(8, ("h"));
    503         if (result & aRONLY ) DEBUG(8, ("r"));
    504         if (result & aSYSTEM) DEBUG(8, ("s"));
    505         if (result & aDIR   ) DEBUG(8, ("d"));
    506         if (result & aARCH  ) DEBUG(8, ("a"));
     508        if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     509        if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     510        if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     511        if (result & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     512        if (result & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    507513        if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
    508514
     
    521527        uint32_t dos_stat_flags = 0;
    522528
    523         if (dosmode & aARCH)
     529        if (dosmode & FILE_ATTRIBUTE_ARCHIVE)
    524530                dos_stat_flags |= UF_DOS_ARCHIVE;
    525         if (dosmode & aHIDDEN)
     531        if (dosmode & FILE_ATTRIBUTE_HIDDEN)
    526532                dos_stat_flags |= UF_DOS_HIDDEN;
    527         if (dosmode & aRONLY)
     533        if (dosmode & FILE_ATTRIBUTE_READONLY)
    528534                dos_stat_flags |= UF_DOS_RO;
    529         if (dosmode & aSYSTEM)
     535        if (dosmode & FILE_ATTRIBUTE_SYSTEM)
    530536                dos_stat_flags |= UF_DOS_SYSTEM;
    531537        if (dosmode & FILE_ATTRIBUTE_NONINDEXED)
     
    554560
    555561        if (smb_fname->st.st_ex_flags & UF_DOS_ARCHIVE)
    556                 *dosmode |= aARCH;
     562                *dosmode |= FILE_ATTRIBUTE_ARCHIVE;
    557563        if (smb_fname->st.st_ex_flags & UF_DOS_HIDDEN)
    558                 *dosmode |= aHIDDEN;
     564                *dosmode |= FILE_ATTRIBUTE_HIDDEN;
    559565        if (smb_fname->st.st_ex_flags & UF_DOS_RO)
    560                 *dosmode |= aRONLY;
     566                *dosmode |= FILE_ATTRIBUTE_READONLY;
    561567        if (smb_fname->st.st_ex_flags & UF_DOS_SYSTEM)
    562                 *dosmode |= aSYSTEM;
     568                *dosmode |= FILE_ATTRIBUTE_SYSTEM;
    563569        if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX)
    564570                *dosmode |= FILE_ATTRIBUTE_NONINDEXED;
     571        if (smb_fname->st.st_ex_flags & FILE_ATTRIBUTE_SPARSE)
     572                *dosmode |= FILE_ATTRIBUTE_SPARSE;
    565573        if (S_ISDIR(smb_fname->st.st_ex_mode))
    566                 *dosmode |= aDIR;
    567 
    568         *dosmode |= set_sparse_flag(&smb_fname->st);
     574                *dosmode |= FILE_ATTRIBUTE_DIRECTORY;
     575
    569576        *dosmode |= set_link_read_only_flag(&smb_fname->st);
    570577
     
    650657                if (p[0] == '.' && !((p[1] == '\0') ||
    651658                                (p[1] == '.' && p[2] == '\0'))) {
    652                         result |= aHIDDEN;
     659                        result |= FILE_ATTRIBUTE_HIDDEN;
    653660                }
    654661        }
     
    659666        if (!used_stat_dos_flags) {
    660667                /* Get the DOS attributes from an EA by preference. */
    661                 if (get_ea_dos_attribute(conn, smb_fname, &result)) {
    662                         result |= set_sparse_flag(&smb_fname->st);
    663                 } else {
     668                if (!get_ea_dos_attribute(conn, smb_fname, &result)) {
    664669                        result |= dos_mode_from_sbuf(conn, smb_fname);
    665670                }
    666671        }
    667672
    668         offline = SMB_VFS_IS_OFFLINE(conn, smb_fname->base_name, &smb_fname->st);
     673        offline = SMB_VFS_IS_OFFLINE(conn, smb_fname, &smb_fname->st);
    669674        if (S_ISREG(smb_fname->st.st_ex_mode) && offline) {
    670675                result |= FILE_ATTRIBUTE_OFFLINE;
     
    673678        /* Optimization : Only call is_hidden_path if it's not already
    674679           hidden. */
    675         if (!(result & aHIDDEN) &&
     680        if (!(result & FILE_ATTRIBUTE_HIDDEN) &&
    676681            IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
    677                 result |= aHIDDEN;
     682                result |= FILE_ATTRIBUTE_HIDDEN;
    678683        }
    679684
     
    686691        DEBUG(8,("dos_mode returning "));
    687692
    688         if (result & aHIDDEN) DEBUG(8, ("h"));
    689         if (result & aRONLY ) DEBUG(8, ("r"));
    690         if (result & aSYSTEM) DEBUG(8, ("s"));
    691         if (result & aDIR   ) DEBUG(8, ("d"));
    692         if (result & aARCH  ) DEBUG(8, ("a"));
     693        if (result & FILE_ATTRIBUTE_HIDDEN) DEBUG(8, ("h"));
     694        if (result & FILE_ATTRIBUTE_READONLY ) DEBUG(8, ("r"));
     695        if (result & FILE_ATTRIBUTE_SYSTEM) DEBUG(8, ("s"));
     696        if (result & FILE_ATTRIBUTE_DIRECTORY   ) DEBUG(8, ("d"));
     697        if (result & FILE_ATTRIBUTE_ARCHIVE  ) DEBUG(8, ("a"));
    693698        if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
    694699
     
    727732
    728733        if (S_ISDIR(smb_fname->st.st_ex_mode))
    729                 dosmode |= aDIR;
     734                dosmode |= FILE_ATTRIBUTE_DIRECTORY;
    730735        else
    731                 dosmode &= ~aDIR;
     736                dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
    732737
    733738        new_create_timespec = smb_fname->st.st_ex_btime;
     
    737742        if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
    738743                if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
    739                         lret = SMB_VFS_SET_OFFLINE(conn, smb_fname->base_name);
     744                        lret = SMB_VFS_SET_OFFLINE(conn, smb_fname);
    740745                        if (lret == -1) {
    741746                                DEBUG(0, ("set_dos_mode: client has asked to "
     
    827832        if (S_ISDIR(smb_fname->st.st_ex_mode) && (unixmode & S_ISGID) &&
    828833                        geteuid() != sec_initial_uid() &&
    829                         !current_user_in_group(smb_fname->st.st_ex_gid)) {
     834                        !current_user_in_group(conn, smb_fname->st.st_ex_gid)) {
    830835                DEBUG(3,("file_set_dosmode: setgid bit cannot be "
    831836                        "set for directory %s\n",
     
    834839                return -1;
    835840        }
    836 
    837841
    838842        ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
     
    885889}
    886890
     891
     892NTSTATUS file_set_sparse(connection_struct *conn,
     893                         files_struct *fsp,
     894                         bool sparse)
     895{
     896        uint32_t old_dosmode;
     897        uint32_t new_dosmode;
     898        NTSTATUS status;
     899
     900        if (!CAN_WRITE(conn)) {
     901                DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
     902                        "on readonly share[%s]\n",
     903                        smb_fname_str_dbg(fsp->fsp_name),
     904                        sparse,
     905                        lp_servicename(SNUM(conn))));
     906                return NT_STATUS_MEDIA_WRITE_PROTECTED;
     907        }
     908
     909        if (!(fsp->access_mask & FILE_WRITE_DATA) &&
     910                        !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
     911                DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
     912                        "access_mask[0x%08X] - access denied\n",
     913                        smb_fname_str_dbg(fsp->fsp_name),
     914                        sparse,
     915                        fsp->access_mask));
     916                return NT_STATUS_ACCESS_DENIED;
     917        }
     918
     919        DEBUG(10,("file_set_sparse: setting sparse bit %u on file %s\n",
     920                  sparse, smb_fname_str_dbg(fsp->fsp_name)));
     921
     922        if (!lp_store_dos_attributes(SNUM(conn))) {
     923                return NT_STATUS_INVALID_DEVICE_REQUEST;
     924        }
     925
     926        status = vfs_stat_fsp(fsp);
     927        if (!NT_STATUS_IS_OK(status)) {
     928                return status;
     929        }
     930
     931        old_dosmode = dos_mode(conn, fsp->fsp_name);
     932
     933        if (sparse && !(old_dosmode & FILE_ATTRIBUTE_SPARSE)) {
     934                new_dosmode = old_dosmode | FILE_ATTRIBUTE_SPARSE;
     935        } else if (!sparse && (old_dosmode & FILE_ATTRIBUTE_SPARSE)) {
     936                new_dosmode = old_dosmode & ~FILE_ATTRIBUTE_SPARSE;
     937        } else {
     938                return NT_STATUS_OK;
     939        }
     940
     941        /* Store the DOS attributes in an EA. */
     942        if (!set_ea_dos_attribute(conn, fsp->fsp_name,
     943                                  new_dosmode)) {
     944                if (errno == 0) {
     945                        errno = EIO;
     946                }
     947                return map_nt_error_from_unix(errno);
     948        }
     949
     950        notify_fname(conn, NOTIFY_ACTION_MODIFIED,
     951                     FILE_NOTIFY_CHANGE_ATTRIBUTES,
     952                     fsp->fsp_name->base_name);
     953
     954        fsp->is_sparse = sparse;
     955
     956        return NT_STATUS_OK;
     957}
     958
    887959/*******************************************************************
    888960 Wrapper around the VFS ntimes that possibly allows DOS semantics rather
Note: See TracChangeset for help on using the changeset viewer.