mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-16 17:55:15 +00:00
6500: Office 2003 Add-ins: Fix for AWC-1505 6501: Fix for AWC-1361 6502: Fixes for locking issues regrading expired content 6503: Fix for AR-1615 6504: WCM-444, WCM-288, WCM-735, WCM-480 6505: WCM-498 wasn't fully fixed 6506: Fix for AWC-1462 6507: Fix for WCM-741 (link validation report for staging sandbox can get stuck) 6508: AR-1650: WS Unit tests fail 6509: Fix for WCM-751 which also solves WCM-570 - also fixed issue to allow deletion of any "broken" webprojects created due to either of those bugs. 6510: Fix for WCM-546 (workflow history panel should be expanded by default) 6511: Fix AWC-1128 6512: Fixes to several to a couple of bugs found under concurrent load. 6513: Build fix for test using an invalid noderef (now stripped out as it does not exist) 6514: Add support for the QueryFile transact request to the IPC$ named pipe handler. Fix for AR-1687. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6740 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
804 lines
25 KiB
Java
804 lines
25 KiB
Java
/*
|
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
* As a special exception to the terms and conditions of version 2.0 of
|
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
|
* FLOSS exception. You should have recieved a copy of the text describing
|
|
* the FLOSS exception, and it is also available here:
|
|
* http://www.alfresco.com/legal/licensing"
|
|
*/
|
|
package org.alfresco.filesys.smb.server;
|
|
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
|
|
import org.alfresco.filesys.server.filesys.FileInfo;
|
|
import org.alfresco.filesys.server.filesys.NetworkFile;
|
|
import org.alfresco.filesys.server.filesys.PathNotFoundException;
|
|
import org.alfresco.filesys.server.filesys.TooManyFilesException;
|
|
import org.alfresco.filesys.server.filesys.TreeConnection;
|
|
import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException;
|
|
import org.alfresco.filesys.smb.PacketType;
|
|
import org.alfresco.filesys.smb.SMBStatus;
|
|
import org.alfresco.filesys.smb.TransactionNames;
|
|
import org.alfresco.filesys.smb.dcerpc.DCEPipeType;
|
|
import org.alfresco.filesys.smb.dcerpc.server.DCEPipeFile;
|
|
import org.alfresco.filesys.smb.dcerpc.server.DCEPipeHandler;
|
|
import org.alfresco.filesys.util.DataBuffer;
|
|
import org.alfresco.filesys.util.DataPacker;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
/**
|
|
* <p>
|
|
* The IPCHandler class processes requests made on the IPC$ remote admin pipe. The code is shared
|
|
* amongst different SMB protocol handlers.
|
|
*/
|
|
class IPCHandler
|
|
{
|
|
|
|
// Debug logging
|
|
|
|
private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol");
|
|
|
|
/**
|
|
* Process a request made on the IPC$ remote admin named pipe.
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param outPkt SMBSrvPacket
|
|
* @exception java.io.IOException If an I/O error occurs
|
|
* @exception SMBSrvException If an SMB protocol error occurs
|
|
*/
|
|
public static void processIPCRequest(SMBSrvSession sess, SMBSrvPacket outPkt) throws java.io.IOException,
|
|
SMBSrvException
|
|
{
|
|
|
|
// Get the received packet from the session and verify that the connection is valid
|
|
|
|
SMBSrvPacket smbPkt = sess.getReceivePacket();
|
|
|
|
// 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(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ Request [" + smbPkt.getTreeId() + "] - cmd = " + smbPkt.getPacketTypeString());
|
|
|
|
// Determine the SMB command
|
|
|
|
switch (smbPkt.getCommand())
|
|
{
|
|
|
|
// Open file request
|
|
|
|
case PacketType.OpenAndX:
|
|
case PacketType.OpenFile:
|
|
procIPCFileOpen(sess, smbPkt, outPkt);
|
|
break;
|
|
|
|
// Read file request
|
|
|
|
case PacketType.ReadFile:
|
|
procIPCFileRead(sess, smbPkt, outPkt);
|
|
break;
|
|
|
|
// Read AndX file request
|
|
|
|
case PacketType.ReadAndX:
|
|
procIPCFileReadAndX(sess, smbPkt, outPkt);
|
|
break;
|
|
|
|
// Write file request
|
|
|
|
case PacketType.WriteFile:
|
|
procIPCFileWrite(sess, smbPkt, outPkt);
|
|
break;
|
|
|
|
// Write AndX file request
|
|
|
|
case PacketType.WriteAndX:
|
|
procIPCFileWriteAndX(sess, smbPkt, outPkt);
|
|
break;
|
|
|
|
// Close file request
|
|
|
|
case PacketType.CloseFile:
|
|
procIPCFileClose(sess, smbPkt, outPkt);
|
|
break;
|
|
|
|
// NT create andX request
|
|
|
|
case PacketType.NTCreateAndX:
|
|
procNTCreateAndX(sess, smbPkt, outPkt);
|
|
break;
|
|
|
|
// Default, respond with an unsupported function error.
|
|
|
|
default:
|
|
sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process an IPC$ transaction request.
|
|
*
|
|
* @param vc VirtualCircuit
|
|
* @param tbuf SrvTransactBuffer
|
|
* @param sess SMBSrvSession
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procTransaction(VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvSession sess, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ Transaction pipe=" + tbuf.getName() + ", subCmd="
|
|
+ NamedPipeTransaction.getSubCommand(tbuf.getFunction()));
|
|
|
|
// Call the required transaction handler
|
|
|
|
if (tbuf.getName().compareTo(TransactionNames.PipeLanman) == 0)
|
|
{
|
|
|
|
// Call the \PIPE\LANMAN transaction handler to process the request
|
|
|
|
if (PipeLanmanHandler.processRequest(tbuf, sess, outPkt))
|
|
return;
|
|
}
|
|
|
|
// Process the pipe command
|
|
|
|
switch (tbuf.getFunction())
|
|
{
|
|
|
|
// Set named pipe handle state
|
|
|
|
case NamedPipeTransaction.SetNmPHandState:
|
|
procSetNamedPipeHandleState(sess, vc, tbuf, outPkt);
|
|
break;
|
|
|
|
// Named pipe transation request, pass the request to the DCE/RPC handler
|
|
|
|
case NamedPipeTransaction.TransactNmPipe:
|
|
DCERPCHandler.processDCERPCRequest(sess, vc, tbuf, outPkt);
|
|
break;
|
|
|
|
// Query file information via handle
|
|
|
|
case PacketType.Trans2QueryFile:
|
|
procTrans2QueryFile(sess, vc, tbuf, outPkt);
|
|
break;
|
|
|
|
// Unknown command
|
|
|
|
default:
|
|
sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process a special IPC$ file open request.
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param rxPkt SMBSrvPacket
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procIPCFileOpen(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Get the data bytes position and length
|
|
|
|
int dataPos = rxPkt.getByteOffset();
|
|
int dataLen = rxPkt.getByteCount();
|
|
byte[] buf = rxPkt.getBuffer();
|
|
|
|
// Extract the filename string
|
|
|
|
String fileName = DataPacker.getString(buf, dataPos, dataLen);
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ Open file = " + fileName);
|
|
|
|
// Check if the requested IPC$ file is valid
|
|
|
|
int pipeType = DCEPipeType.getNameAsType(fileName);
|
|
if (pipeType == -1)
|
|
{
|
|
sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Get the tree connection details
|
|
|
|
TreeConnection conn = sess.findTreeConnection(rxPkt);
|
|
|
|
if (conn == null)
|
|
{
|
|
sess.sendErrorResponseSMB(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(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Build the open file response
|
|
|
|
outPkt.setParameterCount(15);
|
|
|
|
outPkt.setAndXCommand(0xFF);
|
|
outPkt.setParameter(1, 0); // AndX offset
|
|
|
|
outPkt.setParameter(2, fid);
|
|
outPkt.setParameter(3, 0); // file attributes
|
|
outPkt.setParameter(4, 0); // last write time
|
|
outPkt.setParameter(5, 0); // last write date
|
|
outPkt.setParameterLong(6, 0); // file size
|
|
outPkt.setParameter(8, 0);
|
|
outPkt.setParameter(9, 0);
|
|
outPkt.setParameter(10, 0); // named pipe state
|
|
outPkt.setParameter(11, 0);
|
|
outPkt.setParameter(12, 0); // server FID (long)
|
|
outPkt.setParameter(13, 0);
|
|
outPkt.setParameter(14, 0);
|
|
|
|
outPkt.setByteCount(0);
|
|
|
|
// Send the response packet
|
|
|
|
sess.sendResponseSMB(outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process an IPC pipe file read request
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param rxPkt SMBSrvPacket
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procIPCFileRead(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Check if the received packet is a valid read file request
|
|
|
|
if (rxPkt.checkPacketIsValid(5, 0) == false)
|
|
{
|
|
|
|
// Invalid request
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ File Read");
|
|
|
|
// Pass the read request the DCE/RPC handler
|
|
|
|
DCERPCHandler.processDCERPCRead(sess, rxPkt, outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process an IPC pipe file read andX request
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param rxPkt SMBSrvPacket
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procIPCFileReadAndX(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Check if the received packet is a valid read andX file request
|
|
|
|
if (rxPkt.checkPacketIsValid(10, 0) == false)
|
|
{
|
|
|
|
// Invalid request
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ File Read AndX");
|
|
|
|
// Pass the read request the DCE/RPC handler
|
|
|
|
DCERPCHandler.processDCERPCRead(sess, rxPkt, outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process an IPC pipe file write request
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param rxPkt SMBSrvPacket
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procIPCFileWrite(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Check if the received packet is a valid write file request
|
|
|
|
if (rxPkt.checkPacketIsValid(5, 0) == false)
|
|
{
|
|
|
|
// Invalid request
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ File Write");
|
|
|
|
// Pass the write request the DCE/RPC handler
|
|
|
|
DCERPCHandler.processDCERPCRequest(sess, rxPkt, outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process an IPC pipe file write andX request
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param rxPkt SMBSrvPacket
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procIPCFileWriteAndX(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Check if the received packet is a valid write andX request
|
|
|
|
if (rxPkt.checkPacketIsValid(12, 0) == false)
|
|
{
|
|
|
|
// Invalid request
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ File Write AndX");
|
|
|
|
// Pass the write request the DCE/RPC handler
|
|
|
|
DCERPCHandler.processDCERPCRequest(sess, rxPkt, outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process a special IPC$ file close request.
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param rxPkt SMBSrvPacket
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procIPCFileClose(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Check that the received packet looks like a valid file close request
|
|
|
|
if (rxPkt.checkPacketIsValid(3, 0) == false)
|
|
{
|
|
sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
|
|
return;
|
|
}
|
|
|
|
// Get the tree id from the received packet and validate that it is a valid
|
|
// connection id.
|
|
|
|
TreeConnection conn = sess.findTreeConnection(rxPkt);
|
|
|
|
if (conn == null)
|
|
{
|
|
sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Get the file id from the request
|
|
|
|
int fid = rxPkt.getParameter(0);
|
|
DCEPipeFile netFile = (DCEPipeFile) conn.findFile(fid);
|
|
|
|
if (netFile == null)
|
|
{
|
|
sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ File close [" + rxPkt.getTreeId() + "] fid=" + fid);
|
|
|
|
// Remove the file from the connections list of open files
|
|
|
|
conn.removeFile(fid, sess);
|
|
|
|
// Build the close file response
|
|
|
|
outPkt.setParameterCount(0);
|
|
outPkt.setByteCount(0);
|
|
|
|
// Send the response packet
|
|
|
|
sess.sendResponseSMB(outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process a set named pipe handle state request
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param vc VirtualCircuit
|
|
* @param tbuf SrvTransactBuffer
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procSetNamedPipeHandleState(SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Get the request parameters
|
|
|
|
DataBuffer setupBuf = tbuf.getSetupBuffer();
|
|
setupBuf.skipBytes(2);
|
|
int fid = setupBuf.getShort();
|
|
|
|
DataBuffer paramBuf = tbuf.getParameterBuffer();
|
|
int state = paramBuf.getShort();
|
|
|
|
// Get the connection for the request
|
|
|
|
TreeConnection conn = vc.findConnection(tbuf.getTreeId());
|
|
|
|
// Get the IPC pipe file for the specified file id
|
|
|
|
DCEPipeFile netFile = (DCEPipeFile) conn.findFile(fid);
|
|
if (netFile == null)
|
|
{
|
|
sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug(" SetNmPHandState pipe=" + netFile.getName() + ", fid=" + fid + ", state=0x"
|
|
+ Integer.toHexString(state));
|
|
|
|
// Store the named pipe state
|
|
|
|
netFile.setPipeState(state);
|
|
|
|
// Setup the response packet
|
|
|
|
SMBSrvTransPacket.initTransactReply(outPkt, 0, 0, 0, 0);
|
|
|
|
// Send the response packet
|
|
|
|
sess.sendResponseSMB(outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process an NT create andX request
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param rxPkt SMBSrvPacket
|
|
* @param outPkt SMBSrvPacket
|
|
*/
|
|
protected static void procNTCreateAndX(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt)
|
|
throws IOException, SMBSrvException
|
|
{
|
|
|
|
// Get the tree id from the received packet and validate that it is a valid
|
|
// connection id.
|
|
|
|
TreeConnection conn = sess.findTreeConnection(rxPkt);
|
|
|
|
if (conn == null)
|
|
{
|
|
sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr);
|
|
return;
|
|
}
|
|
|
|
// Extract the NT create andX parameters
|
|
|
|
NTParameterPacker prms = new NTParameterPacker(rxPkt.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(rxPkt.getByteOffset());
|
|
String fileName = DataPacker.getUnicodeString(rxPkt.getBuffer(), pos, nameLen);
|
|
if (fileName == null)
|
|
{
|
|
sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("NT Create AndX [" + rxPkt.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(SMBStatus.NTObjectNotFound, SMBStatus.NTErr);
|
|
return;
|
|
}
|
|
|
|
// Check if there is a handler for the pipe file
|
|
|
|
if (DCEPipeHandler.getHandlerForType(pipeType) == null)
|
|
{
|
|
sess.sendErrorResponseSMB(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(SMBStatus.Win32InvalidHandle, SMBStatus.NTErr);
|
|
return;
|
|
}
|
|
|
|
// Build the NT create andX response
|
|
|
|
outPkt.setParameterCount(34);
|
|
|
|
prms.reset(outPkt.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
|
|
|
|
outPkt.setByteCount(0);
|
|
|
|
outPkt.setAndXCommand(0xFF);
|
|
outPkt.setParameter(1, outPkt.getLength()); // AndX offset
|
|
|
|
// Send the response packet
|
|
|
|
sess.sendResponseSMB(outPkt);
|
|
}
|
|
|
|
/**
|
|
* Process a transact2 query file information (via handle) request.
|
|
*
|
|
* @param sess SMBSrvSession
|
|
* @param vc VirtualCircuit
|
|
* @param tbuf Transaction request details
|
|
* @param outPkt SMBSrvPacket
|
|
* @exception java.io.IOException The exception description.
|
|
* @exception org.alfresco.aifs.smb.SMBSrvException SMB protocol exception
|
|
*/
|
|
protected static final void procTrans2QueryFile(SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket outPkt)
|
|
throws java.io.IOException, SMBSrvException {
|
|
|
|
// Get the tree connection details
|
|
|
|
int treeId = tbuf.getTreeId();
|
|
TreeConnection conn = vc.findConnection(treeId);
|
|
|
|
if (conn == null) {
|
|
sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Check if the user has the required access permission
|
|
|
|
if (conn.hasReadAccess() == false) {
|
|
|
|
// User does not have the required access rights
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Get the file id and query path information level
|
|
|
|
DataBuffer paramBuf = tbuf.getParameterBuffer();
|
|
|
|
int fid = paramBuf.getShort();
|
|
int infoLevl = paramBuf.getShort();
|
|
|
|
// Get the file details via the file id
|
|
|
|
NetworkFile netFile = conn.findFile(fid);
|
|
|
|
if (netFile == null) {
|
|
sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
|
|
// Debug
|
|
|
|
if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC))
|
|
logger.debug("IPC$ Query File - level=0x" + Integer.toHexString(infoLevl) + ", fid=" + fid + ", name=" + netFile.getFullName());
|
|
|
|
// Access the shared device disk interface
|
|
|
|
try {
|
|
|
|
// Set the return parameter count, so that the data area position can be calculated.
|
|
|
|
outPkt.setParameterCount(10);
|
|
|
|
// Pack the file information into the data area of the transaction reply
|
|
|
|
byte[] buf = outPkt.getBuffer();
|
|
int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset());
|
|
int dataPos = prmPos + 4;
|
|
|
|
// Pack the return parametes, EA error offset
|
|
|
|
outPkt.setPosition(prmPos);
|
|
outPkt.packWord(0);
|
|
|
|
// Create a data buffer using the SMB packet. The response should always fit into a single
|
|
// reply packet.
|
|
|
|
DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos);
|
|
|
|
// Build the file information from the network file details
|
|
|
|
FileInfo fileInfo = new FileInfo(netFile.getName(), netFile.getFileSize(), netFile.getFileAttributes());
|
|
|
|
fileInfo.setAccessDateTime(netFile.getAccessDate());
|
|
fileInfo.setCreationDateTime(netFile.getCreationDate());
|
|
fileInfo.setModifyDateTime(netFile.getModifyDate());
|
|
fileInfo.setChangeDateTime(netFile.getModifyDate());
|
|
|
|
fileInfo.setFileId(netFile.getFileId());
|
|
|
|
// Pack the file information into the return data packet
|
|
|
|
int dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true);
|
|
|
|
// Check if any data was packed, if not then the information level is not supported
|
|
|
|
if (dataLen == 0) {
|
|
sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
|
|
return;
|
|
}
|
|
|
|
SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, dataLen, dataPos);
|
|
outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset());
|
|
|
|
// Send the transact reply
|
|
|
|
sess.sendResponseSMB(outPkt);
|
|
}
|
|
catch (FileNotFoundException ex) {
|
|
|
|
// Requested file does not exist
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
catch (PathNotFoundException ex) {
|
|
|
|
// Requested path does not exist
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
|
|
return;
|
|
}
|
|
catch (UnsupportedInfoLevelException ex) {
|
|
|
|
// Requested information level is not supported
|
|
|
|
sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
|
|
return;
|
|
}
|
|
}
|
|
} |