1/* 2 Unix SMB/CIFS implementation. 3 SMB transaction2 handling 4 Copyright (C) Jeremy Allison 1994-2003 5 Copyright (C) Stefan (metze) Metzmacher 2003 6 7 Extensively modified by Andrew Tridgell, 1995 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22*/ 23 24#include "includes.h" 25 26extern enum protocol_types Protocol; 27extern int smb_read_error; 28extern int global_oplock_break; 29extern uint32 global_client_caps; 30extern struct current_user current_user; 31 32/* Foxconn modified start pling 11/25/2009 */ 33//#define get_file_size(sbuf) ((sbuf).st_size) 34#define get_file_size(sbuf) get_file_size2(sbuf) 35static SMB_BIG_UINT get_file_size2(struct stat st) 36{ 37 SMB_BIG_UINT file_size_64; 38 SMB_BIG_UINT order; 39 40 /* Check whether file size > 4GB which exceeds 32-bit st->st_size 41 * st->sb_blocks in units of 512 bytes. 42 * If 'st->sb_blocks' x 512 > 4GB, then this file > 4GB. 43 */ 44 if (st.st_blocks >= 8388608L) 45 { 46 order = st.st_blocks / 8388608L; // order = # of 4GB 47 file_size_64 = 0x100000000 * order + (unsigned long)(st.st_size); 48 } 49 else 50 file_size_64 = st.st_size & 0xFFFFFFFF; 51 52 return file_size_64; 53} 54/* Foxconn modified end pling 11/25/2009 */ 55 56#define DIR_ENTRY_SAFETY_MARGIN 4096 57 58/******************************************************************** 59 Roundup a value to the nearest allocation roundup size boundary. 60 Only do this for Windows clients. 61********************************************************************/ 62 63SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val) 64{ 65 SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn)); 66 67 /* Only roundup for Windows clients. */ 68 enum remote_arch_types ra_type = get_remote_arch(); 69 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) { 70 val = SMB_ROUNDUP(val,rval); 71 } 72 return val; 73} 74 75/******************************************************************** 76 Given a stat buffer return the allocated size on disk, taking into 77 account sparse files. 78********************************************************************/ 79 80SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB_STRUCT_STAT *sbuf) 81{ 82 SMB_BIG_UINT ret; 83 84#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) 85 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks; 86#else 87 /* Foxconn modified start pling 11/25/2009 */ 88 /* Set the correct allocation size, even for large files */ 89 //ret = (SMB_BIG_UINT)get_file_size(*sbuf); 90 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks; 91 /* Foxconn modified start pling 11/25/2009 */ 92#endif 93 94 if (!ret && fsp && fsp->initial_allocation_size) 95 ret = fsp->initial_allocation_size; 96 97 return smb_roundup(conn, ret); 98} 99 100/**************************************************************************** 101 Utility functions for dealing with extended attributes. 102****************************************************************************/ 103 104static const char *prohibited_ea_names[] = { 105 SAMBA_POSIX_INHERITANCE_EA_NAME, 106 SAMBA_XATTR_DOS_ATTRIB, 107 NULL 108}; 109 110/**************************************************************************** 111 Refuse to allow clients to overwrite our private xattrs. 112****************************************************************************/ 113 114static BOOL samba_private_attr_name(const char *unix_ea_name) 115{ 116 int i; 117 118 for (i = 0; prohibited_ea_names[i]; i++) { 119 if (strequal( prohibited_ea_names[i], unix_ea_name)) 120 return True; 121 } 122 return False; 123} 124 125struct ea_list { 126 struct ea_list *next, *prev; 127 struct ea_struct ea; 128}; 129 130/**************************************************************************** 131 Get one EA value. Fill in a struct ea_struct. 132****************************************************************************/ 133 134static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, 135 const char *fname, char *ea_name, struct ea_struct *pea) 136{ 137 /* Get the value of this xattr. Max size is 64k. */ 138 size_t attr_size = 256; 139 char *val = NULL; 140 ssize_t sizeret; 141 142 again: 143 144 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size); 145 if (!val) { 146 return False; 147 } 148 149 if (fsp && fsp->fd != -1) { 150 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size); 151 } else { 152 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size); 153 } 154 155 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) { 156 attr_size = 65536; 157 goto again; 158 } 159 160 if (sizeret == -1) { 161 return False; 162 } 163 164 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret)); 165 dump_data(10, val, sizeret); 166 167 pea->flags = 0; 168 if (strnequal(ea_name, "user.", 5)) { 169 pea->name = &ea_name[5]; 170 } else { 171 pea->name = ea_name; 172 } 173 pea->value.data = (unsigned char *)val; 174 pea->value.length = (size_t)sizeret; 175 return True; 176} 177 178/**************************************************************************** 179 Return a linked list of the total EA's. Plus the total size 180****************************************************************************/ 181 182static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len) 183{ 184 /* Get a list of all xattrs. Max namesize is 64k. */ 185 size_t ea_namelist_size = 1024; 186 char *ea_namelist; 187 char *p; 188 ssize_t sizeret; 189 int i; 190 struct ea_list *ea_list_head = NULL; 191 192 *pea_total_len = 0; 193 194 if (!lp_ea_support(SNUM(conn))) { 195 return NULL; 196 } 197 198 for (i = 0, ea_namelist = TALLOC(mem_ctx, ea_namelist_size); i < 6; 199 ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) { 200 if (fsp && fsp->fd != -1) { 201 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size); 202 } else { 203 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size); 204 } 205 206 if (sizeret == -1 && errno == ERANGE) { 207 ea_namelist_size *= 2; 208 } else { 209 break; 210 } 211 } 212 213 if (sizeret == -1) 214 return NULL; 215 216 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret )); 217 218 if (sizeret) { 219 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) { 220 struct ea_list *listp, *tmp; 221 222 if (strnequal(p, "system.", 7) || samba_private_attr_name(p)) 223 continue; 224 225 listp = TALLOC_P(mem_ctx, struct ea_list); 226 if (!listp) 227 return NULL; 228 229 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) { 230 return NULL; 231 } 232 233 { 234 fstring dos_ea_name; 235 push_ascii_fstring(dos_ea_name, listp->ea.name); 236 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length; 237 DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n", 238 *pea_total_len, dos_ea_name, 239 (unsigned int)listp->ea.value.length )); 240 } 241 DLIST_ADD_END(ea_list_head, listp, tmp); 242 } 243 /* Add on 4 for total length. */ 244 if (*pea_total_len) { 245 *pea_total_len += 4; 246 } 247 } 248 249 DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len)); 250 return ea_list_head; 251} 252 253/**************************************************************************** 254 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer 255 that was filled. 256****************************************************************************/ 257 258static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size, 259 connection_struct *conn, files_struct *fsp, const char *fname) 260{ 261 unsigned int ret_data_size = 4; 262 char *p = pdata; 263 size_t total_ea_len; 264 TALLOC_CTX *mem_ctx; 265 struct ea_list *ea_list; 266 267 SMB_ASSERT(total_data_size >= 4); 268 269 SIVAL(pdata,0,0); 270 if (!lp_ea_support(SNUM(conn))) { 271 return 4; 272 } 273 mem_ctx = talloc_init("fill_ea_buffer"); 274 if (!mem_ctx) { 275 return 4; 276 } 277 278 ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len); 279 if (!ea_list) { 280 talloc_destroy(mem_ctx); 281 return 4; 282 } 283 284 if (total_ea_len > total_data_size) { 285 talloc_destroy(mem_ctx); 286 return 4; 287 } 288 289 for (p = pdata + 4; ea_list; ea_list = ea_list->next) { 290 size_t dos_namelen; 291 fstring dos_ea_name; 292 push_ascii_fstring(dos_ea_name, ea_list->ea.name); 293 dos_namelen = strlen(dos_ea_name); 294 if (dos_namelen > 255 || dos_namelen == 0) { 295 break; 296 } 297 if (ea_list->ea.value.length > 65535) { 298 break; 299 } 300 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) { 301 break; 302 } 303 304 /* We know we have room. */ 305 SCVAL(p,0,ea_list->ea.flags); 306 SCVAL(p,1,dos_namelen); 307 SSVAL(p,2,ea_list->ea.value.length); 308 fstrcpy(p+4, dos_ea_name); 309 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 310 311 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length; 312 p += 4 + dos_namelen + 1 + ea_list->ea.value.length; 313 } 314 315 ret_data_size = PTR_DIFF(p, pdata); 316 DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n", 317 ret_data_size, total_ea_len )); 318 talloc_destroy(mem_ctx); 319 SIVAL(pdata,0,ret_data_size); 320 return ret_data_size; 321} 322 323static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname) 324{ 325 size_t total_ea_len = 0; 326 TALLOC_CTX *mem_ctx = NULL; 327 328 if (!lp_ea_support(SNUM(conn))) { 329 return 0; 330 } 331 mem_ctx = talloc_init("estimate_ea_size"); 332 (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len); 333 talloc_destroy(mem_ctx); 334 return total_ea_len; 335} 336 337/**************************************************************************** 338 Ensure the EA name is case insensitive by matching any existing EA name. 339****************************************************************************/ 340 341static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name) 342{ 343 size_t total_ea_len; 344 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name"); 345 struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len); 346 347 for (; ea_list; ea_list = ea_list->next) { 348 if (strequal(&unix_ea_name[5], ea_list->ea.name)) { 349 DEBUG(10,("canonicalize_ea_name: %s -> %s\n", 350 &unix_ea_name[5], ea_list->ea.name)); 351 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6); 352 break; 353 } 354 } 355 talloc_destroy(mem_ctx); 356} 357 358/**************************************************************************** 359 Set or delete an extended attribute. 360****************************************************************************/ 361 362static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, 363 char *pdata, int total_data) 364{ 365 unsigned int namelen; 366 unsigned int ealen; 367 int ret; 368 fstring unix_ea_name; 369 370 if (!lp_ea_support(SNUM(conn))) { 371 return NT_STATUS_EAS_NOT_SUPPORTED; 372 } 373 374 if (total_data < 8) { 375 return NT_STATUS_INVALID_PARAMETER; 376 } 377 378 if (IVAL(pdata,0) > total_data) { 379 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data)); 380 return NT_STATUS_INVALID_PARAMETER; 381 } 382 383 pdata += 4; 384 namelen = CVAL(pdata,1); 385 ealen = SVAL(pdata,2); 386 pdata += 4; 387 if (total_data < 8 + namelen + 1 + ealen) { 388 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n", 389 (unsigned int)total_data, namelen, ealen)); 390 return NT_STATUS_INVALID_PARAMETER; 391 } 392 393 if (pdata[namelen] != '\0') { 394 DEBUG(10,("set_ea: ea name not null terminated\n")); 395 return NT_STATUS_INVALID_PARAMETER; 396 } 397 398 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */ 399 pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE); 400 pdata += (namelen + 1); 401 402 canonicalize_ea_name(conn, fsp, fname, unix_ea_name); 403 404 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen)); 405 if (ealen) { 406 DEBUG(10,("set_ea: data :\n")); 407 dump_data(10, pdata, ealen); 408 } 409 410 if (samba_private_attr_name(unix_ea_name)) { 411 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name)); 412 return NT_STATUS_ACCESS_DENIED; 413 } 414 415 if (ealen == 0) { 416 /* Remove the attribute. */ 417 if (fsp && (fsp->fd != -1)) { 418 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n", 419 unix_ea_name, fsp->fsp_name)); 420 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name); 421 } else { 422 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n", 423 unix_ea_name, fname)); 424 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name); 425 } 426#ifdef ENOATTR 427 /* Removing a non existent attribute always succeeds. */ 428 if (ret == -1 && errno == ENOATTR) { 429 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name)); 430 ret = 0; 431 } 432#endif 433 } else { 434 if (fsp && (fsp->fd != -1)) { 435 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n", 436 unix_ea_name, fsp->fsp_name)); 437 ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0); 438 } else { 439 DEBUG(10,("set_ea: setting ea name %s on file %s.\n", 440 unix_ea_name, fname)); 441 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0); 442 } 443 } 444 445 if (ret == -1) { 446#ifdef ENOTSUP 447 if (errno == ENOTSUP) { 448 return NT_STATUS_EAS_NOT_SUPPORTED; 449 } 450#endif 451 return map_nt_error_from_unix(errno); 452 } 453 454 return NT_STATUS_OK; 455} 456 457/**************************************************************************** 458 Send the required number of replies back. 459 We assume all fields other than the data fields are 460 set correctly for the type of call. 461 HACK ! Always assumes smb_setup field is zero. 462****************************************************************************/ 463 464static int send_trans2_replies(char *outbuf, 465 int bufsize, 466 char *params, 467 int paramsize, 468 char *pdata, 469 int datasize) 470{ 471 /* As we are using a protocol > LANMAN1 then the max_send 472 variable must have been set in the sessetupX call. 473 This takes precedence over the max_xmit field in the 474 global struct. These different max_xmit variables should 475 be merged as this is now too confusing */ 476 477 extern int max_send; 478 int data_to_send = datasize; 479 int params_to_send = paramsize; 480 int useable_space; 481 char *pp = params; 482 char *pd = pdata; 483 int params_sent_thistime, data_sent_thistime, total_sent_thistime; 484 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */ 485 int data_alignment_offset = 0; 486 487 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */ 488 489 set_message(outbuf,10,0,True); 490 491 /* If there genuinely are no parameters or data to send just send the empty packet */ 492 493 if(params_to_send == 0 && data_to_send == 0) { 494 if (!send_smb(smbd_server_fd(),outbuf)) 495 exit_server("send_trans2_replies: send_smb failed."); 496 return 0; 497 } 498 499 /* When sending params and data ensure that both are nicely aligned */ 500 /* Only do this alignment when there is also data to send - else 501 can cause NT redirector problems. */ 502 503 if (((params_to_send % 4) != 0) && (data_to_send != 0)) 504 data_alignment_offset = 4 - (params_to_send % 4); 505 506 /* Space is bufsize minus Netbios over TCP header minus SMB header */ 507 /* The alignment_offset is to align the param bytes on an even byte 508 boundary. NT 4.0 Beta needs this to work correctly. */ 509 510 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf); 511 512 /* useable_space can never be more than max_send minus the alignment offset. */ 513 514 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset)); 515 516 while (params_to_send || data_to_send) { 517 /* Calculate whether we will totally or partially fill this packet */ 518 519 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset; 520 521 /* We can never send more than useable_space */ 522 /* 523 * Note that 'useable_space' does not include the alignment offsets, 524 * but we must include the alignment offsets in the calculation of 525 * the length of the data we send over the wire, as the alignment offsets 526 * are sent here. Fix from Marc_Jacobsen@hp.com. 527 */ 528 529 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset); 530 531 set_message(outbuf, 10, total_sent_thistime, True); 532 533 /* Set total params and data to be sent */ 534 SSVAL(outbuf,smb_tprcnt,paramsize); 535 SSVAL(outbuf,smb_tdrcnt,datasize); 536 537 /* Calculate how many parameters and data we can fit into 538 * this packet. Parameters get precedence 539 */ 540 541 params_sent_thistime = MIN(params_to_send,useable_space); 542 data_sent_thistime = useable_space - params_sent_thistime; 543 data_sent_thistime = MIN(data_sent_thistime,data_to_send); 544 545 SSVAL(outbuf,smb_prcnt, params_sent_thistime); 546 547 /* smb_proff is the offset from the start of the SMB header to the 548 parameter bytes, however the first 4 bytes of outbuf are 549 the Netbios over TCP header. Thus use smb_base() to subtract 550 them from the calculation */ 551 552 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf))); 553 554 if(params_sent_thistime == 0) 555 SSVAL(outbuf,smb_prdisp,0); 556 else 557 /* Absolute displacement of param bytes sent in this packet */ 558 SSVAL(outbuf,smb_prdisp,pp - params); 559 560 SSVAL(outbuf,smb_drcnt, data_sent_thistime); 561 if(data_sent_thistime == 0) { 562 SSVAL(outbuf,smb_droff,0); 563 SSVAL(outbuf,smb_drdisp, 0); 564 } else { 565 /* The offset of the data bytes is the offset of the 566 parameter bytes plus the number of parameters being sent this time */ 567 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - 568 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset); 569 SSVAL(outbuf,smb_drdisp, pd - pdata); 570 } 571 572 /* Copy the param bytes into the packet */ 573 574 if(params_sent_thistime) 575 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime); 576 577 /* Copy in the data bytes */ 578 if(data_sent_thistime) 579 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+ 580 data_alignment_offset,pd,data_sent_thistime); 581 582 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n", 583 params_sent_thistime, data_sent_thistime, useable_space)); 584 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n", 585 params_to_send, data_to_send, paramsize, datasize)); 586 587 /* Send the packet */ 588 if (!send_smb(smbd_server_fd(),outbuf)) 589 exit_server("send_trans2_replies: send_smb failed."); 590 591 pp += params_sent_thistime; 592 pd += data_sent_thistime; 593 594 params_to_send -= params_sent_thistime; 595 data_to_send -= data_sent_thistime; 596 597 /* Sanity check */ 598 if(params_to_send < 0 || data_to_send < 0) { 599 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!", 600 params_to_send, data_to_send)); 601 return -1; 602 } 603 } 604 605 return 0; 606} 607 608/**************************************************************************** 609 Reply to a TRANSACT2_OPEN. 610****************************************************************************/ 611 612static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize, 613 char **pparams, int total_params, char **ppdata, int total_data, 614 unsigned int max_data_bytes) 615{ 616 char *params = *pparams; 617 int16 open_mode; 618 int16 open_attr; 619 BOOL oplock_request; 620#if 0 621 BOOL return_additional_info; 622 int16 open_sattr; 623 time_t open_time; 624#endif 625 int16 open_ofun; 626 int32 open_size; 627 char *pname; 628 pstring fname; 629 SMB_OFF_T size=0; 630 int fmode=0,mtime=0,rmode; 631 SMB_INO_T inode = 0; 632 SMB_STRUCT_STAT sbuf; 633 int smb_action = 0; 634 BOOL bad_path = False; 635 files_struct *fsp; 636 NTSTATUS status; 637 638 /* 639 * Ensure we have enough parameters to perform the operation. 640 */ 641 642 if (total_params < 29) 643 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 644 645 open_mode = SVAL(params, 2); 646 open_attr = SVAL(params,6); 647 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1)); 648#if 0 649 return_additional_info = BITSETW(params,0); 650 open_sattr = SVAL(params, 4); 651 open_time = make_unix_date3(params+8); 652#endif 653 open_ofun = SVAL(params,12); 654 open_size = IVAL(params,14); 655 pname = ¶ms[28]; 656 657 if (IS_IPC(conn)) 658 return(ERROR_DOS(ERRSRV,ERRaccess)); 659 660 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False); 661 if (!NT_STATUS_IS_OK(status)) { 662 return ERROR_NT(status); 663 } 664 665 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n", 666 fname,open_mode, open_attr, open_ofun, open_size)); 667 668 /* XXXX we need to handle passed times, sattr and flags */ 669 670 unix_convert(fname,conn,0,&bad_path,&sbuf); 671 if (bad_path) { 672 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 673 } 674 675 if (!check_name(fname,conn)) { 676 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); 677 } 678 679 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr, 680 oplock_request, &rmode,&smb_action); 681 682 if (!fsp) { 683 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 684 /* We have re-scheduled this call. */ 685 clear_cached_errors(); 686 return -1; 687 } 688 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); 689 } 690 691 size = get_file_size(sbuf); 692 fmode = dos_mode(conn,fname,&sbuf); 693 mtime = sbuf.st_mtime; 694 inode = sbuf.st_ino; 695 if (fmode & aDIR) { 696 close_file(fsp,False); 697 return(ERROR_DOS(ERRDOS,ERRnoaccess)); 698 } 699 700 /* Realloc the size of parameters and data we will return */ 701 params = SMB_REALLOC(*pparams, 28); 702 if( params == NULL ) 703 return(ERROR_DOS(ERRDOS,ERRnomem)); 704 *pparams = params; 705 706 memset((char *)params,'\0',28); 707 SSVAL(params,0,fsp->fnum); 708 SSVAL(params,2,fmode); 709 put_dos_date2(params,4, mtime); 710 SIVAL(params,8, (uint32)size); 711 SSVAL(params,12,rmode); 712 713 if (oplock_request && lp_fake_oplocks(SNUM(conn))) 714 smb_action |= EXTENDED_OPLOCK_GRANTED; 715 716 SSVAL(params,18,smb_action); 717 718 /* 719 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes. 720 */ 721 SIVAL(params,20,inode); 722 723 /* Send the required number of replies */ 724 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0); 725 726 return -1; 727} 728 729/********************************************************* 730 Routine to check if a given string matches exactly. 731 as a special case a mask of "." does NOT match. That 732 is required for correct wildcard semantics 733 Case can be significant or not. 734**********************************************************/ 735 736static BOOL exact_match(char *str,char *mask, BOOL case_sig) 737{ 738 if (mask[0] == '.' && mask[1] == 0) 739 return False; 740 if (case_sig) 741 return strcmp(str,mask)==0; 742 if (StrCaseCmp(str,mask) != 0) { 743 return False; 744 } 745 if (ms_has_wild(str)) { 746 return False; 747 } 748 return True; 749} 750 751/**************************************************************************** 752 Return the filetype for UNIX extensions. 753****************************************************************************/ 754 755static uint32 unix_filetype(mode_t mode) 756{ 757 if(S_ISREG(mode)) 758 return UNIX_TYPE_FILE; 759 else if(S_ISDIR(mode)) 760 return UNIX_TYPE_DIR; 761#ifdef S_ISLNK 762 else if(S_ISLNK(mode)) 763 return UNIX_TYPE_SYMLINK; 764#endif 765#ifdef S_ISCHR 766 else if(S_ISCHR(mode)) 767 return UNIX_TYPE_CHARDEV; 768#endif 769#ifdef S_ISBLK 770 else if(S_ISBLK(mode)) 771 return UNIX_TYPE_BLKDEV; 772#endif 773#ifdef S_ISFIFO 774 else if(S_ISFIFO(mode)) 775 return UNIX_TYPE_FIFO; 776#endif 777#ifdef S_ISSOCK 778 else if(S_ISSOCK(mode)) 779 return UNIX_TYPE_SOCKET; 780#endif 781 782 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode)); 783 return UNIX_TYPE_UNKNOWN; 784} 785 786/**************************************************************************** 787 Map wire perms onto standard UNIX permissions. Obey share restrictions. 788****************************************************************************/ 789 790static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms) 791{ 792 mode_t ret = 0; 793 794 if (perms == SMB_MODE_NO_CHANGE) 795 return pst->st_mode; 796 797 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0); 798 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0); 799 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0); 800 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0); 801 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0); 802 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0); 803 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0); 804 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0); 805 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0); 806#ifdef S_ISVTX 807 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0); 808#endif 809#ifdef S_ISGID 810 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0); 811#endif 812#ifdef S_ISUID 813 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0); 814#endif 815 816 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) { 817 ret &= lp_dir_mask(SNUM(conn)); 818 /* Add in force bits */ 819 ret |= lp_force_dir_mode(SNUM(conn)); 820 } else { 821 /* Apply mode mask */ 822 ret &= lp_create_mask(SNUM(conn)); 823 /* Add in force bits */ 824 ret |= lp_force_create_mode(SNUM(conn)); 825 } 826 827 return ret; 828} 829 830/**************************************************************************** 831 Get a level dependent lanman2 dir entry. 832****************************************************************************/ 833 834static BOOL get_lanman2_dir_entry(connection_struct *conn, 835 void *inbuf, void *outbuf, 836 char *path_mask,int dirtype,int info_level, 837 int requires_resume_key, 838 BOOL dont_descend,char **ppdata, 839 char *base_data, int space_remaining, 840 BOOL *out_of_space, BOOL *got_exact_match, 841 int *last_entry_off) 842{ 843 const char *dname; 844 BOOL found = False; 845 SMB_STRUCT_STAT sbuf; 846 pstring mask; 847 pstring pathreal; 848 pstring fname; 849 char *p, *q, *pdata = *ppdata; 850 uint32 reskey=0; 851 long prev_dirpos=0; 852 int mode=0; 853 /* Foxconn modified start pling 11/23/2009 */ 854 //SMB_OFF_T file_size = 0; 855 SMB_BIG_UINT file_size = 0; 856 /* Foxconn modified start pling 11/23/2009 */ 857 SMB_BIG_UINT allocation_size = 0; 858 uint32 len; 859 time_t mdate=0, adate=0, cdate=0; 860 char *nameptr; 861 char *last_entry_ptr; 862 BOOL was_8_3; 863 int nt_extmode; /* Used for NT connections instead of mode */ 864 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); 865 866 *fname = 0; 867 *out_of_space = False; 868 *got_exact_match = False; 869 870 if (!conn->dirptr) 871 return(False); 872 873 p = strrchr_m(path_mask,'/'); 874 if(p != NULL) { 875 if(p[1] == '\0') 876 pstrcpy(mask,"*.*"); 877 else 878 pstrcpy(mask, p+1); 879 } else 880 pstrcpy(mask, path_mask); 881 882 883 while (!found) { 884 BOOL got_match; 885 /* Needed if we run out of space */ 886 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr); 887 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf); 888 889 /* 890 * Due to bugs in NT client redirectors we are not using 891 * resume keys any more - set them to zero. 892 * Check out the related comments in findfirst/findnext. 893 * JRA. 894 */ 895 896 reskey = 0; 897 898 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n", 899 (long)conn->dirptr,curr_dirpos)); 900 901 if (!dname) 902 return(False); 903 904 pstrcpy(fname,dname); 905 906 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive))) 907 got_match = mask_match(fname, mask, conn->case_sensitive); 908 909 if(!got_match && !mangle_is_8_3(fname, False)) { 910 911 /* 912 * It turns out that NT matches wildcards against 913 * both long *and* short names. This may explain some 914 * of the wildcard wierdness from old DOS clients 915 * that some people have been seeing.... JRA. 916 */ 917 918 pstring newname; 919 pstrcpy( newname, fname); 920 mangle_map( newname, True, False, SNUM(conn)); 921 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive))) 922 got_match = mask_match(newname, mask, conn->case_sensitive); 923 } 924 925 if(got_match) { 926 BOOL isdots = (strequal(fname,"..") || strequal(fname,".")); 927 if (dont_descend && !isdots) 928 continue; 929 930 pstrcpy(pathreal,conn->dirpath); 931 if(needslash) 932 pstrcat(pathreal,"/"); 933 pstrcat(pathreal,dname); 934 935 if (INFO_LEVEL_IS_UNIX(info_level)) { 936 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) { 937 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n", 938 pathreal,strerror(errno))); 939 continue; 940 } 941 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) { 942 943 /* Needed to show the msdfs symlinks as 944 * directories */ 945 946 if(lp_host_msdfs() && 947 lp_msdfs_root(SNUM(conn)) && 948 is_msdfs_link(conn, pathreal, NULL, NULL, 949 &sbuf)) { 950 951 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal)); 952 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR; 953 954 } else { 955 956 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n", 957 pathreal,strerror(errno))); 958 continue; 959 } 960 } 961 962 mode = dos_mode(conn,pathreal,&sbuf); 963 964 if (!dir_check_ftype(conn,mode,dirtype)) { 965 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype)); 966 continue; 967 } 968 969 file_size = get_file_size(sbuf); 970 allocation_size = get_allocation_size(conn,NULL,&sbuf); 971 mdate = sbuf.st_mtime; 972 adate = sbuf.st_atime; 973 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); 974 975 if (lp_dos_filetime_resolution(SNUM(conn))) { 976 cdate &= ~1; 977 mdate &= ~1; 978 adate &= ~1; 979 } 980 981 if(mode & aDIR) { 982 /* This is necessary, as otherwise the 983 * desktop.ini file in this folder is 984 * ignored */ 985 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0); 986 file_size = 0; 987 } 988 989 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname)); 990 991 found = True; 992 } 993 } 994 995 mangle_map(fname,False,True,SNUM(conn)); 996 997 p = pdata; 998 last_entry_ptr = p; 999 1000 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL; 1001 1002 switch (info_level) { 1003 case SMB_INFO_STANDARD: 1004 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n")); 1005 if(requires_resume_key) { 1006 SIVAL(p,0,reskey); 1007 p += 4; 1008 } 1009 put_dos_date2(p,l1_fdateCreation,cdate); 1010 put_dos_date2(p,l1_fdateLastAccess,adate); 1011 put_dos_date2(p,l1_fdateLastWrite,mdate); 1012 SIVAL(p,l1_cbFile,(uint32)file_size); 1013 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size); 1014 SSVAL(p,l1_attrFile,mode); 1015 p += l1_achName; 1016 nameptr = p; 1017 p += align_string(outbuf, p, 0); 1018 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE); 1019 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { 1020 if (len > 2) { 1021 SCVAL(nameptr, -1, len - 2); 1022 } else { 1023 SCVAL(nameptr, -1, 0); 1024 } 1025 } else { 1026 if (len > 1) { 1027 SCVAL(nameptr, -1, len - 1); 1028 } else { 1029 SCVAL(nameptr, -1, 0); 1030 } 1031 } 1032 p += len; 1033 break; 1034 1035 case SMB_INFO_QUERY_EA_SIZE: 1036 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n")); 1037 if(requires_resume_key) { 1038 SIVAL(p,0,reskey); 1039 p += 4; 1040 } 1041 put_dos_date2(p,l2_fdateCreation,cdate); 1042 put_dos_date2(p,l2_fdateLastAccess,adate); 1043 put_dos_date2(p,l2_fdateLastWrite,mdate); 1044 SIVAL(p,l2_cbFile,(uint32)file_size); 1045 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size); 1046 SSVAL(p,l2_attrFile,mode); 1047 { 1048 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 1049 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */ 1050 } 1051 p += l2_achName; 1052 nameptr = p - 1; 1053 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN); 1054 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { 1055 if (len > 2) { 1056 len -= 2; 1057 } else { 1058 len = 0; 1059 } 1060 } else { 1061 if (len > 1) { 1062 len -= 1; 1063 } else { 1064 len = 0; 1065 } 1066 } 1067 SCVAL(nameptr,0,len); 1068 p += len; 1069 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */ 1070 break; 1071 1072 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 1073 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n")); 1074 was_8_3 = mangle_is_8_3(fname, True); 1075 p += 4; 1076 SIVAL(p,0,reskey); p += 4; 1077 put_long_date(p,cdate); p += 8; 1078 put_long_date(p,adate); p += 8; 1079 put_long_date(p,mdate); p += 8; 1080 put_long_date(p,mdate); p += 8; 1081 /* Foxconn modified start pling 11/23/2009 */ 1082 //SOFF_T(p,0,file_size); p += 8; 1083 SOFF64_T(p,0,file_size); p += 8; 1084 /* Foxconn modified end pling 11/23/2009 */ 1085 /* Foxconn modified start pling 03/11/2011 */ 1086 /* Fix potential incorrect file size issue where file size > 4GB. */ 1087 /* SOFF_T(p,0,allocation_size); p += 8; */ 1088 SOFF64_T(p,0,allocation_size); p += 8; 1089 /* Foxconn modified end pling 03/11/2011 */ 1090 SIVAL(p,0,nt_extmode); p += 4; 1091 q = p; p += 4; /* q is placeholder for name length. */ 1092 { 1093 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 1094 SIVAL(p,0,ea_size); /* Extended attributes */ 1095 p += 4; 1096 } 1097 /* Clear the short name buffer. This is 1098 * IMPORTANT as not doing so will trigger 1099 * a Win2k client bug. JRA. 1100 */ 1101 memset(p,'\0',26); 1102 if (!was_8_3 && lp_manglednames(SNUM(conn))) { 1103 pstring mangled_name; 1104 pstrcpy(mangled_name, fname); 1105 mangle_map(mangled_name,True,True,SNUM(conn)); 1106 mangled_name[12] = 0; 1107 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); 1108 SSVAL(p, 0, len); 1109 } else { 1110 SSVAL(p,0,0); 1111 *(p+2) = 0; 1112 } 1113 p += 2 + 24; 1114 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); 1115 SIVAL(q,0,len); 1116 p += len; 1117 len = PTR_DIFF(p, pdata); 1118 len = (len + 3) & ~3; 1119 SIVAL(pdata,0,len); 1120 p = pdata + len; 1121 break; 1122 1123 case SMB_FIND_FILE_DIRECTORY_INFO: 1124 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n")); 1125 p += 4; 1126 SIVAL(p,0,reskey); p += 4; 1127 put_long_date(p,cdate); p += 8; 1128 put_long_date(p,adate); p += 8; 1129 put_long_date(p,mdate); p += 8; 1130 put_long_date(p,mdate); p += 8; 1131 /* Foxconn modified start pling 03/11/2011 */ 1132 /* Fix potential incorrect file size issue if file size > 4GB. */ 1133#if 0 1134 SOFF_T(p,0,file_size); p += 8; 1135 SOFF_T(p,0,allocation_size); p += 8; 1136#endif 1137 SOFF64_T(p,0,file_size); p += 8; 1138 SOFF64_T(p,0,allocation_size); p += 8; 1139 /* Foxconn modified end pling 03/11/2011 */ 1140 SIVAL(p,0,nt_extmode); p += 4; 1141 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII); 1142 SIVAL(p,0,len); 1143 p += 4 + len; 1144 len = PTR_DIFF(p, pdata); 1145 len = (len + 3) & ~3; 1146 SIVAL(pdata,0,len); 1147 p = pdata + len; 1148 break; 1149 1150 case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 1151 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n")); 1152 p += 4; 1153 SIVAL(p,0,reskey); p += 4; 1154 put_long_date(p,cdate); p += 8; 1155 put_long_date(p,adate); p += 8; 1156 put_long_date(p,mdate); p += 8; 1157 put_long_date(p,mdate); p += 8; 1158 /* Foxconn modified start pling 03/11/2011 */ 1159 /* Fix Win7 DOS prompt can't get correct file size > 4GB */ 1160#if 0 1161 SOFF_T(p,0,file_size); p += 8; 1162 SOFF_T(p,0,allocation_size); p += 8; 1163#endif 1164 SOFF64_T(p,0,file_size); p += 8; 1165 SOFF64_T(p,0,allocation_size); p += 8; 1166 /* Foxconn modified end pling 03/11/2011 */ 1167 SIVAL(p,0,nt_extmode); p += 4; 1168 q = p; p += 4; /* q is placeholder for name length. */ 1169 { 1170 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 1171 SIVAL(p,0,ea_size); /* Extended attributes */ 1172 p +=4; 1173 } 1174 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); 1175 SIVAL(q, 0, len); 1176 p += len; 1177 1178 len = PTR_DIFF(p, pdata); 1179 len = (len + 3) & ~3; 1180 SIVAL(pdata,0,len); 1181 p = pdata + len; 1182 break; 1183 1184 case SMB_FIND_FILE_NAMES_INFO: 1185 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n")); 1186 p += 4; 1187 SIVAL(p,0,reskey); p += 4; 1188 p += 4; 1189 /* this must *not* be null terminated or w2k gets in a loop trying to set an 1190 acl on a dir (tridge) */ 1191 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); 1192 SIVAL(p, -4, len); 1193 p += len; 1194 len = PTR_DIFF(p, pdata); 1195 len = (len + 3) & ~3; 1196 SIVAL(pdata,0,len); 1197 p = pdata + len; 1198 break; 1199 1200 case SMB_FIND_ID_FULL_DIRECTORY_INFO: 1201 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n")); 1202 p += 4; 1203 SIVAL(p,0,reskey); p += 4; 1204 put_long_date(p,cdate); p += 8; 1205 put_long_date(p,adate); p += 8; 1206 put_long_date(p,mdate); p += 8; 1207 put_long_date(p,mdate); p += 8; 1208 /* Foxconn modified start pling 03/11/2011 */ 1209 /* Fix potential incorrect file size issue if file size > 4GB. */ 1210#if 0 1211 SOFF_T(p,0,file_size); p += 8; 1212 SOFF_T(p,0,allocation_size); p += 8; 1213#endif 1214 SOFF64_T(p,0,file_size); p += 8; 1215 SOFF64_T(p,0,allocation_size); p += 8; 1216 /* Foxconn modified end pling 03/11/2011 */ 1217 SIVAL(p,0,nt_extmode); p += 4; 1218 q = p; p += 4; /* q is placeholder for name length. */ 1219 { 1220 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 1221 SIVAL(p,0,ea_size); /* Extended attributes */ 1222 p +=4; 1223 } 1224 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */ 1225 SIVAL(p,0,sbuf.st_dev); p += 4; 1226 SIVAL(p,0,sbuf.st_ino); p += 4; 1227 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); 1228 SIVAL(q, 0, len); 1229 p += len; 1230 len = PTR_DIFF(p, pdata); 1231 len = (len + 3) & ~3; 1232 SIVAL(pdata,0,len); 1233 p = pdata + len; 1234 break; 1235 1236 case SMB_FIND_ID_BOTH_DIRECTORY_INFO: 1237 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n")); 1238 was_8_3 = mangle_is_8_3(fname, True); 1239 p += 4; 1240 SIVAL(p,0,reskey); p += 4; 1241 put_long_date(p,cdate); p += 8; 1242 put_long_date(p,adate); p += 8; 1243 put_long_date(p,mdate); p += 8; 1244 put_long_date(p,mdate); p += 8; 1245 /* Foxconn modified start pling 03/11/2011 */ 1246 /* Fix potential incorrect file size issue if file size > 4GB. */ 1247#if 0 1248 SOFF_T(p,0,file_size); p += 8; 1249 SOFF_T(p,0,allocation_size); p += 8; 1250#endif 1251 SOFF64_T(p,0,file_size); p += 8; 1252 SOFF64_T(p,0,allocation_size); p += 8; 1253 /* Foxconn modified end pling 03/11/2011 */ 1254 SIVAL(p,0,nt_extmode); p += 4; 1255 q = p; p += 4; /* q is placeholder for name length */ 1256 { 1257 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 1258 SIVAL(p,0,ea_size); /* Extended attributes */ 1259 p +=4; 1260 } 1261 /* Clear the short name buffer. This is 1262 * IMPORTANT as not doing so will trigger 1263 * a Win2k client bug. JRA. 1264 */ 1265 memset(p,'\0',26); 1266 if (!was_8_3 && lp_manglednames(SNUM(conn))) { 1267 pstring mangled_name; 1268 pstrcpy(mangled_name, fname); 1269 mangle_map(mangled_name,True,True,SNUM(conn)); 1270 mangled_name[12] = 0; 1271 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); 1272 SSVAL(p, 0, len); 1273 } else { 1274 SSVAL(p,0,0); 1275 *(p+2) = 0; 1276 } 1277 p += 26; 1278 SSVAL(p,0,0); p += 2; /* Reserved ? */ 1279 SIVAL(p,0,sbuf.st_dev); p += 4; 1280 SIVAL(p,0,sbuf.st_ino); p += 4; 1281 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII); 1282 SIVAL(q,0,len); 1283 p += len; 1284 len = PTR_DIFF(p, pdata); 1285 len = (len + 3) & ~3; 1286 SIVAL(pdata,0,len); 1287 p = pdata + len; 1288 break; 1289 1290 /* CIFS UNIX Extension. */ 1291 1292 case SMB_FIND_FILE_UNIX: 1293 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n")); 1294 p+= 4; 1295 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */ 1296 1297 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */ 1298 /* Foxconn modified start pling 03/11/2011 */ 1299 /* Fix potential incorrect file size issue if file size > 4GB */ 1300 /* SOFF_T(p,0,get_file_size(sbuf)); */ /* File size 64 Bit */ 1301 SOFF64_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */ 1302 /* Foxconn modified end pling 03/11/2011 */ 1303 p+= 8; 1304 1305 /* Foxconn modified start pling 03/11/2011 */ 1306 /* Fix potential incorrect file size issue if file size > 4GB */ 1307 /* SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); */ /* Number of bytes used on disk - 64 Bit */ 1308 SOFF64_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */ 1309 /* Foxconn modified end pling 03/11/2011 */ 1310 p+= 8; 1311 1312 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */ 1313 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */ 1314 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */ 1315 p+= 24; 1316 1317 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */ 1318 SIVAL(p,4,0); 1319 p+= 8; 1320 1321 SIVAL(p,0,sbuf.st_gid); /* group id of owner */ 1322 SIVAL(p,4,0); 1323 p+= 8; 1324 1325 SIVAL(p,0,unix_filetype(sbuf.st_mode)); 1326 p+= 4; 1327 1328 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */ 1329 SIVAL(p,4,0); 1330 p+= 8; 1331 1332 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */ 1333 SIVAL(p,4,0); 1334 p+= 8; 1335 1336 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */ 1337 p+= 8; 1338 1339 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */ 1340 SIVAL(p,4,0); 1341 p+= 8; 1342 1343 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */ 1344 SIVAL(p,4,0); 1345 p+= 8; 1346 1347 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE); 1348 p += len; 1349 1350 len = PTR_DIFF(p, pdata); 1351 len = (len + 3) & ~3; 1352 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */ 1353 p = pdata + len; 1354 /* End of SMB_QUERY_FILE_UNIX_BASIC */ 1355 1356 break; 1357 1358 default: 1359 return(False); 1360 } 1361 1362 1363 if (PTR_DIFF(p,pdata) > space_remaining) { 1364 /* Move the dirptr back to prev_dirpos */ 1365 dptr_SeekDir(conn->dirptr, prev_dirpos); 1366 *out_of_space = True; 1367 DEBUG(9,("get_lanman2_dir_entry: out of space\n")); 1368 return False; /* Not finished - just out of space */ 1369 } 1370 1371 /* Setup the last entry pointer, as an offset from base_data */ 1372 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data); 1373 /* Advance the data pointer to the next slot */ 1374 *ppdata = p; 1375 1376 return(found); 1377} 1378 1379/**************************************************************************** 1380 Reply to a TRANS2_FINDFIRST. 1381****************************************************************************/ 1382 1383static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize, 1384 char **pparams, int total_params, char **ppdata, int total_data, 1385 unsigned int max_data_bytes) 1386{ 1387 /* We must be careful here that we don't return more than the 1388 allowed number of data bytes. If this means returning fewer than 1389 maxentries then so be it. We assume that the redirector has 1390 enough room for the fixed number of parameter bytes it has 1391 requested. */ 1392 char *params = *pparams; 1393 char *pdata = *ppdata; 1394 int dirtype = SVAL(params,0); 1395 int maxentries = SVAL(params,2); 1396 uint16 findfirst_flags = SVAL(params,4); 1397 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE); 1398 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END); 1399 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME); 1400 int info_level = SVAL(params,6); 1401 pstring directory; 1402 pstring mask; 1403 char *p; 1404 int last_entry_off=0; 1405 int dptr_num = -1; 1406 int numentries = 0; 1407 int i; 1408 BOOL finished = False; 1409 BOOL dont_descend = False; 1410 BOOL out_of_space = False; 1411 int space_remaining; 1412 BOOL bad_path = False; 1413 SMB_STRUCT_STAT sbuf; 1414 NTSTATUS ntstatus = NT_STATUS_OK; 1415 1416 if (total_params < 12) 1417 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 1418 1419 *directory = *mask = 0; 1420 1421 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \ 1422close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", 1423 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key, 1424 info_level, max_data_bytes)); 1425 1426 if (!maxentries) { 1427 /* W2K3 seems to treat zero as 1. */ 1428 maxentries = 1; 1429 } 1430 1431 switch (info_level) { 1432 case SMB_INFO_STANDARD: 1433 case SMB_INFO_QUERY_EA_SIZE: 1434 case SMB_FIND_FILE_DIRECTORY_INFO: 1435 case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 1436 case SMB_FIND_FILE_NAMES_INFO: 1437 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 1438 case SMB_FIND_ID_FULL_DIRECTORY_INFO: 1439 case SMB_FIND_ID_BOTH_DIRECTORY_INFO: 1440 break; 1441 case SMB_FIND_FILE_UNIX: 1442 if (!lp_unix_extensions()) 1443 return(ERROR_DOS(ERRDOS,ERRunknownlevel)); 1444 break; 1445 default: 1446 return(ERROR_DOS(ERRDOS,ERRunknownlevel)); 1447 } 1448 1449 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True); 1450 if (!NT_STATUS_IS_OK(ntstatus)) { 1451 return ERROR_NT(ntstatus); 1452 } 1453 1454 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf); 1455 1456 unix_convert(directory,conn,0,&bad_path,&sbuf); 1457 if (bad_path) { 1458 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 1459 } 1460 if(!check_name(directory,conn)) { 1461 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 1462 } 1463 1464 p = strrchr_m(directory,'/'); 1465 if(p == NULL) { 1466 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */ 1467 if((directory[0] == '.') && (directory[1] == '\0')) 1468 pstrcpy(mask,"*"); 1469 else 1470 pstrcpy(mask,directory); 1471 pstrcpy(directory,"./"); 1472 } else { 1473 pstrcpy(mask,p+1); 1474 *p = 0; 1475 } 1476 1477 DEBUG(5,("dir=%s, mask = %s\n",directory, mask)); 1478 1479 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 1480 if( pdata == NULL ) 1481 return(ERROR_DOS(ERRDOS,ERRnomem)); 1482 1483 *ppdata = pdata; 1484 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 1485 1486 /* Realloc the params space */ 1487 params = SMB_REALLOC(*pparams, 10); 1488 if (params == NULL) 1489 return ERROR_DOS(ERRDOS,ERRnomem); 1490 *pparams = params; 1491 1492 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid)); 1493 if (dptr_num < 0) 1494 return(UNIXERROR(ERRDOS,ERRbadfile)); 1495 1496 /* Save the wildcard match and attribs we are using on this directory - 1497 needed as lanman2 assumes these are being saved between calls */ 1498 1499 if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) { 1500 dptr_close(&dptr_num); 1501 return ERROR_DOS(ERRDOS,ERRnomem); 1502 } 1503 1504 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype)); 1505 1506 /* We don't need to check for VOL here as this is returned by 1507 a different TRANS2 call. */ 1508 1509 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn)))); 1510 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive)) 1511 dont_descend = True; 1512 1513 p = pdata; 1514 space_remaining = max_data_bytes; 1515 out_of_space = False; 1516 1517 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) { 1518 BOOL got_exact_match = False; 1519 1520 /* this is a heuristic to avoid seeking the dirptr except when 1521 absolutely necessary. It allows for a filename of about 40 chars */ 1522 if (space_remaining < DIRLEN_GUESS && numentries > 0) { 1523 out_of_space = True; 1524 finished = False; 1525 } else { 1526 finished = !get_lanman2_dir_entry(conn, 1527 inbuf, outbuf, 1528 mask,dirtype,info_level, 1529 requires_resume_key,dont_descend, 1530 &p,pdata,space_remaining, &out_of_space, &got_exact_match, 1531 &last_entry_off); 1532 } 1533 1534 if (finished && out_of_space) 1535 finished = False; 1536 1537 if (!finished && !out_of_space) 1538 numentries++; 1539 1540 /* 1541 * As an optimisation if we know we aren't looking 1542 * for a wildcard name (ie. the name matches the wildcard exactly) 1543 * then we can finish on any (first) match. 1544 * This speeds up large directory searches. JRA. 1545 */ 1546 1547 if(got_exact_match) 1548 finished = True; 1549 1550 space_remaining = max_data_bytes - PTR_DIFF(p,pdata); 1551 } 1552 1553 /* Check if we can close the dirptr */ 1554 if(close_after_first || (finished && close_if_end)) { 1555 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num)); 1556 dptr_close(&dptr_num); 1557 } 1558 1559 /* 1560 * If there are no matching entries we must return ERRDOS/ERRbadfile - 1561 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if 1562 * the protocol level is less than NT1. Tested with smbclient. JRA. 1563 * This should fix the OS/2 client bug #2335. 1564 */ 1565 1566 if(numentries == 0) { 1567 dptr_close(&dptr_num); 1568 if (Protocol < PROTOCOL_NT1) { 1569 return ERROR_DOS(ERRDOS,ERRnofiles); 1570 } else { 1571 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile); 1572 } 1573 } 1574 1575 /* At this point pdata points to numentries directory entries. */ 1576 1577 /* Set up the return parameter block */ 1578 SSVAL(params,0,dptr_num); 1579 SSVAL(params,2,numentries); 1580 SSVAL(params,4,finished); 1581 SSVAL(params,6,0); /* Never an EA error */ 1582 SSVAL(params,8,last_entry_off); 1583 1584 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata)); 1585 1586 if ((! *directory) && dptr_path(dptr_num)) 1587 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); 1588 1589 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", 1590 smb_fn_name(CVAL(inbuf,smb_com)), 1591 mask, directory, dirtype, numentries ) ); 1592 1593 /* 1594 * Force a name mangle here to ensure that the 1595 * mask as an 8.3 name is top of the mangled cache. 1596 * The reasons for this are subtle. Don't remove 1597 * this code unless you know what you are doing 1598 * (see PR#13758). JRA. 1599 */ 1600 1601 if(!mangle_is_8_3_wildcards( mask, False)) 1602 mangle_map(mask, True, True, SNUM(conn)); 1603 1604 return(-1); 1605} 1606 1607/**************************************************************************** 1608 Reply to a TRANS2_FINDNEXT. 1609****************************************************************************/ 1610 1611static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 1612 char **pparams, int total_params, char **ppdata, int total_data, 1613 unsigned int max_data_bytes) 1614{ 1615 /* We must be careful here that we don't return more than the 1616 allowed number of data bytes. If this means returning fewer than 1617 maxentries then so be it. We assume that the redirector has 1618 enough room for the fixed number of parameter bytes it has 1619 requested. */ 1620 char *params = *pparams; 1621 char *pdata = *ppdata; 1622 int dptr_num = SVAL(params,0); 1623 int maxentries = SVAL(params,2); 1624 uint16 info_level = SVAL(params,4); 1625 uint32 resume_key = IVAL(params,6); 1626 uint16 findnext_flags = SVAL(params,10); 1627 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE); 1628 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END); 1629 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME); 1630 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE); 1631 pstring resume_name; 1632 pstring mask; 1633 pstring directory; 1634 char *p; 1635 uint16 dirtype; 1636 int numentries = 0; 1637 int i, last_entry_off=0; 1638 BOOL finished = False; 1639 BOOL dont_descend = False; 1640 BOOL out_of_space = False; 1641 int space_remaining; 1642 NTSTATUS ntstatus = NT_STATUS_OK; 1643 1644 if (total_params < 12) 1645 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 1646 1647 *mask = *directory = *resume_name = 0; 1648 1649 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True); 1650 if (!NT_STATUS_IS_OK(ntstatus)) { 1651 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to 1652 complain (it thinks we're asking for the directory above the shared 1653 path or an invalid name). Catch this as the resume name is only compared, never used in 1654 a file access. JRA. */ 1655 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) { 1656 pstrcpy(resume_name, ".."); 1657 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) { 1658 pstrcpy(resume_name, "."); 1659 } else { 1660 return ERROR_NT(ntstatus); 1661 } 1662 } 1663 1664 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \ 1665close_after_request=%d, close_if_end = %d requires_resume_key = %d \ 1666resume_key = %d resume name = %s continue=%d level = %d\n", 1667 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 1668 requires_resume_key, resume_key, resume_name, continue_bit, info_level)); 1669 1670 if (!maxentries) { 1671 /* W2K3 seems to treat zero as 1. */ 1672 maxentries = 1; 1673 } 1674 1675 switch (info_level) { 1676 case SMB_INFO_STANDARD: 1677 case SMB_INFO_QUERY_EA_SIZE: 1678 case SMB_FIND_FILE_DIRECTORY_INFO: 1679 case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 1680 case SMB_FIND_FILE_NAMES_INFO: 1681 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 1682 break; 1683 case SMB_FIND_FILE_UNIX: 1684 if (!lp_unix_extensions()) 1685 return(ERROR_DOS(ERRDOS,ERRunknownlevel)); 1686 break; 1687 default: 1688 return ERROR_DOS(ERRDOS,ERRunknownlevel); 1689 } 1690 1691 pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 1692 if(pdata == NULL) 1693 return ERROR_DOS(ERRDOS,ERRnomem); 1694 1695 *ppdata = pdata; 1696 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 1697 1698 /* Realloc the params space */ 1699 params = SMB_REALLOC(*pparams, 6*SIZEOFWORD); 1700 if( params == NULL ) 1701 return ERROR_DOS(ERRDOS,ERRnomem); 1702 1703 *pparams = params; 1704 1705 /* Check that the dptr is valid */ 1706 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) 1707 return ERROR_DOS(ERRDOS,ERRnofiles); 1708 1709 string_set(&conn->dirpath,dptr_path(dptr_num)); 1710 1711 /* Get the wildcard mask from the dptr */ 1712 if((p = dptr_wcard(dptr_num))== NULL) { 1713 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num)); 1714 return ERROR_DOS(ERRDOS,ERRnofiles); 1715 } 1716 1717 pstrcpy(mask, p); 1718 pstrcpy(directory,conn->dirpath); 1719 1720 /* Get the attr mask from the dptr */ 1721 dirtype = dptr_attr(dptr_num); 1722 1723 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n", 1724 dptr_num, mask, dirtype, 1725 (long)conn->dirptr, 1726 dptr_TellDir(conn->dirptr))); 1727 1728 /* We don't need to check for VOL here as this is returned by 1729 a different TRANS2 call. */ 1730 1731 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn)))); 1732 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive)) 1733 dont_descend = True; 1734 1735 p = pdata; 1736 space_remaining = max_data_bytes; 1737 out_of_space = False; 1738 1739 /* 1740 * Seek to the correct position. We no longer use the resume key but 1741 * depend on the last file name instead. 1742 */ 1743 1744 if(*resume_name && !continue_bit) { 1745 SMB_STRUCT_STAT st; 1746 1747 long current_pos = 0; 1748 /* 1749 * Remember, mangle_map is called by 1750 * get_lanman2_dir_entry(), so the resume name 1751 * could be mangled. Ensure we check the unmangled name. 1752 */ 1753 1754 if (mangle_is_mangled(resume_name)) { 1755 mangle_check_cache(resume_name, sizeof(resume_name)-1); 1756 } 1757 1758 /* 1759 * Fix for NT redirector problem triggered by resume key indexes 1760 * changing between directory scans. We now return a resume key of 0 1761 * and instead look for the filename to continue from (also given 1762 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the 1763 * findfirst/findnext (as is usual) then the directory pointer 1764 * should already be at the correct place. 1765 */ 1766 1767 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st); 1768 } /* end if resume_name && !continue_bit */ 1769 1770 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) { 1771 BOOL got_exact_match = False; 1772 1773 /* this is a heuristic to avoid seeking the dirptr except when 1774 absolutely necessary. It allows for a filename of about 40 chars */ 1775 if (space_remaining < DIRLEN_GUESS && numentries > 0) { 1776 out_of_space = True; 1777 finished = False; 1778 } else { 1779 finished = !get_lanman2_dir_entry(conn, 1780 inbuf, outbuf, 1781 mask,dirtype,info_level, 1782 requires_resume_key,dont_descend, 1783 &p,pdata,space_remaining, &out_of_space, &got_exact_match, 1784 &last_entry_off); 1785 } 1786 1787 if (finished && out_of_space) 1788 finished = False; 1789 1790 if (!finished && !out_of_space) 1791 numentries++; 1792 1793 /* 1794 * As an optimisation if we know we aren't looking 1795 * for a wildcard name (ie. the name matches the wildcard exactly) 1796 * then we can finish on any (first) match. 1797 * This speeds up large directory searches. JRA. 1798 */ 1799 1800 if(got_exact_match) 1801 finished = True; 1802 1803 space_remaining = max_data_bytes - PTR_DIFF(p,pdata); 1804 } 1805 1806 /* Check if we can close the dirptr */ 1807 if(close_after_request || (finished && close_if_end)) { 1808 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num)); 1809 dptr_close(&dptr_num); /* This frees up the saved mask */ 1810 } 1811 1812 /* Set up the return parameter block */ 1813 SSVAL(params,0,numentries); 1814 SSVAL(params,2,finished); 1815 SSVAL(params,4,0); /* Never an EA error */ 1816 SSVAL(params,6,last_entry_off); 1817 1818 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata)); 1819 1820 if ((! *directory) && dptr_path(dptr_num)) 1821 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); 1822 1823 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", 1824 smb_fn_name(CVAL(inbuf,smb_com)), 1825 mask, directory, dirtype, numentries ) ); 1826 1827 return(-1); 1828} 1829 1830/**************************************************************************** 1831 Reply to a TRANS2_QFSINFO (query filesystem info). 1832****************************************************************************/ 1833 1834static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 1835 char **pparams, int total_params, char **ppdata, int total_data, 1836 unsigned int max_data_bytes) 1837{ 1838 char *pdata = *ppdata; 1839 char *params = *pparams; 1840 uint16 info_level = SVAL(params,0); 1841 int data_len, len; 1842 SMB_STRUCT_STAT st; 1843 char *vname = volume_label(SNUM(conn)); 1844 int snum = SNUM(conn); 1845 char *fstype = lp_fstype(SNUM(conn)); 1846 int quota_flag = 0; 1847 1848 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); 1849 1850 if(SMB_VFS_STAT(conn,".",&st)!=0) { 1851 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); 1852 return ERROR_DOS(ERRSRV,ERRinvdevice); 1853 } 1854 1855 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 1856 if ( pdata == NULL ) 1857 return ERROR_DOS(ERRDOS,ERRnomem); 1858 1859 *ppdata = pdata; 1860 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 1861 1862 switch (info_level) { 1863 case SMB_INFO_ALLOCATION: 1864 { 1865 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 1866 data_len = 18; 1867 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { 1868 return(UNIXERROR(ERRHRD,ERRgeneral)); 1869 } 1870 1871 block_size = lp_block_size(snum); 1872 if (bsize < block_size) { 1873 SMB_BIG_UINT factor = block_size/bsize; 1874 bsize = block_size; 1875 dsize /= factor; 1876 dfree /= factor; 1877 } 1878 if (bsize > block_size) { 1879 SMB_BIG_UINT factor = bsize/block_size; 1880 bsize = block_size; 1881 dsize *= factor; 1882 dfree *= factor; 1883 } 1884 bytes_per_sector = 512; 1885 sectors_per_unit = bsize/bytes_per_sector; 1886 1887 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \ 1888cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit, 1889 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); 1890 1891 SIVAL(pdata,l1_idFileSystem,st.st_dev); 1892 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit); 1893 SIVAL(pdata,l1_cUnit,dsize); 1894 SIVAL(pdata,l1_cUnitAvail,dfree); 1895 SSVAL(pdata,l1_cbSector,bytes_per_sector); 1896 break; 1897 } 1898 1899 case SMB_INFO_VOLUME: 1900 /* Return volume name */ 1901 /* 1902 * Add volume serial number - hash of a combination of 1903 * the called hostname and the service name. 1904 */ 1905 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) ); 1906 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN); 1907 SCVAL(pdata,l2_vol_cch,len); 1908 data_len = l2_vol_szVolLabel + len; 1909 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", 1910 (unsigned)st.st_ctime, len, vname)); 1911 break; 1912 1913 case SMB_QUERY_FS_ATTRIBUTE_INFO: 1914 case SMB_FS_ATTRIBUTE_INFORMATION: 1915 1916 1917#if defined(HAVE_SYS_QUOTAS) 1918 quota_flag = FILE_VOLUME_QUOTAS; 1919#endif 1920 1921 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| 1922 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)| 1923 quota_flag); /* FS ATTRIBUTES */ 1924 1925 SIVAL(pdata,4,255); /* Max filename component length */ 1926 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it 1927 and will think we can't do long filenames */ 1928 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE); 1929 SIVAL(pdata,8,len); 1930 data_len = 12 + len; 1931 break; 1932 1933 case SMB_QUERY_FS_LABEL_INFO: 1934 case SMB_FS_LABEL_INFORMATION: 1935 len = srvstr_push(outbuf, pdata+4, vname, -1, 0); 1936 data_len = 4 + len; 1937 SIVAL(pdata,0,len); 1938 break; 1939 1940 case SMB_QUERY_FS_VOLUME_INFO: 1941 case SMB_FS_VOLUME_INFORMATION: 1942 1943 /* 1944 * Add volume serial number - hash of a combination of 1945 * the called hostname and the service name. 1946 */ 1947 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ 1948 (str_checksum(get_local_machine_name())<<16)); 1949 1950 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE); 1951 SIVAL(pdata,12,len); 1952 data_len = 18+len; 1953 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 1954 (int)strlen(vname),vname, lp_servicename(snum))); 1955 break; 1956 1957 case SMB_QUERY_FS_SIZE_INFO: 1958 case SMB_FS_SIZE_INFORMATION: 1959 { 1960 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 1961 data_len = 24; 1962 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { 1963 return(UNIXERROR(ERRHRD,ERRgeneral)); 1964 } 1965 block_size = lp_block_size(snum); 1966 if (bsize < block_size) { 1967 SMB_BIG_UINT factor = block_size/bsize; 1968 bsize = block_size; 1969 dsize /= factor; 1970 dfree /= factor; 1971 } 1972 if (bsize > block_size) { 1973 SMB_BIG_UINT factor = bsize/block_size; 1974 bsize = block_size; 1975 dsize *= factor; 1976 dfree *= factor; 1977 } 1978 bytes_per_sector = 512; 1979 sectors_per_unit = bsize/bytes_per_sector; 1980 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \ 1981cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, 1982 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); 1983 SBIG_UINT(pdata,0,dsize); 1984 SBIG_UINT(pdata,8,dfree); 1985 SIVAL(pdata,16,sectors_per_unit); 1986 SIVAL(pdata,20,bytes_per_sector); 1987 break; 1988 } 1989 1990 case SMB_FS_FULL_SIZE_INFORMATION: 1991 { 1992 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 1993 data_len = 32; 1994 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { 1995 return(UNIXERROR(ERRHRD,ERRgeneral)); 1996 } 1997 block_size = lp_block_size(snum); 1998 if (bsize < block_size) { 1999 SMB_BIG_UINT factor = block_size/bsize; 2000 bsize = block_size; 2001 dsize /= factor; 2002 dfree /= factor; 2003 } 2004 if (bsize > block_size) { 2005 SMB_BIG_UINT factor = bsize/block_size; 2006 bsize = block_size; 2007 dsize *= factor; 2008 dfree *= factor; 2009 } 2010 bytes_per_sector = 512; 2011 sectors_per_unit = bsize/bytes_per_sector; 2012 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \ 2013cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, 2014 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); 2015 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */ 2016 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */ 2017 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */ 2018 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */ 2019 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */ 2020 break; 2021 } 2022 2023 case SMB_QUERY_FS_DEVICE_INFO: 2024 case SMB_FS_DEVICE_INFORMATION: 2025 data_len = 8; 2026 SIVAL(pdata,0,0); /* dev type */ 2027 SIVAL(pdata,4,0); /* characteristics */ 2028 break; 2029 2030#ifdef HAVE_SYS_QUOTAS 2031 case SMB_FS_QUOTA_INFORMATION: 2032 /* 2033 * what we have to send --metze: 2034 * 2035 * Unknown1: 24 NULL bytes 2036 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so 2037 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so 2038 * Quota Flags: 2 byte : 2039 * Unknown3: 6 NULL bytes 2040 * 2041 * 48 bytes total 2042 * 2043 * details for Quota Flags: 2044 * 2045 * 0x0020 Log Limit: log if the user exceeds his Hard Quota 2046 * 0x0010 Log Warn: log if the user exceeds his Soft Quota 2047 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota 2048 * 0x0001 Enable Quotas: enable quota for this fs 2049 * 2050 */ 2051 { 2052 /* we need to fake up a fsp here, 2053 * because its not send in this call 2054 */ 2055 files_struct fsp; 2056 SMB_NTQUOTA_STRUCT quotas; 2057 2058 ZERO_STRUCT(fsp); 2059 ZERO_STRUCT(quotas); 2060 2061 fsp.conn = conn; 2062 fsp.fnum = -1; 2063 fsp.fd = -1; 2064 2065 /* access check */ 2066 if (current_user.uid != 0) { 2067 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", 2068 lp_servicename(SNUM(conn)),conn->user)); 2069 return ERROR_DOS(ERRDOS,ERRnoaccess); 2070 } 2071 2072 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { 2073 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); 2074 return ERROR_DOS(ERRSRV,ERRerror); 2075 } 2076 2077 data_len = 48; 2078 2079 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn)))); 2080 2081 /* Unknown1 24 NULL bytes*/ 2082 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0); 2083 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0); 2084 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0); 2085 2086 /* Default Soft Quota 8 bytes */ 2087 SBIG_UINT(pdata,24,quotas.softlim); 2088 2089 /* Default Hard Quota 8 bytes */ 2090 SBIG_UINT(pdata,32,quotas.hardlim); 2091 2092 /* Quota flag 2 bytes */ 2093 SSVAL(pdata,40,quotas.qflags); 2094 2095 /* Unknown3 6 NULL bytes */ 2096 SSVAL(pdata,42,0); 2097 SIVAL(pdata,44,0); 2098 2099 break; 2100 } 2101#endif /* HAVE_SYS_QUOTAS */ 2102 case SMB_FS_OBJECTID_INFORMATION: 2103 data_len = 64; 2104 break; 2105 2106 /* 2107 * Query the version and capabilities of the CIFS UNIX extensions 2108 * in use. 2109 */ 2110 2111 case SMB_QUERY_CIFS_UNIX_INFO: 2112 if (!lp_unix_extensions()) 2113 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2114 data_len = 12; 2115 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION); 2116 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION); 2117 SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */ 2118 break; 2119 2120 case SMB_MAC_QUERY_FS_INFO: 2121 /* 2122 * Thursby MAC extension... ONLY on NTFS filesystems 2123 * once we do streams then we don't need this 2124 */ 2125 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) { 2126 data_len = 88; 2127 SIVAL(pdata,84,0x100); /* Don't support mac... */ 2128 break; 2129 } 2130 /* drop through */ 2131 default: 2132 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2133 } 2134 2135 2136 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len); 2137 2138 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) ); 2139 2140 return -1; 2141} 2142 2143#ifdef HAVE_SYS_QUOTAS 2144/**************************************************************************** 2145 Reply to a TRANS2_SETFSINFO (set filesystem info). 2146****************************************************************************/ 2147 2148static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 2149 char **pparams, int total_params, char **ppdata, int total_data, 2150 unsigned int max_data_bytes) 2151{ 2152 char *pdata = *ppdata; 2153 char *params = *pparams; 2154 files_struct *fsp = NULL; 2155 uint16 info_level; 2156 int outsize; 2157 SMB_NTQUOTA_STRUCT quotas; 2158 2159 ZERO_STRUCT(quotas); 2160 2161 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn)))); 2162 2163 /* access check */ 2164 if ((current_user.uid != 0)||!CAN_WRITE(conn)) { 2165 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", 2166 lp_servicename(SNUM(conn)),conn->user)); 2167 return ERROR_DOS(ERRSRV,ERRaccess); 2168 } 2169 2170 /* */ 2171 if (total_params < 4) { 2172 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n", 2173 total_params)); 2174 return ERROR_DOS(ERRDOS,ERRinvalidparam); 2175 } 2176 2177 fsp = file_fsp(params,0); 2178 2179 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { 2180 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); 2181 return ERROR_NT(NT_STATUS_INVALID_HANDLE); 2182 } 2183 2184 info_level = SVAL(params,2); 2185 2186 switch(info_level) { 2187 case SMB_FS_QUOTA_INFORMATION: 2188 /* note: normaly there're 48 bytes, 2189 * but we didn't use the last 6 bytes for now 2190 * --metze 2191 */ 2192 if (total_data < 42) { 2193 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n", 2194 total_data)); 2195 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2196 } 2197 2198 /* unknown_1 24 NULL bytes in pdata*/ 2199 2200 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ 2201 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24); 2202#ifdef LARGE_SMB_OFF_T 2203 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); 2204#else /* LARGE_SMB_OFF_T */ 2205 if ((IVAL(pdata,28) != 0)&& 2206 ((quotas.softlim != 0xFFFFFFFF)|| 2207 (IVAL(pdata,28)!=0xFFFFFFFF))) { 2208 /* more than 32 bits? */ 2209 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2210 } 2211#endif /* LARGE_SMB_OFF_T */ 2212 2213 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ 2214 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); 2215#ifdef LARGE_SMB_OFF_T 2216 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); 2217#else /* LARGE_SMB_OFF_T */ 2218 if ((IVAL(pdata,36) != 0)&& 2219 ((quotas.hardlim != 0xFFFFFFFF)|| 2220 (IVAL(pdata,36)!=0xFFFFFFFF))) { 2221 /* more than 32 bits? */ 2222 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2223 } 2224#endif /* LARGE_SMB_OFF_T */ 2225 2226 /* quota_flags 2 bytes **/ 2227 quotas.qflags = SVAL(pdata,40); 2228 2229 /* unknown_2 6 NULL bytes follow*/ 2230 2231 /* now set the quotas */ 2232 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { 2233 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); 2234 return ERROR_DOS(ERRSRV,ERRerror); 2235 } 2236 2237 break; 2238 default: 2239 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n", 2240 info_level)); 2241 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2242 break; 2243 } 2244 2245 /* 2246 * sending this reply works fine, 2247 * but I'm not sure it's the same 2248 * like windows do... 2249 * --metze 2250 */ 2251 outsize = set_message(outbuf,10,0,True); 2252 2253 return outsize; 2254} 2255#endif /* HAVE_SYS_QUOTAS */ 2256 2257/**************************************************************************** 2258 Utility function to set bad path error. 2259****************************************************************************/ 2260 2261int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code) 2262{ 2263 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n", 2264 err, (int)bad_path )); 2265 2266 if(err == ENOENT) { 2267 if (bad_path) { 2268 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 2269 } else { 2270 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND); 2271 } 2272 } 2273 return UNIXERROR(def_class,def_code); 2274} 2275 2276#if defined(HAVE_POSIX_ACLS) 2277/**************************************************************************** 2278 Utility function to count the number of entries in a POSIX acl. 2279****************************************************************************/ 2280 2281static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl) 2282{ 2283 unsigned int ace_count = 0; 2284 int entry_id = SMB_ACL_FIRST_ENTRY; 2285 SMB_ACL_ENTRY_T entry; 2286 2287 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) { 2288 /* get_next... */ 2289 if (entry_id == SMB_ACL_FIRST_ENTRY) { 2290 entry_id = SMB_ACL_NEXT_ENTRY; 2291 } 2292 ace_count++; 2293 } 2294 return ace_count; 2295} 2296 2297/**************************************************************************** 2298 Utility function to marshall a POSIX acl into wire format. 2299****************************************************************************/ 2300 2301static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl) 2302{ 2303 int entry_id = SMB_ACL_FIRST_ENTRY; 2304 SMB_ACL_ENTRY_T entry; 2305 2306 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) { 2307 SMB_ACL_TAG_T tagtype; 2308 SMB_ACL_PERMSET_T permset; 2309 unsigned char perms = 0; 2310 unsigned int own_grp; 2311 2312 /* get_next... */ 2313 if (entry_id == SMB_ACL_FIRST_ENTRY) { 2314 entry_id = SMB_ACL_NEXT_ENTRY; 2315 } 2316 2317 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) { 2318 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n")); 2319 return False; 2320 } 2321 2322 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) { 2323 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n")); 2324 return False; 2325 } 2326 2327 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0); 2328 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0); 2329 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0); 2330 2331 SCVAL(pdata,1,perms); 2332 2333 switch (tagtype) { 2334 case SMB_ACL_USER_OBJ: 2335 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ); 2336 own_grp = (unsigned int)pst->st_uid; 2337 SIVAL(pdata,2,own_grp); 2338 SIVAL(pdata,6,0); 2339 break; 2340 case SMB_ACL_USER: 2341 { 2342 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); 2343 if (!puid) { 2344 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n")); 2345 } 2346 own_grp = (unsigned int)*puid; 2347 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype); 2348 SCVAL(pdata,0,SMB_POSIX_ACL_USER); 2349 SIVAL(pdata,2,own_grp); 2350 SIVAL(pdata,6,0); 2351 break; 2352 } 2353 case SMB_ACL_GROUP_OBJ: 2354 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ); 2355 own_grp = (unsigned int)pst->st_gid; 2356 SIVAL(pdata,2,own_grp); 2357 SIVAL(pdata,6,0); 2358 break; 2359 case SMB_ACL_GROUP: 2360 { 2361 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); 2362 if (!pgid) { 2363 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n")); 2364 } 2365 own_grp = (unsigned int)*pgid; 2366 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype); 2367 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP); 2368 SIVAL(pdata,2,own_grp); 2369 SIVAL(pdata,6,0); 2370 break; 2371 } 2372 case SMB_ACL_MASK: 2373 SCVAL(pdata,0,SMB_POSIX_ACL_MASK); 2374 SIVAL(pdata,2,0xFFFFFFFF); 2375 SIVAL(pdata,6,0xFFFFFFFF); 2376 break; 2377 case SMB_ACL_OTHER: 2378 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER); 2379 SIVAL(pdata,2,0xFFFFFFFF); 2380 SIVAL(pdata,6,0xFFFFFFFF); 2381 break; 2382 default: 2383 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n")); 2384 return False; 2385 } 2386 pdata += SMB_POSIX_ACL_ENTRY_SIZE; 2387 } 2388 2389 return True; 2390} 2391#endif 2392 2393/**************************************************************************** 2394 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by 2395 file name or file id). 2396****************************************************************************/ 2397 2398static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 2399 char **pparams, int total_params, char **ppdata, int total_data, 2400 unsigned int max_data_bytes) 2401{ 2402 char *params = *pparams; 2403 char *pdata = *ppdata; 2404 uint16 tran_call = SVAL(inbuf, smb_setup0); 2405 uint16 info_level; 2406 int mode=0; 2407 /* Foxconn modified start pling 12/15/2010 */ 2408 /* SMB_OFF_T file_size=0; */ 2409 SMB_BIG_UINT file_size = 0; 2410 /* Foxconn modified end pling 12/15/2010 */ 2411 SMB_BIG_UINT allocation_size=0; 2412 unsigned int data_size; 2413 unsigned int param_size = 2; 2414 SMB_STRUCT_STAT sbuf; 2415 pstring fname, dos_fname; 2416 char *fullpathname; 2417 char *base_name; 2418 char *p; 2419 SMB_OFF_T pos = 0; 2420 BOOL bad_path = False; 2421 BOOL delete_pending = False; 2422 int len; 2423 time_t c_time; 2424 files_struct *fsp = NULL; 2425 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ 2426 2427 if (!params) 2428 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 2429 2430 ZERO_STRUCT(sbuf); 2431 2432 if (tran_call == TRANSACT2_QFILEINFO) { 2433 if (total_params < 4) 2434 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 2435 2436 fsp = file_fsp(params,0); 2437 info_level = SVAL(params,2); 2438 2439 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); 2440 2441 if(fsp && (fsp->fake_file_handle)) { 2442 /* 2443 * This is actually for the QUOTA_FAKE_FILE --metze 2444 */ 2445 2446 pstrcpy(fname, fsp->fsp_name); 2447 /* We know this name is ok, it's already passed the checks. */ 2448 2449 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) { 2450 /* 2451 * This is actually a QFILEINFO on a directory 2452 * handle (returned from an NT SMB). NT5.0 seems 2453 * to do this call. JRA. 2454 */ 2455 /* We know this name is ok, it's already passed the checks. */ 2456 pstrcpy(fname, fsp->fsp_name); 2457 2458 if (INFO_LEVEL_IS_UNIX(info_level)) { 2459 /* Always do lstat for UNIX calls. */ 2460 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) { 2461 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); 2462 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 2463 } 2464 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) { 2465 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); 2466 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 2467 } 2468 2469 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0; 2470 } else { 2471 /* 2472 * Original code - this is an open file. 2473 */ 2474 CHECK_FSP(fsp,conn); 2475 2476 pstrcpy(fname, fsp->fsp_name); 2477 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) { 2478 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); 2479 return(UNIXERROR(ERRDOS,ERRbadfid)); 2480 } 2481 pos = fsp->position_information; 2482 delete_pending = fsp->delete_on_close; 2483 desired_access = fsp->desired_access; 2484 } 2485 } else { 2486 NTSTATUS status = NT_STATUS_OK; 2487 2488 /* qpathinfo */ 2489 if (total_params < 6) 2490 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 2491 2492 info_level = SVAL(params,0); 2493 2494 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); 2495 2496 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False); 2497 if (!NT_STATUS_IS_OK(status)) { 2498 return ERROR_NT(status); 2499 } 2500 2501 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf); 2502 2503 unix_convert(fname,conn,0,&bad_path,&sbuf); 2504 if (bad_path) { 2505 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 2506 } 2507 if (!check_name(fname,conn)) { 2508 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno))); 2509 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 2510 } 2511 2512 if (INFO_LEVEL_IS_UNIX(info_level)) { 2513 /* Always do lstat for UNIX calls. */ 2514 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) { 2515 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); 2516 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 2517 } 2518 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) { 2519 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); 2520 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 2521 } 2522 } 2523 2524 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) 2525 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2526 2527 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", 2528 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); 2529 2530 p = strrchr_m(fname,'/'); 2531 if (!p) 2532 base_name = fname; 2533 else 2534 base_name = p+1; 2535 2536 mode = dos_mode(conn,fname,&sbuf); 2537 if (!mode) 2538 mode = FILE_ATTRIBUTE_NORMAL; 2539 2540 fullpathname = fname; 2541 file_size = get_file_size(sbuf); 2542 allocation_size = get_allocation_size(conn,fsp,&sbuf); 2543 if (mode & aDIR) { 2544 /* This is necessary, as otherwise the desktop.ini file in 2545 * this folder is ignored */ 2546 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0); 2547 file_size = 0; 2548 } 2549 2550 params = SMB_REALLOC(*pparams,2); 2551 if (params == NULL) 2552 return ERROR_DOS(ERRDOS,ERRnomem); 2553 *pparams = params; 2554 memset((char *)params,'\0',2); 2555 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; 2556 pdata = SMB_REALLOC(*ppdata, data_size); 2557 if ( pdata == NULL ) 2558 return ERROR_DOS(ERRDOS,ERRnomem); 2559 *ppdata = pdata; 2560 2561 if (total_data > 0 && IVAL(pdata,0) == total_data) { 2562 /* uggh, EAs for OS2 */ 2563 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data)); 2564 return ERROR_DOS(ERRDOS,ERReasnotsupported); 2565 } 2566 2567 memset((char *)pdata,'\0',data_size); 2568 2569 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))); 2570 2571 if (fsp) { 2572 if (fsp->pending_modtime) { 2573 /* the pending modtime overrides the current modtime */ 2574 sbuf.st_mtime = fsp->pending_modtime; 2575 } 2576 } else { 2577 /* Do we have this path open ? */ 2578 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino); 2579 if (fsp1 && fsp1->pending_modtime) { 2580 /* the pending modtime overrides the current modtime */ 2581 sbuf.st_mtime = fsp1->pending_modtime; 2582 } 2583 } 2584 2585 if (lp_dos_filetime_resolution(SNUM(conn))) { 2586 c_time &= ~1; 2587 sbuf.st_atime &= ~1; 2588 sbuf.st_ctime &= ~1; 2589 sbuf.st_mtime &= ~1; 2590 } 2591 2592 /* NT expects the name to be in an exact form of the *full* 2593 filename. See the trans2 torture test */ 2594 if (strequal(base_name,".")) { 2595 pstrcpy(dos_fname, "\\"); 2596 } else { 2597 pstr_sprintf(dos_fname, "\\%s", fname); 2598 string_replace(dos_fname, '/', '\\'); 2599 } 2600 2601 switch (info_level) { 2602 case SMB_INFO_STANDARD: 2603 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n")); 2604 data_size = 22; 2605 put_dos_date2(pdata,l1_fdateCreation,c_time); 2606 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); 2607 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ 2608 SIVAL(pdata,l1_cbFile,(uint32)file_size); 2609 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); 2610 SSVAL(pdata,l1_attrFile,mode); 2611 break; 2612 2613 case SMB_INFO_QUERY_EA_SIZE: 2614 { 2615 unsigned int ea_size = estimate_ea_size(conn, fsp, fname); 2616 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); 2617 data_size = 26; 2618 put_dos_date2(pdata,l1_fdateCreation,c_time); 2619 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); 2620 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ 2621 SIVAL(pdata,l1_cbFile,(uint32)file_size); 2622 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); 2623 SSVAL(pdata,l1_attrFile,mode); 2624 SIVAL(pdata,l1_attrFile+2,ea_size); 2625 break; 2626 } 2627 2628 case SMB_INFO_IS_NAME_VALID: 2629 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n")); 2630 if (tran_call == TRANSACT2_QFILEINFO) { 2631 /* os/2 needs this ? really ?*/ 2632 return ERROR_DOS(ERRDOS,ERRbadfunc); 2633 } 2634 data_size = 0; 2635 param_size = 0; 2636 break; 2637 2638 case SMB_INFO_QUERY_EAS_FROM_LIST: 2639 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n")); 2640 data_size = 24; 2641 put_dos_date2(pdata,0,c_time); 2642 put_dos_date2(pdata,4,sbuf.st_atime); 2643 put_dos_date2(pdata,8,sbuf.st_mtime); 2644 SIVAL(pdata,12,(uint32)file_size); 2645 SIVAL(pdata,16,(uint32)allocation_size); 2646 SIVAL(pdata,20,mode); 2647 break; 2648 2649 case SMB_INFO_QUERY_ALL_EAS: 2650 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n")); 2651 /* We have data_size bytes to put EA's into. */ 2652 data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname); 2653 break; 2654 2655 case SMB_FILE_BASIC_INFORMATION: 2656 case SMB_QUERY_FILE_BASIC_INFO: 2657 2658 if (info_level == SMB_QUERY_FILE_BASIC_INFO) { 2659 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n")); 2660 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ 2661 } else { 2662 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n")); 2663 data_size = 40; 2664 SIVAL(pdata,36,0); 2665 } 2666 put_long_date(pdata,c_time); 2667 put_long_date(pdata+8,sbuf.st_atime); 2668 put_long_date(pdata+16,sbuf.st_mtime); /* write time */ 2669 put_long_date(pdata+24,sbuf.st_mtime); /* change time */ 2670 SIVAL(pdata,32,mode); 2671 2672 DEBUG(5,("SMB_QFBI - ")); 2673 { 2674 time_t create_time = c_time; 2675 DEBUG(5,("create: %s ", ctime(&create_time))); 2676 } 2677 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime))); 2678 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime))); 2679 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime))); 2680 DEBUG(5,("mode: %x\n", mode)); 2681 2682 break; 2683 2684 case SMB_FILE_STANDARD_INFORMATION: 2685 case SMB_QUERY_FILE_STANDARD_INFO: 2686 2687 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n")); 2688 data_size = 24; 2689 /* Foxconn modified start pling 03/11/2011 */ 2690 /* Fix potential incorrect file size issue if file size > 4GB*/ 2691#if 0 2692 SOFF_T(pdata,0,allocation_size); 2693 SOFF_T(pdata,8,file_size); 2694#endif 2695 SOFF64_T(pdata,0,allocation_size); 2696 SOFF64_T(pdata,8,file_size); 2697 /* Foxconn modified end pling 03/11/2011 */ 2698 if (delete_pending & sbuf.st_nlink) 2699 SIVAL(pdata,16,sbuf.st_nlink - 1); 2700 else 2701 SIVAL(pdata,16,sbuf.st_nlink); 2702 SCVAL(pdata,20,0); 2703 SCVAL(pdata,21,(mode&aDIR)?1:0); 2704 break; 2705 2706 case SMB_FILE_EA_INFORMATION: 2707 case SMB_QUERY_FILE_EA_INFO: 2708 { 2709 unsigned int ea_size = estimate_ea_size(conn, fsp, fname); 2710 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); 2711 data_size = 4; 2712 SIVAL(pdata,0,ea_size); 2713 break; 2714 } 2715 2716 /* Get the 8.3 name - used if NT SMB was negotiated. */ 2717 case SMB_QUERY_FILE_ALT_NAME_INFO: 2718 case SMB_FILE_ALTERNATE_NAME_INFORMATION: 2719 { 2720 pstring short_name; 2721 2722 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n")); 2723 pstrcpy(short_name,base_name); 2724 /* Mangle if not already 8.3 */ 2725 if(!mangle_is_8_3(short_name, True)) { 2726 mangle_map(short_name,True,True,SNUM(conn)); 2727 } 2728 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE); 2729 data_size = 4 + len; 2730 SIVAL(pdata,0,len); 2731 break; 2732 } 2733 2734 case SMB_QUERY_FILE_NAME_INFO: 2735 /* 2736 this must be *exactly* right for ACLs on mapped drives to work 2737 */ 2738 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE); 2739 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n")); 2740 data_size = 4 + len; 2741 SIVAL(pdata,0,len); 2742 break; 2743 2744 case SMB_FILE_ALLOCATION_INFORMATION: 2745 case SMB_QUERY_FILE_ALLOCATION_INFO: 2746 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); 2747 data_size = 8; 2748 /* Foxconn modified start pling 03/11/2011 */ 2749 /* Fix potential incorrect file size issue if file size > 4GB*/ 2750 /* SOFF_T(pdata,0,allocation_size); */ 2751 SOFF64_T(pdata,0,allocation_size); 2752 /* Foxconn modified end pling 03/11/2011 */ 2753 break; 2754 2755 case SMB_FILE_END_OF_FILE_INFORMATION: 2756 case SMB_QUERY_FILE_END_OF_FILEINFO: 2757 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n")); 2758 data_size = 8; 2759 /* Foxconn modified start pling 03/11/2011 */ 2760 /* Fix potential incorrect file size issue if file size > 4GB.*/ 2761 /* SOFF_T(pdata,0,file_size); */ 2762 SOFF64_T(pdata,0,file_size); 2763 /* Foxconn modified end pling 03/11/2011 */ 2764 break; 2765 2766 case SMB_QUERY_FILE_ALL_INFO: 2767 case SMB_FILE_ALL_INFORMATION: 2768 { 2769 unsigned int ea_size = estimate_ea_size(conn, fsp, fname); 2770 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); 2771 put_long_date(pdata,c_time); 2772 put_long_date(pdata+8,sbuf.st_atime); 2773 put_long_date(pdata+16,sbuf.st_mtime); /* write time */ 2774 put_long_date(pdata+24,sbuf.st_mtime); /* change time */ 2775 SIVAL(pdata,32,mode); 2776 pdata += 40; 2777 /* Foxconn modified start pling 12/15/2010 */ 2778 /* Fix Linux smb client can't see file > 4GB */ 2779#if 0 2780 SOFF_T(pdata,0,allocation_size); 2781 SOFF_T(pdata,8,file_size); 2782#endif 2783 SOFF64_T(pdata,0,allocation_size); 2784 SOFF64_T(pdata,8,file_size); 2785 /* Foxconn modified end pling 12/15/2010 */ 2786 if (delete_pending && sbuf.st_nlink) 2787 SIVAL(pdata,16,sbuf.st_nlink - 1); 2788 else 2789 SIVAL(pdata,16,sbuf.st_nlink); 2790 SCVAL(pdata,20,delete_pending); 2791 SCVAL(pdata,21,(mode&aDIR)?1:0); 2792 pdata += 24; 2793 SIVAL(pdata,0,ea_size); 2794 pdata += 4; /* EA info */ 2795 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE); 2796 SIVAL(pdata,0,len); 2797 pdata += 4 + len; 2798 data_size = PTR_DIFF(pdata,(*ppdata)); 2799 break; 2800 } 2801 case SMB_FILE_INTERNAL_INFORMATION: 2802 /* This should be an index number - looks like 2803 dev/ino to me :-) 2804 2805 I think this causes us to fail the IFSKIT 2806 BasicFileInformationTest. -tpot */ 2807 2808 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); 2809 SIVAL(pdata,0,sbuf.st_dev); 2810 SIVAL(pdata,4,sbuf.st_ino); 2811 data_size = 8; 2812 break; 2813 2814 case SMB_FILE_ACCESS_INFORMATION: 2815 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); 2816 SIVAL(pdata,0,desired_access); 2817 data_size = 4; 2818 break; 2819 2820 case SMB_FILE_NAME_INFORMATION: 2821 /* Pathname with leading '\'. */ 2822 { 2823 size_t byte_len; 2824 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False); 2825 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n")); 2826 SIVAL(pdata,0,byte_len); 2827 data_size = 4 + byte_len; 2828 break; 2829 } 2830 2831 case SMB_FILE_DISPOSITION_INFORMATION: 2832 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); 2833 data_size = 1; 2834 SCVAL(pdata,0,delete_pending); 2835 break; 2836 2837 case SMB_FILE_POSITION_INFORMATION: 2838 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); 2839 data_size = 8; 2840 SOFF_T(pdata,0,pos); 2841 break; 2842 2843 case SMB_FILE_MODE_INFORMATION: 2844 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); 2845 SIVAL(pdata,0,mode); 2846 data_size = 4; 2847 break; 2848 2849 case SMB_FILE_ALIGNMENT_INFORMATION: 2850 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); 2851 SIVAL(pdata,0,0); /* No alignment needed. */ 2852 data_size = 4; 2853 break; 2854 2855#if 0 2856 /* 2857 * NT4 server just returns "invalid query" to this - if we try to answer 2858 * it then NTws gets a BSOD! (tridge). 2859 * W2K seems to want this. JRA. 2860 */ 2861 case SMB_QUERY_FILE_STREAM_INFO: 2862#endif 2863 case SMB_FILE_STREAM_INFORMATION: 2864 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n")); 2865 if (mode & aDIR) { 2866 data_size = 0; 2867 } else { 2868 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False); 2869 SIVAL(pdata,0,0); /* ??? */ 2870 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */ 2871 /* Foxconn modified start pling 03/11/2011 */ 2872 /* Fix potential incorrect file size issue if file size > 4GB.*/ 2873 /* SOFF_T(pdata,8,file_size); */ 2874 SOFF64_T(pdata,8,file_size); 2875 /* Foxconn modified end pling 03/11/2011 */ 2876 SIVAL(pdata,16,allocation_size); 2877 SIVAL(pdata,20,0); /* ??? */ 2878 data_size = 24 + byte_len; 2879 } 2880 break; 2881 2882 case SMB_QUERY_COMPRESSION_INFO: 2883 case SMB_FILE_COMPRESSION_INFORMATION: 2884 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n")); 2885 /* Foxconn modified start pling 03/11/2011 */ 2886 /* Fix potential incorrect file size issue if file size > 4GB.*/ 2887 /* SOFF_T(pdata,0,file_size); */ 2888 SOFF64_T(pdata,0,file_size); 2889 /* Foxconn modified end pling 03/11/2011 */ 2890 SIVAL(pdata,8,0); /* ??? */ 2891 SIVAL(pdata,12,0); /* ??? */ 2892 data_size = 16; 2893 break; 2894 2895 case SMB_FILE_NETWORK_OPEN_INFORMATION: 2896 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n")); 2897 put_long_date(pdata,c_time); 2898 put_long_date(pdata+8,sbuf.st_atime); 2899 put_long_date(pdata+16,sbuf.st_mtime); /* write time */ 2900 put_long_date(pdata+24,sbuf.st_mtime); /* change time */ 2901 /* Foxconn modified start pling 03/11/2011 */ 2902 /* Fix potential incorrect file size issue if file size > 4GB.*/ 2903#if 0 2904 SIVAL(pdata,32,allocation_size); 2905 SOFF_T(pdata,40,file_size); 2906#endif 2907 SOFF64_T(pdata,32,allocation_size); 2908 SOFF64_T(pdata,40,file_size); 2909 /* Foxconn modified end pling 03/11/2011 */ 2910 SIVAL(pdata,48,mode); 2911 SIVAL(pdata,52,0); /* ??? */ 2912 data_size = 56; 2913 break; 2914 2915 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: 2916 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n")); 2917 SIVAL(pdata,0,mode); 2918 SIVAL(pdata,4,0); 2919 data_size = 8; 2920 break; 2921 2922 /* 2923 * CIFS UNIX Extensions. 2924 */ 2925 2926 case SMB_QUERY_FILE_UNIX_BASIC: 2927 2928 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n")); 2929 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode)); 2930 2931 /* Foxconn modified start pling 03/11/2011 */ 2932 /* Fix potential incorrect file size issue if file size > 4GB.*/ 2933 /* SOFF_T(pdata,0,get_file_size(sbuf)); */ /* File size 64 Bit */ 2934 SOFF64_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */ 2935 /* Foxconn modified end pling 03/11/2011 */ 2936 pdata += 8; 2937 2938 /* Foxconn modified start pling 03/11/2011 */ 2939 /* Fix potential incorrect file size issue if file size > 4GB.*/ 2940 /* SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf));*/ /* Number of bytes used on disk - 64 Bit */ 2941 SOFF64_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */ 2942 /* Foxconn modified end pling 03/11/2011 */ 2943 pdata += 8; 2944 2945 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */ 2946 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */ 2947 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */ 2948 pdata += 24; 2949 2950 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */ 2951 SIVAL(pdata,4,0); 2952 pdata += 8; 2953 2954 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */ 2955 SIVAL(pdata,4,0); 2956 pdata += 8; 2957 2958 SIVAL(pdata,0,unix_filetype(sbuf.st_mode)); 2959 pdata += 4; 2960 2961 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */ 2962 SIVAL(pdata,4,0); 2963 pdata += 8; 2964 2965 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */ 2966 SIVAL(pdata,4,0); 2967 pdata += 8; 2968 2969 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */ 2970 pdata += 8; 2971 2972 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */ 2973 SIVAL(pdata,4,0); 2974 pdata += 8; 2975 2976 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */ 2977 SIVAL(pdata,4,0); 2978 pdata += 8+1; 2979 data_size = PTR_DIFF(pdata,(*ppdata)); 2980 2981 { 2982 int i; 2983 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC")); 2984 2985 for (i=0; i<100; i++) 2986 DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); 2987 DEBUG(4,("\n")); 2988 } 2989 2990 break; 2991 2992 case SMB_QUERY_FILE_UNIX_LINK: 2993 { 2994 pstring buffer; 2995 2996 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); 2997#ifdef S_ISLNK 2998 if(!S_ISLNK(sbuf.st_mode)) 2999 return(UNIXERROR(ERRSRV,ERRbadlink)); 3000#else 3001 return(UNIXERROR(ERRDOS,ERRbadlink)); 3002#endif 3003 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */ 3004 if (len == -1) 3005 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3006 buffer[len] = 0; 3007 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE); 3008 pdata += len; 3009 data_size = PTR_DIFF(pdata,(*ppdata)); 3010 3011 break; 3012 } 3013 3014#if defined(HAVE_POSIX_ACLS) 3015 case SMB_QUERY_POSIX_ACL: 3016 { 3017 SMB_ACL_T file_acl = NULL; 3018 SMB_ACL_T def_acl = NULL; 3019 uint16 num_file_acls = 0; 3020 uint16 num_def_acls = 0; 3021 3022 if (fsp && !fsp->is_directory && (fsp->fd != -1)) { 3023 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd); 3024 } else { 3025 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); 3026 } 3027 3028 if (file_acl == NULL && no_acl_syscall_error(errno)) { 3029 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n", 3030 fname )); 3031 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); 3032 } 3033 3034 if (S_ISDIR(sbuf.st_mode)) { 3035 if (fsp && fsp->is_directory) { 3036 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); 3037 } else { 3038 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); 3039 } 3040 def_acl = free_empty_sys_acl(conn, def_acl); 3041 } 3042 3043 num_file_acls = count_acl_entries(conn, file_acl); 3044 num_def_acls = count_acl_entries(conn, def_acl); 3045 3046 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) { 3047 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n", 3048 data_size, 3049 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + 3050 SMB_POSIX_ACL_HEADER_SIZE) )); 3051 if (file_acl) { 3052 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 3053 } 3054 if (def_acl) { 3055 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 3056 } 3057 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL); 3058 } 3059 3060 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION); 3061 SSVAL(pdata,2,num_file_acls); 3062 SSVAL(pdata,4,num_def_acls); 3063 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) { 3064 if (file_acl) { 3065 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 3066 } 3067 if (def_acl) { 3068 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 3069 } 3070 return ERROR_NT(NT_STATUS_INTERNAL_ERROR); 3071 } 3072 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) { 3073 if (file_acl) { 3074 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 3075 } 3076 if (def_acl) { 3077 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 3078 } 3079 return ERROR_NT(NT_STATUS_INTERNAL_ERROR); 3080 } 3081 3082 if (file_acl) { 3083 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 3084 } 3085 if (def_acl) { 3086 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 3087 } 3088 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE; 3089 break; 3090 } 3091#endif 3092 3093 default: 3094 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3095 } 3096 3097 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size); 3098 3099 return(-1); 3100} 3101 3102/**************************************************************************** 3103 Deal with the internal needs of setting the delete on close flag. Note that 3104 as the tdb locking is recursive, it is safe to call this from within 3105 open_file_shared. JRA. 3106****************************************************************************/ 3107 3108NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode) 3109{ 3110 if (delete_on_close) { 3111 /* 3112 * Only allow delete on close for writable files. 3113 */ 3114 3115 if (!lp_delete_readonly(SNUM(fsp->conn))) { 3116 if (dosmode & aRONLY) { 3117 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n", 3118 fsp->fsp_name )); 3119 return NT_STATUS_CANNOT_DELETE; 3120 } 3121 } 3122 3123 /* 3124 * Only allow delete on close for writable shares. 3125 */ 3126 3127 if (!CAN_WRITE(fsp->conn)) { 3128 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n", 3129 fsp->fsp_name )); 3130 return NT_STATUS_ACCESS_DENIED; 3131 } 3132 3133 /* 3134 * Only allow delete on close for files/directories opened with delete intent. 3135 */ 3136 3137 if (!(fsp->desired_access & DELETE_ACCESS)) { 3138 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n", 3139 fsp->fsp_name )); 3140 return NT_STATUS_ACCESS_DENIED; 3141 } 3142 } 3143 3144 if(fsp->is_directory) { 3145 fsp->directory_delete_on_close = delete_on_close; 3146 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n", 3147 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name )); 3148 } else { 3149 fsp->delete_on_close = delete_on_close; 3150 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n", 3151 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name )); 3152 } 3153 3154 return NT_STATUS_OK; 3155} 3156 3157/**************************************************************************** 3158 Sets the delete on close flag over all share modes on this file. 3159 Modify the share mode entry for all files open 3160 on this device and inode to tell other smbds we have 3161 changed the delete on close flag. This will be noticed 3162 in the close code, the last closer will delete the file 3163 if flag is set. 3164****************************************************************************/ 3165 3166NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close) 3167{ 3168 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n", 3169 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name )); 3170 3171 if (fsp->is_directory || fsp->is_stat) 3172 return NT_STATUS_OK; 3173 3174 if (lock_share_entry_fsp(fsp) == False) 3175 return NT_STATUS_ACCESS_DENIED; 3176 3177 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) { 3178 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n", 3179 fsp->fsp_name )); 3180 unlock_share_entry_fsp(fsp); 3181 return NT_STATUS_ACCESS_DENIED; 3182 } 3183 3184 unlock_share_entry_fsp(fsp); 3185 return NT_STATUS_OK; 3186} 3187 3188/**************************************************************************** 3189 Set a hard link (called by UNIX extensions and by NT rename with HARD link 3190 code. 3191****************************************************************************/ 3192 3193NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname) 3194{ 3195 BOOL bad_path_oldname = False; 3196 BOOL bad_path_newname = False; 3197 SMB_STRUCT_STAT sbuf1, sbuf2; 3198 pstring last_component_oldname; 3199 pstring last_component_newname; 3200 NTSTATUS status = NT_STATUS_OK; 3201 3202 ZERO_STRUCT(sbuf1); 3203 ZERO_STRUCT(sbuf2); 3204 3205 /* No wildcards. */ 3206 if (ms_has_wild(newname) || ms_has_wild(oldname)) { 3207 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; 3208 } 3209 3210 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1); 3211 if (bad_path_oldname) { 3212 return NT_STATUS_OBJECT_PATH_NOT_FOUND; 3213 } 3214 3215 /* Quick check for "." and ".." */ 3216 if (last_component_oldname[0] == '.') { 3217 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) { 3218 return NT_STATUS_OBJECT_NAME_INVALID; 3219 } 3220 } 3221 3222 /* source must already exist. */ 3223 if (!VALID_STAT(sbuf1)) { 3224 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3225 } 3226 3227 if (!check_name(oldname,conn)) { 3228 return NT_STATUS_ACCESS_DENIED; 3229 } 3230 3231 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2); 3232 if (bad_path_newname) { 3233 return NT_STATUS_OBJECT_PATH_NOT_FOUND; 3234 } 3235 3236 /* Quick check for "." and ".." */ 3237 if (last_component_newname[0] == '.') { 3238 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) { 3239 return NT_STATUS_OBJECT_NAME_INVALID; 3240 } 3241 } 3242 3243 /* Disallow if newname already exists. */ 3244 if (VALID_STAT(sbuf2)) { 3245 return NT_STATUS_OBJECT_NAME_COLLISION; 3246 } 3247 3248 if (!check_name(newname,conn)) { 3249 return NT_STATUS_ACCESS_DENIED; 3250 } 3251 3252 /* No links from a directory. */ 3253 if (S_ISDIR(sbuf1.st_mode)) { 3254 return NT_STATUS_FILE_IS_A_DIRECTORY; 3255 } 3256 3257 /* Ensure this is within the share. */ 3258 if (!reduce_name(conn, oldname) != 0) 3259 return NT_STATUS_ACCESS_DENIED; 3260 3261 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname )); 3262 3263 if (SMB_VFS_LINK(conn,oldname,newname) != 0) { 3264 status = map_nt_error_from_unix(errno); 3265 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n", 3266 nt_errstr(status), newname, oldname)); 3267 } 3268 3269 return status; 3270} 3271 3272/**************************************************************************** 3273 Reply to a TRANS2_SETFILEINFO (set file info by fileid). 3274****************************************************************************/ 3275 3276static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 3277 char **pparams, int total_params, char **ppdata, int total_data, 3278 unsigned int max_data_bytes) 3279{ 3280 char *params = *pparams; 3281 char *pdata = *ppdata; 3282 uint16 tran_call = SVAL(inbuf, smb_setup0); 3283 uint16 info_level; 3284 int dosmode=0; 3285 /* Foxconn modified start pling 11/19/2009 */ 3286 //SMB_OFF_T size=0; 3287 SMB_BIG_UINT size=0; 3288 /* Foxconn modified end pling 11/19/2009 */ 3289 struct utimbuf tvs; 3290 SMB_STRUCT_STAT sbuf; 3291 pstring fname; 3292 int fd = -1; 3293 BOOL bad_path = False; 3294 files_struct *fsp = NULL; 3295 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE; 3296 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE; 3297 mode_t unixmode = 0; 3298 NTSTATUS status = NT_STATUS_OK; 3299 3300 if (!params) 3301 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 3302 3303 ZERO_STRUCT(sbuf); 3304 3305 if (tran_call == TRANSACT2_SETFILEINFO) { 3306 if (total_params < 4) 3307 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3308 3309 fsp = file_fsp(params,0); 3310 info_level = SVAL(params,2); 3311 3312 if(fsp && (fsp->is_directory || fsp->fd == -1)) { 3313 /* 3314 * This is actually a SETFILEINFO on a directory 3315 * handle (returned from an NT SMB). NT5.0 seems 3316 * to do this call. JRA. 3317 */ 3318 pstrcpy(fname, fsp->fsp_name); 3319 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) { 3320 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno))); 3321 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 3322 } 3323 } else if (fsp && fsp->print_file) { 3324 /* 3325 * Doing a DELETE_ON_CLOSE should cancel a print job. 3326 */ 3327 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { 3328 fsp->share_mode = FILE_DELETE_ON_CLOSE; 3329 3330 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); 3331 3332 SSVAL(params,0,0); 3333 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 3334 return(-1); 3335 } else 3336 return (UNIXERROR(ERRDOS,ERRbadpath)); 3337 } else { 3338 /* 3339 * Original code - this is an open file. 3340 */ 3341 CHECK_FSP(fsp,conn); 3342 3343 pstrcpy(fname, fsp->fsp_name); 3344 fd = fsp->fd; 3345 3346 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) { 3347 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); 3348 return(UNIXERROR(ERRDOS,ERRbadfid)); 3349 } 3350 } 3351 } else { 3352 /* set path info */ 3353 if (total_params < 6) 3354 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3355 3356 info_level = SVAL(params,0); 3357 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False); 3358 if (!NT_STATUS_IS_OK(status)) { 3359 return ERROR_NT(status); 3360 } 3361 unix_convert(fname,conn,0,&bad_path,&sbuf); 3362 if (bad_path) { 3363 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 3364 } 3365 3366 /* 3367 * For CIFS UNIX extensions the target name may not exist. 3368 */ 3369 3370 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) { 3371 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno))); 3372 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 3373 } 3374 3375 if(!check_name(fname, conn)) { 3376 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); 3377 } 3378 3379 } 3380 3381 if (!CAN_WRITE(conn)) 3382 return ERROR_DOS(ERRSRV,ERRaccess); 3383 3384 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) 3385 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3386 3387 if (VALID_STAT(sbuf)) 3388 unixmode = sbuf.st_mode; 3389 3390 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", 3391 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data)); 3392 3393 /* Realloc the parameter and data sizes */ 3394 params = SMB_REALLOC(*pparams,2); 3395 if(params == NULL) 3396 return ERROR_DOS(ERRDOS,ERRnomem); 3397 *pparams = params; 3398 3399 SSVAL(params,0,0); 3400 3401 if (fsp && fsp->pending_modtime) { 3402 /* the pending modtime overrides the current modtime */ 3403 sbuf.st_mtime = fsp->pending_modtime; 3404 } 3405 3406 size = get_file_size(sbuf); 3407 tvs.modtime = sbuf.st_mtime; 3408 tvs.actime = sbuf.st_atime; 3409 dosmode = dos_mode(conn,fname,&sbuf); 3410 unixmode = sbuf.st_mode; 3411 3412 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE; 3413 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE; 3414 3415 switch (info_level) { 3416 case SMB_INFO_STANDARD: 3417 { 3418 if (total_data < 12) 3419 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3420 3421 /* access time */ 3422 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess); 3423 /* write time */ 3424 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite); 3425 break; 3426 } 3427 3428 case SMB_INFO_SET_EA: 3429 status = set_ea(conn, fsp, fname, pdata, total_data); 3430 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) 3431 return ERROR_NT(status); 3432 break; 3433 3434 /* XXXX um, i don't think this is right. 3435 it's also not in the cifs6.txt spec. 3436 */ 3437 case SMB_INFO_QUERY_EAS_FROM_LIST: 3438 if (total_data < 28) 3439 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3440 3441 tvs.actime = make_unix_date2(pdata+8); 3442 tvs.modtime = make_unix_date2(pdata+12); 3443 size = IVAL(pdata,16); 3444 dosmode = IVAL(pdata,24); 3445 break; 3446 3447 /* XXXX nor this. not in cifs6.txt, either. */ 3448 case SMB_INFO_QUERY_ALL_EAS: 3449 if (total_data < 28) 3450 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3451 3452 tvs.actime = make_unix_date2(pdata+8); 3453 tvs.modtime = make_unix_date2(pdata+12); 3454 size = IVAL(pdata,16); 3455 dosmode = IVAL(pdata,24); 3456 break; 3457 3458 case SMB_SET_FILE_BASIC_INFO: 3459 case SMB_FILE_BASIC_INFORMATION: 3460 { 3461 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */ 3462 time_t write_time; 3463 time_t changed_time; 3464 3465 if (total_data < 36) 3466 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3467 3468 /* Ignore create time at offset pdata. */ 3469 3470 /* access time */ 3471 tvs.actime = interpret_long_date(pdata+8); 3472 3473 write_time = interpret_long_date(pdata+16); 3474 changed_time = interpret_long_date(pdata+24); 3475 3476 tvs.modtime = MIN(write_time, changed_time); 3477 3478 if (write_time > tvs.modtime && write_time != (time_t)-1) { 3479 tvs.modtime = write_time; 3480 } 3481 /* Prefer a defined time to an undefined one. */ 3482 if (null_mtime(tvs.modtime)) { 3483 tvs.modtime = null_mtime(write_time) ? changed_time : write_time; 3484 } 3485 3486 /* attributes */ 3487 dosmode = IVAL(pdata,32); 3488 break; 3489 } 3490 3491 case SMB_FILE_ALLOCATION_INFORMATION: 3492 case SMB_SET_FILE_ALLOCATION_INFO: 3493 { 3494 int ret = -1; 3495 SMB_BIG_UINT allocation_size; 3496 3497 if (total_data < 8) 3498 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3499 3500 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0); 3501#ifdef LARGE_SMB_OFF_T 3502 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); 3503#else /* LARGE_SMB_OFF_T */ 3504 /* Foxconn modified start pling 03/11/2011 */ 3505#if 0 3506 if (IVAL(pdata,4) != 0) /* more than 32 bits? */ 3507 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3508#endif 3509 if (IVAL(pdata,4) != 0) /* more than 32 bits? */ 3510 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); 3511 /* Foxconn modified end pling 03/11/2011 */ 3512#endif /* LARGE_SMB_OFF_T */ 3513 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", 3514 fname, (double)allocation_size )); 3515 3516 if (allocation_size) { 3517 allocation_size = smb_roundup(conn, allocation_size); 3518 } 3519 3520 if(allocation_size != get_file_size(sbuf)) { 3521 SMB_STRUCT_STAT new_sbuf; 3522 3523 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n", 3524 fname, (double)allocation_size )); 3525 3526 if (fd == -1) { 3527 files_struct *new_fsp = NULL; 3528 int access_mode = 0; 3529 int action = 0; 3530 3531 if(global_oplock_break) { 3532 /* Queue this file modify as we are the process of an oplock break. */ 3533 3534 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being ")); 3535 DEBUGADD(2,( "in oplock break state.\n")); 3536 3537 push_oplock_pending_smb_message(inbuf, length); 3538 return -1; 3539 } 3540 3541 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA, 3542 SET_OPEN_MODE(DOS_OPEN_RDWR), 3543 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 3544 FILE_ATTRIBUTE_NORMAL, 3545 INTERNAL_OPEN_ONLY, &access_mode, &action); 3546 3547 if (new_fsp == NULL) 3548 return(UNIXERROR(ERRDOS,ERRbadpath)); 3549 ret = vfs_allocate_file_space(new_fsp, allocation_size); 3550 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) { 3551 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n", 3552 new_fsp->fnum, strerror(errno))); 3553 ret = -1; 3554 } 3555 close_file(new_fsp,True); 3556 } else { 3557 ret = vfs_allocate_file_space(fsp, allocation_size); 3558 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) { 3559 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n", 3560 fsp->fnum, strerror(errno))); 3561 ret = -1; 3562 } 3563 } 3564 if (ret == -1) 3565 return ERROR_NT(NT_STATUS_DISK_FULL); 3566 3567 /* Allocate can truncate size... */ 3568 size = get_file_size(new_sbuf); 3569 } 3570 3571 break; 3572 } 3573 3574 case SMB_FILE_END_OF_FILE_INFORMATION: 3575 case SMB_SET_FILE_END_OF_FILE_INFO: 3576 { 3577 if (total_data < 8) 3578 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3579 3580 size = IVAL(pdata,0); 3581#ifdef LARGE_SMB_OFF_T 3582 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); 3583#else /* LARGE_SMB_OFF_T */ 3584 /* Foxconn modified start pling 11/19/2009 */ 3585 /* We should support large file size */ 3586#if 0 3587 if (IVAL(pdata,4) != 0) /* more than 32 bits? */ 3588 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3589#endif 3590 if (IVAL(pdata,4) != 0) { /* more than 32 bits? */ 3591 size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); 3592 } 3593 /* Foxconn modified end pling 11/19/2009 */ 3594#endif /* LARGE_SMB_OFF_T */ 3595 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size )); 3596 break; 3597 } 3598 3599 case SMB_FILE_DISPOSITION_INFORMATION: 3600 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */ 3601 { 3602 BOOL delete_on_close; 3603 3604 if (total_data < 1) 3605 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3606 3607 delete_on_close = (CVAL(pdata,0) ? True : False); 3608 3609 /* Just ignore this set on a path. */ 3610 if (tran_call != TRANSACT2_SETFILEINFO) 3611 break; 3612 3613 if (fsp == NULL) 3614 return(UNIXERROR(ERRDOS,ERRbadfid)); 3615 3616 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode); 3617 3618 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) 3619 return ERROR_NT(status); 3620 3621 /* The set is across all open files on this dev/inode pair. */ 3622 status =set_delete_on_close_over_all(fsp, delete_on_close); 3623 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) 3624 return ERROR_NT(status); 3625 3626 break; 3627 } 3628 3629 case SMB_FILE_POSITION_INFORMATION: 3630 { 3631 SMB_BIG_UINT position_information; 3632 3633 if (total_data < 8) 3634 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3635 3636 position_information = (SMB_BIG_UINT)IVAL(pdata,0); 3637#ifdef LARGE_SMB_OFF_T 3638 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); 3639#else /* LARGE_SMB_OFF_T */ 3640 /* Foxconn modified start pling 03/11/2011 */ 3641 /* Fix potential incorrect file size issue if file size > 4GB */ 3642#if 0 3643 if (IVAL(pdata,4) != 0) /* more than 32 bits? */ 3644 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3645#endif 3646 if (IVAL(pdata,4) != 0) /* more than 32 bits? */ 3647 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); 3648 /* Foxconn modified end pling 03/11/2011 */ 3649#endif /* LARGE_SMB_OFF_T */ 3650 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n", 3651 fname, (double)position_information )); 3652 if (fsp) 3653 fsp->position_information = position_information; 3654 break; 3655 } 3656 3657 /* 3658 * CIFS UNIX extensions. 3659 */ 3660 3661 case SMB_SET_FILE_UNIX_BASIC: 3662 { 3663 uint32 raw_unixmode; 3664 3665 if (total_data < 100) 3666 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3667 3668 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO && 3669 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) { 3670 size=IVAL(pdata,0); /* first 8 Bytes are size */ 3671#ifdef LARGE_SMB_OFF_T 3672 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); 3673#else /* LARGE_SMB_OFF_T */ 3674 /* Foxconn modified start pling 03/11/2011 */ 3675 /* Fix potential incorrect file size issue if file size > 4GB */ 3676#if 0 3677 if (IVAL(pdata,4) != 0) /* more than 32 bits? */ 3678 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3679#endif 3680 if (IVAL(pdata,4) != 0) /* more than 32 bits? */ 3681 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); 3682 /* Foxconn modified end pling 03/11/2011 */ 3683#endif /* LARGE_SMB_OFF_T */ 3684 } 3685 pdata+=24; /* ctime & st_blocks are not changed */ 3686 tvs.actime = interpret_long_date(pdata); /* access_time */ 3687 tvs.modtime = interpret_long_date(pdata+8); /* modification_time */ 3688 pdata+=16; 3689 set_owner = (uid_t)IVAL(pdata,0); 3690 pdata += 8; 3691 set_grp = (gid_t)IVAL(pdata,0); 3692 pdata += 8; 3693 raw_unixmode = IVAL(pdata,28); 3694 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode); 3695 dosmode = 0; /* Ensure dos mode change doesn't override this. */ 3696 3697 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \ 3698size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", 3699 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode)); 3700 3701 if (!VALID_STAT(sbuf)) { 3702 3703 /* 3704 * The only valid use of this is to create character and block 3705 * devices, and named pipes. This is deprecated (IMHO) and 3706 * a new info level should be used for mknod. JRA. 3707 */ 3708 3709 uint32 file_type = IVAL(pdata,0); 3710#if defined(HAVE_MAKEDEV) 3711 uint32 dev_major = IVAL(pdata,4); 3712 uint32 dev_minor = IVAL(pdata,12); 3713#endif 3714 3715 uid_t myuid = geteuid(); 3716 gid_t mygid = getegid(); 3717 SMB_DEV_T dev = (SMB_DEV_T)0; 3718 3719 if (tran_call == TRANSACT2_SETFILEINFO) 3720 return(ERROR_DOS(ERRDOS,ERRnoaccess)); 3721 3722 if (raw_unixmode == SMB_MODE_NO_CHANGE) 3723 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3724 3725#if defined(HAVE_MAKEDEV) 3726 dev = makedev(dev_major, dev_minor); 3727#endif 3728 3729 /* We can only create as the owner/group we are. */ 3730 3731 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE)) 3732 return(ERROR_DOS(ERRDOS,ERRnoaccess)); 3733 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE)) 3734 return(ERROR_DOS(ERRDOS,ERRnoaccess)); 3735 3736 switch (file_type) { 3737#if defined(S_IFIFO) 3738 case UNIX_TYPE_FIFO: 3739 unixmode |= S_IFIFO; 3740 break; 3741#endif 3742#if defined(S_IFSOCK) 3743 case UNIX_TYPE_SOCKET: 3744 unixmode |= S_IFSOCK; 3745 break; 3746#endif 3747#if defined(S_IFCHR) 3748 case UNIX_TYPE_CHARDEV: 3749 unixmode |= S_IFCHR; 3750 break; 3751#endif 3752#if defined(S_IFBLK) 3753 case UNIX_TYPE_BLKDEV: 3754 unixmode |= S_IFBLK; 3755 break; 3756#endif 3757 default: 3758 return(ERROR_DOS(ERRDOS,ERRnoaccess)); 3759 } 3760 3761 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \ 37620%o for file %s\n", (double)dev, unixmode, fname )); 3763 3764 /* Ok - do the mknod. */ 3765 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0) 3766 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3767 3768 inherit_access_acl(conn, fname, unixmode); 3769 3770 SSVAL(params,0,0); 3771 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 3772 return(-1); 3773 } 3774 3775 /* 3776 * Deal with the UNIX specific mode set. 3777 */ 3778 3779 if (raw_unixmode != SMB_MODE_NO_CHANGE) { 3780 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n", 3781 (unsigned int)unixmode, fname )); 3782 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0) 3783 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3784 } 3785 3786 /* 3787 * Deal with the UNIX specific uid set. 3788 */ 3789 3790 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) { 3791 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n", 3792 (unsigned int)set_owner, fname )); 3793 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0) 3794 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3795 } 3796 3797 /* 3798 * Deal with the UNIX specific gid set. 3799 */ 3800 3801 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) { 3802 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n", 3803 (unsigned int)set_owner, fname )); 3804 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0) 3805 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3806 } 3807 break; 3808 } 3809 3810 case SMB_SET_FILE_UNIX_LINK: 3811 { 3812 pstring link_target; 3813 char *newname = fname; 3814 3815 /* Set a symbolic link. */ 3816 /* Don't allow this if follow links is false. */ 3817 3818 if (!lp_symlinks(SNUM(conn))) 3819 return(ERROR_DOS(ERRDOS,ERRnoaccess)); 3820 3821 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE); 3822 3823 /* !widelinks forces the target path to be within the share. */ 3824 /* This means we can interpret the target as a pathname. */ 3825 if (!lp_widelinks(SNUM(conn))) { 3826 pstring rel_name; 3827 char *last_dirp = NULL; 3828 3829 unix_format(link_target); 3830 if (*link_target == '/') { 3831 /* No absolute paths allowed. */ 3832 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3833 } 3834 pstrcpy(rel_name, newname); 3835 last_dirp = strrchr_m(rel_name, '/'); 3836 if (last_dirp) { 3837 last_dirp[1] = '\0'; 3838 } else { 3839 pstrcpy(rel_name, "./"); 3840 } 3841 pstrcat(rel_name, link_target); 3842 3843 if (!check_name(rel_name, conn)) { 3844 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3845 } 3846 } 3847 3848 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n", 3849 fname, link_target )); 3850 3851 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) 3852 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3853 SSVAL(params,0,0); 3854 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 3855 return(-1); 3856 } 3857 3858 case SMB_SET_FILE_UNIX_HLINK: 3859 { 3860 pstring oldname; 3861 char *newname = fname; 3862 3863 /* Set a hard link. */ 3864 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False); 3865 if (!NT_STATUS_IS_OK(status)) { 3866 return ERROR_NT(status); 3867 } 3868 3869 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n", 3870 fname, oldname)); 3871 3872 status = hardlink_internals(conn, oldname, newname); 3873 if (!NT_STATUS_IS_OK(status)) { 3874 return ERROR_NT(status); 3875 } 3876 3877 SSVAL(params,0,0); 3878 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 3879 return(-1); 3880 } 3881 3882 case SMB_FILE_RENAME_INFORMATION: 3883 { 3884 BOOL overwrite; 3885 uint32 root_fid; 3886 uint32 len; 3887 pstring newname; 3888 pstring base_name; 3889 char *p; 3890 3891 if (total_data < 12) 3892 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3893 3894 overwrite = (CVAL(pdata,0) ? True : False); 3895 root_fid = IVAL(pdata,4); 3896 len = IVAL(pdata,8); 3897 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False); 3898 if (!NT_STATUS_IS_OK(status)) { 3899 return ERROR_NT(status); 3900 } 3901 3902 /* Check the new name has no '/' characters. */ 3903 if (strchr_m(newname, '/')) 3904 return ERROR_NT(NT_STATUS_NOT_SUPPORTED); 3905 3906 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf); 3907 3908 /* Create the base directory. */ 3909 pstrcpy(base_name, fname); 3910 p = strrchr_m(base_name, '/'); 3911 if (p) 3912 *p = '\0'; 3913 /* Append the new name. */ 3914 pstrcat(base_name, "/"); 3915 pstrcat(base_name, newname); 3916 3917 if (fsp) { 3918 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n", 3919 fsp->fnum, fsp->fsp_name, base_name )); 3920 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite); 3921 } else { 3922 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n", 3923 fname, newname )); 3924 status = rename_internals(conn, fname, base_name, 0, overwrite); 3925 } 3926 if (!NT_STATUS_IS_OK(status)) { 3927 return ERROR_NT(status); 3928 } 3929 process_pending_change_notify_queue((time_t)0); 3930 SSVAL(params,0,0); 3931 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 3932 return(-1); 3933 } 3934 3935#if defined(HAVE_POSIX_ACLS) 3936 case SMB_SET_POSIX_ACL: 3937 { 3938 uint16 posix_acl_version; 3939 uint16 num_file_acls; 3940 uint16 num_def_acls; 3941 BOOL valid_file_acls = True; 3942 BOOL valid_def_acls = True; 3943 3944 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) { 3945 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3946 } 3947 posix_acl_version = SVAL(pdata,0); 3948 num_file_acls = SVAL(pdata,2); 3949 num_def_acls = SVAL(pdata,4); 3950 3951 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) { 3952 valid_file_acls = False; 3953 num_file_acls = 0; 3954 } 3955 3956 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) { 3957 valid_def_acls = False; 3958 num_def_acls = 0; 3959 } 3960 3961 if (posix_acl_version != SMB_POSIX_ACL_VERSION) { 3962 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3963 } 3964 3965 if (total_data < SMB_POSIX_ACL_HEADER_SIZE + 3966 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) { 3967 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 3968 } 3969 3970 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls, 3971 pdata + SMB_POSIX_ACL_HEADER_SIZE)) { 3972 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3973 } 3974 3975 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls, 3976 pdata + SMB_POSIX_ACL_HEADER_SIZE + 3977 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) { 3978 return(UNIXERROR(ERRDOS,ERRnoaccess)); 3979 } 3980 3981 SSVAL(params,0,0); 3982 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 3983 return(-1); 3984 } 3985#endif 3986 3987 default: 3988 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3989 } 3990 3991 /* get some defaults (no modifications) if any info is zero or -1. */ 3992 if (null_mtime(tvs.actime)) { 3993 tvs.actime = sbuf.st_atime; 3994 } 3995 3996 if (null_mtime(tvs.modtime)) { 3997 tvs.modtime = sbuf.st_mtime; 3998 } 3999 4000 DEBUG(6,("actime: %s " , ctime(&tvs.actime))); 4001 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime))); 4002 DEBUG(6,("size: %.0f ", (double)size)); 4003 4004 if (dosmode) { 4005 if (S_ISDIR(sbuf.st_mode)) 4006 dosmode |= aDIR; 4007 else 4008 dosmode &= ~aDIR; 4009 } 4010 4011 DEBUG(6,("dosmode: %x\n" , dosmode)); 4012 4013 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) || 4014 (info_level == SMB_SET_FILE_ALLOCATION_INFO) || 4015 (info_level == SMB_FILE_ALLOCATION_INFORMATION) || 4016 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) { 4017 4018 /* 4019 * Only do this test if we are not explicitly 4020 * changing the size of a file. 4021 */ 4022 if (!size) 4023 size = get_file_size(sbuf); 4024 } 4025 4026 /* 4027 * Try and set the times, size and mode of this file - 4028 * if they are different from the current values 4029 */ 4030 4031 /* check the mode isn't different, before changing it */ 4032 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) { 4033 4034 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode )); 4035 4036 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) { 4037 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno))); 4038 return(UNIXERROR(ERRDOS,ERRnoaccess)); 4039 } 4040 } 4041 4042 /* Now the size. */ 4043 if (size != get_file_size(sbuf)) { 4044 4045 int ret; 4046 4047 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n", 4048 fname, (double)size )); 4049 4050 if (fd == -1) { 4051 files_struct *new_fsp = NULL; 4052 int access_mode = 0; 4053 int action = 0; 4054 4055 if(global_oplock_break) { 4056 /* Queue this file modify as we are the process of an oplock break. */ 4057 4058 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being ")); 4059 DEBUGADD(2,( "in oplock break state.\n")); 4060 4061 push_oplock_pending_smb_message(inbuf, length); 4062 return -1; 4063 } 4064 4065 new_fsp = open_file_shared(conn, fname, &sbuf, 4066 SET_OPEN_MODE(DOS_OPEN_RDWR), 4067 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 4068 FILE_ATTRIBUTE_NORMAL, 4069 INTERNAL_OPEN_ONLY, &access_mode, &action); 4070 4071 if (new_fsp == NULL) 4072 return(UNIXERROR(ERRDOS,ERRbadpath)); 4073 ret = vfs_set_filelen(new_fsp, size); 4074 close_file(new_fsp,True); 4075 } else { 4076 ret = vfs_set_filelen(fsp, size); 4077 } 4078 4079 if (ret == -1) 4080 return (UNIXERROR(ERRHRD,ERRdiskfull)); 4081 } 4082 4083 /* 4084 * Finally the times. 4085 */ 4086 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) { 4087 if(fsp != NULL) { 4088 /* 4089 * This was a setfileinfo on an open file. 4090 * NT does this a lot. We also need to 4091 * set the time here, as it can be read by 4092 * FindFirst/FindNext and with the patch for bug #2045 4093 * in smbd/fileio.c it ensures that this timestamp is 4094 * kept sticky even after a write. We save the request 4095 * away and will set it on file close and after a write. JRA. 4096 */ 4097 4098 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) { 4099 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) )); 4100 fsp_set_pending_modtime(fsp, tvs.modtime); 4101 } 4102 4103 } 4104 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n")); 4105 4106 if(file_utime(conn, fname, &tvs)!=0) { 4107 return(UNIXERROR(ERRDOS,ERRnoaccess)); 4108 } 4109 } 4110 4111 SSVAL(params,0,0); 4112 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 4113 4114 return(-1); 4115} 4116 4117/**************************************************************************** 4118 Reply to a TRANS2_MKDIR (make directory with extended attributes). 4119****************************************************************************/ 4120 4121static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 4122 char **pparams, int total_params, char **ppdata, int total_data, 4123 unsigned int max_data_bytes) 4124{ 4125 char *params = *pparams; 4126 pstring directory; 4127 int ret = -1; 4128 SMB_STRUCT_STAT sbuf; 4129 BOOL bad_path = False; 4130 NTSTATUS status = NT_STATUS_OK; 4131 4132 if (!CAN_WRITE(conn)) 4133 return ERROR_DOS(ERRSRV,ERRaccess); 4134 4135 if (total_params < 4) 4136 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 4137 4138 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False); 4139 if (!NT_STATUS_IS_OK(status)) { 4140 return ERROR_NT(status); 4141 } 4142 4143 DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); 4144 4145 unix_convert(directory,conn,0,&bad_path,&sbuf); 4146 if (bad_path) { 4147 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 4148 } 4149 if (check_name(directory,conn)) 4150 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True)); 4151 4152 if(ret < 0) { 4153 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno))); 4154 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess); 4155 } 4156 4157 /* Realloc the parameter and data sizes */ 4158 params = SMB_REALLOC(*pparams,2); 4159 if(params == NULL) 4160 return ERROR_DOS(ERRDOS,ERRnomem); 4161 *pparams = params; 4162 4163 SSVAL(params,0,0); 4164 4165 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); 4166 4167 return(-1); 4168} 4169 4170/**************************************************************************** 4171 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes). 4172 We don't actually do this - we just send a null response. 4173****************************************************************************/ 4174 4175static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 4176 char **pparams, int total_params, char **ppdata, int total_data, 4177 unsigned int max_data_bytes) 4178{ 4179 static uint16 fnf_handle = 257; 4180 char *params = *pparams; 4181 uint16 info_level; 4182 4183 if (total_params < 6) 4184 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 4185 4186 info_level = SVAL(params,4); 4187 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level)); 4188 4189 switch (info_level) { 4190 case 1: 4191 case 2: 4192 break; 4193 default: 4194 return ERROR_DOS(ERRDOS,ERRunknownlevel); 4195 } 4196 4197 /* Realloc the parameter and data sizes */ 4198 params = SMB_REALLOC(*pparams,6); 4199 if(params == NULL) 4200 return ERROR_DOS(ERRDOS,ERRnomem); 4201 *pparams = params; 4202 4203 SSVAL(params,0,fnf_handle); 4204 SSVAL(params,2,0); /* No changes */ 4205 SSVAL(params,4,0); /* No EA errors */ 4206 4207 fnf_handle++; 4208 4209 if(fnf_handle == 0) 4210 fnf_handle = 257; 4211 4212 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0); 4213 4214 return(-1); 4215} 4216 4217/**************************************************************************** 4218 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 4219 changes). Currently this does nothing. 4220****************************************************************************/ 4221 4222static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 4223 char **pparams, int total_params, char **ppdata, int total_data, 4224 unsigned int max_data_bytes) 4225{ 4226 char *params = *pparams; 4227 4228 DEBUG(3,("call_trans2findnotifynext\n")); 4229 4230 /* Realloc the parameter and data sizes */ 4231 params = SMB_REALLOC(*pparams,4); 4232 if(params == NULL) 4233 return ERROR_DOS(ERRDOS,ERRnomem); 4234 *pparams = params; 4235 4236 SSVAL(params,0,0); /* No changes */ 4237 SSVAL(params,2,0); /* No EA errors */ 4238 4239 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0); 4240 4241 return(-1); 4242} 4243 4244/**************************************************************************** 4245 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>. 4246****************************************************************************/ 4247 4248static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize, 4249 char **pparams, int total_params, char **ppdata, int total_data, 4250 unsigned int max_data_bytes) 4251{ 4252 char *params = *pparams; 4253 pstring pathname; 4254 int reply_size = 0; 4255 int max_referral_level; 4256 4257 DEBUG(10,("call_trans2getdfsreferral\n")); 4258 4259 if (total_params < 2) 4260 return(ERROR_DOS(ERRDOS,ERRinvalidparam)); 4261 4262 max_referral_level = SVAL(params,0); 4263 4264 if(!lp_host_msdfs()) 4265 return ERROR_DOS(ERRDOS,ERRbadfunc); 4266 4267 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); 4268 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0) 4269 return UNIXERROR(ERRDOS,ERRbadfile); 4270 4271 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); 4272 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size); 4273 4274 return(-1); 4275} 4276 4277#define LMCAT_SPL 0x53 4278#define LMFUNC_GETJOBID 0x60 4279 4280/**************************************************************************** 4281 Reply to a TRANS2_IOCTL - used for OS/2 printing. 4282****************************************************************************/ 4283 4284static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize, 4285 char **pparams, int total_params, char **ppdata, int total_data, 4286 unsigned int max_data_bytes) 4287{ 4288 char *pdata = *ppdata; 4289 files_struct *fsp = file_fsp(inbuf,smb_vwv15); 4290 4291 /* check for an invalid fid before proceeding */ 4292 4293 if (!fsp) 4294 return(ERROR_DOS(ERRDOS,ERRbadfid)); 4295 4296 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) && 4297 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { 4298 pdata = SMB_REALLOC(*ppdata, 32); 4299 if(pdata == NULL) 4300 return ERROR_DOS(ERRDOS,ERRnomem); 4301 *ppdata = pdata; 4302 4303 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2 4304 CAN ACCEPT THIS IN UNICODE. JRA. */ 4305 4306 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */ 4307 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */ 4308 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */ 4309 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32); 4310 return(-1); 4311 } else { 4312 DEBUG(2,("Unknown TRANS2_IOCTL\n")); 4313 return ERROR_DOS(ERRSRV,ERRerror); 4314 } 4315} 4316 4317/**************************************************************************** 4318 Reply to a SMBfindclose (stop trans2 directory search). 4319****************************************************************************/ 4320 4321int reply_findclose(connection_struct *conn, 4322 char *inbuf,char *outbuf,int length,int bufsize) 4323{ 4324 int outsize = 0; 4325 int dptr_num=SVALS(inbuf,smb_vwv0); 4326 START_PROFILE(SMBfindclose); 4327 4328 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num)); 4329 4330 dptr_close(&dptr_num); 4331 4332 outsize = set_message(outbuf,0,0,True); 4333 4334 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num)); 4335 4336 END_PROFILE(SMBfindclose); 4337 return(outsize); 4338} 4339 4340/**************************************************************************** 4341 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search). 4342****************************************************************************/ 4343 4344int reply_findnclose(connection_struct *conn, 4345 char *inbuf,char *outbuf,int length,int bufsize) 4346{ 4347 int outsize = 0; 4348 int dptr_num= -1; 4349 START_PROFILE(SMBfindnclose); 4350 4351 dptr_num = SVAL(inbuf,smb_vwv0); 4352 4353 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num)); 4354 4355 /* We never give out valid handles for a 4356 findnotifyfirst - so any dptr_num is ok here. 4357 Just ignore it. */ 4358 4359 outsize = set_message(outbuf,0,0,True); 4360 4361 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num)); 4362 4363 END_PROFILE(SMBfindnclose); 4364 return(outsize); 4365} 4366 4367/**************************************************************************** 4368 Reply to a SMBtranss2 - just ignore it! 4369****************************************************************************/ 4370 4371int reply_transs2(connection_struct *conn, 4372 char *inbuf,char *outbuf,int length,int bufsize) 4373{ 4374 START_PROFILE(SMBtranss2); 4375 DEBUG(4,("Ignoring transs2 of length %d\n",length)); 4376 END_PROFILE(SMBtranss2); 4377 return(-1); 4378} 4379 4380/**************************************************************************** 4381 Reply to a SMBtrans2. 4382****************************************************************************/ 4383 4384int reply_trans2(connection_struct *conn, 4385 char *inbuf,char *outbuf,int length,int bufsize) 4386{ 4387 int outsize = 0; 4388 unsigned int total_params = SVAL(inbuf, smb_tpscnt); 4389 unsigned int total_data =SVAL(inbuf, smb_tdscnt); 4390 unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt); 4391#if 0 4392 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt); 4393 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt); 4394 BOOL close_tid = BITSETW(inbuf+smb_flags,0); 4395 BOOL no_final_response = BITSETW(inbuf+smb_flags,1); 4396 int32 timeout = IVALS(inbuf,smb_timeout); 4397#endif 4398 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt); 4399 unsigned int tran_call = SVAL(inbuf, smb_setup0); 4400 char *params = NULL, *data = NULL; 4401 unsigned int num_params, num_params_sofar, num_data, num_data_sofar; 4402 START_PROFILE(SMBtrans2); 4403 4404 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) { 4405 /* Queue this open message as we are the process of an 4406 * oplock break. */ 4407 4408 DEBUG(2,("reply_trans2: queueing message trans2open due to being ")); 4409 DEBUGADD(2,( "in oplock break state.\n")); 4410 4411 push_oplock_pending_smb_message(inbuf, length); 4412 END_PROFILE(SMBtrans2); 4413 return -1; 4414 } 4415 4416 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN) 4417 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) { 4418 END_PROFILE(SMBtrans2); 4419 return ERROR_DOS(ERRSRV,ERRaccess); 4420 } 4421 4422 outsize = set_message(outbuf,0,0,True); 4423 4424 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this 4425 is so as a sanity check */ 4426 if (suwcnt != 1) { 4427 /* 4428 * Need to have rc=0 for ioctl to get job id for OS/2. 4429 * Network printing will fail if function is not successful. 4430 * Similar function in reply.c will be used if protocol 4431 * is LANMAN1.0 instead of LM1.2X002. 4432 * Until DosPrintSetJobInfo with PRJINFO3 is supported, 4433 * outbuf doesn't have to be set(only job id is used). 4434 */ 4435 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) && 4436 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) && 4437 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { 4438 DEBUG(2,("Got Trans2 DevIOctl jobid\n")); 4439 } else { 4440 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt)); 4441 DEBUG(2,("Transaction is %d\n",tran_call)); 4442 END_PROFILE(SMBtrans2); 4443 ERROR_DOS(ERRDOS,ERRinvalidparam); 4444 } 4445 } 4446 4447 /* Allocate the space for the maximum needed parameters and data */ 4448 if (total_params > 0) 4449 params = (char *)SMB_MALLOC(total_params); 4450 if (total_data > 0) 4451 data = (char *)SMB_MALLOC(total_data); 4452 4453 if ((total_params && !params) || (total_data && !data)) { 4454 DEBUG(2,("Out of memory in reply_trans2\n")); 4455 SAFE_FREE(params); 4456 SAFE_FREE(data); 4457 END_PROFILE(SMBtrans2); 4458 return ERROR_DOS(ERRDOS,ERRnomem); 4459 } 4460 4461 /* Copy the param and data bytes sent with this request into 4462 the params buffer */ 4463 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt); 4464 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt); 4465 4466 if (num_params > total_params || num_data > total_data) 4467 exit_server("invalid params in reply_trans2"); 4468 4469 if(params) { 4470 unsigned int psoff = SVAL(inbuf, smb_psoff); 4471 if ((psoff + num_params < psoff) || (psoff + num_params < num_params)) 4472 goto bad_param; 4473 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) || 4474 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf))) 4475 goto bad_param; 4476 memcpy( params, smb_base(inbuf) + psoff, num_params); 4477 } 4478 if(data) { 4479 unsigned int dsoff = SVAL(inbuf, smb_dsoff); 4480 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data)) 4481 goto bad_param; 4482 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) || 4483 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf))) 4484 goto bad_param; 4485 memcpy( data, smb_base(inbuf) + dsoff, num_data); 4486 } 4487 4488 srv_signing_trans_start(SVAL(inbuf,smb_mid)); 4489 4490 if(num_data_sofar < total_data || num_params_sofar < total_params) { 4491 /* We need to send an interim response then receive the rest 4492 of the parameter/data bytes */ 4493 outsize = set_message(outbuf,0,0,True); 4494 srv_signing_trans_stop(); 4495 if (!send_smb(smbd_server_fd(),outbuf)) 4496 exit_server("reply_trans2: send_smb failed."); 4497 4498 while (num_data_sofar < total_data || 4499 num_params_sofar < total_params) { 4500 BOOL ret; 4501 unsigned int param_disp; 4502 unsigned int param_off; 4503 unsigned int data_disp; 4504 unsigned int data_off; 4505 4506 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT); 4507 4508 /* 4509 * The sequence number for the trans reply is always 4510 * based on the last secondary received. 4511 */ 4512 4513 srv_signing_trans_start(SVAL(inbuf,smb_mid)); 4514 4515 if ((ret && 4516 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) { 4517 outsize = set_message(outbuf,0,0,True); 4518 if(ret) 4519 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n")); 4520 else 4521 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n", 4522 (smb_read_error == READ_ERROR) ? "error" : "timeout" )); 4523 goto bad_param; 4524 } 4525 4526 /* Revise total_params and total_data in case 4527 they have changed downwards */ 4528 if (SVAL(inbuf, smb_tpscnt) < total_params) 4529 total_params = SVAL(inbuf, smb_tpscnt); 4530 if (SVAL(inbuf, smb_tdscnt) < total_data) 4531 total_data = SVAL(inbuf, smb_tdscnt); 4532 4533 num_params = SVAL(inbuf,smb_spscnt); 4534 param_off = SVAL(inbuf, smb_spsoff); 4535 param_disp = SVAL(inbuf, smb_spsdisp); 4536 num_params_sofar += num_params; 4537 4538 num_data = SVAL(inbuf, smb_sdscnt); 4539 data_off = SVAL(inbuf, smb_sdsoff); 4540 data_disp = SVAL(inbuf, smb_sdsdisp); 4541 num_data_sofar += num_data; 4542 4543 if (num_params_sofar > total_params || num_data_sofar > total_data) 4544 goto bad_param; 4545 4546 if (num_params) { 4547 if (param_disp + num_params > total_params) 4548 goto bad_param; 4549 if ((param_disp + num_params < param_disp) || 4550 (param_disp + num_params < num_params)) 4551 goto bad_param; 4552 if (param_disp > total_params) 4553 goto bad_param; 4554 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) || 4555 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf))) 4556 goto bad_param; 4557 if (params + param_disp < params) 4558 goto bad_param; 4559 4560 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params); 4561 } 4562 if (num_data) { 4563 if (data_disp + num_data > total_data) 4564 goto bad_param; 4565 if ((data_disp + num_data < data_disp) || 4566 (data_disp + num_data < num_data)) 4567 goto bad_param; 4568 if (data_disp > total_data) 4569 goto bad_param; 4570 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) || 4571 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf))) 4572 goto bad_param; 4573 if (data + data_disp < data) 4574 goto bad_param; 4575 4576 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data); 4577 } 4578 } 4579 } 4580 4581 if (Protocol >= PROTOCOL_NT1) { 4582 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */ 4583 } 4584 4585 /* Now we must call the relevant TRANS2 function */ 4586 switch(tran_call) { 4587 case TRANSACT2_OPEN: 4588 START_PROFILE_NESTED(Trans2_open); 4589 outsize = call_trans2open(conn, inbuf, outbuf, bufsize, 4590 ¶ms, total_params, &data, total_data, max_data_bytes); 4591 END_PROFILE_NESTED(Trans2_open); 4592 break; 4593 4594 case TRANSACT2_FINDFIRST: 4595 START_PROFILE_NESTED(Trans2_findfirst); 4596 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize, 4597 ¶ms, total_params, &data, total_data, max_data_bytes); 4598 END_PROFILE_NESTED(Trans2_findfirst); 4599 break; 4600 4601 case TRANSACT2_FINDNEXT: 4602 START_PROFILE_NESTED(Trans2_findnext); 4603 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize, 4604 ¶ms, total_params, &data, total_data, max_data_bytes); 4605 END_PROFILE_NESTED(Trans2_findnext); 4606 break; 4607 4608 case TRANSACT2_QFSINFO: 4609 START_PROFILE_NESTED(Trans2_qfsinfo); 4610 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize, 4611 ¶ms, total_params, &data, total_data, max_data_bytes); 4612 END_PROFILE_NESTED(Trans2_qfsinfo); 4613 break; 4614 4615#ifdef HAVE_SYS_QUOTAS 4616 case TRANSACT2_SETFSINFO: 4617 START_PROFILE_NESTED(Trans2_setfsinfo); 4618 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize, 4619 ¶ms, total_params, &data, total_data, max_data_bytes); 4620 END_PROFILE_NESTED(Trans2_setfsinfo); 4621 break; 4622#endif 4623 case TRANSACT2_QPATHINFO: 4624 case TRANSACT2_QFILEINFO: 4625 START_PROFILE_NESTED(Trans2_qpathinfo); 4626 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize, 4627 ¶ms, total_params, &data, total_data, max_data_bytes); 4628 END_PROFILE_NESTED(Trans2_qpathinfo); 4629 break; 4630 case TRANSACT2_SETPATHINFO: 4631 case TRANSACT2_SETFILEINFO: 4632 START_PROFILE_NESTED(Trans2_setpathinfo); 4633 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize, 4634 ¶ms, total_params, &data, total_data, max_data_bytes); 4635 END_PROFILE_NESTED(Trans2_setpathinfo); 4636 break; 4637 4638 case TRANSACT2_FINDNOTIFYFIRST: 4639 START_PROFILE_NESTED(Trans2_findnotifyfirst); 4640 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize, 4641 ¶ms, total_params, &data, total_data, max_data_bytes); 4642 END_PROFILE_NESTED(Trans2_findnotifyfirst); 4643 break; 4644 4645 case TRANSACT2_FINDNOTIFYNEXT: 4646 START_PROFILE_NESTED(Trans2_findnotifynext); 4647 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize, 4648 ¶ms, total_params, &data, total_data, max_data_bytes); 4649 END_PROFILE_NESTED(Trans2_findnotifynext); 4650 break; 4651 case TRANSACT2_MKDIR: 4652 START_PROFILE_NESTED(Trans2_mkdir); 4653 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize, 4654 ¶ms, total_params, &data, total_data, max_data_bytes); 4655 END_PROFILE_NESTED(Trans2_mkdir); 4656 break; 4657 4658 case TRANSACT2_GET_DFS_REFERRAL: 4659 START_PROFILE_NESTED(Trans2_get_dfs_referral); 4660 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize, 4661 ¶ms, total_params, &data, total_data, max_data_bytes); 4662 END_PROFILE_NESTED(Trans2_get_dfs_referral); 4663 break; 4664 case TRANSACT2_IOCTL: 4665 START_PROFILE_NESTED(Trans2_ioctl); 4666 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize, 4667 ¶ms, total_params, &data, total_data, max_data_bytes); 4668 END_PROFILE_NESTED(Trans2_ioctl); 4669 break; 4670 default: 4671 /* Error in request */ 4672 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call)); 4673 SAFE_FREE(params); 4674 SAFE_FREE(data); 4675 END_PROFILE(SMBtrans2); 4676 srv_signing_trans_stop(); 4677 return ERROR_DOS(ERRSRV,ERRerror); 4678 } 4679 4680 /* As we do not know how many data packets will need to be 4681 returned here the various call_trans2xxxx calls 4682 must send their own. Thus a call_trans2xxx routine only 4683 returns a value other than -1 when it wants to send 4684 an error packet. 4685 */ 4686 4687 srv_signing_trans_stop(); 4688 4689 SAFE_FREE(params); 4690 SAFE_FREE(data); 4691 END_PROFILE(SMBtrans2); 4692 return outsize; /* If a correct response was needed the 4693 call_trans2xxx calls have already sent 4694 it. If outsize != -1 then it is returning */ 4695 4696 bad_param: 4697 4698 srv_signing_trans_stop(); 4699 SAFE_FREE(params); 4700 SAFE_FREE(data); 4701 END_PROFILE(SMBtrans2); 4702 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 4703} 4704