1 17 package org.alfresco.filesys.smb.server; 18 19 import java.io.IOException ; 20 import java.net.InetAddress ; 21 import java.net.SocketException ; 22 import java.util.Enumeration ; 23 import java.util.Hashtable ; 24 import java.util.Vector ; 25 26 import org.alfresco.filesys.netbios.NetBIOSException; 27 import org.alfresco.filesys.netbios.NetBIOSName; 28 import org.alfresco.filesys.netbios.NetBIOSPacket; 29 import org.alfresco.filesys.netbios.NetBIOSSession; 30 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; 31 import org.alfresco.filesys.server.SrvSession; 32 import org.alfresco.filesys.server.auth.SrvAuthenticator; 33 import org.alfresco.filesys.server.core.DeviceInterface; 34 import org.alfresco.filesys.server.core.SharedDevice; 35 import org.alfresco.filesys.server.filesys.DiskDeviceContext; 36 import org.alfresco.filesys.server.filesys.DiskInterface; 37 import org.alfresco.filesys.server.filesys.NetworkFile; 38 import org.alfresco.filesys.server.filesys.SearchContext; 39 import org.alfresco.filesys.server.filesys.TooManyConnectionsException; 40 import org.alfresco.filesys.server.filesys.TreeConnection; 41 import org.alfresco.filesys.smb.Capability; 42 import org.alfresco.filesys.smb.DataType; 43 import org.alfresco.filesys.smb.Dialect; 44 import org.alfresco.filesys.smb.DialectSelector; 45 import org.alfresco.filesys.smb.NTTime; 46 import org.alfresco.filesys.smb.PacketType; 47 import org.alfresco.filesys.smb.SMBDate; 48 import org.alfresco.filesys.smb.SMBErrorText; 49 import org.alfresco.filesys.smb.SMBStatus; 50 import org.alfresco.filesys.smb.server.notify.NotifyRequest; 51 import org.alfresco.filesys.smb.server.notify.NotifyRequestList; 52 import org.alfresco.filesys.util.DataPacker; 53 import org.alfresco.filesys.util.StringList; 54 import org.apache.commons.logging.Log; 55 import org.apache.commons.logging.LogFactory; 56 57 66 public class SMBSrvSession extends SrvSession implements Runnable 67 { 68 private static Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); 70 71 73 private static final int DefaultBufferSize = 0x010000 + RFCNetBIOSProtocol.HEADER_LEN; 74 private static final int LanManBufferSize = 8192; 75 76 78 private static final int DefaultConnections = 4; 79 private static final int MaxConnections = 16; 80 81 83 private static final int TreeIdMask = 0x0000FFFF; 84 85 87 private static final int DefaultSearches = 8; 88 private static final int MaxSearches = 256; 89 90 95 private static final int LanManMaxMultiplexed = 1; 96 private static final int NTMaxMultiplexed = 4; 97 98 100 private static final int MaxVirtualCircuits = 0; 101 102 104 private PacketHandler m_pktHandler; 105 106 108 private byte[] m_buf; 109 private int m_rxlen; 110 111 113 private SMBSrvPacket m_smbPkt; 114 115 117 private ProtocolHandler m_handler; 118 119 121 private int m_state = SMBSrvSessionState.NBSESSREQ; 122 123 125 private int m_dialect = Dialect.Unknown; 126 127 129 private String m_callerNBName; 130 private String m_targetNBName; 131 132 134 private Hashtable <Integer , TreeConnection> m_connections; 135 private int m_treeId; 136 137 139 private SearchContext[] m_search; 140 private int m_searchCount; 141 142 144 private SrvTransactBuffer m_transact; 145 146 148 private NotifyRequestList m_notifyList; 149 private boolean m_notifyPending; 150 151 154 private int m_defFlags; 155 private int m_defFlags2; 156 157 163 private Vector <SMBSrvPacket> m_asynchQueue; 164 165 167 private int m_maxBufSize; 168 private int m_maxMultiplex; 169 170 172 private int m_clientCaps; 173 174 176 public static final int DBG_NETBIOS = 0x00000001; public static final int DBG_STATE = 0x00000002; public static final int DBG_NEGOTIATE = 0x00000004; public static final int DBG_TREE = 0x00000008; public static final int DBG_SEARCH = 0x00000010; public static final int DBG_INFO = 0x00000020; public static final int DBG_FILE = 0x00000040; public static final int DBG_FILEIO = 0x00000080; public static final int DBG_TRAN = 0x00000100; public static final int DBG_ECHO = 0x00000200; public static final int DBG_ERROR = 0x00000400; public static final int DBG_IPC = 0x00000800; public static final int DBG_LOCK = 0x00001000; public static final int DBG_PKTTYPE = 0x00002000; public static final int DBG_DCERPC = 0x00004000; public static final int DBG_STATECACHE = 0x00008000; public static final int DBG_NOTIFY = 0x00010000; public static final int DBG_STREAMS = 0x00020000; public static final int DBG_SOCKET = 0x00040000; 196 202 public SMBSrvSession(PacketHandler handler, SMBServer srv) 203 { 204 super(-1, srv, handler.isProtocolName(), null); 205 206 208 m_pktHandler = handler; 209 210 212 m_buf = new byte[DefaultBufferSize]; 213 m_smbPkt = new SMBSrvPacket(m_buf); 214 215 218 if (isProtocol() == SMBSrvPacket.PROTOCOL_TCPIP || isProtocol() == SMBSrvPacket.PROTOCOL_WIN32NETBIOS) 219 { 220 221 223 setState(SMBSrvSessionState.SMBNEGOTIATE); 224 225 227 if (handler.hasClientName()) 228 m_callerNBName = handler.getClientName(); 229 } 230 } 231 232 237 public final int isProtocol() 238 { 239 return m_pktHandler.isProtocol(); 240 } 241 242 248 protected int addConnection(SharedDevice shrDev) throws TooManyConnectionsException 249 { 250 251 253 if (m_connections == null) 254 m_connections = new Hashtable <Integer , TreeConnection>(DefaultConnections); 255 256 258 int treeId = 0; 259 260 synchronized (m_connections) 261 { 262 263 265 if (m_connections.size() == MaxConnections) 266 throw new TooManyConnectionsException(); 267 268 270 treeId = (m_treeId++ & TreeIdMask); 271 Integer key = new Integer (treeId); 272 273 while (m_connections.contains(key)) 274 { 275 276 278 treeId = (m_treeId++ & TreeIdMask); 279 key = new Integer (treeId); 280 } 281 282 284 m_connections.put(key, new TreeConnection(shrDev)); 285 } 286 287 289 return treeId; 290 } 291 292 297 protected final int allocateSearchSlot() 298 { 299 300 302 if (m_search == null) 303 m_search = new SearchContext[DefaultSearches]; 304 305 307 int idx = 0; 308 309 while (idx < m_search.length && m_search[idx] != null) 310 idx++; 311 312 314 if (idx == m_search.length) 315 { 316 317 319 if (m_search.length >= MaxSearches) 320 return -1; 321 322 324 SearchContext[] newSearch = new SearchContext[m_search.length * 2]; 325 System.arraycopy(m_search, 0, newSearch, 0, m_search.length); 326 m_search = newSearch; 327 } 328 329 331 m_searchCount++; 332 return idx; 333 } 334 335 339 protected final void cleanupSession() 340 { 341 342 344 if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) 345 logger.debug("Cleanup session, searches=" + getSearchCount() + ", treeConns=" + getConnectionCount() 346 + ", changeNotify=" + getNotifyChangeCount()); 347 348 350 if (m_search != null) 351 { 352 353 355 for (int idx = 0; idx < m_search.length; idx++) 356 { 357 358 360 if (m_search[idx] != null) 361 deallocateSearchSlot(idx); 362 } 363 364 366 m_search = null; 367 m_searchCount = 0; 368 } 369 370 372 if (m_connections != null) 373 { 374 375 synchronized (m_connections) 376 { 377 378 380 Enumeration <TreeConnection> enm = m_connections.elements(); 381 382 while (enm.hasMoreElements()) 383 { 384 385 387 TreeConnection tree = enm.nextElement(); 388 DeviceInterface devIface = tree.getInterface(); 389 390 392 if (tree.openFileCount() > 0) 393 { 394 395 397 for (int i = 0; i < tree.getFileTableLength(); i++) 398 { 399 400 402 NetworkFile curFile = tree.findFile(i); 403 if (curFile != null && devIface instanceof DiskInterface) 404 { 405 406 408 DiskInterface diskIface = (DiskInterface) devIface; 409 410 try 411 { 412 413 415 tree.removeFile(i, this); 416 417 419 diskIface.closeFile(this, tree, curFile); 420 } 421 catch (Exception ex) 422 { 423 } 424 } 425 } 426 } 427 429 if (devIface != null) 430 devIface.treeClosed(this, tree); 431 } 432 433 435 m_connections.clear(); 436 } 437 } 438 439 441 try 442 { 443 445 endTransaction(); 446 } 447 catch ( Exception ex) 448 { 449 451 if ( logger.isDebugEnabled()) 452 logger.debug("Error committing transaction", ex); 453 } 454 455 457 if (m_notifyList != null && m_notifyList.numberOfRequests() > 0) 458 { 459 460 462 for (int i = 0; i < m_notifyList.numberOfRequests(); i++) 463 { 464 465 468 NotifyRequest curReq = m_notifyList.getRequest(i); 469 curReq.getDiskContext().getChangeHandler().removeNotifyRequests(this); 470 } 471 } 472 473 475 getSMBServer().deleteTemporaryShares(this); 476 } 477 478 481 protected final void closeSocket() 482 { 483 484 486 setShutdown(true); 487 488 490 try 491 { 492 m_pktHandler.closeHandler(); 493 } 494 catch (Exception ex) 495 { 496 } 497 } 498 499 502 public final void closeSession() 503 { 504 505 507 super.closeSession(); 508 509 try 510 { 511 512 514 setState(SMBSrvSessionState.NBHANGUP); 515 setShutdown(true); 516 517 519 m_pktHandler.closeHandler(); 520 } 521 catch (Exception ex) 522 { 523 } 524 525 } 526 527 532 protected final void deallocateSearchSlot(int ctxId) 533 { 534 535 537 if (m_search == null || ctxId >= m_search.length) 538 return; 539 540 542 if (m_search[ctxId] != null) 543 m_search[ctxId].closeSearch(); 544 545 547 m_searchCount--; 548 m_search[ctxId] = null; 549 } 550 551 554 public void finalize() 555 { 556 557 559 cleanupSession(); 560 561 563 closeSocket(); 564 } 565 566 572 protected final TreeConnection findConnection(int treeId) 573 { 574 575 577 if (m_connections == null) 578 return null; 579 580 582 return (TreeConnection) m_connections.get(new Integer (treeId)); 583 } 584 585 590 protected final byte[] getBuffer() 591 { 592 return m_buf; 593 } 594 595 600 public final int getConnectionCount() 601 { 602 return m_connections != null ? m_connections.size() : 0; 603 } 604 605 610 public final int getDefaultFlags() 611 { 612 return m_defFlags; 613 } 614 615 620 public final int getDefaultFlags2() 621 { 622 return m_defFlags2; 623 } 624 625 630 public final int getNotifyChangeCount() 631 { 632 if (m_notifyList == null) 633 return 0; 634 return m_notifyList.numberOfRequests(); 635 } 636 637 642 public final int getClientMaximumBufferSize() 643 { 644 return m_maxBufSize; 645 } 646 647 652 public final int getClientMaximumMultiplex() 653 { 654 return m_maxMultiplex; 655 } 656 657 662 public final int getClientCapabilities() 663 { 664 return m_clientCaps; 665 } 666 667 673 public final boolean hasClientCapability(int cap) 674 { 675 if ((m_clientCaps & cap) != 0) 676 return true; 677 return false; 678 } 679 680 685 public final int getNegotiatedSMBDialect() 686 { 687 return m_dialect; 688 } 689 690 695 public final PacketHandler getPacketHandler() 696 { 697 return m_pktHandler; 698 } 699 700 705 public final SMBSrvPacket getReceivePacket() 706 { 707 return m_smbPkt; 708 } 709 710 715 public final String getRemoteNetBIOSName() 716 { 717 return m_callerNBName; 718 } 719 720 725 public final boolean hasTargetNetBIOSName() 726 { 727 return m_targetNBName != null ? true : false; 728 } 729 730 735 public final String getTargetNetBIOSName() 736 { 737 return m_targetNBName; 738 } 739 740 745 public final boolean hasRemoteAddress() 746 { 747 return m_pktHandler.hasRemoteAddress(); 748 } 749 750 755 public final InetAddress getRemoteAddress() 756 { 757 return m_pktHandler.getRemoteAddress(); 758 } 759 760 766 protected final SearchContext getSearchContext(int srchId) 767 { 768 769 771 if (m_search == null || srchId >= m_search.length) 772 return null; 773 774 776 return m_search[srchId]; 777 } 778 779 784 public final int getSearchCount() 785 { 786 return m_searchCount; 787 } 788 789 794 public final SMBServer getSMBServer() 795 { 796 return (SMBServer) getServer(); 797 } 798 799 804 public final String getServerName() 805 { 806 return getSMBServer().getServerName(); 807 } 808 809 814 private void hangupSession(String reason) 815 { 816 817 819 if (logger.isDebugEnabled() && hasDebug(DBG_NETBIOS)) 820 logger.debug("## Session closing - " + reason); 821 822 824 setState(SMBSrvSessionState.NBHANGUP); 825 } 826 827 832 public final boolean hasMacintoshExtensions() 833 { 834 return getSMBServer().getConfiguration().hasMacintoshExtensions(); 835 } 836 837 842 public final boolean hasNotifyPending() 843 { 844 return m_notifyPending; 845 } 846 847 852 public final void setNotifyPending(boolean pend) 853 { 854 m_notifyPending = pend; 855 } 856 857 862 public final void setClientMaximumBufferSize(int maxBuf) 863 { 864 m_maxBufSize = maxBuf; 865 } 866 867 872 public final void setClientMaximumMultiplex(int maxMpx) 873 { 874 m_maxMultiplex = maxMpx; 875 } 876 877 882 public final void setClientCapabilities(int flags) 883 { 884 m_clientCaps = flags; 885 } 886 887 892 public final void setDefaultFlags(int flags) 893 { 894 m_defFlags = flags; 895 } 896 897 902 public final void setDefaultFlags2(int flags) 903 { 904 m_defFlags2 = flags; 905 } 906 907 912 public final void setReceivePacket(SMBSrvPacket pkt) 913 { 914 m_smbPkt = pkt; 915 m_buf = pkt.getBuffer(); 916 } 917 918 924 protected final void setSearchContext(int slot, SearchContext srch) 925 { 926 927 929 if (m_search == null || slot > m_search.length) 930 return; 931 932 934 m_search[slot] = srch; 935 } 936 937 942 protected void setState(int state) 943 { 944 945 947 if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) 948 logger.debug("State changed to " + SMBSrvSessionState.getStateAsString(state)); 949 950 952 m_state = state; 953 } 954 955 959 protected void procNetBIOSSessionRequest() throws IOException , NetBIOSException 960 { 961 962 964 NetBIOSPacket nbPkt = new NetBIOSPacket(m_buf); 965 966 if (m_rxlen < RFCNetBIOSProtocol.SESSREQ_LEN || nbPkt.getHeaderType() != RFCNetBIOSProtocol.SESSION_REQUEST) 967 throw new NetBIOSException("NBREQ Invalid packet"); 968 969 971 if (m_buf[4] != (byte) 32 || m_buf[38] != (byte) 32) 972 throw new NetBIOSException("NBREQ Invalid NetBIOS name data"); 973 974 976 StringBuffer nbName = new StringBuffer (32); 977 for (int i = 0; i < 32; i++) 978 nbName.append((char) m_buf[5 + i]); 979 String toName = NetBIOSSession.DecodeName(nbName.toString()); 980 toName = toName.trim(); 981 982 nbName.setLength(0); 983 for (int i = 0; i < 32; i++) 984 nbName.append((char) m_buf[39 + i]); 985 String fromName = NetBIOSSession.DecodeName(nbName.toString()); 986 fromName = fromName.trim(); 987 988 990 if (logger.isDebugEnabled() && hasDebug(DBG_NETBIOS)) 991 logger.debug("NetBIOS CALL From " + fromName + " to " + toName); 992 993 995 boolean forThisServer = false; 996 997 if (toName.compareTo(getServerName()) == 0 || toName.compareTo(NetBIOSName.SMBServer) == 0 998 || toName.compareTo(NetBIOSName.SMBServer2) == 0 || toName.compareTo("*") == 0) 999 { 1000 1001 1003 forThisServer = true; 1004 } 1005 else 1006 { 1007 1008 1010 InetAddress [] srvAddr = getSMBServer().getServerAddresses(); 1011 if (srvAddr != null) 1012 { 1013 1014 1016 int idx = 0; 1017 1018 while (idx < srvAddr.length && forThisServer == false) 1019 { 1020 1021 1023 if (srvAddr[idx++].getHostAddress().compareTo(toName) == 0) 1024 forThisServer = true; 1025 } 1026 } 1027 } 1028 1029 1031 if (forThisServer == false) 1032 throw new NetBIOSException("NBREQ Called name is not this server (" + toName + ")"); 1033 1034 1036 if (logger.isDebugEnabled() && hasDebug(DBG_NETBIOS)) 1037 logger.debug("NetBIOS session request from " + fromName); 1038 1039 1041 m_callerNBName = fromName; 1042 m_targetNBName = toName; 1043 1044 1046 setRemoteName(fromName); 1047 1048 1050 nbPkt.setHeaderType(RFCNetBIOSProtocol.SESSION_ACK); 1051 nbPkt.setHeaderFlags(0); 1052 nbPkt.setHeaderLength(0); 1053 1054 1056 m_pktHandler.writePacket(m_buf, 0, 4); 1057 1058 1060 setState(SMBSrvSessionState.SMBNEGOTIATE); 1061 } 1062 1063 1066 protected void procSMBNegotiate() throws SMBSrvException, IOException 1067 { 1068 1069 1071 m_smbPkt = new SMBSrvPacket(m_buf); 1072 1073 1075 m_buf[0] = (byte) RFCNetBIOSProtocol.SESSION_MESSAGE; 1076 1077 1079 if (m_smbPkt.getCommand() != PacketType.Negotiate || m_smbPkt.checkPacketIsValid(0, 2) == false) 1080 { 1081 sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); 1082 return; 1083 } 1084 1085 1087 int dataPos = m_smbPkt.getByteOffset(); 1088 int dataLen = m_smbPkt.getByteCount(); 1089 1090 String diaStr = null; 1091 StringList dialects = new StringList(); 1092 1093 while (dataLen > 0) 1094 { 1095 1096 1098 diaStr = DataPacker.getDataString(DataType.Dialect, m_buf, dataPos, dataLen, false); 1099 if (diaStr != null) 1100 { 1101 1102 1104 dialects.addString(diaStr); 1105 } 1106 else 1107 { 1108 1109 1112 sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); 1113 setState(SMBSrvSessionState.NBHANGUP); 1114 return; 1115 } 1116 1117 1119 dataPos += diaStr.length() + 2; dataLen -= diaStr.length() + 2; 1121 } 1122 1123 1125 DialectSelector dia = getSMBServer().getSMBDialects(); 1126 int diaIdx = -1; 1127 1128 for (int i = 0; i < Dialect.Max; i++) 1129 { 1130 1131 1133 if (dia.hasDialect(i)) 1134 { 1135 1136 1140 for (int j = 0; j < Dialect.SMB_PROT_MAXSTRING; j++) 1141 { 1142 1143 1145 if (Dialect.DialectType(j) == i && dialects.containsString(Dialect.DialectString(j))) 1146 { 1147 1148 1151 if (i > diaIdx) 1152 diaIdx = i; 1153 } 1154 } 1155 } 1156 } 1157 1158 1160 if (logger.isDebugEnabled() && hasDebug(DBG_NEGOTIATE)) 1161 { 1162 if (diaIdx == -1) 1163 logger.debug("Failed to negotiate SMB dialect"); 1164 else 1165 logger.debug("Negotiated SMB dialect - " + Dialect.DialectTypeString(diaIdx)); 1166 } 1167 1168 1170 if (diaIdx != -1) 1171 { 1172 1173 1175 m_dialect = diaIdx; 1176 1177 1179 diaIdx = dialects.findString(Dialect.DialectTypeString(diaIdx)); 1180 1181 1184 m_handler = ProtocolFactory.getHandler(m_dialect); 1185 if (m_handler != null) 1186 { 1187 1188 1190 if (logger.isDebugEnabled() && hasDebug(DBG_NEGOTIATE)) 1191 logger.debug("Assigned protocol handler - " + m_handler.getClass().getName()); 1192 1193 1195 m_handler.setSession(this); 1196 } 1197 else 1198 { 1199 1200 1204 diaIdx = -1; 1205 } 1206 } 1207 1208 1210 if (m_dialect == -1 || m_dialect <= Dialect.CorePlus) 1211 { 1212 1213 1215 m_smbPkt.setParameterCount(1); 1216 m_smbPkt.setParameter(0, diaIdx); 1217 m_smbPkt.setByteCount(0); 1218 1219 m_smbPkt.setTreeId(0); 1220 m_smbPkt.setUserId(0); 1221 } 1222 else if (m_dialect <= Dialect.LanMan2_1) 1223 { 1224 1225 1227 m_smbPkt.setFlags(SMBSrvPacket.FLG_CASELESS); 1228 m_smbPkt.setFlags2(SMBSrvPacket.FLG2_LONGFILENAMES); 1229 1230 1234 SrvAuthenticator auth = getServer().getConfiguration().getAuthenticator(); 1235 int secMode = 0; 1236 1237 if (auth != null) 1238 { 1239 1240 1242 if (auth.getAccessMode() == SrvAuthenticator.USER_MODE) 1243 secMode = 1; 1244 1245 1247 if (auth.hasEncryptPasswords()) 1248 secMode += 2; 1249 } 1250 1251 1253 m_smbPkt.setParameterCount(13); 1254 m_smbPkt.setParameter(0, diaIdx); 1255 m_smbPkt.setParameter(1, secMode); m_smbPkt.setParameter(2, LanManBufferSize); 1257 m_smbPkt.setParameter(3, LanManMaxMultiplexed); m_smbPkt.setParameter(4, MaxVirtualCircuits); m_smbPkt.setParameter(5, 0); 1261 1263 m_smbPkt.setParameterLong(6, (int) (System.currentTimeMillis() & 0xFFFFFFFF)); 1264 1265 1267 SMBDate srvDate = new SMBDate(System.currentTimeMillis()); 1268 m_smbPkt.setParameter(8, srvDate.asSMBTime()); 1269 m_smbPkt.setParameter(9, srvDate.asSMBDate()); 1270 1271 1273 m_smbPkt.setParameter(10, getServer().getConfiguration().getTimeZoneOffset()); 1274 1275 1277 m_smbPkt.setParameter(11, 8); m_smbPkt.setParameter(12, 0); 1279 1280 1282 setChallengeKey(auth.getChallengeKey(this)); 1283 int pos = m_smbPkt.getByteOffset(); 1284 byte[] buf = m_smbPkt.getBuffer(); 1285 1286 if (hasChallengeKey() == false) 1287 { 1288 1289 1291 for (int i = 0; i < 8; i++) 1292 buf[pos++] = 0; 1293 } 1294 else 1295 { 1296 1297 1299 byte[] key = getChallengeKey(); 1300 for (int i = 0; i < key.length; i++) 1301 buf[pos++] = key[i]; 1302 } 1303 1304 1306 String domain = getServer().getConfiguration().getDomainName(); 1307 if (domain != null) 1308 pos = DataPacker.putString(domain, buf, pos, true); 1309 1310 m_smbPkt.setByteCount(pos - m_smbPkt.getByteOffset()); 1311 1312 m_smbPkt.setTreeId(0); 1313 m_smbPkt.setUserId(0); 1314 } 1315 else if (m_dialect == Dialect.NT) 1316 { 1317 1318 1320 setDefaultFlags(SMBSrvPacket.FLG_CASELESS); 1321 setDefaultFlags2(SMBSrvPacket.FLG2_LONGFILENAMES + SMBSrvPacket.FLG2_UNICODE); 1322 1323 1326 SrvAuthenticator auth = getServer().getConfiguration().getAuthenticator(); 1327 int secMode = 0; 1328 1329 if (auth != null) 1330 { 1331 1332 1334 if (auth.getAccessMode() == SrvAuthenticator.USER_MODE) 1335 secMode = 1; 1336 1337 1339 if (auth.hasEncryptPasswords()) 1340 secMode += 2; 1341 } 1342 1343 1345 NTParameterPacker nt = new NTParameterPacker(m_smbPkt.getBuffer()); 1346 1347 m_smbPkt.setParameterCount(17); 1348 nt.packWord(diaIdx); nt.packByte(secMode); nt.packWord(NTMaxMultiplexed); nt.packWord(MaxVirtualCircuits); 1354 int maxBufSize = m_smbPkt.getBuffer().length - RFCNetBIOSProtocol.HEADER_LEN; 1355 nt.packInt(maxBufSize); 1356 1357 nt.packInt(0); 1359 1361 nt.packInt((int) (System.currentTimeMillis() & 0xFFFFFFFFL)); 1362 1363 1365 nt.packInt(Capability.Unicode + Capability.RemoteAPIs + Capability.NTSMBs + Capability.NTFind 1366 + Capability.NTStatus + Capability.LargeFiles + Capability.LargeRead + Capability.LargeWrite); 1367 1368 1370 long srvTime = NTTime.toNTTime(new java.util.Date (System.currentTimeMillis())); 1371 1372 nt.packLong(srvTime); 1373 nt.packWord(getServer().getConfiguration().getTimeZoneOffset()); 1374 1375 1377 nt.packByte(8); 1379 1381 setChallengeKey(auth.getChallengeKey(this)); 1382 1383 int pos = m_smbPkt.getByteOffset(); 1384 byte[] buf = m_smbPkt.getBuffer(); 1385 1386 if (hasChallengeKey() == false) 1387 { 1388 1389 1391 for (int i = 0; i < 8; i++) 1392 buf[pos++] = 0; 1393 } 1394 else 1395 { 1396 1397 1399 byte[] key = getChallengeKey(); 1400 1401 for (int i = 0; i < key.length; i++) 1402 buf[pos++] = key[i]; 1403 } 1404 1405 1407 String domain = getServer().getConfiguration().getDomainName(); 1408 if (domain != null) 1409 pos = DataPacker.putUnicodeString(domain, buf, pos, true); 1410 1411 1413 pos = DataPacker.putUnicodeString(getServerName(), buf, pos, true); 1414 1415 1417 m_smbPkt.setByteCount(pos - m_smbPkt.getByteOffset()); 1418 1419 m_smbPkt.setFlags( getDefaultFlags()); 1420 m_smbPkt.setFlags2( getDefaultFlags2()); 1421 1422 m_smbPkt.setTreeId(0); 1423 m_smbPkt.setUserId(0); 1424 } 1425 1426 1428 if (m_smbPkt.isResponse() == false) 1429 m_smbPkt.setFlags(m_smbPkt.getFlags() + SMBPacket.FLG_RESPONSE); 1430 1431 1433 m_pktHandler.writePacket(m_smbPkt, m_smbPkt.getLength()); 1434 1435 1439 if (m_dialect == -1) 1440 setState(SMBSrvSessionState.NBHANGUP); 1441 else if (Dialect.DialectSupportsCommand(m_dialect, PacketType.SessionSetupAndX)) 1442 setState(SMBSrvSessionState.SMBSESSSETUP); 1443 else 1444 setState(SMBSrvSessionState.SMBSESSION); 1445 1446 1448 if (m_dialect != -1) 1449 getSMBServer().sessionOpened(this); 1450 } 1451 1452 1457 protected void removeConnection(int treeId) 1458 { 1459 1460 1462 if (m_connections == null) 1463 return; 1464 1465 1467 synchronized (m_connections) 1468 { 1469 1470 1472 Integer key = new Integer (treeId); 1473 TreeConnection tree = (TreeConnection) m_connections.get(key); 1474 1475 1477 if (tree != null) 1478 { 1479 1480 1482 tree.closeConnection(this); 1483 1484 1486 m_connections.remove(key); 1487 } 1488 } 1489 } 1490 1491 1494 public void run() 1495 { 1496 try 1497 { 1498 1500 if (logger.isDebugEnabled() && hasDebug(SMBSrvSession.DBG_NEGOTIATE)) 1501 logger.debug("Server session started"); 1502 1503 1505 while (m_state != SMBSrvSessionState.NBHANGUP) 1506 { 1507 1508 1512 m_rxlen = -1; 1513 1514 1516 m_rxlen = m_pktHandler.readPacket(m_smbPkt); 1517 1518 1520 if (m_rxlen == 0) 1521 continue; 1522 1523 1525 if (m_rxlen == -1) 1526 { 1527 hangupSession("Remote disconnect"); 1528 continue; 1529 } 1530 1531 1533 m_smbPkt.setReceivedLength(m_rxlen); 1534 1535 1537 m_reqCount++; 1538 1539 1541 switch (m_state) 1542 { 1543 1544 1546 case SMBSrvSessionState.NBSESSREQ: 1547 procNetBIOSSessionRequest(); 1548 break; 1549 1550 1552 case SMBSrvSessionState.SMBNEGOTIATE: 1553 procSMBNegotiate(); 1554 break; 1555 1556 1558 case SMBSrvSessionState.SMBSESSSETUP: 1559 m_handler.runProtocol(); 1560 break; 1561 1562 1564 case SMBSrvSessionState.SMBSESSION: 1565 1566 1568 runHandler(); 1569 break; 1570 1571 } 1573 1575 try 1576 { 1577 1579 endTransaction(); 1580 } 1581 catch ( Exception ex) 1582 { 1583 1585 if ( logger.isDebugEnabled()) 1586 logger.debug("Error committing transaction", ex); 1587 } 1588 1589 1591 Thread.yield(); 1592 1593 } } 1595 catch (SocketException ex) 1596 { 1597 1598 1600 logger.error("Socket closed by remote client"); 1601 } 1602 catch (Exception ex) 1603 { 1604 1605 1607 if (isShutdown() == false) 1608 logger.error("Closing session due to exception", ex); 1609 } 1610 catch (Throwable ex) 1611 { 1612 logger.error("Closing session due to throwable", ex); 1613 } 1614 finally 1615 { 1616 1618 if ( hasUserTransaction()) 1619 { 1620 try 1621 { 1622 getUserTransaction().rollback(); 1623 } 1624 catch (Exception ex) 1625 { 1626 logger.warn("Failed to rollback transaction", ex); 1627 } 1628 } 1629 } 1630 1631 1633 cleanupSession(); 1634 1635 1637 if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) 1638 logger.debug("Server session closed"); 1639 1640 1642 closeSocket(); 1643 1644 1646 getSMBServer().sessionClosed(this); 1647 } 1648 1649 1652 protected final void runHandler() throws IOException , SMBSrvException, TooManyConnectionsException 1653 { 1654 1655 1657 if (m_rxlen < NetBIOSPacket.MIN_RXLEN) 1658 return; 1659 1660 1662 if (logger.isDebugEnabled() && hasDebug(DBG_PKTTYPE)) 1663 logger.debug("Rx packet type - " + m_smbPkt.getPacketTypeString() + ", SID=" + m_smbPkt.getSID()); 1664 1665 1667 if (m_handler.runProtocol() == false) 1668 { 1669 1670 1673 sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); 1674 } 1675 1676 1678 while (hasAsynchResponse()) 1679 { 1680 1681 1683 SMBSrvPacket asynchPkt = removeFirstAsynchResponse(); 1684 sendResponseSMB(asynchPkt, asynchPkt.getLength()); 1685 1686 1688 if (logger.isDebugEnabled() && hasDebug(DBG_NOTIFY)) 1689 logger.debug("Sent queued asynch response type=" + asynchPkt.getPacketTypeString() + ", mid=" 1690 + asynchPkt.getMultiplexId() + ", pid=" + asynchPkt.getProcessId()); 1691 } 1692 } 1693 1694 1700 public final void sendResponseSMB(SMBSrvPacket pkt) throws IOException 1701 { 1702 sendResponseSMB(pkt, pkt.getLength()); 1703 } 1704 1705 1712 public synchronized final void sendResponseSMB(SMBSrvPacket pkt, int len) throws IOException 1713 { 1714 1715 1717 if (pkt.isResponse() == false) 1718 pkt.setFlags(pkt.getFlags() + SMBSrvPacket.FLG_RESPONSE); 1719 1720 1722 pkt.setFlags(pkt.getFlags() | getDefaultFlags()); 1723 1724 1726 int flags2 = pkt.getFlags2() | getDefaultFlags2(); 1727 flags2 &= ~(SMBPacket.FLG2_EXTENDEDATTRIB + SMBPacket.FLG2_EXTENDNEGOTIATE + SMBPacket.FLG2_DFSRESOLVE + SMBPacket.FLG2_SECURITYSIGS); 1728 1729 pkt.setFlags2(flags2); 1730 1731 1733 m_pktHandler.writePacket(pkt, len); 1734 m_pktHandler.flushPacket(); 1735 } 1736 1737 1742 public final void sendSuccessResponseSMB() throws IOException 1743 { 1744 1745 1747 if (m_smbPkt.isResponse() == false) 1748 m_smbPkt.setFlags(m_smbPkt.getFlags() + SMBSrvPacket.FLG_RESPONSE); 1749 1750 1752 m_smbPkt.setFlags(m_smbPkt.getFlags() | getDefaultFlags()); 1753 m_smbPkt.setFlags2(m_smbPkt.getFlags2() | getDefaultFlags2()); 1754 1755 1757 m_smbPkt.setParameterCount(0); 1758 m_smbPkt.setByteCount(0); 1759 1760 if (m_smbPkt.isLongErrorCode()) 1761 m_smbPkt.setLongErrorCode(SMBStatus.NTSuccess); 1762 else 1763 { 1764 m_smbPkt.setErrorClass(SMBStatus.Success); 1765 m_smbPkt.setErrorCode(SMBStatus.Success); 1766 } 1767 1768 1770 sendResponseSMB(m_smbPkt, m_smbPkt.getLength()); 1771 } 1772 1773 1781 public final void sendErrorResponseSMB(int ntCode, int stdCode, int stdClass) throws java.io.IOException 1782 { 1783 1784 1786 if (m_smbPkt.isLongErrorCode()) 1787 { 1788 1789 1791 sendErrorResponseSMB(ntCode, SMBStatus.NTErr); 1792 } 1793 else 1794 { 1795 1796 1798 sendErrorResponseSMB(stdCode, stdClass); 1799 } 1800 } 1801 1802 1808 public final void sendErrorResponseSMB(int errCode, int errClass) throws java.io.IOException 1809 { 1810 1811 1813 if (m_smbPkt.isResponse() == false) 1814 m_smbPkt.setFlags(m_smbPkt.getFlags() + SMBSrvPacket.FLG_RESPONSE); 1815 1816 1818 m_smbPkt.setParameterCount(0); 1819 m_smbPkt.setByteCount(0); 1820 1821 1823 m_smbPkt.setFlags(m_smbPkt.getFlags() | getDefaultFlags()); 1824 m_smbPkt.setFlags2(m_smbPkt.getFlags2() | getDefaultFlags2()); 1825 1826 1828 if (errClass == SMBStatus.NTErr) 1829 { 1830 1831 1833 if (m_smbPkt.isLongErrorCode() == false) 1834 m_smbPkt.setFlags2(m_smbPkt.getFlags2() + SMBSrvPacket.FLG2_LONGERRORCODE); 1835 1836 1838 m_smbPkt.setLongErrorCode(errCode); 1839 } 1840 else 1841 { 1842 1843 1845 if (m_smbPkt.isLongErrorCode() == true) 1846 m_smbPkt.setFlags2(m_smbPkt.getFlags2() - SMBSrvPacket.FLG2_LONGERRORCODE); 1847 1848 1850 m_smbPkt.setErrorCode(errCode); 1851 m_smbPkt.setErrorClass(errClass); 1852 } 1853 1854 1856 sendResponseSMB(m_smbPkt, m_smbPkt.getLength()); 1857 1858 1860 if (logger.isDebugEnabled() && hasDebug(DBG_ERROR)) 1861 logger.debug("Error : Cmd = " + m_smbPkt.getPacketTypeString() + " - " 1862 + SMBErrorText.ErrorString(errClass, errCode)); 1863 } 1864 1865 1873 public final boolean sendAsynchResponseSMB(SMBSrvPacket pkt, int len) throws IOException 1874 { 1875 1876 1878 boolean sts = false; 1879 1880 if (m_rxlen == -1 && m_pktHandler.availableBytes() == 0) 1881 { 1882 1883 1885 sendResponseSMB(pkt, len); 1886 m_pktHandler.flushPacket(); 1887 1888 1890 sts = true; 1891 } 1892 else 1893 { 1894 1895 1897 queueAsynchResponseSMB(pkt); 1898 } 1899 1900 1902 return sts; 1903 } 1904 1905 1910 protected final synchronized void queueAsynchResponseSMB(SMBSrvPacket pkt) 1911 { 1912 1913 1915 if (m_asynchQueue == null) 1916 { 1917 1918 1920 m_asynchQueue = new Vector <SMBSrvPacket>(); 1921 } 1922 1923 1925 m_asynchQueue.addElement(pkt); 1926 } 1927 1928 1933 protected final synchronized boolean hasAsynchResponse() 1934 { 1935 1936 1938 if (m_asynchQueue != null && m_asynchQueue.size() > 0) 1939 return true; 1940 return false; 1941 } 1942 1943 1948 protected final synchronized SMBSrvPacket removeFirstAsynchResponse() 1949 { 1950 1951 1953 if (m_asynchQueue == null || m_asynchQueue.size() == 0) 1954 return null; 1955 1956 1958 return m_asynchQueue.remove(0); 1959 } 1960 1961 1970 public final NotifyRequest findNotifyRequest(int mid, int tid, int uid, int pid) 1971 { 1972 1973 1975 if (m_notifyList == null) 1976 return null; 1977 1978 1980 return m_notifyList.findRequest(mid, tid, uid, pid); 1981 } 1982 1983 1991 public final NotifyRequest findNotifyRequest(NetworkFile dir, int filter, boolean watchTree) 1992 { 1993 1994 1996 if (m_notifyList == null) 1997 return null; 1998 1999 2001 return m_notifyList.findRequest(dir, filter, watchTree); 2002 } 2003 2004 2010 public final void addNotifyRequest(NotifyRequest req, DiskDeviceContext ctx) 2011 { 2012 2013 2015 if (m_notifyList == null) 2016 m_notifyList = new NotifyRequestList(); 2017 2018 2020 m_notifyList.addRequest(req); 2021 ctx.addNotifyRequest(req); 2022 } 2023 2024 2029 public final void removeNotifyRequest(NotifyRequest req) 2030 { 2031 2032 2034 if (m_notifyList == null) 2035 return; 2036 2037 2039 m_notifyList.removeRequest(req); 2040 if (req.getDiskContext() != null) 2041 req.getDiskContext().removeNotifyRequest(req); 2042 } 2043 2044 2049 protected final boolean hasTransaction() 2050 { 2051 return m_transact != null ? true : false; 2052 } 2053 2054 2059 protected final SrvTransactBuffer getTransaction() 2060 { 2061 return m_transact; 2062 } 2063 2064 2069 protected final void setTransaction(SrvTransactBuffer buf) 2070 { 2071 m_transact = buf; 2072 } 2073} | Popular Tags |