Changeset 745 for trunk/server/source3/smbd/dosmode.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/smbd/dosmode.c
r599 r745 20 20 21 21 #include "includes.h" 22 #include "system/filesys.h" 22 23 #include "librpc/gen_ndr/ndr_xattr.h" 24 #include "../libcli/security/security.h" 25 #include "smbd/smbd.h" 23 26 24 27 static uint32_t filter_mode_by_protocol(uint32_t mode) … … 34 37 } 35 38 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 #endif43 return 0;44 }45 46 39 static int set_link_read_only_flag(const SMB_STRUCT_STAT *const sbuf) 47 40 { … … 49 42 #if LINKS_READ_ONLY 50 43 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode)) 51 return aRONLY;44 return FILE_ATTRIBUTE_READONLY; 52 45 #endif 53 46 #endif … … 183 176 if ((smb_fname->st.st_ex_mode & S_IWUSR) == 0) { 184 177 #else 185 if (os2_isattribute(smb_fname->base_name, aRONLY) == 0) {178 if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_READONLY) == 0) { 186 179 #endif 187 result |= aRONLY;180 result |= FILE_ATTRIBUTE_READONLY; 188 181 } 189 182 } else if (ro_opts == MAP_READONLY_PERMISSIONS) { 190 183 /* Check actual permissions for read-only. */ 191 184 if (!can_write_to_file(conn, smb_fname)) { 192 result |= aRONLY;185 result |= FILE_ATTRIBUTE_READONLY; 193 186 } 194 187 } /* Else never set the readonly bit. */ … … 197 190 if (MAP_ARCHIVE(conn) && ((smb_fname->st.st_ex_mode & S_IXUSR) != 0)) 198 191 #else 199 if (os2_isattribute(smb_fname->base_name, aARCH) == 0)192 if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_ARCHIVE) == 0) 200 193 #endif 201 result |= aARCH;194 result |= FILE_ATTRIBUTE_ARCHIVE; 202 195 203 196 #ifndef __OS2__ 204 197 if (MAP_SYSTEM(conn) && ((smb_fname->st.st_ex_mode & S_IXGRP) != 0)) 205 198 #else 206 if (os2_isattribute(smb_fname->base_name, aSYSTEM) == 0)199 if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_SYSTEM) == 0) 207 200 #endif 208 result |= aSYSTEM;201 result |= FILE_ATTRIBUTE_SYSTEM; 209 202 210 203 #ifndef __OS2__ 211 204 if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0)) 212 205 #else 213 if (os2_isattribute(smb_fname->base_name, aHIDDEN) == 0)206 if (os2_isattribute(smb_fname->base_name, FILE_ATTRIBUTE_HIDDEN) == 0) 214 207 #endif 215 result |= aHIDDEN;208 result |= FILE_ATTRIBUTE_HIDDEN; 216 209 217 210 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 221 213 result |= set_link_read_only_flag(&smb_fname->st); 222 214 223 215 DEBUG(8,("dos_mode_from_sbuf returning ")); 224 216 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")); 230 222 231 223 DEBUG(8,("\n")); … … 266 258 ) { 267 259 #endif 268 269 260 #ifdef __OS2__ //on os2 no error in case of ./.. and errno 2 270 261 if ((strncmp(smb_fname->base_name, "./..", 4) !=0) || (errno !=2)) 271 262 #endif 272 DEBUG(1,("get_ea_dos_attribute s: Cannot get attribute "263 DEBUG(1,("get_ea_dos_attribute: Cannot get attribute " 273 264 "from EA on file %s: Error = %s\n", 274 265 smb_fname_str_dbg(smb_fname), … … 282 273 blob.length = sizeret; 283 274 284 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL,&dosattrib,275 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib, 285 276 (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 } 286 285 287 286 DEBUG(10,("get_ea_dos_attribute: %s attr = %s\n", … … 302 301 create_time); 303 302 304 DEBUG(10,("get_ea_dos_attribute s: file %s case 1 "303 DEBUG(10,("get_ea_dos_attribute: file %s case 1 " 305 304 "set btime %s\n", 306 305 smb_fname_str_dbg(smb_fname), … … 324 323 create_time); 325 324 326 DEBUG(10,("get_ea_dos_attribute s: file %s case 3 "325 DEBUG(10,("get_ea_dos_attribute: file %s case 3 " 327 326 "set btime %s\n", 328 327 smb_fname_str_dbg(smb_fname), … … 331 330 } 332 331 break; 333 334 DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on "335 336 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)); 337 336 return false; 338 337 } 339 338 340 339 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)); 344 344 345 345 DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr)); 346 346 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")); 352 352 353 353 DEBUG(8,("\n")); … … 368 368 enum ndr_err_code ndr_err; 369 369 DATA_BLOB blob; 370 files_struct *fsp = NULL;371 bool ret = false;372 370 373 371 if (!lp_store_dos_attributes(SNUM(conn))) { … … 385 383 smb_fname->st.st_ex_btime); 386 384 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 387 390 ndr_err = ndr_push_struct_blob( 388 &blob, talloc_tos(), NULL,&dosattrib,391 &blob, talloc_tos(), &dosattrib, 389 392 (ndr_push_flags_fn_t)ndr_push_xattr_DOSATTRIB); 390 393 … … 402 405 SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length, 403 406 0) == -1) { 407 bool ret = false; 408 files_struct *fsp = NULL; 409 404 410 if((errno != EPERM) && (errno != EACCES)) { 405 411 if (errno == ENOSYS … … 434 440 if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname, 435 441 &fsp))) 436 return ret;442 return false; 437 443 become_root(); 438 if (SMB_VFS_ SETXATTR(conn, smb_fname->base_name,444 if (SMB_VFS_FSETXATTR(fsp, 439 445 SAMBA_XATTR_DOS_ATTRIB, blob.data, 440 446 blob.length, 0) == 0) { … … 479 485 if (p[0] == '.' && !((p[1] == '\0') || 480 486 (p[1] == '.' && p[2] == '\0'))) { 481 result |= aHIDDEN;487 result |= FILE_ATTRIBUTE_HIDDEN; 482 488 } 483 489 } … … 487 493 /* Optimization : Only call is_hidden_path if it's not already 488 494 hidden. */ 489 if (!(result & aHIDDEN) &&495 if (!(result & FILE_ATTRIBUTE_HIDDEN) && 490 496 IS_HIDDEN_PATH(conn, smb_fname->base_name)) { 491 result |= aHIDDEN;497 result |= FILE_ATTRIBUTE_HIDDEN; 492 498 } 493 499 … … 500 506 DEBUG(8,("dos_mode_msdfs returning ")); 501 507 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")); 507 513 if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); 508 514 … … 521 527 uint32_t dos_stat_flags = 0; 522 528 523 if (dosmode & aARCH)529 if (dosmode & FILE_ATTRIBUTE_ARCHIVE) 524 530 dos_stat_flags |= UF_DOS_ARCHIVE; 525 if (dosmode & aHIDDEN)531 if (dosmode & FILE_ATTRIBUTE_HIDDEN) 526 532 dos_stat_flags |= UF_DOS_HIDDEN; 527 if (dosmode & aRONLY)533 if (dosmode & FILE_ATTRIBUTE_READONLY) 528 534 dos_stat_flags |= UF_DOS_RO; 529 if (dosmode & aSYSTEM)535 if (dosmode & FILE_ATTRIBUTE_SYSTEM) 530 536 dos_stat_flags |= UF_DOS_SYSTEM; 531 537 if (dosmode & FILE_ATTRIBUTE_NONINDEXED) … … 554 560 555 561 if (smb_fname->st.st_ex_flags & UF_DOS_ARCHIVE) 556 *dosmode |= aARCH;562 *dosmode |= FILE_ATTRIBUTE_ARCHIVE; 557 563 if (smb_fname->st.st_ex_flags & UF_DOS_HIDDEN) 558 *dosmode |= aHIDDEN;564 *dosmode |= FILE_ATTRIBUTE_HIDDEN; 559 565 if (smb_fname->st.st_ex_flags & UF_DOS_RO) 560 *dosmode |= aRONLY;566 *dosmode |= FILE_ATTRIBUTE_READONLY; 561 567 if (smb_fname->st.st_ex_flags & UF_DOS_SYSTEM) 562 *dosmode |= aSYSTEM;568 *dosmode |= FILE_ATTRIBUTE_SYSTEM; 563 569 if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX) 564 570 *dosmode |= FILE_ATTRIBUTE_NONINDEXED; 571 if (smb_fname->st.st_ex_flags & FILE_ATTRIBUTE_SPARSE) 572 *dosmode |= FILE_ATTRIBUTE_SPARSE; 565 573 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 569 576 *dosmode |= set_link_read_only_flag(&smb_fname->st); 570 577 … … 650 657 if (p[0] == '.' && !((p[1] == '\0') || 651 658 (p[1] == '.' && p[2] == '\0'))) { 652 result |= aHIDDEN;659 result |= FILE_ATTRIBUTE_HIDDEN; 653 660 } 654 661 } … … 659 666 if (!used_stat_dos_flags) { 660 667 /* 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)) { 664 669 result |= dos_mode_from_sbuf(conn, smb_fname); 665 670 } 666 671 } 667 672 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); 669 674 if (S_ISREG(smb_fname->st.st_ex_mode) && offline) { 670 675 result |= FILE_ATTRIBUTE_OFFLINE; … … 673 678 /* Optimization : Only call is_hidden_path if it's not already 674 679 hidden. */ 675 if (!(result & aHIDDEN) &&680 if (!(result & FILE_ATTRIBUTE_HIDDEN) && 676 681 IS_HIDDEN_PATH(conn, smb_fname->base_name)) { 677 result |= aHIDDEN;682 result |= FILE_ATTRIBUTE_HIDDEN; 678 683 } 679 684 … … 686 691 DEBUG(8,("dos_mode returning ")); 687 692 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")); 693 698 if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); 694 699 … … 727 732 728 733 if (S_ISDIR(smb_fname->st.st_ex_mode)) 729 dosmode |= aDIR;734 dosmode |= FILE_ATTRIBUTE_DIRECTORY; 730 735 else 731 dosmode &= ~ aDIR;736 dosmode &= ~FILE_ATTRIBUTE_DIRECTORY; 732 737 733 738 new_create_timespec = smb_fname->st.st_ex_btime; … … 737 742 if (dosmode & FILE_ATTRIBUTE_OFFLINE) { 738 743 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); 740 745 if (lret == -1) { 741 746 DEBUG(0, ("set_dos_mode: client has asked to " … … 827 832 if (S_ISDIR(smb_fname->st.st_ex_mode) && (unixmode & S_ISGID) && 828 833 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)) { 830 835 DEBUG(3,("file_set_dosmode: setgid bit cannot be " 831 836 "set for directory %s\n", … … 834 839 return -1; 835 840 } 836 837 841 838 842 ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode); … … 885 889 } 886 890 891 892 NTSTATUS 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 887 959 /******************************************************************* 888 960 Wrapper around the VFS ntimes that possibly allows DOS semantics rather
Note:
See TracChangeset
for help on using the changeset viewer.