Changeset 862 for trunk/server/source3/smbd/trans2.c
- Timestamp:
- May 13, 2014, 11:39:04 AM (11 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 860
- Property svn:mergeinfo changed
-
trunk/server/source3/smbd/trans2.c
r792 r862 25 25 26 26 #include "includes.h" 27 #include "ntioctl.h" 27 28 #include "system/filesys.h" 28 29 #include "version.h" … … 337 338 } 338 339 340 if (listp->ea.value.length == 0) { 341 /* 342 * We can never return a zero length EA. 343 * Windows reports the EA's as corrupted. 344 */ 345 TALLOC_FREE(listp); 346 continue; 347 } 348 339 349 push_ascii_fstring(dos_ea_name, listp->ea.name); 340 350 … … 420 430 uint8_t *p = (uint8_t *)pdata; 421 431 uint8_t *last_start = NULL; 432 bool store_data = (pdata != NULL); 422 433 423 434 *ret_data_size = 0; … … 431 442 fstring dos_ea_name; 432 443 size_t this_size; 433 434 if (last_start) { 444 size_t pad = 0; 445 446 if (last_start && store_data) { 435 447 SIVAL(last_start, 0, PTR_DIFF(p, last_start)); 436 448 } … … 449 461 450 462 if (ea_list->next) { 451 size_t pad = 4 - (this_size % 4);463 pad = (4 - (this_size % 4)) % 4; 452 464 this_size += pad; 453 465 } … … 458 470 459 471 /* We know we have room. */ 460 SIVAL(p, 0x00, 0); /* next offset */ 461 SCVAL(p, 0x04, ea_list->ea.flags); 462 SCVAL(p, 0x05, dos_namelen); 463 SSVAL(p, 0x06, ea_list->ea.value.length); 464 fstrcpy((char *)(p+0x08), dos_ea_name); 465 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 472 if (store_data) { 473 SIVAL(p, 0x00, 0); /* next offset */ 474 SCVAL(p, 0x04, ea_list->ea.flags); 475 SCVAL(p, 0x05, dos_namelen); 476 SSVAL(p, 0x06, ea_list->ea.value.length); 477 fstrcpy((char *)(p+0x08), dos_ea_name); 478 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 479 if (pad) { 480 memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length, 481 '\0', 482 pad); 483 } 484 } 466 485 467 486 total_data_size -= this_size; … … 477 496 { 478 497 size_t total_ea_len = 0; 498 struct ea_list *ea_list = NULL; 479 499 TALLOC_CTX *mem_ctx = NULL; 480 500 … … 483 503 } 484 504 mem_ctx = talloc_tos(); 485 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 505 ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 506 if (ea_list == NULL) { 507 return 0; 508 } 509 if(conn->sconn->using_smb2) { 510 NTSTATUS status; 511 unsigned int ret_data_size; 512 /* 513 * We're going to be using fill_ea_chained_buffer() to 514 * marshall EA's - this size is significantly larger 515 * than the SMB1 buffer. Re-calculate the size without 516 * marshalling. 517 */ 518 status = fill_ea_chained_buffer(mem_ctx, 519 NULL, 520 65535, 521 &ret_data_size, 522 conn, 523 ea_list); 524 if (!NT_STATUS_IS_OK(status)) { 525 ret_data_size = 0; 526 } 527 total_ea_len = ret_data_size; 528 } 529 486 530 return total_ea_len; 487 531 } … … 1744 1788 SIVAL(p,0,mode); p += 4; 1745 1789 q = p; p += 4; /* q is placeholder for name length. */ 1746 { 1790 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 1791 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 1792 } else { 1747 1793 unsigned int ea_size = estimate_ea_size(conn, NULL, 1748 1794 smb_fname->base_name); 1749 1795 SIVAL(p,0,ea_size); /* Extended attributes */ 1750 p += 4;1751 }1796 } 1797 p += 4; 1752 1798 /* Clear the short name buffer. This is 1753 1799 * IMPORTANT as not doing so will trigger … … 1921 1967 SIVAL(p,0,mode); p += 4; 1922 1968 q = p; p += 4; /* q is placeholder for name length. */ 1923 { 1969 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 1970 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 1971 } else { 1924 1972 unsigned int ea_size = estimate_ea_size(conn, NULL, 1925 1973 smb_fname->base_name); 1926 1974 SIVAL(p,0,ea_size); /* Extended attributes */ 1927 p +=4;1928 }1975 } 1976 p +=4; 1929 1977 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */ 1930 1978 SBVAL(p,0,file_index); p += 8; … … 1967 2015 SIVAL(p,0,mode); p += 4; 1968 2016 q = p; p += 4; /* q is placeholder for name length */ 1969 { 2017 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 2018 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 2019 } else { 1970 2020 unsigned int ea_size = estimate_ea_size(conn, NULL, 1971 2021 smb_fname->base_name); 1972 2022 SIVAL(p,0,ea_size); /* Extended attributes */ 1973 p +=4;1974 }2023 } 2024 p +=4; 1975 2025 /* Clear the short name buffer. This is 1976 2026 * IMPORTANT as not doing so will trigger … … 2935 2985 uint16_t flags2, 2936 2986 unsigned int max_data_bytes, 2987 size_t *fixed_portion, 2988 struct smb_filename *fname, 2937 2989 char **ppdata, 2938 2990 int *ret_data_len) … … 2943 2995 int snum = SNUM(conn); 2944 2996 char *fstype = lp_fstype(SNUM(conn)); 2997 const char *filename = NULL; 2945 2998 uint32 additional_flags = 0; 2946 struct smb_filename smb_fname _dot;2999 struct smb_filename smb_fname; 2947 3000 SMB_STRUCT_STAT st; 3001 NTSTATUS status = NT_STATUS_OK; 3002 3003 if (fname == NULL || fname->base_name == NULL) { 3004 filename = "."; 3005 } else { 3006 filename = fname->base_name; 3007 } 2948 3008 2949 3009 if (IS_IPC(conn)) { … … 2958 3018 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); 2959 3019 2960 ZERO_STRUCT(smb_fname _dot);2961 smb_fname _dot.base_name = discard_const_p(char, ".");2962 2963 if(SMB_VFS_STAT(conn, &smb_fname _dot) != 0) {3020 ZERO_STRUCT(smb_fname); 3021 smb_fname.base_name = discard_const_p(char, filename); 3022 3023 if(SMB_VFS_STAT(conn, &smb_fname) != 0) { 2964 3024 DEBUG(2,("stat of . failed (%s)\n", strerror(errno))); 2965 3025 return map_nt_error_from_unix(errno); 2966 3026 } 2967 3027 2968 st = smb_fname _dot.st;3028 st = smb_fname.st; 2969 3029 2970 3030 *ppdata = (char *)SMB_REALLOC( … … 2977 3037 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 2978 3038 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; 3039 3040 *fixed_portion = 0; 2979 3041 2980 3042 switch (info_level) { … … 2983 3045 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 2984 3046 data_len = 18; 2985 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3047 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 2986 3048 return map_nt_error_from_unix(errno); 2987 3049 } … … 3070 3132 SIVAL(pdata,8,len); 3071 3133 data_len = 12 + len; 3134 if (max_data_bytes >= 16 && data_len > max_data_bytes) { 3135 /* the client only requested a portion of the 3136 file system name */ 3137 data_len = max_data_bytes; 3138 status = STATUS_BUFFER_OVERFLOW; 3139 } 3140 *fixed_portion = 16; 3072 3141 break; 3073 3142 … … 3099 3168 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 3100 3169 (int)strlen(vname),vname, lp_servicename(snum))); 3170 if (max_data_bytes >= 24 && data_len > max_data_bytes) { 3171 /* the client only requested a portion of the 3172 volume label */ 3173 data_len = max_data_bytes; 3174 status = STATUS_BUFFER_OVERFLOW; 3175 } 3176 3101 3177 break; 3102 3178 … … 3106 3182 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 3107 3183 data_len = 24; 3108 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3184 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 3109 3185 return map_nt_error_from_unix(errno); 3110 3186 } … … 3131 3207 SIVAL(pdata,16,sectors_per_unit); 3132 3208 SIVAL(pdata,20,bytes_per_sector); 3209 *fixed_portion = 24; 3133 3210 break; 3134 3211 } … … 3138 3215 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 3139 3216 data_len = 32; 3140 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3217 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 3141 3218 return map_nt_error_from_unix(errno); 3142 3219 } … … 3164 3241 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */ 3165 3242 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */ 3243 *fixed_portion = 32; 3166 3244 break; 3167 3245 } … … 3178 3256 SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */ 3179 3257 SIVAL(pdata,4,characteristics); 3258 *fixed_portion = 8; 3180 3259 break; 3181 3260 } … … 3331 3410 } 3332 3411 3333 rc = SMB_VFS_STATVFS(conn, ".", &svfs);3412 rc = SMB_VFS_STATVFS(conn, filename, &svfs); 3334 3413 3335 3414 if (!rc) { … … 3352 3431 return NT_STATUS_DOS(ERRSRV, ERRerror); 3353 3432 } 3433 *fixed_portion = 24; 3354 3434 break; 3355 3435 } … … 3482 3562 3483 3563 *ret_data_len = data_len; 3484 return NT_STATUS_OK;3564 return status; 3485 3565 } 3486 3566 … … 3498 3578 uint16_t info_level; 3499 3579 int data_len = 0; 3580 size_t fixed_portion; 3500 3581 NTSTATUS status; 3501 3582 … … 3524 3605 req->flags2, 3525 3606 max_data_bytes, 3607 &fixed_portion, 3608 NULL, 3526 3609 ppdata, &data_len); 3527 3610 if (!NT_STATUS_IS_OK(status)) { … … 4076 4159 unsigned int ofs = 0; 4077 4160 4078 for (i = 0; i < num_streams && ofs <= max_data_bytes; i++) { 4161 if (max_data_bytes < 32) { 4162 return NT_STATUS_INFO_LENGTH_MISMATCH; 4163 } 4164 4165 for (i = 0; i < num_streams; i++) { 4079 4166 unsigned int next_offset; 4080 4167 size_t namelen; … … 4095 4182 namelen -= 2; 4096 4183 4184 /* 4185 * We cannot overflow ... 4186 */ 4187 if ((ofs + 24 + namelen) > max_data_bytes) { 4188 DEBUG(10, ("refusing to overflow reply at stream %u\n", 4189 i)); 4190 TALLOC_FREE(namebuf); 4191 return STATUS_BUFFER_OVERFLOW; 4192 } 4193 4097 4194 SIVAL(data, ofs+4, namelen); 4098 4195 SOFF_T(data, ofs+8, streams[i].size); … … 4109 4206 unsigned int align = ndr_align_size(next_offset, 8); 4110 4207 4208 if ((next_offset + align) > max_data_bytes) { 4209 DEBUG(10, ("refusing to overflow align " 4210 "reply at stream %u\n", 4211 i)); 4212 TALLOC_FREE(namebuf); 4213 return STATUS_BUFFER_OVERFLOW; 4214 } 4215 4111 4216 memset(data+next_offset, 0, align); 4112 4217 next_offset += align; … … 4118 4223 ofs = next_offset; 4119 4224 } 4225 4226 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs)); 4120 4227 4121 4228 *data_size = ofs; … … 4207 4314 uint16_t flags2, 4208 4315 unsigned int max_data_bytes, 4316 size_t *fixed_portion, 4209 4317 char **ppdata, 4210 4318 unsigned int *pdata_size) … … 4342 4450 file_index = get_FileIndex(conn, psbuf); 4343 4451 4452 *fixed_portion = 0; 4453 4344 4454 switch (info_level) { 4345 4455 case SMB_INFO_STANDARD: … … 4479 4589 DEBUG(5,("change: %s ", ctime(&c_time))); 4480 4590 DEBUG(5,("mode: %x\n", mode)); 4591 *fixed_portion = data_size; 4481 4592 break; 4482 4593 … … 4492 4603 SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0); 4493 4604 SSVAL(pdata,22,0); /* Padding. */ 4605 *fixed_portion = 24; 4494 4606 break; 4495 4607 … … 4501 4613 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); 4502 4614 data_size = 4; 4615 *fixed_portion = 4; 4503 4616 SIVAL(pdata,0,ea_size); 4504 4617 break; … … 4522 4635 data_size = 4 + len; 4523 4636 SIVAL(pdata,0,len); 4637 *fixed_portion = 8; 4524 4638 break; 4525 4639 } … … 4585 4699 pdata += 4 + len; 4586 4700 data_size = PTR_DIFF(pdata,(*ppdata)); 4701 *fixed_portion = 10; 4587 4702 break; 4588 4703 } … … 4622 4737 pdata += 4 + len; 4623 4738 data_size = PTR_DIFF(pdata,(*ppdata)); 4739 *fixed_portion = 104; 4624 4740 break; 4625 4741 } … … 4629 4745 SBVAL(pdata, 0, file_index); 4630 4746 data_size = 8; 4747 *fixed_portion = 8; 4631 4748 break; 4632 4749 … … 4635 4752 SIVAL(pdata, 0, access_mask); 4636 4753 data_size = 4; 4754 *fixed_portion = 4; 4637 4755 break; 4638 4756 … … 4652 4770 data_size = 1; 4653 4771 SCVAL(pdata,0,delete_pending); 4772 *fixed_portion = 1; 4654 4773 break; 4655 4774 … … 4658 4777 data_size = 8; 4659 4778 SOFF_T(pdata,0,pos); 4779 *fixed_portion = 8; 4660 4780 break; 4661 4781 … … 4664 4784 SIVAL(pdata,0,mode); 4665 4785 data_size = 4; 4786 *fixed_portion = 4; 4666 4787 break; 4667 4788 … … 4670 4791 SIVAL(pdata,0,0); /* No alignment needed. */ 4671 4792 data_size = 4; 4793 *fixed_portion = 4; 4672 4794 break; 4673 4795 … … 4708 4830 DEBUG(10, ("marshall_stream_info failed: %s\n", 4709 4831 nt_errstr(status))); 4832 TALLOC_FREE(streams); 4710 4833 return status; 4711 4834 } 4712 4835 4713 4836 TALLOC_FREE(streams); 4837 4838 *fixed_portion = 32; 4714 4839 4715 4840 break; … … 4722 4847 SIVAL(pdata,12,0); /* ??? */ 4723 4848 data_size = 16; 4849 *fixed_portion = 16; 4724 4850 break; 4725 4851 … … 4735 4861 SIVAL(pdata,52,0); /* ??? */ 4736 4862 data_size = 56; 4863 *fixed_portion = 56; 4737 4864 break; 4738 4865 … … 4742 4869 SIVAL(pdata,4,0); 4743 4870 data_size = 8; 4871 *fixed_portion = 8; 4744 4872 break; 4745 4873 … … 5011 5139 int lock_data_count = 0; 5012 5140 char *lock_data = NULL; 5141 size_t fixed_portion; 5013 5142 NTSTATUS status = NT_STATUS_OK; 5014 5143 … … 5372 5501 lock_data_count, lock_data, 5373 5502 req->flags2, max_data_bytes, 5503 &fixed_portion, 5374 5504 ppdata, &data_size); 5375 5505 if (!NT_STATUS_IS_OK(status)) { 5376 5506 reply_nterror(req, status); 5507 return; 5508 } 5509 if (fixed_portion > max_data_bytes) { 5510 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); 5377 5511 return; 5378 5512 } … … 7325 7459 create_disp = FILE_OPEN_IF; 7326 7460 break; 7461 case SMB_O_EXCL: 7462 /* O_EXCL on its own without O_CREAT is undefined. 7463 We deliberately ignore it as some versions of 7464 Linux CIFSFS can send a bare O_EXCL on the 7465 wire which other filesystems in the kernel 7466 ignore. See bug 9519 for details. */ 7467 7468 /* Fallthrough. */ 7469 7327 7470 case 0: 7328 7471 /* File exists open. File not exist fail. */ 7329 7472 create_disp = FILE_OPEN; 7330 7473 break; 7331 case SMB_O_EXCL:7332 /* O_EXCL on its own without O_CREAT is undefined. */7333 7474 default: 7334 7475 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n", … … 7583 7724 } 7584 7725 /* Fail with sharing violation. */ 7726 TALLOC_FREE(lck); 7585 7727 close_file(req, fsp, NORMAL_CLOSE); 7586 TALLOC_FREE(lck);7587 7728 return NT_STATUS_SHARING_VIOLATION; 7588 7729 } … … 7598 7739 smb_fname); 7599 7740 7741 TALLOC_FREE(lck); 7742 7600 7743 if (!NT_STATUS_IS_OK(status)) { 7601 7744 close_file(req, fsp, NORMAL_CLOSE); 7602 TALLOC_FREE(lck);7603 7745 return status; 7604 7746 } 7605 TALLOC_FREE(lck);7606 7747 return close_file(req, fsp, NORMAL_CLOSE); 7607 7748 }
Note:
See TracChangeset
for help on using the changeset viewer.