/** * Process an NT create andX request * * @param sess SMBSrvSession * @param smbPkt SMBSrvPacket * @exception IOException * @exception SMBSrvException */ protected static void procNTCreateAndX(SMBSrvSession sess, SMBSrvPacket smbPkt) throws IOException, SMBSrvException { // Get the tree id from the received packet and validate that it is a valid // connection id. TreeConnection conn = sess.findTreeConnection(smbPkt); if (conn == null) { sess.sendErrorResponseSMB(smbPkt, SMBStatus.NTInvalidParameter, SMBStatus.NTErr); return; } // Extract the NT create andX parameters NTParameterPacker prms = new NTParameterPacker(smbPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 5); int nameLen = prms.unpackWord(); int flags = prms.unpackInt(); int rootFID = prms.unpackInt(); int accessMask = prms.unpackInt(); long allocSize = prms.unpackLong(); int attrib = prms.unpackInt(); int shrAccess = prms.unpackInt(); int createDisp = prms.unpackInt(); int createOptn = prms.unpackInt(); int impersonLev = prms.unpackInt(); int secFlags = prms.unpackByte(); // Extract the filename string int pos = DataPacker.wordAlign(smbPkt.getByteOffset()); String fileName = DataPacker.getUnicodeString(smbPkt.getBuffer(), pos, nameLen); if (fileName == null) { sess.sendErrorResponseSMB(smbPkt, SMBStatus.NTInvalidParameter, SMBStatus.NTErr); return; } // Debug if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC)) sess.debugPrintln( "NT Create AndX [" + smbPkt.getTreeId() + "] name=" + fileName + ", flags=0x" + Integer.toHexString(flags) + ", attr=0x" + Integer.toHexString(attrib) + ", allocSize=" + allocSize); // Check if the pipe name is a short or long name if (fileName.startsWith("\\PIPE") == false) fileName = "\\PIPE" + fileName; // Check if the requested IPC$ file is valid int pipeType = DCEPipeType.getNameAsType(fileName); if (pipeType == -1) { sess.sendErrorResponseSMB(smbPkt, SMBStatus.NTObjectNotFound, SMBStatus.NTErr); return; } // Check if there is a handler for the pipe file if (DCEPipeHandler.getHandlerForType(pipeType) == null) { sess.sendErrorResponseSMB(smbPkt, SMBStatus.NTAccessDenied, SMBStatus.NTErr); return; } // Create a network file for the special pipe DCEPipeFile pipeFile = new DCEPipeFile(pipeType); pipeFile.setGrantedAccess(NetworkFile.READWRITE); // Add the file to the list of open files for this tree connection int fid = -1; try { fid = conn.addFile(pipeFile, sess); } catch (TooManyFilesException ex) { // Too many files are open on this connection, cannot open any more files. sess.sendErrorResponseSMB(smbPkt, SMBStatus.Win32InvalidHandle, SMBStatus.NTErr); return; } // Build the NT create andX response boolean extendedResponse = (flags & WinNT.ExtendedResponse) != 0; smbPkt.setParameterCount(extendedResponse ? 42 : 34); prms.reset(smbPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 4); prms.packByte(0); prms.packWord(fid); prms.packInt(0x0001); // File existed and was opened prms.packLong(0); // Creation time prms.packLong(0); // Last access time prms.packLong(0); // Last write time prms.packLong(0); // Change time prms.packInt(0x0080); // File attributes prms.packLong(4096); // Allocation size prms.packLong(0); // End of file prms.packWord(2); // File type - named pipe, message mode prms.packByte(0xFF); // Pipe instancing count prms.packByte(0x05); // IPC state bits prms.packByte(0); // directory flag // Pack the extra extended response area, if requested if (extendedResponse == true) { // 22 byte block of zeroes prms.packLong(0); prms.packLong(0); prms.packInt(0); prms.packWord(0); // Pack the permissions prms.packInt(0x1F01FF); // 6 byte block of zeroes prms.packInt(0); prms.packWord(0); } smbPkt.setByteCount(0); smbPkt.setAndXCommand(0xFF); smbPkt.setParameter(1, smbPkt.getLength()); // AndX offset // Send the response packet sess.sendResponseSMB(smbPkt); }
/** * Process a special IPC$ file open request. * * @param sess SMBSrvSession * @param smbPkt SMBSrvPacket * @exception IOException * @exception SMBSrvException */ protected static void procIPCFileOpen(SMBSrvSession sess, SMBSrvPacket smbPkt) throws IOException, SMBSrvException { // Get the data bytes position and length int dataPos = smbPkt.getByteOffset(); int dataLen = smbPkt.getByteCount(); byte[] buf = smbPkt.getBuffer(); // Extract the filename string String fileName = DataPacker.getString(buf, dataPos, dataLen); // Debug if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC)) sess.debugPrintln("IPC$ Open file = " + fileName); // Check if the requested IPC$ file is valid int pipeType = DCEPipeType.getNameAsType(fileName); if (pipeType == -1) { sess.sendErrorResponseSMB(smbPkt, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); return; } // Get the tree connection details TreeConnection conn = sess.findTreeConnection(smbPkt); if (conn == null) { sess.sendErrorResponseSMB(smbPkt, SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); return; } // Create a network file for the special pipe DCEPipeFile pipeFile = new DCEPipeFile(pipeType); pipeFile.setGrantedAccess(NetworkFile.READWRITE); // Add the file to the list of open files for this tree connection int fid = -1; try { fid = conn.addFile(pipeFile, sess); } catch (TooManyFilesException ex) { // Too many files are open on this connection, cannot open any more files. sess.sendErrorResponseSMB(smbPkt, SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); return; } // Build the open file response smbPkt.setParameterCount(15); smbPkt.setAndXCommand(0xFF); smbPkt.setParameter(1, 0); // AndX offset smbPkt.setParameter(2, fid); smbPkt.setParameter(3, 0); // file attributes smbPkt.setParameter(4, 0); // last write time smbPkt.setParameter(5, 0); // last write date smbPkt.setParameterLong(6, 0); // file size smbPkt.setParameter(8, 0); smbPkt.setParameter(9, 0); smbPkt.setParameter(10, 0); // named pipe state smbPkt.setParameter(11, 0); smbPkt.setParameter(12, 0); // server FID (long) smbPkt.setParameter(13, 0); smbPkt.setParameter(14, 0); smbPkt.setByteCount(0); // Send the response packet sess.sendResponseSMB(smbPkt); }