Changeset 740 for vendor/current/source3/smbd/dosmode.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/dosmode.c
r597 r740 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 … … 181 174 /* Original Samba method - map inverse of user "w" bit. */ 182 175 if ((smb_fname->st.st_ex_mode & S_IWUSR) == 0) { 183 result |= aRONLY;176 result |= FILE_ATTRIBUTE_READONLY; 184 177 } 185 178 } else if (ro_opts == MAP_READONLY_PERMISSIONS) { 186 179 /* Check actual permissions for read-only. */ 187 180 if (!can_write_to_file(conn, smb_fname)) { 188 result |= aRONLY;181 result |= FILE_ATTRIBUTE_READONLY; 189 182 } 190 183 } /* Else never set the readonly bit. */ 191 184 192 185 if (MAP_ARCHIVE(conn) && ((smb_fname->st.st_ex_mode & S_IXUSR) != 0)) 193 result |= aARCH;186 result |= FILE_ATTRIBUTE_ARCHIVE; 194 187 195 188 if (MAP_SYSTEM(conn) && ((smb_fname->st.st_ex_mode & S_IXGRP) != 0)) 196 result |= aSYSTEM;189 result |= FILE_ATTRIBUTE_SYSTEM; 197 190 198 191 if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0)) 199 result |= aHIDDEN;192 result |= FILE_ATTRIBUTE_HIDDEN; 200 193 201 194 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 205 197 result |= set_link_read_only_flag(&smb_fname->st); 206 198 207 199 DEBUG(8,("dos_mode_from_sbuf returning ")); 208 200 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")); 214 206 215 207 DEBUG(8,("\n")); … … 250 242 ) { 251 243 #endif 252 DEBUG(1,("get_ea_dos_attribute s: Cannot get attribute "244 DEBUG(1,("get_ea_dos_attribute: Cannot get attribute " 253 245 "from EA on file %s: Error = %s\n", 254 246 smb_fname_str_dbg(smb_fname), … … 262 254 blob.length = sizeret; 263 255 264 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL,&dosattrib,256 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib, 265 257 (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 } 266 266 267 267 DEBUG(10,("get_ea_dos_attribute: %s attr = %s\n", … … 282 282 create_time); 283 283 284 DEBUG(10,("get_ea_dos_attribute s: file %s case 1 "284 DEBUG(10,("get_ea_dos_attribute: file %s case 1 " 285 285 "set btime %s\n", 286 286 smb_fname_str_dbg(smb_fname), … … 304 304 create_time); 305 305 306 DEBUG(10,("get_ea_dos_attribute s: file %s case 3 "306 DEBUG(10,("get_ea_dos_attribute: file %s case 3 " 307 307 "set btime %s\n", 308 308 smb_fname_str_dbg(smb_fname), … … 311 311 } 312 312 break; 313 314 DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on "315 316 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)); 317 317 return false; 318 318 } 319 319 320 320 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)); 324 325 325 326 DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr)); 326 327 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")); 332 333 333 334 DEBUG(8,("\n")); … … 348 349 enum ndr_err_code ndr_err; 349 350 DATA_BLOB blob; 350 files_struct *fsp = NULL;351 bool ret = false;352 351 353 352 if (!lp_store_dos_attributes(SNUM(conn))) { … … 365 364 smb_fname->st.st_ex_btime); 366 365 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 367 371 ndr_err = ndr_push_struct_blob( 368 &blob, talloc_tos(), NULL,&dosattrib,372 &blob, talloc_tos(), &dosattrib, 369 373 (ndr_push_flags_fn_t)ndr_push_xattr_DOSATTRIB); 370 374 … … 382 386 SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length, 383 387 0) == -1) { 388 bool ret = false; 389 files_struct *fsp = NULL; 390 384 391 if((errno != EPERM) && (errno != EACCES)) { 385 392 if (errno == ENOSYS … … 414 421 if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname, 415 422 &fsp))) 416 return ret;423 return false; 417 424 become_root(); 418 if (SMB_VFS_ SETXATTR(conn, smb_fname->base_name,425 if (SMB_VFS_FSETXATTR(fsp, 419 426 SAMBA_XATTR_DOS_ATTRIB, blob.data, 420 427 blob.length, 0) == 0) { … … 459 466 if (p[0] == '.' && !((p[1] == '\0') || 460 467 (p[1] == '.' && p[2] == '\0'))) { 461 result |= aHIDDEN;468 result |= FILE_ATTRIBUTE_HIDDEN; 462 469 } 463 470 } … … 467 474 /* Optimization : Only call is_hidden_path if it's not already 468 475 hidden. */ 469 if (!(result & aHIDDEN) &&476 if (!(result & FILE_ATTRIBUTE_HIDDEN) && 470 477 IS_HIDDEN_PATH(conn, smb_fname->base_name)) { 471 result |= aHIDDEN;478 result |= FILE_ATTRIBUTE_HIDDEN; 472 479 } 473 480 … … 480 487 DEBUG(8,("dos_mode_msdfs returning ")); 481 488 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")); 487 494 if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); 488 495 … … 501 508 uint32_t dos_stat_flags = 0; 502 509 503 if (dosmode & aARCH)510 if (dosmode & FILE_ATTRIBUTE_ARCHIVE) 504 511 dos_stat_flags |= UF_DOS_ARCHIVE; 505 if (dosmode & aHIDDEN)512 if (dosmode & FILE_ATTRIBUTE_HIDDEN) 506 513 dos_stat_flags |= UF_DOS_HIDDEN; 507 if (dosmode & aRONLY)514 if (dosmode & FILE_ATTRIBUTE_READONLY) 508 515 dos_stat_flags |= UF_DOS_RO; 509 if (dosmode & aSYSTEM)516 if (dosmode & FILE_ATTRIBUTE_SYSTEM) 510 517 dos_stat_flags |= UF_DOS_SYSTEM; 511 518 if (dosmode & FILE_ATTRIBUTE_NONINDEXED) … … 534 541 535 542 if (smb_fname->st.st_ex_flags & UF_DOS_ARCHIVE) 536 *dosmode |= aARCH;543 *dosmode |= FILE_ATTRIBUTE_ARCHIVE; 537 544 if (smb_fname->st.st_ex_flags & UF_DOS_HIDDEN) 538 *dosmode |= aHIDDEN;545 *dosmode |= FILE_ATTRIBUTE_HIDDEN; 539 546 if (smb_fname->st.st_ex_flags & UF_DOS_RO) 540 *dosmode |= aRONLY;547 *dosmode |= FILE_ATTRIBUTE_READONLY; 541 548 if (smb_fname->st.st_ex_flags & UF_DOS_SYSTEM) 542 *dosmode |= aSYSTEM;549 *dosmode |= FILE_ATTRIBUTE_SYSTEM; 543 550 if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX) 544 551 *dosmode |= FILE_ATTRIBUTE_NONINDEXED; 552 if (smb_fname->st.st_ex_flags & FILE_ATTRIBUTE_SPARSE) 553 *dosmode |= FILE_ATTRIBUTE_SPARSE; 545 554 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 549 557 *dosmode |= set_link_read_only_flag(&smb_fname->st); 550 558 … … 630 638 if (p[0] == '.' && !((p[1] == '\0') || 631 639 (p[1] == '.' && p[2] == '\0'))) { 632 result |= aHIDDEN;640 result |= FILE_ATTRIBUTE_HIDDEN; 633 641 } 634 642 } … … 639 647 if (!used_stat_dos_flags) { 640 648 /* 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)) { 644 650 result |= dos_mode_from_sbuf(conn, smb_fname); 645 651 } 646 652 } 647 653 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); 649 655 if (S_ISREG(smb_fname->st.st_ex_mode) && offline) { 650 656 result |= FILE_ATTRIBUTE_OFFLINE; … … 653 659 /* Optimization : Only call is_hidden_path if it's not already 654 660 hidden. */ 655 if (!(result & aHIDDEN) &&661 if (!(result & FILE_ATTRIBUTE_HIDDEN) && 656 662 IS_HIDDEN_PATH(conn, smb_fname->base_name)) { 657 result |= aHIDDEN;663 result |= FILE_ATTRIBUTE_HIDDEN; 658 664 } 659 665 … … 666 672 DEBUG(8,("dos_mode returning ")); 667 673 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")); 673 679 if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); 674 680 … … 707 713 708 714 if (S_ISDIR(smb_fname->st.st_ex_mode)) 709 dosmode |= aDIR;715 dosmode |= FILE_ATTRIBUTE_DIRECTORY; 710 716 else 711 dosmode &= ~ aDIR;717 dosmode &= ~FILE_ATTRIBUTE_DIRECTORY; 712 718 713 719 new_create_timespec = smb_fname->st.st_ex_btime; … … 717 723 if (dosmode & FILE_ATTRIBUTE_OFFLINE) { 718 724 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); 720 726 if (lret == -1) { 721 727 DEBUG(0, ("set_dos_mode: client has asked to " … … 807 813 if (S_ISDIR(smb_fname->st.st_ex_mode) && (unixmode & S_ISGID) && 808 814 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)) { 810 816 DEBUG(3,("file_set_dosmode: setgid bit cannot be " 811 817 "set for directory %s\n", … … 814 820 return -1; 815 821 } 816 817 822 818 823 ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode); … … 865 870 } 866 871 872 873 NTSTATUS 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 867 940 /******************************************************************* 868 941 Wrapper around the VFS ntimes that possibly allows DOS semantics rather
Note:
See TracChangeset
for help on using the changeset viewer.