Changeset 860 for vendor/current/source3/smbd/trans2.c
- Timestamp:
- May 12, 2014, 8:58:38 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/trans2.c
r746 r860 25 25 26 26 #include "includes.h" 27 #include "ntioctl.h" 27 28 #include "system/filesys.h" 28 29 #include "version.h" … … 329 330 } 330 331 332 if (listp->ea.value.length == 0) { 333 /* 334 * We can never return a zero length EA. 335 * Windows reports the EA's as corrupted. 336 */ 337 TALLOC_FREE(listp); 338 continue; 339 } 340 331 341 push_ascii_fstring(dos_ea_name, listp->ea.name); 332 342 … … 412 422 uint8_t *p = (uint8_t *)pdata; 413 423 uint8_t *last_start = NULL; 424 bool store_data = (pdata != NULL); 414 425 415 426 *ret_data_size = 0; … … 423 434 fstring dos_ea_name; 424 435 size_t this_size; 425 426 if (last_start) { 436 size_t pad = 0; 437 438 if (last_start && store_data) { 427 439 SIVAL(last_start, 0, PTR_DIFF(p, last_start)); 428 440 } … … 441 453 442 454 if (ea_list->next) { 443 size_t pad = 4 - (this_size % 4);455 pad = (4 - (this_size % 4)) % 4; 444 456 this_size += pad; 445 457 } … … 450 462 451 463 /* We know we have room. */ 452 SIVAL(p, 0x00, 0); /* next offset */ 453 SCVAL(p, 0x04, ea_list->ea.flags); 454 SCVAL(p, 0x05, dos_namelen); 455 SSVAL(p, 0x06, ea_list->ea.value.length); 456 fstrcpy((char *)(p+0x08), dos_ea_name); 457 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 464 if (store_data) { 465 SIVAL(p, 0x00, 0); /* next offset */ 466 SCVAL(p, 0x04, ea_list->ea.flags); 467 SCVAL(p, 0x05, dos_namelen); 468 SSVAL(p, 0x06, ea_list->ea.value.length); 469 fstrcpy((char *)(p+0x08), dos_ea_name); 470 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 471 if (pad) { 472 memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length, 473 '\0', 474 pad); 475 } 476 } 458 477 459 478 total_data_size -= this_size; … … 469 488 { 470 489 size_t total_ea_len = 0; 490 struct ea_list *ea_list = NULL; 471 491 TALLOC_CTX *mem_ctx = NULL; 472 492 … … 475 495 } 476 496 mem_ctx = talloc_tos(); 477 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 497 ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 498 if (ea_list == NULL) { 499 return 0; 500 } 501 if(conn->sconn->using_smb2) { 502 NTSTATUS status; 503 unsigned int ret_data_size; 504 /* 505 * We're going to be using fill_ea_chained_buffer() to 506 * marshall EA's - this size is significantly larger 507 * than the SMB1 buffer. Re-calculate the size without 508 * marshalling. 509 */ 510 status = fill_ea_chained_buffer(mem_ctx, 511 NULL, 512 65535, 513 &ret_data_size, 514 conn, 515 ea_list); 516 if (!NT_STATUS_IS_OK(status)) { 517 ret_data_size = 0; 518 } 519 total_ea_len = ret_data_size; 520 } 521 478 522 return total_ea_len; 479 523 } … … 1731 1775 SIVAL(p,0,mode); p += 4; 1732 1776 q = p; p += 4; /* q is placeholder for name length. */ 1733 { 1777 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 1778 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 1779 } else { 1734 1780 unsigned int ea_size = estimate_ea_size(conn, NULL, 1735 1781 smb_fname->base_name); 1736 1782 SIVAL(p,0,ea_size); /* Extended attributes */ 1737 p += 4;1738 }1783 } 1784 p += 4; 1739 1785 /* Clear the short name buffer. This is 1740 1786 * IMPORTANT as not doing so will trigger … … 1908 1954 SIVAL(p,0,mode); p += 4; 1909 1955 q = p; p += 4; /* q is placeholder for name length. */ 1910 { 1956 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 1957 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 1958 } else { 1911 1959 unsigned int ea_size = estimate_ea_size(conn, NULL, 1912 1960 smb_fname->base_name); 1913 1961 SIVAL(p,0,ea_size); /* Extended attributes */ 1914 p +=4;1915 }1962 } 1963 p +=4; 1916 1964 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */ 1917 1965 SBVAL(p,0,file_index); p += 8; … … 1954 2002 SIVAL(p,0,mode); p += 4; 1955 2003 q = p; p += 4; /* q is placeholder for name length */ 1956 { 2004 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 2005 SIVAL(p, 0, IO_REPARSE_TAG_DFS); 2006 } else { 1957 2007 unsigned int ea_size = estimate_ea_size(conn, NULL, 1958 2008 smb_fname->base_name); 1959 2009 SIVAL(p,0,ea_size); /* Extended attributes */ 1960 p +=4;1961 }2010 } 2011 p +=4; 1962 2012 /* Clear the short name buffer. This is 1963 2013 * IMPORTANT as not doing so will trigger … … 2922 2972 uint16_t flags2, 2923 2973 unsigned int max_data_bytes, 2974 size_t *fixed_portion, 2975 struct smb_filename *fname, 2924 2976 char **ppdata, 2925 2977 int *ret_data_len) … … 2930 2982 int snum = SNUM(conn); 2931 2983 char *fstype = lp_fstype(SNUM(conn)); 2984 const char *filename = NULL; 2932 2985 uint32 additional_flags = 0; 2933 struct smb_filename smb_fname _dot;2986 struct smb_filename smb_fname; 2934 2987 SMB_STRUCT_STAT st; 2988 NTSTATUS status = NT_STATUS_OK; 2989 2990 if (fname == NULL || fname->base_name == NULL) { 2991 filename = "."; 2992 } else { 2993 filename = fname->base_name; 2994 } 2935 2995 2936 2996 if (IS_IPC(conn)) { … … 2945 3005 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); 2946 3006 2947 ZERO_STRUCT(smb_fname _dot);2948 smb_fname _dot.base_name = discard_const_p(char, ".");2949 2950 if(SMB_VFS_STAT(conn, &smb_fname _dot) != 0) {3007 ZERO_STRUCT(smb_fname); 3008 smb_fname.base_name = discard_const_p(char, filename); 3009 3010 if(SMB_VFS_STAT(conn, &smb_fname) != 0) { 2951 3011 DEBUG(2,("stat of . failed (%s)\n", strerror(errno))); 2952 3012 return map_nt_error_from_unix(errno); 2953 3013 } 2954 3014 2955 st = smb_fname _dot.st;3015 st = smb_fname.st; 2956 3016 2957 3017 *ppdata = (char *)SMB_REALLOC( … … 2964 3024 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 2965 3025 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; 3026 3027 *fixed_portion = 0; 2966 3028 2967 3029 switch (info_level) { … … 2970 3032 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 2971 3033 data_len = 18; 2972 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3034 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 2973 3035 return map_nt_error_from_unix(errno); 2974 3036 } … … 3057 3119 SIVAL(pdata,8,len); 3058 3120 data_len = 12 + len; 3121 if (max_data_bytes >= 16 && data_len > max_data_bytes) { 3122 /* the client only requested a portion of the 3123 file system name */ 3124 data_len = max_data_bytes; 3125 status = STATUS_BUFFER_OVERFLOW; 3126 } 3127 *fixed_portion = 16; 3059 3128 break; 3060 3129 … … 3086 3155 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 3087 3156 (int)strlen(vname),vname, lp_servicename(snum))); 3157 if (max_data_bytes >= 24 && data_len > max_data_bytes) { 3158 /* the client only requested a portion of the 3159 volume label */ 3160 data_len = max_data_bytes; 3161 status = STATUS_BUFFER_OVERFLOW; 3162 } 3163 3088 3164 break; 3089 3165 … … 3093 3169 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 3094 3170 data_len = 24; 3095 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3171 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 3096 3172 return map_nt_error_from_unix(errno); 3097 3173 } … … 3118 3194 SIVAL(pdata,16,sectors_per_unit); 3119 3195 SIVAL(pdata,20,bytes_per_sector); 3196 *fixed_portion = 24; 3120 3197 break; 3121 3198 } … … 3125 3202 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 3126 3203 data_len = 32; 3127 if (get_dfree_info(conn, ".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {3204 if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) { 3128 3205 return map_nt_error_from_unix(errno); 3129 3206 } … … 3151 3228 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */ 3152 3229 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */ 3230 *fixed_portion = 32; 3153 3231 break; 3154 3232 } … … 3165 3243 SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */ 3166 3244 SIVAL(pdata,4,characteristics); 3245 *fixed_portion = 8; 3167 3246 break; 3168 3247 } … … 3318 3397 } 3319 3398 3320 rc = SMB_VFS_STATVFS(conn, ".", &svfs);3399 rc = SMB_VFS_STATVFS(conn, filename, &svfs); 3321 3400 3322 3401 if (!rc) { … … 3339 3418 return NT_STATUS_DOS(ERRSRV, ERRerror); 3340 3419 } 3420 *fixed_portion = 24; 3341 3421 break; 3342 3422 } … … 3469 3549 3470 3550 *ret_data_len = data_len; 3471 return NT_STATUS_OK;3551 return status; 3472 3552 } 3473 3553 … … 3485 3565 uint16_t info_level; 3486 3566 int data_len = 0; 3567 size_t fixed_portion; 3487 3568 NTSTATUS status; 3488 3569 … … 3511 3592 req->flags2, 3512 3593 max_data_bytes, 3594 &fixed_portion, 3595 NULL, 3513 3596 ppdata, &data_len); 3514 3597 if (!NT_STATUS_IS_OK(status)) { … … 4063 4146 unsigned int ofs = 0; 4064 4147 4065 for (i = 0; i < num_streams && ofs <= max_data_bytes; i++) { 4148 if (max_data_bytes < 32) { 4149 return NT_STATUS_INFO_LENGTH_MISMATCH; 4150 } 4151 4152 for (i = 0; i < num_streams; i++) { 4066 4153 unsigned int next_offset; 4067 4154 size_t namelen; … … 4082 4169 namelen -= 2; 4083 4170 4171 /* 4172 * We cannot overflow ... 4173 */ 4174 if ((ofs + 24 + namelen) > max_data_bytes) { 4175 DEBUG(10, ("refusing to overflow reply at stream %u\n", 4176 i)); 4177 TALLOC_FREE(namebuf); 4178 return STATUS_BUFFER_OVERFLOW; 4179 } 4180 4084 4181 SIVAL(data, ofs+4, namelen); 4085 4182 SOFF_T(data, ofs+8, streams[i].size); … … 4096 4193 unsigned int align = ndr_align_size(next_offset, 8); 4097 4194 4195 if ((next_offset + align) > max_data_bytes) { 4196 DEBUG(10, ("refusing to overflow align " 4197 "reply at stream %u\n", 4198 i)); 4199 TALLOC_FREE(namebuf); 4200 return STATUS_BUFFER_OVERFLOW; 4201 } 4202 4098 4203 memset(data+next_offset, 0, align); 4099 4204 next_offset += align; … … 4105 4210 ofs = next_offset; 4106 4211 } 4212 4213 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs)); 4107 4214 4108 4215 *data_size = ofs; … … 4194 4301 uint16_t flags2, 4195 4302 unsigned int max_data_bytes, 4303 size_t *fixed_portion, 4196 4304 char **ppdata, 4197 4305 unsigned int *pdata_size) … … 4329 4437 file_index = get_FileIndex(conn, psbuf); 4330 4438 4439 *fixed_portion = 0; 4440 4331 4441 switch (info_level) { 4332 4442 case SMB_INFO_STANDARD: … … 4466 4576 DEBUG(5,("change: %s ", ctime(&c_time))); 4467 4577 DEBUG(5,("mode: %x\n", mode)); 4578 *fixed_portion = data_size; 4468 4579 break; 4469 4580 … … 4479 4590 SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0); 4480 4591 SSVAL(pdata,22,0); /* Padding. */ 4592 *fixed_portion = 24; 4481 4593 break; 4482 4594 … … 4488 4600 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); 4489 4601 data_size = 4; 4602 *fixed_portion = 4; 4490 4603 SIVAL(pdata,0,ea_size); 4491 4604 break; … … 4509 4622 data_size = 4 + len; 4510 4623 SIVAL(pdata,0,len); 4624 *fixed_portion = 8; 4511 4625 break; 4512 4626 } … … 4572 4686 pdata += 4 + len; 4573 4687 data_size = PTR_DIFF(pdata,(*ppdata)); 4688 *fixed_portion = 10; 4574 4689 break; 4575 4690 } … … 4609 4724 pdata += 4 + len; 4610 4725 data_size = PTR_DIFF(pdata,(*ppdata)); 4726 *fixed_portion = 104; 4611 4727 break; 4612 4728 } … … 4616 4732 SBVAL(pdata, 0, file_index); 4617 4733 data_size = 8; 4734 *fixed_portion = 8; 4618 4735 break; 4619 4736 … … 4622 4739 SIVAL(pdata, 0, access_mask); 4623 4740 data_size = 4; 4741 *fixed_portion = 4; 4624 4742 break; 4625 4743 … … 4639 4757 data_size = 1; 4640 4758 SCVAL(pdata,0,delete_pending); 4759 *fixed_portion = 1; 4641 4760 break; 4642 4761 … … 4645 4764 data_size = 8; 4646 4765 SOFF_T(pdata,0,pos); 4766 *fixed_portion = 8; 4647 4767 break; 4648 4768 … … 4651 4771 SIVAL(pdata,0,mode); 4652 4772 data_size = 4; 4773 *fixed_portion = 4; 4653 4774 break; 4654 4775 … … 4657 4778 SIVAL(pdata,0,0); /* No alignment needed. */ 4658 4779 data_size = 4; 4780 *fixed_portion = 4; 4659 4781 break; 4660 4782 … … 4695 4817 DEBUG(10, ("marshall_stream_info failed: %s\n", 4696 4818 nt_errstr(status))); 4819 TALLOC_FREE(streams); 4697 4820 return status; 4698 4821 } 4699 4822 4700 4823 TALLOC_FREE(streams); 4824 4825 *fixed_portion = 32; 4701 4826 4702 4827 break; … … 4709 4834 SIVAL(pdata,12,0); /* ??? */ 4710 4835 data_size = 16; 4836 *fixed_portion = 16; 4711 4837 break; 4712 4838 … … 4722 4848 SIVAL(pdata,52,0); /* ??? */ 4723 4849 data_size = 56; 4850 *fixed_portion = 56; 4724 4851 break; 4725 4852 … … 4729 4856 SIVAL(pdata,4,0); 4730 4857 data_size = 8; 4858 *fixed_portion = 8; 4731 4859 break; 4732 4860 … … 4998 5126 int lock_data_count = 0; 4999 5127 char *lock_data = NULL; 5128 size_t fixed_portion; 5000 5129 NTSTATUS status = NT_STATUS_OK; 5001 5130 … … 5359 5488 lock_data_count, lock_data, 5360 5489 req->flags2, max_data_bytes, 5490 &fixed_portion, 5361 5491 ppdata, &data_size); 5362 5492 if (!NT_STATUS_IS_OK(status)) { 5363 5493 reply_nterror(req, status); 5494 return; 5495 } 5496 if (fixed_portion > max_data_bytes) { 5497 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); 5364 5498 return; 5365 5499 } … … 7308 7442 create_disp = FILE_OPEN_IF; 7309 7443 break; 7444 case SMB_O_EXCL: 7445 /* O_EXCL on its own without O_CREAT is undefined. 7446 We deliberately ignore it as some versions of 7447 Linux CIFSFS can send a bare O_EXCL on the 7448 wire which other filesystems in the kernel 7449 ignore. See bug 9519 for details. */ 7450 7451 /* Fallthrough. */ 7452 7310 7453 case 0: 7311 7454 /* File exists open. File not exist fail. */ 7312 7455 create_disp = FILE_OPEN; 7313 7456 break; 7314 case SMB_O_EXCL:7315 /* O_EXCL on its own without O_CREAT is undefined. */7316 7457 default: 7317 7458 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n", … … 7566 7707 } 7567 7708 /* Fail with sharing violation. */ 7709 TALLOC_FREE(lck); 7568 7710 close_file(req, fsp, NORMAL_CLOSE); 7569 TALLOC_FREE(lck);7570 7711 return NT_STATUS_SHARING_VIOLATION; 7571 7712 } … … 7581 7722 smb_fname); 7582 7723 7724 TALLOC_FREE(lck); 7725 7583 7726 if (!NT_STATUS_IS_OK(status)) { 7584 7727 close_file(req, fsp, NORMAL_CLOSE); 7585 TALLOC_FREE(lck);7586 7728 return status; 7587 7729 } 7588 TALLOC_FREE(lck);7589 7730 return close_file(req, fsp, NORMAL_CLOSE); 7590 7731 }
Note:
See TracChangeset
for help on using the changeset viewer.