1 17 package org.alfresco.filesys.smb.server; 18 19 import java.io.FileNotFoundException ; 20 import java.io.IOException ; 21 22 import org.alfresco.filesys.locking.FileLock; 23 import org.alfresco.filesys.locking.LockConflictException; 24 import org.alfresco.filesys.locking.NotLockedException; 25 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; 26 import org.alfresco.filesys.server.auth.ClientInfo; 27 import org.alfresco.filesys.server.auth.InvalidUserException; 28 import org.alfresco.filesys.server.auth.SrvAuthenticator; 29 import org.alfresco.filesys.server.auth.acl.AccessControl; 30 import org.alfresco.filesys.server.auth.acl.AccessControlManager; 31 import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; 32 import org.alfresco.filesys.server.core.ShareType; 33 import org.alfresco.filesys.server.core.SharedDevice; 34 import org.alfresco.filesys.server.filesys.AccessDeniedException; 35 import org.alfresco.filesys.server.filesys.DirectoryNotEmptyException; 36 import org.alfresco.filesys.server.filesys.DiskDeviceContext; 37 import org.alfresco.filesys.server.filesys.DiskFullException; 38 import org.alfresco.filesys.server.filesys.DiskInterface; 39 import org.alfresco.filesys.server.filesys.FileAccess; 40 import org.alfresco.filesys.server.filesys.FileAction; 41 import org.alfresco.filesys.server.filesys.FileAttribute; 42 import org.alfresco.filesys.server.filesys.FileExistsException; 43 import org.alfresco.filesys.server.filesys.FileInfo; 44 import org.alfresco.filesys.server.filesys.FileName; 45 import org.alfresco.filesys.server.filesys.FileOfflineException; 46 import org.alfresco.filesys.server.filesys.FileOpenParams; 47 import org.alfresco.filesys.server.filesys.FileSharingException; 48 import org.alfresco.filesys.server.filesys.FileStatus; 49 import org.alfresco.filesys.server.filesys.FileSystem; 50 import org.alfresco.filesys.server.filesys.IOControlNotImplementedException; 51 import org.alfresco.filesys.server.filesys.IOCtlInterface; 52 import org.alfresco.filesys.server.filesys.NetworkFile; 53 import org.alfresco.filesys.server.filesys.NotifyChange; 54 import org.alfresco.filesys.server.filesys.PathNotFoundException; 55 import org.alfresco.filesys.server.filesys.SearchContext; 56 import org.alfresco.filesys.server.filesys.SrvDiskInfo; 57 import org.alfresco.filesys.server.filesys.TooManyConnectionsException; 58 import org.alfresco.filesys.server.filesys.TooManyFilesException; 59 import org.alfresco.filesys.server.filesys.TreeConnection; 60 import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException; 61 import org.alfresco.filesys.server.filesys.VolumeInfo; 62 import org.alfresco.filesys.server.locking.FileLockingInterface; 63 import org.alfresco.filesys.server.locking.LockManager; 64 import org.alfresco.filesys.smb.DataType; 65 import org.alfresco.filesys.smb.FileInfoLevel; 66 import org.alfresco.filesys.smb.FindFirstNext; 67 import org.alfresco.filesys.smb.InvalidUNCPathException; 68 import org.alfresco.filesys.smb.LockingAndX; 69 import org.alfresco.filesys.smb.NTIOCtl; 70 import org.alfresco.filesys.smb.NTTime; 71 import org.alfresco.filesys.smb.PCShare; 72 import org.alfresco.filesys.smb.PacketType; 73 import org.alfresco.filesys.smb.SMBDate; 74 import org.alfresco.filesys.smb.SMBException; 75 import org.alfresco.filesys.smb.SMBStatus; 76 import org.alfresco.filesys.smb.WinNT; 77 import org.alfresco.filesys.smb.server.notify.NotifyChangeEventList; 78 import org.alfresco.filesys.smb.server.notify.NotifyChangeHandler; 79 import org.alfresco.filesys.smb.server.notify.NotifyRequest; 80 import org.alfresco.filesys.smb.server.ntfs.NTFSStreamsInterface; 81 import org.alfresco.filesys.smb.server.ntfs.StreamInfoList; 82 import org.alfresco.filesys.util.DataBuffer; 83 import org.alfresco.filesys.util.DataPacker; 84 import org.alfresco.filesys.util.HexDump; 85 import org.alfresco.filesys.util.WildCard; 86 import org.apache.commons.logging.Log; 87 import org.apache.commons.logging.LogFactory; 88 89 95 public class NTProtocolHandler extends CoreProtocolHandler 96 { 97 private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); 98 99 103 public static final boolean ReturnDotFiles = true; 104 105 107 public static final boolean FakeOpLocks = false; 108 109 111 public static final int FileSizeChangeRate = 10; 112 113 117 private static byte[] _sdEveryOne = { 0x01, 0x00, 0x04, (byte) 0x80, 0x14, 0x00, 0x00, 0x00, 118 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 0x2c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 120 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 121 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 122 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1c, 0x00, 123 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 124 (byte) 0xff, 0x01, 0x1f, 0x00, 0x01, 0x01, 0x00, 0x00, 125 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 126 }; 127 128 131 protected NTProtocolHandler() 132 { 133 super(); 134 } 135 136 141 protected NTProtocolHandler(SMBSrvSession sess) 142 { 143 super(sess); 144 } 145 146 151 public String getName() 152 { 153 return "NT"; 154 } 155 156 163 public boolean runProtocol() throws java.io.IOException , SMBSrvException, TooManyConnectionsException 164 { 165 166 168 if (m_smbPkt == null) 169 m_smbPkt = m_sess.getReceivePacket(); 170 171 173 if (m_smbPkt.checkPacketSignature() == false) 174 throw new IOException ("Invalid SMB signature"); 175 176 180 SMBSrvPacket outPkt = m_smbPkt; 181 boolean chainedCmd = hasChainedCommand(m_smbPkt); 182 183 if (chainedCmd) 184 { 185 186 188 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STATE)) 189 logger.debug("AndX Command = 0x" + Integer.toHexString(m_smbPkt.getAndXCommand())); 190 191 193 outPkt = new SMBSrvPacket(m_smbPkt, m_smbPkt.getPacketLength()); 194 } 195 196 198 m_smbPkt.resetBytePointer(); 199 200 204 m_sess.setProcessId(m_smbPkt.getProcessId()); 205 206 208 boolean handledOK = true; 209 210 switch (m_smbPkt.getCommand()) 211 { 212 213 215 case PacketType.SessionSetupAndX: 216 procSessionSetup(outPkt); 217 break; 218 219 221 case PacketType.TreeConnectAndX: 222 procTreeConnectAndX(outPkt); 223 break; 224 225 227 case PacketType.Transaction: 228 case PacketType.Transaction2: 229 procTransact2(outPkt); 230 break; 231 232 234 case PacketType.TransactionSecond: 235 case PacketType.Transaction2Second: 236 procTransact2Secondary(outPkt); 237 break; 238 239 241 case PacketType.FindClose2: 242 procFindClose(outPkt); 243 break; 244 245 247 case PacketType.OpenAndX: 248 procOpenAndX(outPkt); 249 break; 250 251 253 case PacketType.CloseFile: 254 procCloseFile(outPkt); 255 break; 256 257 259 case PacketType.ReadAndX: 260 procReadAndX(outPkt); 261 break; 262 263 265 case PacketType.WriteAndX: 266 procWriteAndX(outPkt); 267 break; 268 269 271 case PacketType.RenameFile: 272 procRenameFile(outPkt); 273 break; 274 275 277 case PacketType.DeleteFile: 278 procDeleteFile(outPkt); 279 break; 280 281 283 case PacketType.DeleteDirectory: 284 procDeleteDirectory(outPkt); 285 break; 286 287 289 case PacketType.TreeDisconnect: 290 procTreeDisconnect(outPkt); 291 break; 292 293 295 case PacketType.LockingAndX: 296 procLockingAndX(outPkt); 297 break; 298 299 301 case PacketType.LogoffAndX: 302 procLogoffAndX(outPkt); 303 break; 304 305 307 case PacketType.NTCreateAndX: 308 procNTCreateAndX(outPkt); 309 break; 310 311 313 case PacketType.TreeConnect: 314 super.runProtocol(); 315 break; 316 317 319 case PacketType.NTCancel: 320 procNTCancel(outPkt); 321 break; 322 323 325 case PacketType.NTTransact: 326 procNTTransaction(outPkt); 327 break; 328 329 331 case PacketType.NTTransactSecond: 332 procNTTransactionSecondary(outPkt); 333 break; 334 335 337 case PacketType.Echo: 338 super.procEcho(outPkt); 339 break; 340 341 343 default: 344 345 349 int treeId = m_smbPkt.getTreeId(); 350 TreeConnection conn = null; 351 if (treeId != -1) 352 conn = m_sess.findConnection(treeId); 353 354 if (conn != null) 355 { 356 357 360 if (conn.getSharedDevice().getType() == ShareType.DISK 361 || conn.getSharedDevice().getType() == ShareType.PRINTER) 362 { 363 364 366 handledOK = super.runProtocol(); 367 } 368 else if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 369 { 370 371 373 IPCHandler.processIPCRequest(m_sess, outPkt); 374 handledOK = true; 375 } 376 } 377 break; 378 } 379 380 382 return handledOK; 383 } 384 385 390 protected void procSessionSetup(SMBSrvPacket outPkt) throws SMBSrvException, IOException , 391 TooManyConnectionsException 392 { 393 394 396 if (m_smbPkt.checkPacketIsValid(13, 0) == false) 397 { 398 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 399 return; 400 } 401 402 404 int maxBufSize = m_smbPkt.getParameter(2); 405 int maxMpx = m_smbPkt.getParameter(3); 406 int vcNum = m_smbPkt.getParameter(4); 407 int sessKey = m_smbPkt.getParameterLong(5); 408 int ascPwdLen = m_smbPkt.getParameter(7); 409 int uniPwdLen = m_smbPkt.getParameter(8); 410 int capabs = m_smbPkt.getParameter(11); 411 412 414 int dataPos = m_smbPkt.getByteOffset(); 415 int dataLen = m_smbPkt.getByteCount(); 416 byte[] buf = m_smbPkt.getBuffer(); 417 418 420 boolean isUni = m_smbPkt.isUnicode(); 421 422 424 byte[] ascPwd = m_smbPkt.unpackBytes(ascPwdLen); 425 byte[] uniPwd = m_smbPkt.unpackBytes(uniPwdLen); 426 427 429 String user = m_smbPkt.unpackString(isUni); 430 431 if (user == null) 432 { 433 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 434 return; 435 } 436 437 439 String domain = ""; 440 441 if (m_smbPkt.hasMoreData()) 442 { 443 444 446 domain = m_smbPkt.unpackString(isUni); 447 448 if (domain == null) 449 { 450 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 451 SMBStatus.ErrSrv); 452 return; 453 } 454 } 455 456 458 String clientOS = ""; 459 460 if (m_smbPkt.hasMoreData()) 461 { 462 463 465 clientOS = m_smbPkt.unpackString(isUni); 466 467 if (clientOS == null) 468 { 469 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 470 SMBStatus.ErrSrv); 471 return; 472 } 473 } 474 475 477 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) 478 { 479 logger.debug("NT Session setup from user=" + user + ", password=" 480 + (uniPwd != null ? HexDump.hexString(uniPwd) : "none") + ", ANSIpwd=" 481 + (ascPwd != null ? HexDump.hexString(ascPwd) : "none") + ", domain=" + domain + ", os=" + clientOS 482 + ", VC=" + vcNum + ", maxBuf=" + maxBufSize + ", maxMpx=" + maxMpx 483 + ", challenge=" + HexDump.hexString(m_sess.getChallengeKey())); 484 logger.debug(" MID=" + m_smbPkt.getMultiplexId() + ", UID=" + m_smbPkt.getUserId() + ", PID=" 485 + m_smbPkt.getProcessId()); 486 } 487 488 491 m_sess.setClientMaximumBufferSize(maxBufSize); 492 m_sess.setClientMaximumMultiplex(maxMpx); 493 m_sess.setClientCapabilities(capabs); 494 495 497 ClientInfo client = new ClientInfo(user, uniPwd); 498 client.setANSIPassword(ascPwd); 499 client.setDomain(domain); 500 client.setOperatingSystem(clientOS); 501 502 if (m_sess.hasRemoteAddress()) 503 client.setClientAddress(m_sess.getRemoteAddress().getHostAddress()); 504 505 507 if (user.length() == 0 && domain.length() == 0 && uniPwdLen == 0 && ascPwdLen == 1) 508 client.setLogonType(ClientInfo.LogonNull); 509 510 512 SrvAuthenticator auth = getSession().getSMBServer().getAuthenticator(); 513 boolean isGuest = false; 514 515 if (auth != null && auth.getAccessMode() == SrvAuthenticator.USER_MODE) 516 { 517 518 520 int sts = auth.authenticateUser(client, m_sess, SrvAuthenticator.NTLM1); 521 522 if (sts > 0 && (sts & SrvAuthenticator.AUTH_GUEST) != 0) 523 { 524 525 527 isGuest = true; 528 529 531 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) 532 logger.debug("User " + user + ", logged on as guest"); 533 } 534 else if (sts != SrvAuthenticator.AUTH_ALLOW) 535 { 536 537 541 if (getSession().getClientInformation() != null && client.getUserName().length() == 0) 542 { 543 544 546 client = getSession().getClientInformation(); 547 548 550 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) 551 logger.debug("Null client information, reusing existing client=" + client); 552 } 553 else 554 { 555 556 558 m_sess.sendErrorResponseSMB(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 559 560 562 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) 563 logger.debug("User " + user + ", access denied"); 564 return; 565 } 566 } 567 else if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) 568 { 569 570 572 logger.debug("User " + user + " logged on " 573 + (client != null ? " (type " + client.getLogonTypeString() + ")" : "")); 574 } 575 } 576 577 579 if (getSession().getClientInformation() == null 580 || getSession().getClientInformation().getUserName().length() == 0) 581 { 582 583 585 getSession().setClientInformation(client); 586 } 587 588 590 client.setGuest(isGuest); 591 getSession().setLoggedOn(true); 592 593 595 outPkt.setParameterCount(3); 596 outPkt.setParameter(0, 0); outPkt.setParameter(1, 0); outPkt.setParameter(2, isGuest ? 1 : 0); 599 outPkt.setByteCount(0); 600 601 outPkt.setTreeId(0); 602 outPkt.setUserId(0); 603 604 606 int flags = outPkt.getFlags(); 607 flags &= ~SMBSrvPacket.FLG_CASELESS; 608 outPkt.setFlags(flags); 609 610 int flags2 = SMBSrvPacket.FLG2_LONGFILENAMES; 611 if (isUni) 612 flags2 += SMBSrvPacket.FLG2_UNICODE; 613 outPkt.setFlags2(flags2); 614 615 617 int pos = outPkt.getByteOffset(); 618 buf = outPkt.getBuffer(); 619 620 if (isUni) 621 pos = DataPacker.wordAlign(pos); 622 623 pos = DataPacker.putString("Java", buf, pos, true, isUni); 624 pos = DataPacker.putString("Alfresco CIFS Server " + m_sess.getServer().isVersion(), buf, pos, true, isUni); 625 pos = DataPacker.putString(m_sess.getServer().getConfiguration().getDomainName(), buf, pos, true, isUni); 626 627 outPkt.setByteCount(pos - outPkt.getByteOffset()); 628 629 631 if (m_smbPkt.hasAndXCommand() && dataPos < m_smbPkt.getReceivedLength()) 632 { 633 634 636 pos = procAndXCommands(outPkt); 637 pos -= RFCNetBIOSProtocol.HEADER_LEN; 638 } 639 else 640 { 641 642 644 outPkt.setAndXCommand(SMBSrvPacket.NO_ANDX_CMD); 645 } 646 647 649 m_sess.sendResponseSMB(outPkt, pos); 650 651 653 m_sess.setState(SMBSrvSessionState.SMBSESSION); 654 655 657 m_sess.getSMBServer().sessionLoggedOn(m_sess); 658 } 659 660 666 protected final int procAndXCommands(SMBSrvPacket outPkt) 667 { 668 669 671 return procAndXCommands(outPkt, outPkt.getByteOffset() + outPkt.getByteCount(), null); 672 } 673 674 682 protected final int procAndXCommands(SMBSrvPacket outPkt, int endPos, NetworkFile file) 683 { 684 685 687 int andxCmd = m_smbPkt.getAndXCommand(); 688 int andxOff = m_smbPkt.getParameter(1) + RFCNetBIOSProtocol.HEADER_LEN; 689 690 692 outPkt.setAndXCommand(andxCmd); 693 outPkt.setParameter(1, andxOff - RFCNetBIOSProtocol.HEADER_LEN); 694 695 697 int paramBlk = SMBSrvPacket.WORDCNT; 698 699 701 int endOfPkt = endPos; 702 boolean andxErr = false; 703 704 while (andxCmd != SMBSrvPacket.NO_ANDX_CMD && andxErr == false) 705 { 706 707 709 int prevEndOfPkt = endOfPkt; 710 boolean endOfChain = false; 711 712 switch (andxCmd) 713 { 714 715 717 case PacketType.TreeConnectAndX: 718 endOfPkt = procChainedTreeConnectAndX(andxOff, outPkt, endOfPkt); 719 break; 720 721 723 case PacketType.CloseFile: 724 endOfPkt = procChainedClose(andxOff, outPkt, endOfPkt); 725 endOfChain = true; 726 break; 727 728 730 case PacketType.ReadAndX: 731 endOfPkt = procChainedReadAndX(andxOff, outPkt, endOfPkt, file); 732 break; 733 734 736 default: 737 break; 738 } 739 740 742 outPkt.setAndXCommand(paramBlk, andxCmd); 743 outPkt.setAndXParameter(paramBlk, 1, prevEndOfPkt - RFCNetBIOSProtocol.HEADER_LEN); 744 745 749 if (endOfChain == false) 750 { 751 752 754 andxCmd = m_smbPkt.getAndXParameter(andxOff, 0) & 0x00FF; 755 andxOff = m_smbPkt.getAndXParameter(andxOff, 1); 756 757 759 paramBlk = prevEndOfPkt; 760 } 761 else 762 { 763 764 766 andxCmd = SMBSrvPacket.NO_ANDX_CMD; 767 } 768 769 771 if (outPkt.getErrorCode() != SMBStatus.Success) 772 andxErr = true; 773 } 774 775 777 return endOfPkt; 778 } 779 780 788 protected final int procChainedTreeConnectAndX(int cmdOff, SMBSrvPacket outPkt, int endOff) 789 { 790 791 793 int flags = m_smbPkt.getAndXParameter(cmdOff, 2); 794 int pwdLen = m_smbPkt.getAndXParameter(cmdOff, 3); 795 796 798 m_smbPkt.setBytePointer(m_smbPkt.getAndXByteOffset(cmdOff), m_smbPkt.getAndXByteCount(cmdOff)); 799 800 802 String pwd = null; 803 804 if (pwdLen > 0) 805 { 806 byte[] pwdByt = m_smbPkt.unpackBytes(pwdLen); 807 pwd = new String (pwdByt); 808 } 809 810 812 boolean unicode = m_smbPkt.isUnicode(); 813 814 String uncPath = m_smbPkt.unpackString(unicode); 815 if (uncPath == null) 816 { 817 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 818 SMBStatus.ErrSrv); 819 return endOff; 820 } 821 822 824 String service = m_smbPkt.unpackString(false); 825 if (service == null) 826 { 827 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 828 SMBStatus.ErrSrv); 829 return endOff; 830 } 831 832 835 int servType = ShareType.ServiceAsType(service); 836 if (servType == ShareType.UNKNOWN && service.compareTo("?????") != 0) 837 { 838 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 839 SMBStatus.ErrSrv); 840 return endOff; 841 } 842 843 845 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) 846 logger.debug("NT ANDX Tree Connect AndX - " + uncPath + ", " + service); 847 848 850 PCShare share = null; 851 852 try 853 { 854 share = new PCShare(uncPath); 855 } 856 catch (InvalidUNCPathException ex) 857 { 858 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 859 SMBStatus.ErrSrv); 860 return endOff; 861 } 862 863 865 if (servType == ShareType.NAMEDPIPE && share.getShareName().compareTo("IPC$") == 0) 866 servType = ShareType.ADMINPIPE; 867 868 870 if (m_sess.hasClientInformation() && m_sess.getClientInformation().isNullSession() 871 && servType != ShareType.ADMINPIPE) 872 { 873 874 876 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, 877 SMBStatus.ErrDos); 878 return endOff; 879 } 880 881 883 SharedDevice shareDev = null; 884 885 try 886 { 887 888 890 shareDev = m_sess.getSMBServer().findShare(share.getNodeName(), share.getShareName(), servType, m_sess, 891 true); 892 } 893 catch (InvalidUserException ex) 894 { 895 896 898 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, 899 SMBStatus.ErrDos); 900 return endOff; 901 } 902 catch (Exception ex) 903 { 904 905 907 logger.error("Exception in TreeConnectAndX", ex); 908 909 911 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, 912 SMBStatus.ErrSrv); 913 return endOff; 914 } 915 916 918 if (shareDev == null || (servType != ShareType.UNKNOWN && shareDev.getType() != servType)) 919 { 920 921 923 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, 924 SMBStatus.ErrSrv); 925 return endOff; 926 } 927 928 930 SrvAuthenticator auth = getSession().getSMBServer().getAuthenticator(); 931 int sharePerm = FileAccess.Writeable; 932 933 if (auth != null && auth.getAccessMode() == SrvAuthenticator.SHARE_MODE) 934 { 935 936 938 sharePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess); 939 if (sharePerm < 0) 940 { 941 942 944 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, 945 SMBStatus.ErrDos); 946 return endOff; 947 } 948 } 949 950 954 if (getSession().getServer().hasAccessControlManager() && shareDev.hasAccessControls()) 955 { 956 957 959 AccessControlManager aclMgr = getSession().getServer().getAccessControlManager(); 960 961 965 int aclPerm = aclMgr.checkAccessControl(getSession(), shareDev); 966 967 if (aclPerm == FileAccess.NoAccess) 968 { 969 970 972 outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, 973 SMBStatus.ErrDos); 974 return endOff; 975 } 976 977 979 if (aclPerm != AccessControl.Default) 980 sharePerm = aclPerm; 981 } 982 983 985 TreeConnection tree = null; 986 987 try 988 { 989 990 992 int treeId = m_sess.addConnection(shareDev); 993 outPkt.setTreeId(treeId); 994 995 997 tree = m_sess.findConnection(treeId); 998 tree.setPermission(sharePerm); 999 1000 1002 if (tree.getInterface() != null) 1003 tree.getInterface().treeOpened(m_sess, tree); 1004 1005 1007 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) 1008 logger.debug("ANDX Tree Connect AndX - Allocated Tree Id = " + treeId); 1009 } 1010 catch (TooManyConnectionsException ex) 1011 { 1012 1013 1015 outPkt.setError(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv); 1016 return endOff; 1017 } 1018 1019 1021 outPkt.setAndXParameterCount(endOff, 2); 1022 outPkt.setAndXParameter(endOff, 0, SMBSrvPacket.NO_ANDX_CMD); 1023 outPkt.setAndXParameter(endOff, 1, 0); 1024 1025 1027 int pos = outPkt.getAndXByteOffset(endOff); 1028 byte[] outBuf = outPkt.getBuffer(); 1029 pos = DataPacker.putString(ShareType.TypeAsService(shareDev.getType()), outBuf, pos, true); 1030 1031 1033 String devType = ""; 1034 1035 try 1036 { 1037 1039 if ( shareDev.getType() == ShareType.DISK) 1040 { 1041 1044 if (shareDev.getInterface() instanceof NTFSStreamsInterface) 1045 { 1046 1047 1049 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) shareDev.getInterface(); 1050 if (ntfsStreams.hasStreamsEnabled(m_sess, tree)) 1051 devType = FileSystem.TypeNTFS; 1052 } 1053 else 1054 { 1055 1057 DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); 1058 devType = diskCtx.getFilesystemType(); 1059 } 1060 } 1061 } 1062 catch (InvalidDeviceInterfaceException ex) 1063 { 1064 1065 1067 logger.error("TreeConnectAndX error", ex); 1068 } 1069 1070 1072 pos = DataPacker.putString(devType, outBuf, pos, true, outPkt.isUnicode()); 1073 1074 int bytLen = pos - outPkt.getAndXByteOffset(endOff); 1075 outPkt.setAndXByteCount(endOff, bytLen); 1076 1077 1079 return pos; 1080 } 1081 1082 1091 protected final int procChainedReadAndX(int cmdOff, SMBSrvPacket outPkt, int endOff, NetworkFile netFile) 1092 { 1093 1094 1097 int treeId = m_smbPkt.getTreeId(); 1098 TreeConnection conn = m_sess.findConnection(treeId); 1099 1100 if (conn == null) 1101 { 1102 outPkt.setError(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 1103 return endOff; 1104 } 1105 1106 1108 long offset = (long) m_smbPkt.getAndXParameterLong(cmdOff, 3); offset &= 0xFFFFFFFFL; 1111 int maxCount = m_smbPkt.getAndXParameter(cmdOff, 5); 1112 1113 1115 if (m_smbPkt.getAndXParameterCount(cmdOff) == 12) 1116 { 1117 long topOff = (long) m_smbPkt.getAndXParameterLong(cmdOff, 10); 1118 offset += topOff << 32; 1119 } 1120 1121 1123 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 1124 logger.debug("Chained File Read AndX : Size=" + maxCount + " ,Pos=" + offset); 1125 1126 1128 byte[] buf = outPkt.getBuffer(); 1129 int dataPos = 0; 1130 int rdlen = 0; 1131 1132 try 1133 { 1134 1135 1137 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 1138 1139 1141 outPkt.setAndXParameterCount(endOff, 12); 1142 dataPos = outPkt.getAndXByteOffset(endOff); 1143 dataPos = DataPacker.wordAlign(dataPos); 1145 1147 int dataLen = buf.length - dataPos; 1148 if (dataLen < maxCount) 1149 maxCount = dataLen; 1150 1151 1153 rdlen = disk.readFile(m_sess, conn, netFile, buf, dataPos, maxCount, offset); 1154 1155 1157 outPkt.setAndXParameter(endOff, 0, SMBSrvPacket.NO_ANDX_CMD); 1158 outPkt.setAndXParameter(endOff, 1, 0); 1159 1160 outPkt.setAndXParameter(endOff, 2, 0); outPkt.setAndXParameter(endOff, 3, 0); outPkt.setAndXParameter(endOff, 4, 0); outPkt.setAndXParameter(endOff, 5, rdlen); outPkt.setAndXParameter(endOff, 6, dataPos - RFCNetBIOSProtocol.HEADER_LEN); 1168 1170 for (int i = 7; i < 12; i++) 1171 outPkt.setAndXParameter(endOff, i, 0); 1172 1173 1175 outPkt.setAndXByteCount(endOff, (dataPos + rdlen) - outPkt.getAndXByteOffset(endOff)); 1176 1177 1179 endOff = dataPos + rdlen; 1180 } 1181 catch (InvalidDeviceInterfaceException ex) 1182 { 1183 1184 1186 outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 1187 return endOff; 1188 } 1189 catch (java.io.IOException ex) 1190 { 1191 } 1192 1193 1195 return endOff; 1196 } 1197 1198 1206 protected final int procChainedClose(int cmdOff, SMBSrvPacket outPkt, int endOff) 1207 { 1208 1209 1212 int treeId = m_smbPkt.getTreeId(); 1213 TreeConnection conn = m_sess.findConnection(treeId); 1214 1215 if (conn == null) 1216 { 1217 outPkt.setError(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 1218 return endOff; 1219 } 1220 1221 1223 int fid = m_smbPkt.getAndXParameter(cmdOff, 0); 1224 int ftime = m_smbPkt.getAndXParameter(cmdOff, 1); 1225 int fdate = m_smbPkt.getAndXParameter(cmdOff, 2); 1226 1227 NetworkFile netFile = conn.findFile(fid); 1228 1229 if (netFile == null) 1230 { 1231 outPkt.setError(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 1232 return endOff; 1233 } 1234 1235 1237 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 1238 logger.debug("Chained File Close [" + treeId + "] fid=" + fid); 1239 1240 1242 try 1243 { 1244 1245 1247 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 1248 1249 1253 if (disk != null) 1254 disk.closeFile(m_sess, conn, netFile); 1255 1256 1258 netFile.setClosed(true); 1259 } 1260 catch (InvalidDeviceInterfaceException ex) 1261 { 1262 1263 1265 outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 1266 return endOff; 1267 } 1268 catch (java.io.IOException ex) 1269 { 1270 } 1271 1272 1274 outPkt.setAndXParameterCount(endOff, 0); 1275 outPkt.setAndXByteCount(endOff, 0); 1276 1277 endOff = outPkt.getAndXByteOffset(endOff) - RFCNetBIOSProtocol.HEADER_LEN; 1278 1279 1281 conn.removeFile(fid, getSession()); 1282 1283 1285 return endOff; 1286 } 1287 1288 1296 1297 protected void procTreeConnectAndX(SMBSrvPacket outPkt) throws SMBSrvException, TooManyConnectionsException, 1298 java.io.IOException 1299 { 1300 1301 1303 if (m_smbPkt.checkPacketIsValid(4, 3) == false) 1304 { 1305 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1306 return; 1307 } 1308 1309 1311 int flags = m_smbPkt.getParameter(2); 1312 int pwdLen = m_smbPkt.getParameter(3); 1313 1314 1316 m_smbPkt.resetBytePointer(); 1317 1318 1320 boolean unicode = m_smbPkt.isUnicode(); 1321 1322 1324 String pwd = null; 1325 1326 if (pwdLen > 0) 1327 { 1328 byte[] pwdByts = m_smbPkt.unpackBytes(pwdLen); 1329 pwd = new String (pwdByts); 1330 } 1331 1332 1334 String uncPath = m_smbPkt.unpackString(unicode); 1335 if (uncPath == null) 1336 { 1337 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1338 return; 1339 } 1340 1341 1343 String service = m_smbPkt.unpackString(false); 1344 if (service == null) 1345 { 1346 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1347 return; 1348 } 1349 1350 1353 int servType = ShareType.ServiceAsType(service); 1354 if (servType == ShareType.UNKNOWN && service.compareTo("?????") != 0) 1355 { 1356 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1357 return; 1358 } 1359 1360 1362 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) 1363 logger.debug("NT Tree Connect AndX - " + uncPath + ", " + service); 1364 1365 1367 String shareName = null; 1368 String hostName = null; 1369 1370 if (uncPath.startsWith("\\")) 1371 { 1372 1373 try 1374 { 1375 PCShare share = new PCShare(uncPath); 1376 shareName = share.getShareName(); 1377 hostName = share.getNodeName(); 1378 } 1379 catch (InvalidUNCPathException ex) 1380 { 1381 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 1382 SMBStatus.ErrSrv); 1383 return; 1384 } 1385 } 1386 else 1387 shareName = uncPath; 1388 1389 1391 if (servType == ShareType.NAMEDPIPE && shareName.compareTo("IPC$") == 0) 1392 servType = ShareType.ADMINPIPE; 1393 1394 1396 if (m_sess.hasClientInformation() && m_sess.getClientInformation().isNullSession() 1397 && servType != ShareType.ADMINPIPE) 1398 { 1399 1400 1402 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 1403 return; 1404 } 1405 1406 1408 SharedDevice shareDev = null; 1409 1410 try 1411 { 1412 1413 1415 shareDev = m_sess.getSMBServer().findShare(hostName, shareName, servType, m_sess, true); 1416 } 1417 catch (InvalidUserException ex) 1418 { 1419 1420 1422 m_sess.sendErrorResponseSMB(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 1423 return; 1424 } 1425 catch (Exception ex) 1426 { 1427 1428 1430 logger.error("TreeConnectAndX error", ex); 1431 1432 1434 m_sess.sendErrorResponseSMB(SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv); 1435 return; 1436 } 1437 1438 1440 if (shareDev == null || (servType != ShareType.UNKNOWN && shareDev.getType() != servType)) 1441 { 1442 m_sess.sendErrorResponseSMB(SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv); 1443 return; 1444 } 1445 1446 1449 SrvAuthenticator auth = getSession().getSMBServer().getAuthenticator(); 1450 int sharePerm = FileAccess.Writeable; 1451 1452 if (auth != null) 1453 { 1454 1455 1457 sharePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess); 1458 if (sharePerm < 0) 1459 { 1460 1461 1463 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) 1464 logger.debug("Tree connect to " + shareName + ", access denied"); 1465 1466 1468 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 1469 return; 1470 } 1471 } 1472 1473 1477 if (getSession().getServer().hasAccessControlManager() && shareDev.hasAccessControls()) 1478 { 1479 1480 1482 AccessControlManager aclMgr = getSession().getServer().getAccessControlManager(); 1483 1484 1488 int aclPerm = aclMgr.checkAccessControl(getSession(), shareDev); 1489 1490 if (aclPerm == FileAccess.NoAccess) 1491 { 1492 1493 1495 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 1496 return; 1497 } 1498 1499 1501 if (aclPerm != AccessControl.Default) 1502 sharePerm = aclPerm; 1503 } 1504 1505 1507 int treeId = m_sess.addConnection(shareDev); 1508 outPkt.setTreeId(treeId); 1509 1510 1512 TreeConnection tree = m_sess.findConnection(treeId); 1513 tree.setPermission(sharePerm); 1514 1515 1517 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) 1518 logger.debug("Tree Connect AndX - Allocated Tree Id = " + treeId + ", Permission = " 1519 + FileAccess.asString(sharePerm)); 1520 1521 1523 outPkt.setParameterCount(3); 1524 outPkt.setAndXCommand(0xFF); outPkt.setParameter(1, 0); 1526 outPkt.setParameter(2, 0); 1527 1528 1530 int pos = outPkt.getByteOffset(); 1531 pos = DataPacker.putString(ShareType.TypeAsService(shareDev.getType()), m_smbPkt.getBuffer(), pos, true); 1532 1533 1535 String devType = ""; 1536 1537 try 1538 { 1539 1541 if ( shareDev.getType() == ShareType.DISK) 1542 { 1543 1546 if (shareDev.getInterface() instanceof NTFSStreamsInterface) 1547 { 1548 1549 1551 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) shareDev.getInterface(); 1552 if (ntfsStreams.hasStreamsEnabled(m_sess, tree)) 1553 devType = FileSystem.TypeNTFS; 1554 } 1555 else 1556 { 1557 1559 DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); 1560 devType = diskCtx.getFilesystemType(); 1561 } 1562 } 1563 } 1564 catch (InvalidDeviceInterfaceException ex) 1565 { 1566 1567 1569 logger.error("TreeConnectAndX error", ex); 1570 } 1571 1572 1574 pos = DataPacker.putString(devType, m_smbPkt.getBuffer(), pos, true, outPkt.isUnicode()); 1575 outPkt.setByteCount(pos - outPkt.getByteOffset()); 1576 1577 1579 m_sess.sendResponseSMB(outPkt); 1580 1581 1583 if (tree.getInterface() != null) 1584 tree.getInterface().treeOpened(m_sess, tree); 1585 } 1586 1587 1594 protected void procCloseFile(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 1595 { 1596 1597 1599 if (m_smbPkt.checkPacketIsValid(3, 0) == false) 1600 { 1601 m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); 1602 return; 1603 } 1604 1605 1608 int treeId = m_smbPkt.getTreeId(); 1609 TreeConnection conn = m_sess.findConnection(treeId); 1610 1611 if (conn == null) 1612 { 1613 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 1614 return; 1615 } 1616 1617 1619 if (conn.hasReadAccess() == false) 1620 { 1621 1622 1624 m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); 1625 return; 1626 } 1627 1628 1630 int fid = m_smbPkt.getParameter(0); 1631 int ftime = m_smbPkt.getParameter(1); 1632 int fdate = m_smbPkt.getParameter(2); 1633 1634 NetworkFile netFile = conn.findFile(fid); 1635 1636 if (netFile == null) 1637 { 1638 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); 1639 return; 1640 } 1641 1642 1644 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 1645 logger.debug("File close [" + treeId + "] fid=" + fid); 1646 1647 1649 try 1650 { 1651 1652 1654 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 1655 1656 1660 if (disk != null) 1661 disk.closeFile(m_sess, conn, netFile); 1662 1663 1665 netFile.setClosed(true); 1666 } 1667 catch (AccessDeniedException ex) 1668 { 1669 1671 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 1672 return; 1673 } 1674 catch (InvalidDeviceInterfaceException ex) 1675 { 1676 1677 1679 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 1680 return; 1681 } 1682 catch (java.io.IOException ex) 1683 { 1684 } 1685 1686 1688 conn.removeFile(fid, getSession()); 1689 1690 1692 outPkt.setParameterCount(0); 1693 outPkt.setByteCount(0); 1694 1695 1697 m_sess.sendResponseSMB(outPkt); 1698 1699 1701 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 1702 if (netFile.getWriteCount() > 0 && diskCtx.hasChangeHandler()) 1703 diskCtx.getChangeHandler().notifyFileSizeChanged(netFile.getFullName()); 1704 1705 if (netFile.hasDeleteOnClose() && diskCtx.hasChangeHandler()) 1706 diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, netFile.getFullName()); 1707 } 1708 1709 1715 protected void procTransact2(SMBSrvPacket outPkt) throws IOException , SMBSrvException 1716 { 1717 1718 1720 if (m_smbPkt.checkPacketIsValid(14, 0) == false) 1721 { 1722 1723 1725 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1726 return; 1727 } 1728 1729 1732 int treeId = m_smbPkt.getTreeId(); 1733 TreeConnection conn = m_sess.findConnection(treeId); 1734 1735 if (conn == null) 1736 { 1737 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 1738 return; 1739 } 1740 1741 1743 if (conn.hasReadAccess() == false) 1744 { 1745 1746 1748 m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); 1749 return; 1750 } 1751 1752 1754 SMBSrvTransPacket tranPkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); 1755 1756 1758 SrvTransactBuffer transBuf = null; 1759 int subCmd = tranPkt.getSubFunction(); 1760 1761 if (tranPkt.getTotalParameterCount() == tranPkt.getRxParameterBlockLength() 1762 && tranPkt.getTotalDataCount() == tranPkt.getRxDataBlockLength()) 1763 { 1764 1765 1769 transBuf = new SrvTransactBuffer(tranPkt); 1770 } 1771 else 1772 { 1773 1774 1776 transBuf = new SrvTransactBuffer(tranPkt.getSetupCount(), tranPkt.getTotalParameterCount(), tranPkt 1777 .getTotalDataCount()); 1778 transBuf.setType(tranPkt.getCommand()); 1779 transBuf.setFunction(subCmd); 1780 1781 1783 byte[] buf = tranPkt.getBuffer(); 1784 1785 transBuf.appendSetup(buf, tranPkt.getSetupOffset(), tranPkt.getSetupCount() * 2); 1786 transBuf.appendParameter(buf, tranPkt.getRxParameterBlock(), tranPkt.getRxParameterBlockLength()); 1787 transBuf.appendData(buf, tranPkt.getRxDataBlock(), tranPkt.getRxDataBlockLength()); 1788 } 1789 1790 1792 transBuf.setReturnLimits(tranPkt.getMaximumReturnSetupCount(), tranPkt.getMaximumReturnParameterCount(), 1793 tranPkt.getMaximumReturnDataCount()); 1794 1795 1799 if (transBuf.isMultiPacket()) 1800 { 1801 1802 1804 m_sess.setTransaction(transBuf); 1805 1806 1808 m_sess.sendSuccessResponseSMB(); 1809 return; 1810 } 1811 1812 1815 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 1816 { 1817 IPCHandler.procTransaction(transBuf, m_sess, outPkt); 1818 return; 1819 } 1820 1821 1823 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 1824 logger.debug("Transaction [" + treeId + "] tbuf=" + transBuf); 1825 1826 1828 processTransactionBuffer(transBuf, outPkt); 1829 } 1830 1831 1837 protected void procTransact2Secondary(SMBSrvPacket outPkt) throws IOException , SMBSrvException 1838 { 1839 1840 1842 if (m_smbPkt.checkPacketIsValid(8, 0) == false) 1843 { 1844 1845 1847 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1848 return; 1849 } 1850 1851 1854 int treeId = m_smbPkt.getTreeId(); 1855 TreeConnection conn = m_sess.findConnection(treeId); 1856 1857 if (conn == null) 1858 { 1859 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 1860 return; 1861 } 1862 1863 1865 if (conn.hasReadAccess() == false) 1866 { 1867 1868 1870 m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); 1871 return; 1872 } 1873 1874 1876 if (m_sess.hasTransaction() == false 1877 || (m_sess.getTransaction().isType() == PacketType.Transaction && m_smbPkt.getCommand() != PacketType.TransactionSecond) 1878 || (m_sess.getTransaction().isType() == PacketType.Transaction2 && m_smbPkt.getCommand() != PacketType.Transaction2Second)) 1879 { 1880 1881 1884 m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1885 return; 1886 } 1887 1888 1890 SMBSrvTransPacket tpkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); 1891 byte[] buf = tpkt.getBuffer(); 1892 SrvTransactBuffer transBuf = m_sess.getTransaction(); 1893 1894 1896 int plen = tpkt.getSecondaryParameterBlockCount(); 1897 if (plen > 0) 1898 { 1899 1900 1902 DataBuffer paramBuf = transBuf.getParameterBuffer(); 1903 paramBuf.appendData(buf, tpkt.getSecondaryParameterBlockOffset(), plen); 1904 } 1905 1906 1908 int dlen = tpkt.getSecondaryDataBlockCount(); 1909 if (dlen > 0) 1910 { 1911 1912 1914 DataBuffer dataBuf = transBuf.getDataBuffer(); 1915 dataBuf.appendData(buf, tpkt.getSecondaryDataBlockOffset(), dlen); 1916 } 1917 1918 1920 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 1921 logger.debug("Transaction Secondary [" + treeId + "] paramLen=" + plen + ", dataLen=" + dlen); 1922 1923 1925 int totParam = tpkt.getTotalParameterCount(); 1926 int totData = tpkt.getTotalDataCount(); 1927 1928 int paramDisp = tpkt.getParameterBlockDisplacement(); 1929 int dataDisp = tpkt.getDataBlockDisplacement(); 1930 1931 if ((paramDisp + plen) == totParam && (dataDisp + dlen) == totData) 1932 { 1933 1934 1936 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 1937 logger.debug("Transaction complete, processing ..."); 1938 1939 1941 m_sess.setTransaction(null); 1942 1943 1946 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 1947 { 1948 IPCHandler.procTransaction(transBuf, m_sess, outPkt); 1949 return; 1950 } 1951 1952 1954 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 1955 logger.debug("Transaction second [" + treeId + "] tbuf=" + transBuf); 1956 1957 1959 processTransactionBuffer(transBuf, outPkt); 1960 } 1961 else 1962 { 1963 1964 1967 m_sess.sendSuccessResponseSMB(); 1968 } 1969 } 1970 1971 1979 private final void processTransactionBuffer(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws IOException , 1980 SMBSrvException 1981 { 1982 1983 1985 switch (tbuf.getFunction()) 1986 { 1987 1988 1990 case PacketType.Trans2FindFirst: 1991 procTrans2FindFirst(tbuf, outPkt); 1992 break; 1993 1994 1996 case PacketType.Trans2FindNext: 1997 procTrans2FindNext(tbuf, outPkt); 1998 break; 1999 2000 2002 case PacketType.Trans2QueryFileSys: 2003 procTrans2QueryFileSys(tbuf, outPkt); 2004 break; 2005 2006 2008 case PacketType.Trans2QueryPath: 2009 procTrans2QueryPath(tbuf, outPkt); 2010 break; 2011 2012 2014 case PacketType.Trans2QueryFile: 2015 procTrans2QueryFile(tbuf, outPkt); 2016 break; 2017 2018 2020 case PacketType.Trans2SetFile: 2021 procTrans2SetFile(tbuf, outPkt); 2022 break; 2023 2024 2026 case PacketType.Trans2SetPath: 2027 procTrans2SetPath(tbuf, outPkt); 2028 break; 2029 2030 2032 default: 2033 2034 2036 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 2037 break; 2038 } 2039 } 2040 2041 2048 protected final void procFindClose(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 2049 { 2050 2051 2053 if (m_smbPkt.checkPacketIsValid(1, 0) == false) 2054 { 2055 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 2056 return; 2057 } 2058 2059 2061 int treeId = m_smbPkt.getTreeId(); 2062 TreeConnection conn = m_sess.findConnection(treeId); 2063 2064 if (conn == null) 2065 { 2066 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 2067 return; 2068 } 2069 2070 2072 if (conn.hasReadAccess() == false) 2073 { 2074 2075 2077 m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); 2078 return; 2079 } 2080 2081 2083 int searchId = m_smbPkt.getParameter(0); 2084 2085 2087 SearchContext ctx = m_sess.getSearchContext(searchId); 2088 2089 if (ctx == null) 2090 { 2091 2092 2094 m_sess.sendSuccessResponseSMB(); 2095 return; 2096 } 2097 2098 2100 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 2101 logger.debug("Close trans search [" + searchId + "]"); 2102 2103 2105 m_sess.deallocateSearchSlot(searchId); 2106 2107 2109 m_sess.sendSuccessResponseSMB(); 2110 } 2111 2112 2117 protected final void procLockingAndX(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 2118 { 2119 2120 2122 if (m_smbPkt.checkPacketIsValid(8, 0) == false) 2123 { 2124 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 2125 return; 2126 } 2127 2128 2130 int treeId = m_smbPkt.getTreeId(); 2131 TreeConnection conn = m_sess.findConnection(treeId); 2132 2133 if (conn == null) 2134 { 2135 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 2136 return; 2137 } 2138 2139 2141 if (conn.hasReadAccess() == false) 2142 { 2143 2144 2146 m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); 2147 return; 2148 } 2149 2150 2152 int fid = m_smbPkt.getParameter(2); 2153 int lockType = m_smbPkt.getParameter(3); 2154 long lockTmo = m_smbPkt.getParameterLong(4); 2155 int unlockCnt = m_smbPkt.getParameter(6); 2156 int lockCnt = m_smbPkt.getParameter(7); 2157 2158 NetworkFile netFile = conn.findFile(fid); 2159 2160 if (netFile == null) 2161 { 2162 m_sess.sendErrorResponseSMB(SMBStatus.Win32InvalidHandle, SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); 2163 return; 2164 } 2165 2166 2168 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) 2169 logger.debug("File Lock [" + netFile.getFileId() + "] : type=0x" + Integer.toHexString(lockType) + ", tmo=" 2170 + lockTmo + ", locks=" + lockCnt + ", unlocks=" + unlockCnt); 2171 2172 DiskInterface disk = null; 2173 try 2174 { 2175 2176 2178 disk = (DiskInterface) conn.getSharedDevice().getInterface(); 2179 } 2180 catch (InvalidDeviceInterfaceException ex) 2181 { 2182 2183 2185 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2186 return; 2187 } 2188 2189 2191 if (disk instanceof FileLockingInterface) 2192 { 2193 2194 2196 FileLockingInterface lockInterface = (FileLockingInterface) disk; 2197 LockManager lockMgr = lockInterface.getLockManager(m_sess, conn); 2198 2199 2201 m_smbPkt.resetBytePointer(); 2202 boolean largeFileLock = LockingAndX.hasLargeFiles(lockType); 2203 2204 2206 if ((unlockCnt + lockCnt) == 1) 2207 { 2208 2209 2211 int pid = m_smbPkt.unpackWord(); 2212 long offset = -1; 2213 long length = -1; 2214 2215 if (largeFileLock == false) 2216 { 2217 2218 2220 offset = m_smbPkt.unpackInt(); 2221 length = m_smbPkt.unpackInt(); 2222 } 2223 else 2224 { 2225 2226 2228 m_smbPkt.skipBytes(2); 2229 2230 offset = ((long) m_smbPkt.unpackInt()) << 32; 2231 offset += (long) m_smbPkt.unpackInt(); 2232 2233 length = ((long) m_smbPkt.unpackInt()) << 32; 2234 length += (long) m_smbPkt.unpackInt(); 2235 } 2236 2237 2239 FileLock fLock = lockMgr.createLockObject(m_sess, conn, netFile, offset, length, pid); 2240 2241 2243 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) 2244 logger.debug(" Single " + (lockCnt == 1 ? "Lock" : "UnLock") + " lock=" + fLock.toString()); 2245 2246 2248 try 2249 { 2250 2251 2253 if (unlockCnt > 0) 2254 { 2255 2256 2258 lockMgr.unlockFile(m_sess, conn, netFile, fLock); 2259 } 2260 else 2261 { 2262 2263 2265 lockMgr.lockFile(m_sess, conn, netFile, fLock); 2266 } 2267 } 2268 catch (NotLockedException ex) 2269 { 2270 2271 2273 m_sess.sendErrorResponseSMB(SMBStatus.DOSNotLocked, SMBStatus.ErrDos); 2274 return; 2275 } 2276 catch (LockConflictException ex) 2277 { 2278 2279 2281 m_sess 2282 .sendErrorResponseSMB(SMBStatus.NTLockNotGranted, SMBStatus.DOSLockConflict, 2283 SMBStatus.ErrDos); 2284 return; 2285 } 2286 catch (IOException ex) 2287 { 2288 2289 2291 m_sess.sendErrorResponseSMB(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); 2292 return; 2293 } 2294 } 2295 else 2296 { 2297 2298 2300 } 2301 } 2302 else 2303 { 2304 2305 2308 if (unlockCnt > 0) 2309 { 2310 2311 2313 m_sess.sendErrorResponseSMB(SMBStatus.DOSNotLocked, SMBStatus.ErrDos); 2314 return; 2315 } 2316 } 2317 2318 2320 outPkt.setParameterCount(2); 2321 outPkt.setAndXCommand(0xFF); 2322 outPkt.setParameter(1, 0); 2323 outPkt.setByteCount(0); 2324 2325 2327 m_sess.sendResponseSMB(outPkt); 2328 } 2329 2330 2335 protected final void procLogoffAndX(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 2336 { 2337 2338 2340 if (m_smbPkt.checkPacketIsValid(15, 1) == false) 2341 { 2342 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 2343 return; 2344 } 2345 2346 2348 m_sess.sendSuccessResponseSMB(); 2349 } 2350 2351 2356 protected final void procOpenAndX(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 2357 { 2358 2359 2361 if (m_smbPkt.checkPacketIsValid(15, 1) == false) 2362 { 2363 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 2364 return; 2365 } 2366 2367 2369 int treeId = m_smbPkt.getTreeId(); 2370 TreeConnection conn = m_sess.findConnection(treeId); 2371 2372 if (conn == null) 2373 { 2374 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 2375 return; 2376 } 2377 2378 2380 if (conn.hasReadAccess() == false) 2381 { 2382 2383 2385 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2386 return; 2387 } 2388 2389 2393 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 2394 { 2395 2396 2398 IPCHandler.processIPCRequest(m_sess, outPkt); 2399 return; 2400 } 2401 else if (conn.getSharedDevice().getType() != ShareType.DISK) 2402 { 2403 2404 2406 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2407 return; 2408 } 2409 2410 2412 int flags = m_smbPkt.getParameter(2); 2413 int access = m_smbPkt.getParameter(3); 2414 int srchAttr = m_smbPkt.getParameter(4); 2415 int fileAttr = m_smbPkt.getParameter(5); 2416 int crTime = m_smbPkt.getParameter(6); 2417 int crDate = m_smbPkt.getParameter(7); 2418 int openFunc = m_smbPkt.getParameter(8); 2419 int allocSiz = m_smbPkt.getParameterLong(9); 2420 2421 2423 String fileName = m_smbPkt.unpackString(m_smbPkt.isUnicode()); 2424 if (fileName == null) 2425 { 2426 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2427 return; 2428 } 2429 2430 2432 long crDateTime = 0L; 2433 if (crTime > 0 && crDate > 0) 2434 crDateTime = new SMBDate(crDate, crTime).getTime(); 2435 2436 FileOpenParams params = new FileOpenParams(fileName, openFunc, access, srchAttr, fileAttr, allocSiz, crDateTime); 2437 2438 2440 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 2441 logger.debug("File Open AndX [" + treeId + "] params=" + params); 2442 2443 2445 int fid; 2446 NetworkFile netFile = null; 2447 int respAction = 0; 2448 2449 try 2450 { 2451 2452 2454 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 2455 2456 2458 int fileSts = disk.fileExists(m_sess, conn, fileName); 2459 2460 if (fileSts == FileStatus.NotExist) 2461 { 2462 2463 2465 if (FileAction.createNotExists(openFunc)) 2466 { 2467 2468 2470 netFile = disk.createFile(m_sess, conn, params); 2471 2472 2474 respAction = FileAction.FileCreated; 2475 } 2476 else 2477 { 2478 2479 2481 if (fileSts == FileStatus.DirectoryExists) 2482 { 2483 2484 2486 m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2487 } 2488 else 2489 { 2490 2491 2493 m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 2494 } 2495 return; 2496 } 2497 } 2498 else 2499 { 2500 2501 2503 netFile = disk.openFile(m_sess, conn, params); 2504 2505 2507 if (FileAction.truncateExistingFile(openFunc)) 2508 respAction = FileAction.FileTruncated; 2509 else 2510 respAction = FileAction.FileExisted; 2511 } 2512 2513 2515 fid = conn.addFile(netFile, getSession()); 2516 2517 } 2518 catch (InvalidDeviceInterfaceException ex) 2519 { 2520 2521 2523 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2524 return; 2525 } 2526 catch (TooManyFilesException ex) 2527 { 2528 2529 2531 m_sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); 2532 return; 2533 } 2534 catch (AccessDeniedException ex) 2535 { 2536 2537 2539 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2540 return; 2541 } 2542 catch (FileSharingException ex) 2543 { 2544 2545 2547 m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, 2548 SMBStatus.ErrDos); 2549 return; 2550 } 2551 catch (FileOfflineException ex) 2552 { 2553 2554 2556 m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd); 2557 return; 2558 } 2559 catch (java.io.IOException ex) 2560 { 2561 2562 2564 m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 2565 return; 2566 } 2567 2568 2570 outPkt.setParameterCount(15); 2571 2572 outPkt.setAndXCommand(0xFF); 2573 outPkt.setParameter(1, 0); 2575 outPkt.setParameter(2, fid); 2576 outPkt.setParameter(3, netFile.getFileAttributes()); 2578 SMBDate modDate = null; 2579 2580 if (netFile.hasModifyDate()) 2581 modDate = new SMBDate(netFile.getModifyDate()); 2582 2583 outPkt.setParameter(4, modDate != null ? modDate.asSMBTime() : 0); outPkt.setParameter(5, modDate != null ? modDate.asSMBDate() : 0); outPkt.setParameterLong(6, netFile.getFileSizeInt()); outPkt.setParameter(8, netFile.getGrantedAccess()); 2587 outPkt.setParameter(9, OpenAndX.FileTypeDisk); 2588 outPkt.setParameter(10, 0); outPkt.setParameter(11, respAction); 2590 outPkt.setParameter(12, 0); outPkt.setParameter(13, 0); 2592 outPkt.setParameter(14, 0); 2593 2594 outPkt.setByteCount(0); 2595 2596 2598 m_sess.sendResponseSMB(outPkt); 2599 } 2600 2601 2606 protected final void procReadAndX(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 2607 { 2608 2609 2611 if (m_smbPkt.checkPacketIsValid(10, 0) == false) 2612 { 2613 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 2614 return; 2615 } 2616 2617 2619 int treeId = m_smbPkt.getTreeId(); 2620 TreeConnection conn = m_sess.findConnection(treeId); 2621 2622 if (conn == null) 2623 { 2624 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 2625 return; 2626 } 2627 2628 2630 if (conn.hasReadAccess() == false) 2631 { 2632 2633 2635 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2636 return; 2637 } 2638 2639 2642 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 2643 { 2644 2645 2647 IPCHandler.processIPCRequest(m_sess, outPkt); 2648 return; 2649 } 2650 2651 2653 int fid = m_smbPkt.getParameter(2); 2654 long offset = (long) m_smbPkt.getParameterLong(3); offset &= 0xFFFFFFFFL; 2656 int maxCount = m_smbPkt.getParameter(5); 2657 2658 2660 if (m_smbPkt.getParameterCount() == 12) 2661 { 2662 long topOff = (long) m_smbPkt.getParameterLong(10); 2663 offset += topOff << 32; 2664 } 2665 2666 NetworkFile netFile = conn.findFile(fid); 2667 2668 if (netFile == null) 2669 { 2670 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); 2671 return; 2672 } 2673 2674 2676 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) 2677 logger.debug("File Read AndX [" + netFile.getFileId() + "] : Size=" + maxCount + " ,Pos=" + offset); 2678 2679 2681 byte[] buf = outPkt.getBuffer(); 2682 int dataPos = 0; 2683 int rdlen = 0; 2684 2685 try 2686 { 2687 2688 2690 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 2691 2692 2694 outPkt.setParameterCount(12); 2695 dataPos = outPkt.getByteOffset(); 2696 dataPos = DataPacker.wordAlign(dataPos); 2698 2700 int dataLen = buf.length - dataPos; 2701 if (dataLen < maxCount) 2702 maxCount = dataLen; 2703 2704 2706 rdlen = disk.readFile(m_sess, conn, netFile, buf, dataPos, maxCount, offset); 2707 } 2708 catch (InvalidDeviceInterfaceException ex) 2709 { 2710 2711 2713 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2714 return; 2715 } 2716 catch (FileOfflineException ex) 2717 { 2718 2719 2721 m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDReadFault, SMBStatus.ErrHrd); 2722 return; 2723 } 2724 catch (LockConflictException ex) 2725 { 2726 2727 2729 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) 2730 logger.debug("Read Lock Error [" + netFile.getFileId() + "] : Size=" + maxCount + " ,Pos=" + offset); 2731 2732 2734 m_sess.sendErrorResponseSMB(SMBStatus.NTLockConflict, SMBStatus.DOSLockConflict, SMBStatus.ErrDos); 2735 return; 2736 } 2737 catch (AccessDeniedException ex) 2738 { 2739 2740 2742 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2743 return; 2744 } 2745 catch (java.io.IOException ex) 2746 { 2747 2748 2750 m_sess.sendErrorResponseSMB(SMBStatus.HRDReadFault, SMBStatus.ErrHrd); 2751 return; 2752 } 2753 2754 2756 outPkt.setAndXCommand(0xFF); outPkt.setParameter(1, 0); 2758 outPkt.setParameter(2, 0); outPkt.setParameter(3, 0); outPkt.setParameter(4, 0); outPkt.setParameter(5, rdlen); outPkt.setParameter(6, dataPos - RFCNetBIOSProtocol.HEADER_LEN); 2764 2766 for (int i = 7; i < 12; i++) 2767 outPkt.setParameter(i, 0); 2768 2769 2771 outPkt.setByteCount((dataPos + rdlen) - outPkt.getByteOffset()); 2772 2773 2775 if (m_smbPkt.hasAndXCommand()) 2776 { 2777 2778 2780 int pos = procAndXCommands(outPkt, outPkt.getPacketLength(), netFile); 2781 2782 2784 m_sess.sendResponseSMB(outPkt, pos); 2785 } 2786 else 2787 { 2788 2789 2791 m_sess.sendResponseSMB(outPkt); 2792 } 2793 } 2794 2795 2802 protected void procRenameFile(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 2803 { 2804 2805 2807 if (m_smbPkt.checkPacketIsValid(1, 4) == false) 2808 { 2809 m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); 2810 return; 2811 } 2812 2813 2816 int treeId = m_smbPkt.getTreeId(); 2817 TreeConnection conn = m_sess.findConnection(treeId); 2818 2819 if (conn == null) 2820 { 2821 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 2822 return; 2823 } 2824 2825 2827 if (conn.hasWriteAccess() == false) 2828 { 2829 2830 2832 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2833 return; 2834 } 2835 2836 2838 boolean isUni = m_smbPkt.isUnicode(); 2839 2840 2842 m_smbPkt.resetBytePointer(); 2843 2844 2846 if (m_smbPkt.unpackByte() != DataType.ASCII) 2847 { 2848 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2849 return; 2850 } 2851 2852 String oldName = m_smbPkt.unpackString(isUni); 2853 if (oldName == null) 2854 { 2855 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2856 return; 2857 } 2858 2859 2861 if (m_smbPkt.unpackByte() != DataType.ASCII) 2862 { 2863 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2864 return; 2865 } 2866 2867 String newName = m_smbPkt.unpackString(isUni); 2868 if (newName == null) 2869 { 2870 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2871 return; 2872 } 2873 2874 2876 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 2877 logger.debug("File Rename [" + treeId + "] old name=" + oldName + ", new name=" + newName); 2878 2879 2881 int fid; 2882 NetworkFile netFile = null; 2883 2884 try 2885 { 2886 2887 2889 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 2890 2891 2893 disk.renameFile(m_sess, conn, oldName, newName); 2894 } 2895 catch (InvalidDeviceInterfaceException ex) 2896 { 2897 2898 2900 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 2901 return; 2902 } 2903 catch (FileNotFoundException ex) 2904 { 2905 2906 2908 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 2909 return; 2910 } 2911 catch (FileExistsException ex) 2912 { 2913 2914 2916 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, 2917 SMBStatus.ErrDos); 2918 return; 2919 } 2920 catch (AccessDeniedException ex) 2921 { 2922 2923 2925 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2926 return; 2927 } 2928 catch (FileSharingException ex) 2929 { 2930 2931 2933 m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, 2934 SMBStatus.ErrDos); 2935 return; 2936 } 2937 2938 2940 outPkt.setParameterCount(0); 2941 outPkt.setByteCount(0); 2942 2943 2945 m_sess.sendResponseSMB(outPkt); 2946 2947 2949 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 2950 if (diskCtx.hasChangeHandler()) 2951 diskCtx.getChangeHandler().notifyRename(oldName, newName); 2952 } 2953 2954 2961 protected void procDeleteFile(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 2962 { 2963 2964 2966 if (m_smbPkt.checkPacketIsValid(1, 2) == false) 2967 { 2968 m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); 2969 return; 2970 } 2971 2972 2975 int treeId = m_smbPkt.getTreeId(); 2976 TreeConnection conn = m_sess.findConnection(treeId); 2977 2978 if (conn == null) 2979 { 2980 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 2981 return; 2982 } 2983 2984 2986 if (conn.hasWriteAccess() == false) 2987 { 2988 2989 2991 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 2992 return; 2993 } 2994 2995 2997 boolean isUni = m_smbPkt.isUnicode(); 2998 2999 3001 m_smbPkt.resetBytePointer(); 3002 3003 3005 if (m_smbPkt.unpackByte() != DataType.ASCII) 3006 { 3007 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3008 return; 3009 } 3010 3011 String fileName = m_smbPkt.unpackString(isUni); 3012 if (fileName == null) 3013 { 3014 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3015 return; 3016 } 3017 3018 3020 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 3021 logger.debug("File Delete [" + treeId + "] name=" + fileName); 3022 3023 3025 int fid; 3026 NetworkFile netFile = null; 3027 3028 try 3029 { 3030 3031 3033 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 3034 3035 3037 disk.deleteFile(m_sess, conn, fileName); 3038 } 3039 catch (InvalidDeviceInterfaceException ex) 3040 { 3041 3042 3044 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3045 return; 3046 } 3047 catch (AccessDeniedException ex) 3048 { 3049 3050 3052 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 3053 return; 3054 } 3055 catch (java.io.IOException ex) 3056 { 3057 3058 3060 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 3061 return; 3062 } 3063 3064 3066 outPkt.setParameterCount(0); 3067 outPkt.setByteCount(0); 3068 3069 3071 m_sess.sendResponseSMB(outPkt); 3072 3073 3075 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 3076 if (diskCtx.hasChangeHandler()) 3077 diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, fileName); 3078 } 3079 3080 3087 protected void procDeleteDirectory(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 3088 { 3089 3090 3092 if (m_smbPkt.checkPacketIsValid(0, 2) == false) 3093 { 3094 m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); 3095 return; 3096 } 3097 3098 3101 int treeId = m_smbPkt.getTreeId(); 3102 TreeConnection conn = m_sess.findConnection(treeId); 3103 3104 if (conn == null) 3105 { 3106 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 3107 return; 3108 } 3109 3110 3112 if (conn.hasWriteAccess() == false) 3113 { 3114 3115 3117 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 3118 return; 3119 } 3120 3121 3123 boolean isUni = m_smbPkt.isUnicode(); 3124 3125 3127 m_smbPkt.resetBytePointer(); 3128 3129 3131 if (m_smbPkt.unpackByte() != DataType.ASCII) 3132 { 3133 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3134 return; 3135 } 3136 3137 String dirName = m_smbPkt.unpackString(isUni); 3138 if (dirName == null) 3139 { 3140 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3141 return; 3142 } 3143 3144 3146 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 3147 logger.debug("Directory Delete [" + treeId + "] name=" + dirName); 3148 3149 3151 try 3152 { 3153 3154 3156 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 3157 3158 3160 disk.deleteDirectory(m_sess, conn, dirName); 3161 } 3162 catch (InvalidDeviceInterfaceException ex) 3163 { 3164 3165 3167 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3168 return; 3169 } 3170 catch (AccessDeniedException ex) 3171 { 3172 3173 3175 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 3176 return; 3177 } 3178 catch (DirectoryNotEmptyException ex) 3179 { 3180 3181 3183 m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryNotEmpty, SMBStatus.ErrDos); 3184 return; 3185 } 3186 catch (java.io.IOException ex) 3187 { 3188 3189 3191 m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos); 3192 return; 3193 } 3194 3195 3197 outPkt.setParameterCount(0); 3198 outPkt.setByteCount(0); 3199 3200 3202 m_sess.sendResponseSMB(outPkt); 3203 3204 3206 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 3207 if (diskCtx.hasChangeHandler()) 3208 diskCtx.getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionRemoved, dirName); 3209 } 3210 3211 3219 protected final void procTrans2FindFirst(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException , 3220 SMBSrvException 3221 { 3222 3223 3225 int treeId = m_smbPkt.getTreeId(); 3226 TreeConnection conn = m_sess.findConnection(treeId); 3227 3228 if (conn == null) 3229 { 3230 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 3231 return; 3232 } 3233 3234 3236 if (conn.hasReadAccess() == false) 3237 { 3238 3239 3241 m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); 3242 return; 3243 } 3244 3245 3247 DataBuffer paramBuf = tbuf.getParameterBuffer(); 3248 3249 int srchAttr = paramBuf.getShort(); 3250 int maxFiles = paramBuf.getShort(); 3251 int srchFlag = paramBuf.getShort(); 3252 int infoLevl = paramBuf.getShort(); 3253 paramBuf.skipBytes(4); 3254 3255 String srchPath = paramBuf.getString(tbuf.isUnicode()); 3256 3257 3259 if (srchPath == null || srchPath.length() == 0) 3260 { 3261 3262 3264 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3265 return; 3266 } 3267 else if (srchPath.endsWith("\\")) 3268 { 3269 3270 3272 srchPath = srchPath + "*.*"; 3273 } 3274 3275 3278 if (infoLevl == FindInfoPacker.InfoMacHfsInfo && getSession().hasMacintoshExtensions() == false) 3279 { 3280 3281 3283 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 3284 return; 3285 } 3286 3287 3289 SearchContext ctx = null; 3290 DiskInterface disk = null; 3291 int searchId = -1; 3292 boolean wildcardSearch = false; 3293 3294 try 3295 { 3296 3297 3299 disk = (DiskInterface) conn.getSharedDevice().getInterface(); 3300 3301 3303 searchId = m_sess.allocateSearchSlot(); 3304 if (searchId == -1) 3305 { 3306 3307 3309 m_sess.sendErrorResponseSMB(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv); 3310 return; 3311 } 3312 3313 3315 if (WildCard.containsWildcards(srchPath) || WildCard.containsUnicodeWildcard(srchPath)) 3316 wildcardSearch = true; 3317 3318 3320 if (tbuf.isUnicode() && WildCard.containsUnicodeWildcard(srchPath)) 3321 { 3322 3323 3325 srchPath = WildCard.convertUnicodeWildcardToDOS(srchPath); 3326 3327 3329 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3330 logger.debug("Converted Unicode wildcards to:" + srchPath); 3331 } 3332 3333 3335 ctx = disk.startSearch(m_sess, conn, srchPath, srchAttr); 3336 if (ctx != null) 3337 { 3338 3339 3341 ctx.setTreeId(treeId); 3342 ctx.setMaximumFiles(maxFiles); 3343 } 3344 else 3345 { 3346 3347 3349 m_sess.sendErrorResponseSMB(SMBStatus.NTNoSuchFile, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 3350 return; 3351 } 3352 3353 3355 m_sess.setSearchContext(searchId, ctx); 3356 3357 3359 SrvTransactBuffer replyBuf = new SrvTransactBuffer(tbuf); 3360 DataBuffer dataBuf = replyBuf.getDataBuffer(); 3361 3362 3364 int maxLen = replyBuf.getReturnDataLimit(); 3365 3366 3368 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3369 logger.debug("Start trans search [" + searchId + "] - " + srchPath + ", attr=0x" 3370 + Integer.toHexString(srchAttr) + ", maxFiles=" + maxFiles + ", maxLen=" + maxLen 3371 + ", infoLevel=" + infoLevl + ", flags=0x" + Integer.toHexString(srchFlag)); 3372 3373 3375 int fileCnt = 0; 3376 int packLen = 0; 3377 int lastNameOff = 0; 3378 3379 3381 boolean resumeIds = false; 3382 if (infoLevl == FindInfoPacker.InfoStandard && (srchFlag & FindFirstNext.ReturnResumeKey) != 0) 3383 { 3384 3385 3388 resumeIds = true; 3389 } 3390 3391 3393 if (wildcardSearch == true && ReturnDotFiles == true) 3394 { 3395 3396 3398 if (resumeIds == true) 3399 { 3400 dataBuf.putInt(-1); 3401 maxLen -= 4; 3402 } 3403 3404 lastNameOff = dataBuf.getPosition(); 3405 FileInfo dotInfo = new FileInfo(".", 0, FileAttribute.Directory); 3406 dotInfo.setFileId(dotInfo.getFileName().hashCode()); 3407 3408 packLen = FindInfoPacker.packInfo(dotInfo, dataBuf, infoLevl, tbuf.isUnicode()); 3409 3410 3412 fileCnt++; 3413 maxLen -= packLen; 3414 3415 3417 if (resumeIds == true) 3418 { 3419 dataBuf.putInt(-2); 3420 maxLen -= 4; 3421 } 3422 3423 lastNameOff = dataBuf.getPosition(); 3424 dotInfo.setFileName(".."); 3425 dotInfo.setFileId(dotInfo.getFileName().hashCode()); 3426 3427 packLen = FindInfoPacker.packInfo(dotInfo, dataBuf, infoLevl, tbuf.isUnicode()); 3428 3429 3431 fileCnt++; 3432 maxLen -= packLen; 3433 } 3434 3435 boolean pktDone = false; 3436 boolean searchDone = false; 3437 3438 FileInfo info = new FileInfo(); 3439 3440 while (pktDone == false && fileCnt < maxFiles) 3441 { 3442 3443 3445 if (ctx.nextFileInfo(info) == false) 3446 { 3447 3448 3450 pktDone = true; 3451 searchDone = true; 3452 } 3453 3454 3456 else if (FindInfoPacker.calcInfoSize(info, infoLevl, false, true) <= maxLen) 3457 { 3458 3459 3461 if (resumeIds == true) 3462 { 3463 dataBuf.putInt(ctx.getResumeId()); 3464 maxLen -= 4; 3465 } 3466 3467 3469 lastNameOff = dataBuf.getPosition(); 3470 3471 3473 packLen = FindInfoPacker.packInfo(info, dataBuf, infoLevl, tbuf.isUnicode()); 3474 3475 3477 fileCnt++; 3478 3479 3481 maxLen -= packLen; 3482 } 3483 else 3484 { 3485 3486 3488 ctx.restartAt(info); 3489 3490 3492 pktDone = true; 3493 } 3494 } 3495 3496 3499 if (wildcardSearch == false && fileCnt == 0) 3500 throw new FileNotFoundException (srchPath); 3501 3502 3505 if (maxFiles == 1 && fileCnt == 1) 3506 searchDone = true; 3507 3508 3510 FindInfoPacker.clearNextOffset(dataBuf, infoLevl, lastNameOff); 3511 3512 3514 paramBuf = replyBuf.getParameterBuffer(); 3515 3516 paramBuf.putShort(searchId); 3517 paramBuf.putShort(fileCnt); 3518 paramBuf.putShort(ctx.hasMoreFiles() ? 0 : 1); 3519 paramBuf.putShort(0); 3520 paramBuf.putShort(lastNameOff); 3521 3522 3524 SMBSrvTransPacket tpkt = new SMBSrvTransPacket(outPkt.getBuffer()); 3525 tpkt.doTransactionResponse(m_sess, replyBuf); 3526 3527 3529 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3530 logger.debug("Search [" + searchId + "] Returned " + fileCnt + " files, dataLen=" + dataBuf.getLength() 3531 + ", moreFiles=" + ctx.hasMoreFiles()); 3532 3533 3535 if (searchDone == true || ctx.hasMoreFiles() == false) 3536 { 3537 3538 3540 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3541 logger.debug("End start search [" + searchId + "] (Search complete)"); 3542 3543 3545 m_sess.deallocateSearchSlot(searchId); 3546 } 3547 } 3548 catch (FileNotFoundException ex) 3549 { 3550 3551 3553 m_sess.sendErrorResponseSMB(SMBStatus.NTNoSuchFile, SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); 3554 } 3555 catch (PathNotFoundException ex) 3556 { 3557 3558 3560 if (searchId != -1) 3561 m_sess.deallocateSearchSlot(searchId); 3562 3563 3565 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 3566 return; 3567 } 3568 catch (InvalidDeviceInterfaceException ex) 3569 { 3570 3571 3573 if (searchId != -1) 3574 m_sess.deallocateSearchSlot(searchId); 3575 3576 3578 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3579 } 3580 catch (UnsupportedInfoLevelException ex) 3581 { 3582 3583 3585 if (searchId != -1) 3586 m_sess.deallocateSearchSlot(searchId); 3587 3588 3590 m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 3591 } 3592 } 3593 3594 3602 protected final void procTrans2FindNext(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException , 3603 SMBSrvException 3604 { 3605 3606 3608 int treeId = m_smbPkt.getTreeId(); 3609 TreeConnection conn = m_sess.findConnection(treeId); 3610 3611 if (conn == null) 3612 { 3613 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 3614 return; 3615 } 3616 3617 3619 if (conn.hasReadAccess() == false) 3620 { 3621 3622 3624 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 3625 return; 3626 } 3627 3628 3630 DataBuffer paramBuf = tbuf.getParameterBuffer(); 3631 3632 int searchId = paramBuf.getShort(); 3633 int maxFiles = paramBuf.getShort(); 3634 int infoLevl = paramBuf.getShort(); 3635 int reskey = paramBuf.getInt(); 3636 int srchFlag = paramBuf.getShort(); 3637 3638 String resumeName = paramBuf.getString(tbuf.isUnicode()); 3639 3640 3642 SearchContext ctx = null; 3643 DiskInterface disk = null; 3644 3645 try 3646 { 3647 3648 3650 disk = (DiskInterface) conn.getSharedDevice().getInterface(); 3651 3652 3654 ctx = m_sess.getSearchContext(searchId); 3655 if (ctx == null) 3656 { 3657 3658 3660 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3661 logger.debug("Search context null - [" + searchId + "]"); 3662 3663 3665 m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); 3666 return; 3667 } 3668 3669 3671 SrvTransactBuffer replyBuf = new SrvTransactBuffer(tbuf); 3672 DataBuffer dataBuf = replyBuf.getDataBuffer(); 3673 3674 3676 int maxLen = replyBuf.getReturnDataLimit(); 3677 3678 3680 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3681 logger.debug("Continue search [" + searchId + "] - " + resumeName + ", maxFiles=" + maxFiles 3682 + ", maxLen=" + maxLen + ", infoLevel=" + infoLevl + ", flags=0x" 3683 + Integer.toHexString(srchFlag)); 3684 3685 3687 int fileCnt = 0; 3688 int packLen = 0; 3689 int lastNameOff = 0; 3690 3691 3693 boolean resumeIds = false; 3694 if (infoLevl == FindInfoPacker.InfoStandard && (srchFlag & FindFirstNext.ReturnResumeKey) != 0) 3695 { 3696 3697 3700 resumeIds = true; 3701 } 3702 3703 3705 boolean pktDone = false; 3706 boolean searchDone = false; 3707 3708 FileInfo info = new FileInfo(); 3709 3710 while (pktDone == false && fileCnt < maxFiles) 3711 { 3712 3713 3715 if (ctx.nextFileInfo(info) == false) 3716 { 3717 3718 3720 pktDone = true; 3721 searchDone = true; 3722 } 3723 3724 3726 else if (FindInfoPacker.calcInfoSize(info, infoLevl, false, true) <= maxLen) 3727 { 3728 3729 3731 if (resumeIds == true) 3732 { 3733 dataBuf.putInt(ctx.getResumeId()); 3734 maxLen -= 4; 3735 } 3736 3737 3739 lastNameOff = dataBuf.getPosition(); 3740 3741 3743 packLen = FindInfoPacker.packInfo(info, dataBuf, infoLevl, tbuf.isUnicode()); 3744 3745 3747 fileCnt++; 3748 3749 3751 maxLen -= packLen; 3752 } 3753 else 3754 { 3755 3756 3758 ctx.restartAt(info); 3759 3760 3762 pktDone = true; 3763 } 3764 } 3765 3766 3768 paramBuf = replyBuf.getParameterBuffer(); 3769 3770 paramBuf.putShort(fileCnt); 3771 paramBuf.putShort(ctx.hasMoreFiles() ? 0 : 1); 3772 paramBuf.putShort(0); 3773 paramBuf.putShort(lastNameOff); 3774 3775 3777 SMBSrvTransPacket tpkt = new SMBSrvTransPacket(outPkt.getBuffer()); 3778 tpkt.doTransactionResponse(m_sess, replyBuf); 3779 3780 3782 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3783 logger.debug("Search [" + searchId + "] Returned " + fileCnt + " files, dataLen=" + dataBuf.getLength() 3784 + ", moreFiles=" + ctx.hasMoreFiles()); 3785 3786 3788 if (searchDone == true || ctx.hasMoreFiles() == false) 3789 { 3790 3791 3793 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) 3794 logger.debug("End start search [" + searchId + "] (Search complete)"); 3795 3796 3798 m_sess.deallocateSearchSlot(searchId); 3799 } 3800 } 3801 catch (FileNotFoundException ex) 3802 { 3803 3804 3806 if (searchId != -1) 3807 m_sess.deallocateSearchSlot(searchId); 3808 3809 3811 m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); 3812 } 3813 catch (InvalidDeviceInterfaceException ex) 3814 { 3815 3816 3818 if (searchId != -1) 3819 m_sess.deallocateSearchSlot(searchId); 3820 3821 3823 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 3824 } 3825 catch (UnsupportedInfoLevelException ex) 3826 { 3827 3828 3830 if (searchId != -1) 3831 m_sess.deallocateSearchSlot(searchId); 3832 3833 3835 m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 3836 } 3837 } 3838 3839 3847 protected final void procTrans2QueryFileSys(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) 3848 throws java.io.IOException , SMBSrvException 3849 { 3850 3851 3853 int treeId = m_smbPkt.getTreeId(); 3854 TreeConnection conn = m_sess.findConnection(treeId); 3855 3856 if (conn == null) 3857 { 3858 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 3859 return; 3860 } 3861 3862 3864 if (conn.hasReadAccess() == false) 3865 { 3866 3867 3869 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 3870 return; 3871 } 3872 3873 3875 DataBuffer paramBuf = tbuf.getParameterBuffer(); 3876 3877 int infoLevl = paramBuf.getShort(); 3878 3879 3881 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 3882 logger.debug("Query File System Info - level = 0x" + Integer.toHexString(infoLevl)); 3883 3884 3886 try 3887 { 3888 3889 3891 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 3892 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 3893 3894 3896 outPkt.setParameterCount(10); 3897 3898 3900 byte[] buf = outPkt.getBuffer(); 3901 int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); 3902 int dataPos = prmPos; 3904 3908 DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); 3909 3910 3912 SrvDiskInfo diskInfo = null; 3913 VolumeInfo volInfo = null; 3914 3915 switch (infoLevl) 3916 { 3917 3918 3920 case DiskInfoPacker.InfoStandard: 3921 3922 3924 diskInfo = getDiskInformation(disk, diskCtx); 3925 3926 3928 DiskInfoPacker.packStandardInfo(diskInfo, replyBuf); 3929 break; 3930 3931 3933 case DiskInfoPacker.InfoVolume: 3934 3935 3937 volInfo = getVolumeInformation(disk, diskCtx); 3938 3939 3941 DiskInfoPacker.packVolumeInfo(volInfo, replyBuf, tbuf.isUnicode()); 3942 break; 3943 3944 3946 case DiskInfoPacker.InfoFsVolume: 3947 3948 3950 volInfo = getVolumeInformation(disk, diskCtx); 3951 3952 3954 DiskInfoPacker.packFsVolumeInformation(volInfo, replyBuf, tbuf.isUnicode()); 3955 break; 3956 3957 3959 case DiskInfoPacker.InfoFsSize: 3960 3961 3963 diskInfo = getDiskInformation(disk, diskCtx); 3964 3965 3967 DiskInfoPacker.packFsSizeInformation(diskInfo, replyBuf); 3968 break; 3969 3970 3972 case DiskInfoPacker.InfoFsDevice: 3973 DiskInfoPacker.packFsDevice(NTIOCtl.DeviceDisk, diskCtx.getDeviceAttributes(), replyBuf); 3974 break; 3975 3976 3978 case DiskInfoPacker.InfoFsAttribute: 3979 String fsType = diskCtx.getFilesystemType(); 3980 3981 if (disk instanceof NTFSStreamsInterface) 3982 { 3983 3984 3986 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 3987 if (ntfsStreams.hasStreamsEnabled(m_sess, conn)) 3988 fsType = "NTFS"; 3989 } 3990 3991 3993 DiskInfoPacker.packFsAttribute(diskCtx.getFilesystemAttributes(), 255, fsType, tbuf.isUnicode(), 3994 replyBuf); 3995 break; 3996 3997 3999 case DiskInfoPacker.InfoMacFsInfo: 4000 4001 4009 boolean ntfs = false; 4010 4011 if (disk instanceof NTFSStreamsInterface) 4012 { 4013 4014 4016 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 4017 ntfs = ntfsStreams.hasStreamsEnabled(m_sess, conn); 4018 } 4019 4020 4022 if (ntfs == false) 4023 { 4024 4025 4027 diskInfo = getDiskInformation(disk, diskCtx); 4028 volInfo = getVolumeInformation(disk, diskCtx); 4029 4030 4032 DiskInfoPacker.packMacFsInformation(diskInfo, volInfo, ntfs, replyBuf); 4033 } 4034 break; 4035 4036 4038 case DiskInfoPacker.InfoFullFsSize: 4039 4040 4042 diskInfo = getDiskInformation(disk, diskCtx); 4043 long userLimit = diskInfo.getTotalUnits(); 4044 4045 4047 DiskInfoPacker.packFullFsSizeInformation(userLimit, diskInfo, replyBuf); 4048 break; 4049 } 4050 4051 4053 if (replyBuf.getPosition() == dataPos) 4054 { 4055 m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 4056 return; 4057 } 4058 4059 int bytCnt = replyBuf.getPosition() - outPkt.getByteOffset(); 4060 replyBuf.setEndOfBuffer(); 4061 int dataLen = replyBuf.getLength(); 4062 SMBSrvTransPacket.initTransactReply(outPkt, 0, prmPos, dataLen, dataPos); 4063 outPkt.setByteCount(bytCnt); 4064 4065 4067 m_sess.sendResponseSMB(outPkt); 4068 } 4069 catch (InvalidDeviceInterfaceException ex) 4070 { 4071 4072 4074 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 4075 return; 4076 } 4077 } 4078 4079 4087 protected final void procTrans2QueryPath(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException , 4088 SMBSrvException 4089 { 4090 4091 4093 int treeId = m_smbPkt.getTreeId(); 4094 TreeConnection conn = m_sess.findConnection(treeId); 4095 4096 if (conn == null) 4097 { 4098 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 4099 return; 4100 } 4101 4102 4104 if (conn.hasReadAccess() == false) 4105 { 4106 4107 4109 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 4110 return; 4111 } 4112 4113 4115 DataBuffer paramBuf = tbuf.getParameterBuffer(); 4116 4117 int infoLevl = paramBuf.getShort(); 4118 paramBuf.skipBytes(4); 4119 4120 String path = paramBuf.getString(tbuf.isUnicode()); 4121 4122 4124 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4125 logger.debug("Query Path - level = 0x" + Integer.toHexString(infoLevl) + ", path = " + path); 4126 4127 4129 try 4130 { 4131 4132 4134 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 4135 4136 4138 outPkt.setParameterCount(10); 4139 4140 4142 byte[] buf = outPkt.getBuffer(); 4143 int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); 4144 int dataPos = prmPos + 4; 4145 4146 4148 outPkt.setPosition(prmPos); 4149 outPkt.packWord(0); 4150 4151 4155 DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); 4156 4157 4159 boolean streams = false; 4160 4161 if (disk instanceof NTFSStreamsInterface) 4162 { 4163 4164 4166 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 4167 streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); 4168 } 4169 4170 4172 if ( streams == false && path.indexOf(FileOpenParams.StreamSeparator) != -1) 4173 { 4174 4176 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 4177 return; 4178 } 4179 4180 4182 int dataLen = 0; 4183 4184 if (streams == true 4185 && (infoLevl == FileInfoLevel.PathFileStreamInfo || infoLevl == FileInfoLevel.NTFileStreamInfo)) 4186 { 4187 4188 4190 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STREAMS)) 4191 logger.debug("Get NTFS streams list path=" + path); 4192 4193 4195 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 4196 StreamInfoList streamList = ntfsStreams.getStreamList(m_sess, conn, path); 4197 4198 if (streamList == null) 4199 { 4200 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.SRVNonSpecificError, 4201 SMBStatus.ErrSrv); 4202 return; 4203 } 4204 4205 4207 dataLen = QueryInfoPacker.packStreamFileInfo(streamList, replyBuf, true); 4208 } 4209 else 4210 { 4211 4212 4214 FileInfo fileInfo = disk.getFileInformation(m_sess, conn, path); 4215 4216 if (fileInfo == null) 4217 { 4218 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, 4219 SMBStatus.ErrDos); 4220 return; 4221 } 4222 4223 4225 dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true); 4226 } 4227 4228 4230 if (dataLen == 0) 4231 { 4232 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 4233 SMBStatus.ErrSrv); 4234 return; 4235 } 4236 4237 SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, dataLen, dataPos); 4238 outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset()); 4239 4240 4242 m_sess.sendResponseSMB(outPkt); 4243 } 4244 catch (AccessDeniedException ex) 4245 { 4246 4247 4249 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 4250 return; 4251 } 4252 catch (FileNotFoundException ex) 4253 { 4254 4255 4257 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 4258 return; 4259 } 4260 catch (PathNotFoundException ex) 4261 { 4262 4263 4265 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 4266 return; 4267 } 4268 catch (InvalidDeviceInterfaceException ex) 4269 { 4270 4271 4273 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 4274 return; 4275 } 4276 catch (UnsupportedInfoLevelException ex) 4277 { 4278 4279 4281 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 4282 return; 4283 } 4284 } 4285 4286 4294 protected final void procTrans2QueryFile(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException , 4295 SMBSrvException 4296 { 4297 4298 4300 int treeId = m_smbPkt.getTreeId(); 4301 TreeConnection conn = m_sess.findConnection(treeId); 4302 4303 if (conn == null) 4304 { 4305 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 4306 return; 4307 } 4308 4309 4311 if (conn.hasReadAccess() == false) 4312 { 4313 4314 4316 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 4317 return; 4318 } 4319 4320 4322 DataBuffer paramBuf = tbuf.getParameterBuffer(); 4323 4324 int fid = paramBuf.getShort(); 4325 int infoLevl = paramBuf.getShort(); 4326 4327 4329 NetworkFile netFile = conn.findFile(fid); 4330 4331 if (netFile == null) 4332 { 4333 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); 4334 return; 4335 } 4336 4337 4339 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4340 logger.debug("Query File - level=0x" + Integer.toHexString(infoLevl) + ", fid=" + fid + ", stream=" 4341 + netFile.getStreamId() + ", name=" + netFile.getFullName()); 4342 4343 4345 try 4346 { 4347 4348 4350 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 4351 4352 4354 outPkt.setParameterCount(10); 4355 4356 4358 byte[] buf = outPkt.getBuffer(); 4359 int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); 4360 int dataPos = prmPos + 4; 4361 4362 4364 outPkt.setPosition(prmPos); 4365 outPkt.packWord(0); 4366 4367 4371 DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); 4372 4373 4375 boolean streams = false; 4376 4377 if (disk instanceof NTFSStreamsInterface) 4378 { 4379 4380 4382 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 4383 streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); 4384 } 4385 4386 4388 int dataLen = 0; 4389 4390 if (streams == true 4391 && (infoLevl == FileInfoLevel.PathFileStreamInfo || infoLevl == FileInfoLevel.NTFileStreamInfo)) 4392 { 4393 4394 4396 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STREAMS)) 4397 logger.debug("Get NTFS streams list fid=" + fid + ", name=" + netFile.getFullName()); 4398 4399 4401 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 4402 StreamInfoList streamList = ntfsStreams.getStreamList(m_sess, conn, netFile.getFullName()); 4403 4404 if (streamList == null) 4405 { 4406 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.SRVNonSpecificError, 4407 SMBStatus.ErrSrv); 4408 return; 4409 } 4410 4411 4413 dataLen = QueryInfoPacker.packStreamFileInfo(streamList, replyBuf, true); 4414 } 4415 else 4416 { 4417 4418 4420 FileInfo fileInfo = disk.getFileInformation(m_sess, conn, netFile.getFullNameStream()); 4421 4422 if (fileInfo == null) 4423 { 4424 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.SRVNonSpecificError, 4425 SMBStatus.ErrSrv); 4426 return; 4427 } 4428 4429 4431 dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true); 4432 } 4433 4434 4436 if (dataLen == 0) 4437 { 4438 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, 4439 SMBStatus.ErrSrv); 4440 return; 4441 } 4442 4443 SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, dataLen, dataPos); 4444 outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset()); 4445 4446 4448 m_sess.sendResponseSMB(outPkt); 4449 } 4450 catch (AccessDeniedException ex) 4451 { 4452 4453 4455 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 4456 return; 4457 } 4458 catch (FileNotFoundException ex) 4459 { 4460 4461 4463 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 4464 return; 4465 } 4466 catch (PathNotFoundException ex) 4467 { 4468 4469 4471 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 4472 return; 4473 } 4474 catch (InvalidDeviceInterfaceException ex) 4475 { 4476 4477 4479 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 4480 return; 4481 } 4482 catch (UnsupportedInfoLevelException ex) 4483 { 4484 4485 4487 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 4488 return; 4489 } 4490 } 4491 4492 4500 protected final void procTrans2SetFile(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException , 4501 SMBSrvException 4502 { 4503 4504 4506 int treeId = m_smbPkt.getTreeId(); 4507 TreeConnection conn = m_sess.findConnection(treeId); 4508 4509 if (conn == null) 4510 { 4511 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 4512 return; 4513 } 4514 4515 4517 if (conn.hasWriteAccess() == false) 4518 { 4519 4520 4522 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 4523 return; 4524 } 4525 4526 4528 DataBuffer paramBuf = tbuf.getParameterBuffer(); 4529 4530 int fid = paramBuf.getShort(); 4531 int infoLevl = paramBuf.getShort(); 4532 4533 4535 NetworkFile netFile = conn.findFile(fid); 4536 4537 if (netFile == null) 4538 { 4539 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); 4540 return; 4541 } 4542 4543 4545 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4546 logger.debug("Set File - level=0x" + Integer.toHexString(infoLevl) + ", fid=" + fid + ", name=" 4547 + netFile.getFullName()); 4548 4549 4551 try 4552 { 4553 4554 4556 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 4557 4558 4560 DataBuffer dataBuf = tbuf.getDataBuffer(); 4561 FileInfo finfo = null; 4562 4563 switch (infoLevl) 4564 { 4565 4566 4568 case FileInfoLevel.SetBasicInfo: 4569 4570 4572 int setFlags = 0; 4573 finfo = new FileInfo(netFile.getFullName(), 0, -1); 4574 4575 4577 long timeNow = System.currentTimeMillis(); 4578 4579 long nttim = dataBuf.getLong(); 4580 boolean hasSetTime = false; 4581 4582 if (nttim != 0L) 4583 { 4584 if (nttim != -1L) 4585 { 4586 finfo.setCreationDateTime(NTTime.toJavaDate(nttim)); 4587 setFlags += FileInfo.SetCreationDate; 4588 } 4589 hasSetTime = true; 4590 } 4591 4592 4594 nttim = dataBuf.getLong(); 4595 4596 if (nttim != 0L) 4597 { 4598 if (nttim != -1L) 4599 { 4600 finfo.setAccessDateTime(NTTime.toJavaDate(nttim)); 4601 setFlags += FileInfo.SetAccessDate; 4602 } 4603 else 4604 { 4605 finfo.setAccessDateTime(timeNow); 4606 setFlags += FileInfo.SetAccessDate; 4607 } 4608 hasSetTime = true; 4609 } 4610 4611 4613 nttim = dataBuf.getLong(); 4614 4615 if (nttim > 0L) 4616 { 4617 if (nttim != -1L) 4618 { 4619 finfo.setModifyDateTime(NTTime.toJavaDate(nttim)); 4620 setFlags += FileInfo.SetModifyDate; 4621 } 4622 else 4623 { 4624 finfo.setModifyDateTime(timeNow); 4625 setFlags += FileInfo.SetModifyDate; 4626 } 4627 hasSetTime = true; 4628 } 4629 4630 4632 nttim = dataBuf.getLong(); 4633 4634 if (nttim > 0L) 4635 { 4636 if (nttim != -1L) 4637 { 4638 finfo.setChangeDateTime(NTTime.toJavaDate(nttim)); 4639 setFlags += FileInfo.SetChangeDate; 4640 } 4641 hasSetTime = true; 4642 } 4643 4644 4646 int attr = dataBuf.getInt(); 4647 int unknown = dataBuf.getInt(); 4648 4649 if (hasSetTime == false && unknown == 0) 4650 { 4651 finfo.setFileAttributes(attr); 4652 setFlags += FileInfo.SetAttributes; 4653 } 4654 4655 4657 finfo.setFileInformationFlags(setFlags); 4658 disk.setFileInformation(m_sess, conn, netFile.getFullName(), finfo); 4659 4660 4662 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4663 logger.debug(" Set Basic Info [" + treeId + "] name=" + netFile.getFullName() + ", attr=0x" 4664 + Integer.toHexString(attr) + ", setTime=" + hasSetTime + ", setFlags=0x" 4665 + Integer.toHexString(setFlags) + ", unknown=" + unknown); 4666 break; 4667 4668 4670 case FileInfoLevel.SetEndOfFileInfo: 4671 4672 4674 long eofPos = dataBuf.getLong(); 4675 4676 4678 disk.truncateFile(m_sess, conn, netFile, eofPos); 4679 4680 4682 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4683 logger.debug(" Set end of file position fid=" + fid + ", eof=" + eofPos); 4684 break; 4685 4686 4688 case FileInfoLevel.SetAllocationInfo: 4689 4690 4692 long allocSize = dataBuf.getLong(); 4693 4694 4696 disk.truncateFile(m_sess, conn, netFile, allocSize); 4697 4698 4700 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4701 logger.debug(" Set allocation size fid=" + fid + ", allocSize=" + allocSize); 4702 break; 4703 4704 4706 case FileInfoLevel.NTFileRenameInfo: 4707 4708 4710 boolean streams = false; 4711 4712 if (disk instanceof NTFSStreamsInterface) 4713 { 4714 4715 4717 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 4718 streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); 4719 } 4720 4721 4723 if (streams == false) 4724 { 4725 4726 4728 m_sess.sendErrorResponseSMB(SMBStatus.NTNotSupported, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 4729 return; 4730 } 4731 4732 4734 boolean overwrite = dataBuf.getByte() == 1 ? true : false; 4735 dataBuf.skipBytes(3); 4736 4737 int rootFid = dataBuf.getInt(); 4738 int nameLen = dataBuf.getInt(); 4739 String newName = dataBuf.getString(nameLen, true); 4740 4741 4743 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4744 logger.debug(" Set rename fid=" + fid + ", newName=" + newName + ", overwrite=" + overwrite 4745 + ", rootFID=" + rootFid); 4746 4747 4750 if (newName.indexOf(FileName.DOS_SEPERATOR_STR) != -1) 4751 { 4752 4753 4755 m_sess.sendErrorResponseSMB(SMBStatus.NTNotSupported, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 4756 return; 4757 } 4758 4759 4761 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STREAMS)) 4762 logger.debug("Rename stream fid=" + fid + ", name=" + netFile.getFullNameStream() + ", newName=" 4763 + newName + ", overwrite=" + overwrite); 4764 4765 4767 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 4768 ntfsStreams.renameStream(m_sess, conn, netFile.getFullNameStream(), newName, overwrite); 4769 break; 4770 4771 4773 case FileInfoLevel.SetDispositionInfo: 4774 case FileInfoLevel.NTFileDispositionInfo: 4775 4776 4778 int flag = dataBuf.getByte(); 4779 boolean delFlag = flag == 1 ? true : false; 4780 4781 4785 FileInfo delInfo = new FileInfo(); 4786 delInfo.setDeleteOnClose(delFlag); 4787 delInfo.setFileInformationFlags(FileInfo.SetDeleteOnClose); 4788 4789 disk.setFileInformation(m_sess, conn, netFile.getFullName(), delInfo); 4790 4791 4793 netFile.setDeleteOnClose(delFlag); 4794 4795 4797 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4798 logger.debug(" Set file disposition fid=" + fid + ", name=" + netFile.getName() + ", delete=" 4799 + delFlag); 4800 break; 4801 } 4802 4803 4805 outPkt.setParameterCount(10); 4806 4807 4809 byte[] buf = outPkt.getBuffer(); 4810 int prmPos = outPkt.getByteOffset(); 4811 4812 4817 prmPos = DataPacker.longwordAlign(prmPos); 4818 DataPacker.putIntelShort(0, buf, prmPos); 4819 4820 SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, 0, prmPos + 4); 4821 outPkt.setByteCount((prmPos - outPkt.getByteOffset()) + 4); 4822 4823 4825 m_sess.sendResponseSMB(outPkt); 4826 4827 4829 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 4830 4831 if (diskCtx.hasChangeHandler() && netFile.getFullName() != null) 4832 { 4833 4834 4836 NotifyChangeHandler changeHandler = diskCtx.getChangeHandler(); 4837 4838 4840 if (finfo != null) 4841 { 4842 4843 4845 if (finfo.hasSetFlag(FileInfo.SetAttributes)) 4846 changeHandler.notifyAttributesChanged(netFile.getFullName(), netFile.isDirectory()); 4847 4848 4850 if (finfo.hasSetFlag(FileInfo.SetModifyDate)) 4851 changeHandler.notifyLastWriteTimeChanged(netFile.getFullName(), netFile.isDirectory()); 4852 } 4853 else if (infoLevl == FileInfoLevel.SetAllocationInfo || infoLevl == FileInfoLevel.SetEndOfFileInfo) 4854 { 4855 4856 4858 changeHandler.notifyFileSizeChanged(netFile.getFullName()); 4859 } 4860 } 4861 } 4862 catch (FileNotFoundException ex) 4863 { 4864 4865 4867 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 4868 return; 4869 } 4870 catch (AccessDeniedException ex) 4871 { 4872 4873 4875 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 4876 return; 4877 } 4878 catch (DiskFullException ex) 4879 { 4880 4881 4883 m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); 4884 return; 4885 } 4886 catch (InvalidDeviceInterfaceException ex) 4887 { 4888 4889 4891 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 4892 return; 4893 } 4894 } 4895 4896 4904 protected final void procTrans2SetPath(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException , 4905 SMBSrvException 4906 { 4907 4908 4910 int treeId = m_smbPkt.getTreeId(); 4911 TreeConnection conn = m_sess.findConnection(treeId); 4912 4913 if (conn == null) 4914 { 4915 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 4916 return; 4917 } 4918 4919 4921 if (conn.hasWriteAccess() == false) 4922 { 4923 4924 4926 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 4927 return; 4928 } 4929 4930 4932 DataBuffer paramBuf = tbuf.getParameterBuffer(); 4933 4934 int infoLevl = paramBuf.getShort(); 4935 paramBuf.skipBytes(4); 4936 4937 String path = paramBuf.getString(tbuf.isUnicode()); 4938 4939 4941 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 4942 logger.debug("Set Path - path=" + path + ", level=0x" + Integer.toHexString(infoLevl)); 4943 4944 4946 try 4947 { 4948 4949 4951 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 4952 4953 4955 DataBuffer dataBuf = tbuf.getDataBuffer(); 4956 FileInfo finfo = null; 4957 4958 switch (infoLevl) 4959 { 4960 4961 4963 case FileInfoLevel.SetStandard: 4964 4965 4967 int setFlags = 0; 4968 finfo = new FileInfo(path, 0, -1); 4969 4970 4972 int smbDate = dataBuf.getShort(); 4973 int smbTime = dataBuf.getShort(); 4974 4975 boolean hasSetTime = false; 4976 4977 if (smbDate != 0 && smbTime != 0) 4978 { 4979 finfo.setCreationDateTime(new SMBDate(smbDate, smbTime).getTime()); 4980 setFlags += FileInfo.SetCreationDate; 4981 hasSetTime = true; 4982 } 4983 4984 4986 smbDate = dataBuf.getShort(); 4987 smbTime = dataBuf.getShort(); 4988 4989 if (smbDate != 0 && smbTime != 0) 4990 { 4991 finfo.setAccessDateTime(new SMBDate(smbDate, smbTime).getTime()); 4992 setFlags += FileInfo.SetAccessDate; 4993 hasSetTime = true; 4994 } 4995 4996 4998 smbDate = dataBuf.getShort(); 4999 smbTime = dataBuf.getShort(); 5000 5001 if (smbDate != 0 && smbTime != 0) 5002 { 5003 finfo.setModifyDateTime(new SMBDate(smbDate, smbTime).getTime()); 5004 setFlags += FileInfo.SetModifyDate; 5005 hasSetTime = true; 5006 } 5007 5008 5010 int fileSize = dataBuf.getInt(); 5011 if (fileSize != 0) 5012 { 5013 finfo.setFileSize(fileSize); 5014 setFlags += FileInfo.SetFileSize; 5015 } 5016 5017 fileSize = dataBuf.getInt(); 5018 if (fileSize != 0) 5019 { 5020 finfo.setAllocationSize(fileSize); 5021 setFlags += FileInfo.SetAllocationSize; 5022 } 5023 5024 5026 int attr = dataBuf.getInt(); 5027 int eaListLen = dataBuf.getInt(); 5028 5029 if (hasSetTime == false && eaListLen == 0) 5030 { 5031 finfo.setFileAttributes(attr); 5032 setFlags += FileInfo.SetAttributes; 5033 } 5034 5035 5037 finfo.setFileInformationFlags(setFlags); 5038 disk.setFileInformation(m_sess, conn, path, finfo); 5039 5040 5042 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) 5043 logger.debug(" Set Standard Info [" + treeId + "] name=" + path + ", attr=0x" 5044 + Integer.toHexString(attr) + ", setTime=" + hasSetTime + ", setFlags=0x" 5045 + Integer.toHexString(setFlags) + ", eaListLen=" + eaListLen); 5046 break; 5047 } 5048 5049 5051 outPkt.setParameterCount(10); 5052 5053 5055 byte[] buf = outPkt.getBuffer(); 5056 int prmPos = outPkt.getByteOffset(); 5057 5058 5063 prmPos = DataPacker.longwordAlign(prmPos); 5064 DataPacker.putIntelShort(0, buf, prmPos); 5065 5066 SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, 0, prmPos + 4); 5067 outPkt.setByteCount((prmPos - outPkt.getByteOffset()) + 4); 5068 5069 5071 m_sess.sendResponseSMB(outPkt); 5072 5073 5075 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 5076 5077 if (diskCtx.hasChangeHandler() && path != null) 5078 { 5079 5080 5082 NotifyChangeHandler changeHandler = diskCtx.getChangeHandler(); 5083 5084 5086 if (finfo != null) 5087 { 5088 5089 5091 int fileSts = disk.fileExists(m_sess, conn, path); 5092 5093 5095 if (finfo.hasSetFlag(FileInfo.SetAttributes)) 5096 changeHandler.notifyAttributesChanged(path, fileSts == FileStatus.DirectoryExists ? true 5097 : false); 5098 5099 5101 if (finfo.hasSetFlag(FileInfo.SetModifyDate)) 5102 changeHandler.notifyLastWriteTimeChanged(path, fileSts == FileStatus.DirectoryExists ? true 5103 : false); 5104 } 5105 } 5106 } 5107 catch (FileNotFoundException ex) 5108 { 5109 5110 5112 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 5113 return; 5114 } 5115 catch (AccessDeniedException ex) 5116 { 5117 5118 5120 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5121 return; 5122 } 5123 catch (DiskFullException ex) 5124 { 5125 5126 5128 m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); 5129 return; 5130 } 5131 catch (InvalidDeviceInterfaceException ex) 5132 { 5133 5134 5136 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 5137 return; 5138 } 5139 } 5140 5141 5146 protected final void procWriteAndX(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 5147 { 5148 5149 5151 if (m_smbPkt.checkPacketIsValid(12, 0) == false) 5152 { 5153 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 5154 return; 5155 } 5156 5157 5159 int treeId = m_smbPkt.getTreeId(); 5160 TreeConnection conn = m_sess.findConnection(treeId); 5161 5162 if (conn == null) 5163 { 5164 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 5165 return; 5166 } 5167 5168 5170 if (conn.hasWriteAccess() == false) 5171 { 5172 5173 5175 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5176 return; 5177 } 5178 5179 5182 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 5183 { 5184 5185 5187 IPCHandler.processIPCRequest(m_sess, outPkt); 5188 return; 5189 } 5190 5191 5193 int fid = m_smbPkt.getParameter(2); 5194 long offset = (long) (((long) m_smbPkt.getParameterLong(3)) & 0xFFFFFFFFL); int dataPos = m_smbPkt.getParameter(11) + RFCNetBIOSProtocol.HEADER_LEN; 5198 5199 int dataLen = m_smbPkt.getParameter(10); 5200 int dataLenHigh = 0; 5201 5202 if (m_smbPkt.getReceivedLength() > 0xFFFF) 5203 dataLenHigh = m_smbPkt.getParameter(9) & 0x0001; 5204 5205 if (dataLenHigh > 0) 5206 dataLen += (dataLenHigh << 16); 5207 5208 5210 if (m_smbPkt.getParameterCount() == 14) 5211 { 5212 long topOff = (long) (((long) m_smbPkt.getParameterLong(12)) & 0xFFFFFFFFL); 5213 offset += topOff << 32; 5214 } 5215 5216 NetworkFile netFile = conn.findFile(fid); 5217 5218 if (netFile == null) 5219 { 5220 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); 5221 return; 5222 } 5223 5224 5226 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) 5227 logger.debug("File Write AndX [" + netFile.getFileId() + "] : Size=" + dataLen + " ,Pos=" + offset); 5228 5229 5231 byte[] buf = m_smbPkt.getBuffer(); 5232 int wrtlen = 0; 5233 5234 5236 try 5237 { 5238 5239 5241 DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); 5242 5243 5245 wrtlen = disk.writeFile(m_sess, conn, netFile, buf, dataPos, dataLen, offset); 5246 } 5247 catch (InvalidDeviceInterfaceException ex) 5248 { 5249 5250 5252 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 5253 return; 5254 } 5255 catch (AccessDeniedException ex) 5256 { 5257 5258 5260 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) 5261 logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString()); 5262 5263 5265 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5266 return; 5267 } 5268 catch (LockConflictException ex) 5269 { 5270 5271 5273 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) 5274 logger.debug("Write Lock Error [" + netFile.getFileId() + "] : Size=" + dataLen + " ,Pos=" + offset); 5275 5276 5278 m_sess.sendErrorResponseSMB(SMBStatus.NTLockConflict, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5279 return; 5280 } 5281 catch (DiskFullException ex) 5282 { 5283 5284 5286 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) 5287 logger.debug("Write Quota Error [" + netFile.getFileId() + "] Disk full : Size=" + dataLen + " ,Pos=" 5288 + offset); 5289 5290 5292 m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); 5293 return; 5294 } 5295 catch (java.io.IOException ex) 5296 { 5297 5298 5300 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) 5301 logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString()); 5302 5303 5305 m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); 5306 return; 5307 } 5308 5309 5311 outPkt.setParameterCount(6); 5312 outPkt.setAndXCommand(0xFF); 5313 outPkt.setParameter(1, 0); outPkt.setParameter(2, wrtlen); 5315 outPkt.setParameter(3, 0xFFFF); 5316 5317 if (dataLenHigh > 0) 5318 { 5319 outPkt.setParameter(4, dataLen >> 16); 5320 outPkt.setParameter(5, 0); 5321 } 5322 else 5323 { 5324 outPkt.setParameterLong(4, 0); 5325 } 5326 5327 outPkt.setByteCount(0); 5328 outPkt.setParameter(1, outPkt.getLength()); 5329 5330 5332 m_sess.sendResponseSMB(outPkt); 5333 5334 5338 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 5339 5340 if (netFile.getWriteCount() % FileSizeChangeRate == 0 && diskCtx.hasChangeHandler() 5341 && netFile.getFullName() != null) 5342 { 5343 5344 5346 NotifyChangeHandler changeHandler = diskCtx.getChangeHandler(); 5347 5348 5350 changeHandler.notifyFileSizeChanged(netFile.getFullName()); 5351 } 5352 } 5353 5354 5359 protected final void procNTCreateAndX(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 5360 { 5361 5362 5364 if (m_smbPkt.checkPacketIsValid(24, 1) == false) 5365 { 5366 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 5367 return; 5368 } 5369 5370 5372 int treeId = m_smbPkt.getTreeId(); 5373 TreeConnection conn = m_sess.findConnection(treeId); 5374 5375 if (conn == null) 5376 { 5377 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 5378 return; 5379 } 5380 5381 5383 if (conn.hasReadAccess() == false) 5384 { 5385 5386 5388 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5389 return; 5390 } 5391 5392 5396 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 5397 { 5398 5399 5401 IPCHandler.processIPCRequest(m_sess, outPkt); 5402 return; 5403 } 5404 else if (conn.getSharedDevice().getType() != ShareType.DISK) 5405 { 5406 5407 5409 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5410 return; 5411 } 5412 5413 5415 NTParameterPacker prms = new NTParameterPacker(m_smbPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 5); 5416 5417 int nameLen = prms.unpackWord(); 5418 int flags = prms.unpackInt(); 5419 int rootFID = prms.unpackInt(); 5420 int accessMask = prms.unpackInt(); 5421 long allocSize = prms.unpackLong(); 5422 int attrib = prms.unpackInt(); 5423 int shrAccess = prms.unpackInt(); 5424 int createDisp = prms.unpackInt(); 5425 int createOptn = prms.unpackInt(); 5426 int impersonLev = prms.unpackInt(); 5427 int secFlags = prms.unpackByte(); 5428 5429 5431 String fileName = DataPacker.getUnicodeString(m_smbPkt.getBuffer(), DataPacker.wordAlign(m_smbPkt 5432 .getByteOffset()), nameLen / 2); 5433 if (fileName == null) 5434 { 5435 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 5436 return; 5437 } 5438 5439 5441 DiskInterface disk = null; 5442 try 5443 { 5444 5445 5447 disk = (DiskInterface) conn.getSharedDevice().getInterface(); 5448 } 5449 catch (InvalidDeviceInterfaceException ex) 5450 { 5451 5452 5454 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 5455 return; 5456 } 5457 5458 5462 if ( FileName.containsStreamName(fileName)) 5463 { 5464 5465 5467 boolean streams = false; 5468 5469 if (disk instanceof NTFSStreamsInterface) 5470 { 5471 5472 5474 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 5475 streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); 5476 } 5477 5478 5480 if (streams == false) 5481 { 5482 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 5483 return; 5484 } 5485 } 5486 5487 5489 FileOpenParams params = new FileOpenParams(fileName, createDisp, accessMask, attrib, shrAccess, allocSize, 5490 createOptn, rootFID, impersonLev, secFlags); 5491 5493 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 5494 logger.debug("NT Create AndX [" + treeId + "] params=" + params); 5495 5496 5498 int fid; 5499 NetworkFile netFile = null; 5500 int respAction = 0; 5501 5502 try 5503 { 5504 5505 5507 int fileSts = disk.fileExists(m_sess, conn, fileName); 5508 5509 if (fileSts == FileStatus.NotExist) 5510 { 5511 5512 5514 if (createDisp == FileAction.NTCreate || createDisp == FileAction.NTOpenIf 5515 || createDisp == FileAction.NTOverwriteIf || createDisp == FileAction.NTSupersede) 5516 { 5517 5518 5520 if (conn.hasWriteAccess() == false) 5521 { 5522 5523 5525 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, 5526 SMBStatus.ErrDos); 5527 return; 5528 } 5529 5530 5532 if ((createOptn & WinNT.CreateDirectory) == 0) 5533 { 5534 5535 5537 netFile = disk.createFile(m_sess, conn, params); 5538 } 5539 else 5540 { 5541 5542 5544 disk.createDirectory(m_sess, conn, params); 5545 netFile = disk.openFile(m_sess, conn, params); 5546 } 5547 5548 5550 if (netFile != null && (createOptn & WinNT.CreateDeleteOnClose) != 0) 5551 netFile.setDeleteOnClose(true); 5552 5553 5555 respAction = FileAction.FileCreated; 5556 } 5557 else 5558 { 5559 5560 5562 if (fileSts == FileStatus.DirectoryExists) 5563 { 5564 5565 5567 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, 5568 SMBStatus.ErrDos); 5569 return; 5570 } 5571 else 5572 { 5573 5574 5576 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, 5577 SMBStatus.ErrDos); 5578 return; 5579 } 5580 } 5581 } 5582 else if (createDisp == FileAction.NTCreate) 5583 { 5584 5585 5587 if (fileSts == FileStatus.FileExists || fileSts == FileStatus.DirectoryExists) 5588 { 5589 5590 5592 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, 5593 SMBStatus.ErrDos); 5594 return; 5595 } 5596 else 5597 { 5598 5599 5601 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5602 return; 5603 } 5604 } 5605 else 5606 { 5607 5608 5610 netFile = disk.openFile(m_sess, conn, params); 5611 5612 5614 if (createDisp == FileAction.NTSupersede || createDisp == FileAction.NTOverwriteIf) 5615 { 5616 5617 5619 disk.truncateFile(m_sess, conn, netFile, 0L); 5620 5621 5623 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 5624 logger.debug(" [" + treeId + "] name=" + fileName + " truncated"); 5625 } 5626 5627 5629 respAction = FileAction.FileExisted; 5630 } 5631 5632 5634 fid = conn.addFile(netFile, getSession()); 5635 5636 } 5637 catch (TooManyFilesException ex) 5638 { 5639 5640 5642 m_sess.sendErrorResponseSMB(SMBStatus.NTTooManyOpenFiles, SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); 5643 return; 5644 } 5645 catch (AccessDeniedException ex) 5646 { 5647 5648 5650 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5651 return; 5652 } 5653 catch (FileExistsException ex) 5654 { 5655 5656 5658 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, 5659 SMBStatus.ErrDos); 5660 return; 5661 } 5662 catch (FileSharingException ex) 5663 { 5664 5665 5667 m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, 5668 SMBStatus.ErrDos); 5669 return; 5670 } 5671 catch (FileOfflineException ex) 5672 { 5673 5674 5676 m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd); 5677 return; 5678 } 5679 catch (java.io.IOException ex) 5680 { 5681 5682 5684 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 5685 return; 5686 } 5687 5688 5690 outPkt.setParameterCount( 34); 5691 5692 outPkt.setAndXCommand(0xFF); 5693 outPkt.setParameter(1, 0); 5695 prms.reset(outPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 4); 5696 5697 5699 boolean fakeOpLocks = FakeOpLocks; 5700 String fname = params.getPath().toUpperCase(); 5701 5702 if ( fname.endsWith( ".URL")){ 5703 5704 5706 fakeOpLocks = true; 5707 } 5708 5709 5711 if (fakeOpLocks == true) 5712 { 5713 5714 5716 if ((flags & WinNT.RequestBatchOplock) != 0) 5717 { 5718 5719 5721 prms.packByte(2); 5722 } 5723 else if ((flags & WinNT.RequestOplock) != 0) 5724 { 5725 5726 5728 prms.packByte(1); 5729 } 5730 else 5731 { 5732 5733 5735 prms.packByte(0); 5736 } 5737 } 5738 else 5739 prms.packByte(0); 5740 5741 5743 prms.packWord(fid); 5744 prms.packInt(respAction); 5745 5746 5748 if (netFile.hasCreationDate()) 5749 prms.packLong(NTTime.toNTTime(netFile.getCreationDate())); 5750 else 5751 prms.packLong(0); 5752 5753 if ( netFile.hasAccessDate()) 5754 prms.packLong(NTTime.toNTTime(netFile.getAccessDate())); 5755 else 5756 prms.packLong(0); 5757 5758 if (netFile.hasModifyDate()) 5759 { 5760 long modDate = NTTime.toNTTime(netFile.getModifyDate()); 5761 prms.packLong(modDate); 5762 prms.packLong(modDate); 5763 } 5764 else 5765 { 5766 prms.packLong(0); prms.packLong(0); } 5769 5770 prms.packInt(netFile.getFileAttributes()); 5771 5772 5774 long fileSize = netFile.getFileSize(); 5775 if (fileSize > 0L) 5776 fileSize = (fileSize + 512L) & 0xFFFFFFFFFFFFFE00L; 5777 5778 prms.packLong(fileSize); prms.packLong(netFile.getFileSize()); prms.packWord(0); prms.packWord((flags & WinNT.ExtendedResponse) != 0 ? 7 : 0); prms.packByte(netFile.isDirectory() ? 1 : 0); 5783 5784 prms.packWord(0); 5786 5788 int endPos = prms.getPosition(); 5789 outPkt.setParameter(1, endPos - RFCNetBIOSProtocol.HEADER_LEN); 5790 5791 5793 if (m_smbPkt.hasAndXCommand()) 5794 { 5795 5796 5798 endPos = procAndXCommands(outPkt, endPos, netFile); 5799 } 5800 5801 5803 m_sess.sendResponseSMB(outPkt, endPos - RFCNetBIOSProtocol.HEADER_LEN); 5804 5805 5807 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 5808 if (diskCtx.hasChangeHandler() && respAction == FileAction.FileCreated) 5809 { 5810 5811 5813 if (netFile.isDirectory()) 5814 diskCtx.getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, fileName); 5815 else 5816 diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, fileName); 5817 } 5818 } 5819 5820 5825 protected final void procNTCancel(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 5826 { 5827 5828 5830 if (m_smbPkt.checkPacketIsValid(0, 0) == false) 5831 { 5832 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 5833 return; 5834 } 5835 5836 5838 int treeId = m_smbPkt.getTreeId(); 5839 TreeConnection conn = m_sess.findConnection(treeId); 5840 5841 if (conn == null) 5842 { 5843 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 5844 return; 5845 } 5846 5847 5849 NotifyRequest req = m_sess.findNotifyRequest(m_smbPkt.getMultiplexId(), m_smbPkt.getTreeId(), m_smbPkt 5850 .getUserId(), m_smbPkt.getProcessId()); 5851 if (req != null) 5852 { 5853 5854 5856 m_sess.removeNotifyRequest(req); 5857 5858 5860 m_smbPkt.setParameterCount(0); 5861 m_smbPkt.setByteCount(0); 5862 5863 5865 if (m_smbPkt.isLongErrorCode() == false) 5866 m_smbPkt.setFlags2(m_smbPkt.getFlags2() + SMBSrvPacket.FLG2_LONGERRORCODE); 5867 5868 5870 m_smbPkt.setLongErrorCode(SMBStatus.NTCancelled); 5871 5872 5874 if (m_smbPkt.isUnicode() == false) 5875 m_smbPkt.setFlags2(m_smbPkt.getFlags2() + SMBSrvPacket.FLG2_UNICODE); 5876 5877 5879 m_sess.sendResponseSMB(m_smbPkt); 5880 5881 5883 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) 5884 { 5885 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 5886 logger.debug("NT Cancel notify mid=" + req.getMultiplexId() + ", dir=" + req.getWatchPath() 5887 + ", queue=" + diskCtx.getChangeHandler().getRequestQueueSize()); 5888 } 5889 } 5890 else 5891 { 5892 5893 5895 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 5896 } 5897 } 5898 5899 5904 protected final void procNTTransaction(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 5905 { 5906 5907 5909 if (m_smbPkt.checkPacketIsValid(19, 0) == false) 5910 { 5911 5912 5914 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 5915 return; 5916 } 5917 5918 5921 int treeId = m_smbPkt.getTreeId(); 5922 TreeConnection conn = m_sess.findConnection(treeId); 5923 5924 if (conn == null) 5925 { 5926 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 5927 return; 5928 } 5929 5930 5932 if (conn.hasReadAccess() == false) 5933 { 5934 5935 5937 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 5938 return; 5939 } 5940 5941 5943 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 5944 { 5945 IPCHandler.processIPCRequest(m_sess, outPkt); 5946 return; 5947 } 5948 5949 5951 NTTransPacket ntTrans = new NTTransPacket(m_smbPkt.getBuffer()); 5952 int subCmd = ntTrans.getNTFunction(); 5953 5954 5956 if (subCmd == PacketType.NTTransNotifyChange) 5957 { 5958 5959 5961 procNTTransactNotifyChange(ntTrans, outPkt); 5962 return; 5963 } 5964 5965 5967 SrvTransactBuffer transBuf = null; 5968 5969 if (ntTrans.getTotalParameterCount() == ntTrans.getParameterBlockCount() 5970 && ntTrans.getTotalDataCount() == ntTrans.getDataBlockCount()) 5971 { 5972 5973 5977 transBuf = new SrvTransactBuffer(ntTrans); 5978 } 5979 else 5980 { 5981 5982 5984 transBuf = new SrvTransactBuffer(ntTrans.getSetupCount(), ntTrans.getTotalParameterCount(), ntTrans 5985 .getTotalDataCount()); 5986 transBuf.setType(ntTrans.getCommand()); 5987 transBuf.setFunction(subCmd); 5988 5989 5991 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 5992 logger.debug("NT Transaction [" + treeId + "] transbuf=" + transBuf); 5993 5994 5996 byte[] buf = ntTrans.getBuffer(); 5997 int cnt = ntTrans.getSetupCount(); 5998 5999 if (cnt > 0) 6000 transBuf.appendSetup(buf, ntTrans.getSetupOffset(), cnt * 2); 6001 6002 6004 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6005 logger.debug("NT Transaction [" + treeId + "] pcnt=" + ntTrans.getNTParameter(4) + ", offset=" 6006 + ntTrans.getNTParameter(5)); 6007 6008 cnt = ntTrans.getParameterBlockCount(); 6009 6010 if (cnt > 0) 6011 transBuf.appendParameter(buf, ntTrans.getParameterBlockOffset(), cnt); 6012 6013 cnt = ntTrans.getDataBlockCount(); 6014 if (cnt > 0) 6015 transBuf.appendData(buf, ntTrans.getDataBlockOffset(), cnt); 6016 } 6017 6018 6020 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6021 logger.debug("NT Transaction [" + treeId + "] cmd=0x" + Integer.toHexString(subCmd) + ", multiPkt=" 6022 + transBuf.isMultiPacket()); 6023 6024 6028 if (transBuf.isMultiPacket()) 6029 { 6030 6031 6033 m_sess.setTransaction(transBuf); 6034 6035 6037 m_sess.sendSuccessResponseSMB(); 6038 return; 6039 } 6040 6041 6043 processNTTransactionBuffer(transBuf, ntTrans); 6044 } 6045 6046 6051 protected final void procNTTransactionSecondary(SMBSrvPacket outPkt) throws java.io.IOException , SMBSrvException 6052 { 6053 6054 6056 if (m_smbPkt.checkPacketIsValid(18, 0) == false) 6057 { 6058 6059 6061 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6062 return; 6063 } 6064 6065 6068 int treeId = m_smbPkt.getTreeId(); 6069 TreeConnection conn = m_sess.findConnection(treeId); 6070 6071 if (conn == null) 6072 { 6073 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 6074 return; 6075 } 6076 6077 6079 if (conn.hasReadAccess() == false) 6080 { 6081 6082 6084 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6085 return; 6086 } 6087 6088 6090 if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) 6091 { 6092 IPCHandler.processIPCRequest(m_sess, outPkt); 6093 return; 6094 } 6095 6096 6098 if (m_sess.hasTransaction() == false || m_sess.getTransaction().isType() != PacketType.NTTransact) 6099 { 6100 6101 6103 m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6104 return; 6105 } 6106 6107 6109 NTTransPacket ntTrans = new NTTransPacket(m_smbPkt.getBuffer()); 6110 byte[] buf = ntTrans.getBuffer(); 6111 SrvTransactBuffer transBuf = m_sess.getTransaction(); 6112 6113 6115 int plen = ntTrans.getParameterBlockCount(); 6116 if (plen > 0) 6117 { 6118 6119 6121 DataBuffer paramBuf = transBuf.getParameterBuffer(); 6122 paramBuf.appendData(buf, ntTrans.getParameterBlockOffset(), plen); 6123 } 6124 6125 6127 int dlen = ntTrans.getDataBlockCount(); 6128 if (dlen > 0) 6129 { 6130 6131 6133 DataBuffer dataBuf = transBuf.getDataBuffer(); 6134 dataBuf.appendData(buf, ntTrans.getDataBlockOffset(), dlen); 6135 } 6136 6137 6139 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6140 logger.debug("NT Transaction Secondary [" + treeId + "] paramLen=" + plen + ", dataLen=" + dlen); 6141 6142 6144 int totParam = ntTrans.getTotalParameterCount(); 6145 int totData = ntTrans.getTotalDataCount(); 6146 6147 int paramDisp = ntTrans.getParameterBlockDisplacement(); 6148 int dataDisp = ntTrans.getDataBlockDisplacement(); 6149 6150 if ((paramDisp + plen) == totParam && (dataDisp + dlen) == totData) 6151 { 6152 6153 6155 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6156 logger.debug("NT Transaction complete, processing ..."); 6157 6158 6160 m_sess.setTransaction(null); 6161 6162 6164 processNTTransactionBuffer(transBuf, ntTrans); 6165 } 6166 6167 } 6169 6170 6178 private final void processNTTransactionBuffer(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException , 6179 SMBSrvException 6180 { 6181 6182 6184 switch (tbuf.getFunction()) 6185 { 6186 6187 6189 case PacketType.NTTransCreate: 6190 procNTTransactCreate(tbuf, outPkt); 6191 break; 6192 6193 6195 case PacketType.NTTransIOCtl: 6196 procNTTransactIOCtl(tbuf, outPkt); 6197 break; 6198 6199 6201 case PacketType.NTTransQuerySecurityDesc: 6202 procNTTransactQuerySecurityDesc(tbuf, outPkt); 6203 break; 6204 6205 6207 case PacketType.NTTransSetSecurityDesc: 6208 procNTTransactSetSecurityDesc(tbuf, outPkt); 6209 break; 6210 6211 6213 case PacketType.NTTransRename: 6214 procNTTransactRename(tbuf, outPkt); 6215 break; 6216 6217 6219 case PacketType.NTTransGetUserQuota: 6220 6221 6223 m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 6224 break; 6225 6226 6228 case PacketType.NTTransSetUserQuota: 6229 6230 6232 m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 6233 break; 6234 6235 6237 default: 6238 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6239 break; 6240 } 6241 } 6242 6243 6251 protected final void procNTTransactCreate(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException , 6252 SMBSrvException 6253 { 6254 6255 6257 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6258 logger.debug("NT TransactCreate"); 6259 6260 6262 if (tbuf.hasParameterBuffer() && tbuf.getParameterBuffer().getLength() < 52) 6263 { 6264 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6265 return; 6266 } 6267 6268 6270 int treeId = tbuf.getTreeId(); 6271 TreeConnection conn = m_sess.findConnection(treeId); 6272 6273 if (conn == null) 6274 { 6275 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 6276 return; 6277 } 6278 6279 6281 if (conn.hasWriteAccess() == false) 6282 { 6283 6284 6286 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6287 return; 6288 } 6289 6290 6292 if (conn.getSharedDevice().getType() != ShareType.DISK) 6293 { 6294 6295 6297 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6298 return; 6299 } 6300 6301 6303 DataBuffer tparams = tbuf.getParameterBuffer(); 6304 6305 int flags = tparams.getInt(); 6306 int rootFID = tparams.getInt(); 6307 int accessMask = tparams.getInt(); 6308 long allocSize = tparams.getLong(); 6309 int attrib = tparams.getInt(); 6310 int shrAccess = tparams.getInt(); 6311 int createDisp = tparams.getInt(); 6312 int createOptn = tparams.getInt(); 6313 int sdLen = tparams.getInt(); 6314 int eaLen = tparams.getInt(); 6315 int nameLen = tparams.getInt(); 6316 int impersonLev = tparams.getInt(); 6317 int secFlags = tparams.getByte(); 6318 6319 6321 tparams.wordAlign(); 6322 String fileName = tparams.getString(nameLen, true); 6323 6324 if (fileName == null) 6325 { 6326 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6327 return; 6328 } 6329 6330 6332 DiskInterface disk = null; 6333 try 6334 { 6335 6336 6338 disk = (DiskInterface) conn.getSharedDevice().getInterface(); 6339 } 6340 catch (InvalidDeviceInterfaceException ex) 6341 { 6342 6343 6345 m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 6346 return; 6347 } 6348 6349 6353 if (fileName.indexOf(FileOpenParams.StreamSeparator) != -1) 6354 { 6355 6356 6358 boolean streams = false; 6359 6360 if (disk instanceof NTFSStreamsInterface) 6361 { 6362 6363 6365 NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; 6366 streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); 6367 } 6368 6369 6371 if (streams == false) 6372 { 6373 6374 6376 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 6377 return; 6378 } 6379 } 6380 6381 6383 FileOpenParams params = new FileOpenParams(fileName, createDisp, accessMask, attrib, shrAccess, allocSize, 6384 createOptn, rootFID, impersonLev, secFlags); 6385 6387 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 6388 logger.debug("NT TransactCreate [" + treeId + "] params=" + params + " secDescLen=" + sdLen 6389 + ", extAttribLen=" + eaLen); 6390 6391 6393 int fid; 6394 NetworkFile netFile = null; 6395 int respAction = 0; 6396 6397 try 6398 { 6399 6400 6402 int fileSts = disk.fileExists(m_sess, conn, fileName); 6403 6404 if (fileSts == FileStatus.NotExist) 6405 { 6406 6407 6409 if (createDisp == FileAction.NTCreate || createDisp == FileAction.NTOpenIf 6410 || createDisp == FileAction.NTOverwriteIf || createDisp == FileAction.NTSupersede) 6411 { 6412 6413 6415 if ((createOptn & WinNT.CreateDirectory) == 0) 6416 { 6417 6418 6420 netFile = disk.createFile(m_sess, conn, params); 6421 } 6422 else 6423 { 6424 6425 6427 disk.createDirectory(m_sess, conn, params); 6428 netFile = disk.openFile(m_sess, conn, params); 6429 } 6430 6431 6433 respAction = FileAction.FileCreated; 6434 } 6435 else 6436 { 6437 6438 6440 if (fileSts == FileStatus.DirectoryExists) 6441 { 6442 6443 6445 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, 6446 SMBStatus.ErrDos); 6447 return; 6448 } 6449 else 6450 { 6451 6452 6454 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, 6455 SMBStatus.ErrDos); 6456 return; 6457 } 6458 } 6459 } 6460 else if (createDisp == FileAction.NTCreate) 6461 { 6462 6463 6465 if (fileSts == FileStatus.FileExists || fileSts == FileStatus.DirectoryExists) 6466 { 6467 6468 6470 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, 6471 SMBStatus.ErrDos); 6472 return; 6473 } 6474 else 6475 { 6476 6477 6479 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6480 return; 6481 } 6482 } 6483 else 6484 { 6485 6486 6488 netFile = disk.openFile(m_sess, conn, params); 6489 6490 6492 if (createDisp == FileAction.NTSupersede || createDisp == FileAction.NTOverwriteIf) 6493 { 6494 6495 6497 disk.truncateFile(m_sess, conn, netFile, 0L); 6498 6499 6501 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) 6502 logger.debug(" [" + treeId + "] name=" + fileName + " truncated"); 6503 } 6504 6505 6507 respAction = FileAction.FileExisted; 6508 } 6509 6510 6512 fid = conn.addFile(netFile, getSession()); 6513 } 6514 catch (TooManyFilesException ex) 6515 { 6516 6517 6519 m_sess.sendErrorResponseSMB(SMBStatus.NTTooManyOpenFiles, SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); 6520 return; 6521 } 6522 catch (AccessDeniedException ex) 6523 { 6524 6525 6527 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6528 return; 6529 } 6530 catch (FileExistsException ex) 6531 { 6532 6533 6535 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, 6536 SMBStatus.ErrDos); 6537 return; 6538 } 6539 catch (FileSharingException ex) 6540 { 6541 6542 6544 m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, 6545 SMBStatus.ErrDos); 6546 return; 6547 } 6548 catch (FileOfflineException ex) 6549 { 6550 6551 6553 m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd); 6554 return; 6555 } 6556 catch (java.io.IOException ex) 6557 { 6558 6559 6561 m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); 6562 return; 6563 } 6564 6565 6567 DataBuffer prms = new DataBuffer(128); 6568 6569 6571 if ((flags & WinNT.RequestBatchOplock) != 0) 6572 { 6573 6574 6576 prms.putByte(2); 6577 } 6578 else if ((flags & WinNT.RequestOplock) != 0) 6579 { 6580 6581 6583 prms.putByte(1); 6584 } 6585 else 6586 { 6587 6588 6590 prms.putByte(0); 6591 } 6592 prms.putByte(0); 6594 6596 prms.putShort(fid); 6597 prms.putInt(respAction); 6598 6599 6601 prms.putInt(0); 6602 6603 6605 if (netFile.hasCreationDate()) 6606 prms.putLong(NTTime.toNTTime(netFile.getCreationDate())); 6607 else 6608 prms.putLong(0); 6609 6610 if (netFile.hasModifyDate()) 6611 { 6612 long modDate = NTTime.toNTTime(netFile.getModifyDate()); 6613 prms.putLong(modDate); 6614 prms.putLong(modDate); 6615 prms.putLong(modDate); 6616 } 6617 else 6618 { 6619 prms.putLong(0); prms.putLong(0); prms.putLong(0); } 6623 6624 prms.putInt(netFile.getFileAttributes()); 6625 6626 6628 prms.putLong(netFile.getFileSize()); prms.putLong(netFile.getFileSize()); prms.putShort(0); prms.putShort(0); prms.putByte(netFile.isDirectory() ? 1 : 0); 6633 6634 6636 outPkt.initTransactReply(prms.getBuffer(), prms.getLength(), null, 0); 6637 6638 6640 m_sess.sendResponseSMB(outPkt); 6641 6642 6644 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 6645 if (diskCtx.hasChangeHandler() && respAction == FileAction.FileCreated) 6646 { 6647 6648 6650 if (netFile.isDirectory()) 6651 diskCtx.getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, fileName); 6652 else 6653 diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, fileName); 6654 } 6655 } 6656 6657 6665 protected final void procNTTransactIOCtl(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException , 6666 SMBSrvException 6667 { 6668 6669 6671 int treeId = tbuf.getTreeId(); 6672 TreeConnection conn = m_sess.findConnection(treeId); 6673 6674 if (conn == null) { 6675 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 6676 return; 6677 } 6678 6679 6681 DataBuffer setupBuf = tbuf.getSetupBuffer(); 6682 6683 int ctrlCode = setupBuf.getInt(); 6684 int fid = setupBuf.getShort(); 6685 boolean fsctrl = setupBuf.getByte() == 1 ? true : false; 6686 int filter = setupBuf.getByte(); 6687 6688 6690 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6691 logger.debug("NT IOCtl code=" + NTIOCtl.asString(ctrlCode) + ", fid=" + fid + ", fsctrl=" + fsctrl + ", filter=" + filter); 6692 6693 6695 DiskInterface disk = null; 6696 try { 6697 6698 6700 disk = (DiskInterface) conn.getSharedDevice().getInterface(); 6701 } 6702 catch (InvalidDeviceInterfaceException ex) { 6703 6704 6706 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); 6707 return; 6708 } 6709 6710 6712 if ( disk instanceof IOCtlInterface) { 6713 6714 6716 IOCtlInterface ioControl = (IOCtlInterface) disk; 6717 6718 try { 6719 6720 6722 DataBuffer response = ioControl.processIOControl(m_sess, conn, ctrlCode, fid, tbuf.getDataBuffer(), fsctrl, filter); 6723 6724 6726 if ( response != null) { 6727 6728 6730 outPkt.initTransactReply(null, 0, response.getBuffer(), response.getLength(), 1); 6731 outPkt.setSetupParameter(0, response.getLength()); 6732 } 6733 else { 6734 6735 6737 outPkt.initTransactReply(null, 0, null, 0, 1); 6738 outPkt.setSetupParameter(0, 0); 6739 } 6740 } 6741 catch (IOControlNotImplementedException ex) { 6742 6743 6745 m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); 6746 return; 6747 } 6748 catch (SMBException ex) { 6749 6750 6752 m_sess.sendErrorResponseSMB(ex.getErrorCode(), SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); 6753 return; 6754 } 6755 6756 6758 m_sess.sendResponseSMB(outPkt); 6759 } 6760 else { 6761 6762 6764 m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 6765 } 6766 } 6767 6768 6776 protected final void procNTTransactQuerySecurityDesc(SrvTransactBuffer tbuf, NTTransPacket outPkt) 6777 throws IOException , SMBSrvException 6778 { 6779 6780 6782 int treeId = tbuf.getTreeId(); 6783 TreeConnection conn = m_sess.findConnection(treeId); 6784 6785 if (conn == null) 6786 { 6787 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 6788 return; 6789 } 6790 6791 6793 if (conn.hasReadAccess() == false) 6794 { 6795 6796 6798 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6799 return; 6800 } 6801 6802 6804 DataBuffer paramBuf = tbuf.getParameterBuffer(); 6805 6806 int fid = paramBuf.getShort(); 6807 int flags = paramBuf.getShort(); 6808 6809 6811 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6812 logger.debug("NT QuerySecurityDesc fid=" + fid + ", flags=" + flags); 6813 6814 6816 NetworkFile netFile = conn.findFile(fid); 6817 6818 if (netFile == null) 6819 { 6820 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 6821 return; 6822 } 6823 6824 6827 if (tbuf.getReturnDataLimit() == 0) 6828 { 6829 6830 6832 byte[] paramblk = new byte[4]; 6833 DataPacker.putIntelInt(_sdEveryOne.length, paramblk, 0); 6834 6835 6837 outPkt.initTransactReply(paramblk, paramblk.length, null, 0); 6838 6839 6843 outPkt.setLongErrorCode(SMBStatus.NTBufferTooSmall); 6844 } 6845 else 6846 { 6847 6848 6850 byte[] paramblk = new byte[4]; 6851 DataPacker.putIntelInt(_sdEveryOne.length, paramblk, 0); 6852 6853 6857 outPkt.initTransactReply(paramblk, paramblk.length, _sdEveryOne, _sdEveryOne.length); 6858 } 6859 6860 6862 m_sess.sendResponseSMB(outPkt); 6863 } 6864 6865 6873 protected final void procNTTransactSetSecurityDesc(SrvTransactBuffer tbuf, NTTransPacket outPkt) 6874 throws IOException , SMBSrvException 6875 { 6876 6877 6879 DataBuffer paramBuf = tbuf.getParameterBuffer(); 6880 6881 6883 int treeId = tbuf.getTreeId(); 6884 TreeConnection conn = m_sess.findConnection(treeId); 6885 6886 if (conn == null) 6887 { 6888 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 6889 return; 6890 } 6891 6892 6894 if (conn.hasWriteAccess() == false) 6895 { 6896 6897 6899 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6900 return; 6901 } 6902 6903 6905 int fid = paramBuf.getShort(); 6906 paramBuf.skipBytes(2); 6907 int flags = paramBuf.getInt(); 6908 6909 6911 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 6912 logger.debug("NT SetSecurityDesc fid=" + fid + ", flags=" + flags); 6913 6914 6916 m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6917 } 6918 6919 6927 protected final void procNTTransactNotifyChange(NTTransPacket ntpkt, SMBSrvPacket outPkt) throws IOException , 6928 SMBSrvException 6929 { 6930 6931 6933 int treeId = ntpkt.getTreeId(); 6934 TreeConnection conn = m_sess.findConnection(treeId); 6935 6936 if (conn == null) 6937 { 6938 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 6939 return; 6940 } 6941 6942 6944 if (conn.hasReadAccess() == false) 6945 { 6946 6947 6949 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 6950 return; 6951 } 6952 6953 6955 if (conn.getContext() == null || conn.getContext() instanceof DiskDeviceContext == false) 6956 { 6957 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6958 return; 6959 } 6960 6961 6963 DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); 6964 if (diskCtx.hasChangeHandler() == false) 6965 { 6966 6967 6969 m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6970 return; 6971 } 6972 6973 6975 ntpkt.resetSetupPointer(); 6976 6977 int filter = ntpkt.unpackInt(); 6978 int fid = ntpkt.unpackWord(); 6979 boolean watchTree = ntpkt.unpackByte() == 1 ? true : false; 6980 int mid = ntpkt.getMultiplexId(); 6981 6982 6984 NetworkFile dir = conn.findFile(fid); 6985 if (dir == null) 6986 { 6987 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 6988 return; 6989 } 6990 6991 6995 int maxQueue = 0; 6996 6997 6999 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) 7000 logger.debug("NT NotifyChange fid=" + fid + ", mid=" + mid + ", filter=0x" + Integer.toHexString(filter) 7001 + ", dir=" + dir.getFullName() + ", maxQueue=" + maxQueue); 7002 7003 7008 NotifyRequest req = m_sess.findNotifyRequest(dir, filter, watchTree); 7009 7010 if (req != null && req.isCompleted()) 7011 { 7012 7013 7015 req.setMultiplexId(mid); 7016 req.setCompleted(false); 7017 7018 7020 if (req.hasBufferedEvents() || req.hasNotifyEnum()) 7021 { 7022 7023 7025 NotifyChangeEventList bufList = req.getBufferedEventList(); 7026 req.clearBufferedEvents(); 7027 7028 7030 diskCtx.getChangeHandler().sendBufferedNotifications(req, bufList); 7031 7032 7034 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) 7035 { 7036 if (bufList == null) 7037 logger.debug(" Sent buffered notifications, req=" + req.toString() + ", Enum"); 7038 else 7039 logger.debug(" Sent buffered notifications, req=" + req.toString() + ", count=" 7040 + bufList.numberOfEvents()); 7041 } 7042 } 7043 else 7044 { 7045 7046 7048 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) 7049 logger.debug(" Reset notify request, " + req.toString()); 7050 } 7051 } 7052 else 7053 { 7054 7055 7057 req = new NotifyRequest(filter, watchTree, m_sess, dir, mid, ntpkt.getTreeId(), ntpkt.getProcessId(), ntpkt 7058 .getUserId(), maxQueue); 7059 7060 7062 m_sess.addNotifyRequest(req, diskCtx); 7063 7064 7066 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) 7067 logger.debug(" Added new request, " + req.toString()); 7068 } 7069 7070 } 7074 7075 7083 protected final void procNTTransactRename(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException , 7084 SMBSrvException 7085 { 7086 7087 7089 DataBuffer paramBuf = tbuf.getParameterBuffer(); 7090 7091 7093 int treeId = tbuf.getTreeId(); 7094 TreeConnection conn = m_sess.findConnection(treeId); 7095 7096 if (conn == null) 7097 { 7098 m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); 7099 return; 7100 } 7101 7102 7104 if (conn.hasWriteAccess() == false) 7105 { 7106 7107 7109 m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); 7110 return; 7111 } 7112 7113 7115 if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) 7116 logger.debug("NT TransactRename"); 7117 7118 7120 m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 7121 } 7122} | Popular Tags |