/**
   * Process a NetPrintQGetInfo transaction request.
   *
   * @param sess Server session that received the request.
   * @param tbuf Transaction buffer
   * @param prmDesc Parameter descriptor string.
   * @param dataDesc Data descriptor string.
   * @param tpkt Transaction reply packet
   * @return true if the transaction has been processed, else false.
   */
  protected static final boolean procNetPrintQGetInfo(
      SMBSrvSession sess,
      TransactBuffer tbuf,
      String prmDesc,
      String dataDesc,
      SMBSrvTransPacket tpkt)
      throws IOException, SMBSrvException {

    // Validate the parameter string

    if (prmDesc.compareTo("zWrLh") != 0)
      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // Unpack the share get information specific parameters

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    String shareName = paramBuf.getString(32, false);
    int infoLevel = paramBuf.getShort();
    int bufSize = paramBuf.getShort();

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("NetPrintQGetInfo - " + shareName + ", infoLevel=" + infoLevel);

    // We did not process the request

    return false;
  }
Example #2
0
  /**
   * Process an IPC$ transaction request.
   *
   * @param vc VirtualCircuit
   * @param tbuf SrvTransactBuffer
   * @param sess SMBSrvSession
   * @param smbPkt SMBSrvPacket
   */
  protected static void procTransaction(
      VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvSession sess, SMBSrvPacket smbPkt)
      throws IOException, SMBSrvException {

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln(
          "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, smbPkt)) return;
    }

    // Process the pipe command

    switch (tbuf.getFunction()) {

        // Set named pipe handle state

      case NamedPipeTransaction.SetNmPHandState:
        procSetNamedPipeHandleState(sess, vc, tbuf, smbPkt);
        break;

        // Named pipe transation request, pass the request to the DCE/RPC handler

      case NamedPipeTransaction.TransactNmPipe:
        DCERPCHandler.processDCERPCRequest(sess, vc, tbuf, smbPkt);
        break;

        // Query file information via handle

      case PacketType.Trans2QueryFile:
        procTrans2QueryFile(sess, vc, tbuf, smbPkt);
        break;

        // Unknown command

      default:
        sess.sendErrorResponseSMB(smbPkt, SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
        break;
    }
  }
Example #3
0
  /**
   * Process a set named pipe handle state request
   *
   * @param sess SMBSrvSession
   * @param vc VirtualCircuit
   * @param tbuf SrvTransactBuffer
   * @param smbPkt SMBSrvPacket
   */
  protected static void procSetNamedPipeHandleState(
      SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket smbPkt)
      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(smbPkt, SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
      return;
    }

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln(
          "  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(smbPkt, 0, 0, 0, 0);

    // Send the response packet

    sess.sendResponseSMB(smbPkt);
  }
Example #4
0
  /**
   * Process an IPC pipe file write andX request
   *
   * @param sess SMBSrvSession
   * @param smbPkt SMBSrvPacket
   * @exception IOException
   * @exception SMBSrvException
   */
  protected static void procIPCFileWriteAndX(SMBSrvSession sess, SMBSrvPacket smbPkt)
      throws IOException, SMBSrvException {

    // Check if the received packet is a valid write andX request

    if (smbPkt.checkPacketIsValid(12, 0) == false) {

      // Invalid request

      sess.sendErrorResponseSMB(smbPkt, SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
      return;
    }

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("IPC$ File Write AndX");

    // Pass the write request the DCE/RPC handler

    DCERPCHandler.processDCERPCRequest(sess, smbPkt);
  }
Example #5
0
  /**
   * Process a special IPC$ file close request.
   *
   * @param sess SMBSrvSession
   * @param smbPkt SMBSrvPacket
   * @exception IOException
   * @exception SMBSrvException
   */
  protected static void procIPCFileClose(SMBSrvSession sess, SMBSrvPacket smbPkt)
      throws IOException, SMBSrvException {

    // Check that the received packet looks like a valid file close request

    if (smbPkt.checkPacketIsValid(3, 0) == false) {
      sess.sendErrorResponseSMB(smbPkt, 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(smbPkt);

    if (conn == null) {
      sess.sendErrorResponseSMB(smbPkt, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
      return;
    }

    // Get the file id from the request

    int fid = smbPkt.getParameter(0);
    DCEPipeFile netFile = (DCEPipeFile) conn.findFile(fid);

    if (netFile == null) {
      sess.sendErrorResponseSMB(smbPkt, SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
      return;
    }

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("IPC$ File close [" + smbPkt.getTreeId() + "] fid=" + fid);

    // Remove the file from the connections list of open files

    conn.removeFile(fid, sess);

    // Build the close file response

    smbPkt.setParameterCount(0);
    smbPkt.setByteCount(0);

    // Send the response packet

    sess.sendResponseSMB(smbPkt);
  }
  /**
   * Process a \PIPE\LANMAN transaction request.
   *
   * @param tbuf Transaction setup, parameter and data buffers
   * @param sess SMB server session that received the transaction.
   * @param trans Packet to use for reply
   * @return true if the transaction has been handled, else false.
   * @exception java.io.IOException The exception description.
   * @exception org.alfresco.aifs.smb.SMBSrvException The exception description.
   */
  public static final boolean processRequest(
      TransactBuffer tbuf, SMBSrvSession sess, SMBSrvPacket trans)
      throws IOException, SMBSrvException {

    // Create a transaction packet

    SMBSrvTransPacket tpkt = new SMBSrvTransPacket(trans.getBuffer());

    // Get the transaction command code, parameter descriptor and data descriptor strings from
    // the parameter block.

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    int cmd = paramBuf.getShort();
    String prmDesc = paramBuf.getString(false);
    String dataDesc = paramBuf.getString(false);

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln(
          "\\PIPE\\LANMAN\\ transact request, cmd="
              + cmd
              + ", prm="
              + prmDesc
              + ", data="
              + dataDesc);

    // Call the required transaction handler

    boolean processed = false;

    switch (cmd) {

        // Share

      case PacketType.RAPShareEnum:
        processed = procNetShareEnum(sess, tbuf, prmDesc, dataDesc, tpkt);
        break;

        // Get share information

      case PacketType.RAPShareGetInfo:
        processed = procNetShareGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt);
        break;

        // Workstation information

      case PacketType.RAPWkstaGetInfo:
        processed = procNetWkstaGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt);
        break;

        // Server information

      case PacketType.RAPServerGetInfo:
        processed = procNetServerGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt);
        break;

        // Print queue information

      case PacketType.NetPrintQGetInfo:
        processed = procNetPrintQGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt);
        break;

        // No handler

      default:

        // Debug

        if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
          sess.debugPrintln(
              "No handler for \\PIPE\\LANMAN\\ request, cmd="
                  + cmd
                  + ", prm="
                  + prmDesc
                  + ", data="
                  + dataDesc);
        break;
    }

    // Check if the transaction packet has allocated an associated packet from the pool, we need to
    // copy the associated packet
    // to the outer request packet so that it is released back to the pool.

    if (tpkt.hasAssociatedPacket()) {

      Debug.println(
          "[SMB] PipeLanManHandler allocated associated packet, len="
              + tpkt.getAssociatedPacket().getBufferLength());

      // Copy the associated packet to the outer request packet

      trans.setAssociatedPacket(tpkt.getAssociatedPacket());
      tpkt.setAssociatedPacket(null);
    }

    // Return the transaction processed status

    return processed;
  }
  /**
   * Process a NetWkstaGetInfo transaction request.
   *
   * @param sess Server session that received the request.
   * @param tbuf Transaction buffer
   * @param prmDesc Parameter descriptor string.
   * @param dataDesc Data descriptor string.
   * @param tpkt Transaction reply packet
   * @return true if the transaction has been processed, else false.
   */
  protected static final boolean procNetWkstaGetInfo(
      SMBSrvSession sess,
      TransactBuffer tbuf,
      String prmDesc,
      String dataDesc,
      SMBSrvTransPacket tpkt)
      throws IOException, SMBSrvException {

    // Validate the parameter string

    if (prmDesc.compareTo("WrLh") != 0)
      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // Unpack the share get information specific parameters

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    int infoLevel = paramBuf.getShort();
    int bufSize = paramBuf.getShort();

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("NetWkstaGetInfo infoLevel=" + infoLevel);

    // Check if the information level requested and data descriptor string match

    if ((infoLevel == 1 && dataDesc.compareTo("zzzBBzzz") == 0)
        || (infoLevel == 10 && dataDesc.compareTo("zzzBBzz") == 0)) {

      // Create the transaction reply data buffer

      TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, 1024);

      // Pack the data block, calculate the size of the fixed data block

      DataBuffer dataBuf = replyBuf.getDataBuffer();
      int strPos = SMBSrvTransPacket.CalculateDataItemSize(dataDesc);

      // Pack the server name

      dataBuf.putStringPointer(strPos);
      strPos = dataBuf.putStringAt(sess.getServerName(), strPos, false, true);

      // Pack the user name

      dataBuf.putStringPointer(strPos);
      strPos = dataBuf.putStringAt("", strPos, false, true);

      // Pack the domain name

      dataBuf.putStringPointer(strPos);

      String domain = sess.getSMBServer().getCIFSConfiguration().getDomainName();
      if (domain == null) domain = "";
      strPos = dataBuf.putStringAt(domain, strPos, false, true);

      // Pack the major/minor version number

      dataBuf.putByte(4);
      dataBuf.putByte(2);

      // Pack the logon domain

      dataBuf.putStringPointer(strPos);
      strPos = dataBuf.putStringAt("", strPos, false, true);

      // Check if the other domains should be packed

      if (infoLevel == 1 && dataDesc.compareTo("zzzBBzzz") == 0) {

        // Pack the other domains

        dataBuf.putStringPointer(strPos);
        strPos = dataBuf.putStringAt("", strPos, false, true);
      }

      // Set the data block length

      dataBuf.setLength(strPos);

      // Pack the parameter block

      paramBuf = replyBuf.getParameterBuffer();

      paramBuf.putShort(0); // status code
      paramBuf.putShort(0); // converter for strings
      paramBuf.putShort(dataBuf.getLength());
      paramBuf.putShort(0); // number of entries

      // Send the transaction response

      tpkt.doTransactionResponse(sess, replyBuf);
    } else {

      // Debug

      if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
        sess.debugPrintln(
            "NetWkstaGetInfo UNSUPPORTED infoLevel=" + infoLevel + ", dataDesc=" + dataDesc);

      // Unsupported request

      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);
    }

    // We processed the request

    return true;
  }
  /**
   * Process a NetShareGetInfo transaction request.
   *
   * @param sess Server session that received the request.
   * @param tbuf Transaction buffer
   * @param prmDesc Parameter descriptor string.
   * @param dataDesc Data descriptor string.
   * @param tpkt Transaction reply packet
   * @return true if the transaction has been processed, else false.
   */
  protected static final boolean procNetShareGetInfo(
      SMBSrvSession sess,
      TransactBuffer tbuf,
      String prmDesc,
      String dataDesc,
      SMBSrvTransPacket tpkt)
      throws IOException, SMBSrvException {

    // Validate the parameter string

    if (prmDesc.compareTo("zWrLh") != 0)
      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // Unpack the share get information specific parameters

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    String shareName = paramBuf.getString(32, false);
    int infoLevel = paramBuf.getShort();
    int bufSize = paramBuf.getShort();

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("NetShareGetInfo - " + shareName + ", infoLevel=" + infoLevel);

    // Check if the information level requested and data descriptor string match

    if (infoLevel == 1 && dataDesc.compareTo("B13BWz") == 0) {

      // Find the required share information

      SharedDevice share = null;

      try {

        // Get the shared device details

        share = sess.getSMBServer().findShare(null, shareName, ShareType.UNKNOWN, sess, false);
      } catch (Exception ex) {
      }

      if (share == null) {
        sess.sendErrorResponseSMB(tpkt, SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);
        return true;
      }

      // Create the transaction reply data buffer

      TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, 1024);

      // Pack the parameter block

      paramBuf = replyBuf.getParameterBuffer();

      paramBuf.putShort(0); // status code
      paramBuf.putShort(0); // converter for strings
      paramBuf.putShort(1); // number of entries

      // Pack the data block, calculate the size of the fixed data block

      DataBuffer dataBuf = replyBuf.getDataBuffer();
      int strPos = SMBSrvTransPacket.CalculateDataItemSize("B13BWz");

      // Pack the share name

      dataBuf.putStringPointer(strPos);
      strPos = dataBuf.putFixedStringAt(share.getName(), 13, strPos);

      // Pack unknown byte, alignment ?

      dataBuf.putByte(0);

      // Pack the share type flags

      dataBuf.putShort(share.getType());

      // Pack the share comment

      dataBuf.putStringPointer(strPos);

      if (share.getComment() != null)
        strPos = dataBuf.putStringAt(share.getComment(), strPos, false, true);
      else strPos = dataBuf.putStringAt("", strPos, false, true);

      // Set the data block length

      dataBuf.setLength(strPos);

      // Send the transaction response

      tpkt.doTransactionResponse(sess, replyBuf);
    } else {

      // Debug

      if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
        sess.debugPrintln(
            "NetShareGetInfo - UNSUPPORTED "
                + shareName
                + ", infoLevel="
                + infoLevel
                + ", dataDesc="
                + dataDesc);

      // Server error

      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);
    }

    // We processed the request

    return true;
  }
  /**
   * Process a NetShareEnum transaction request.
   *
   * @param sess Server session that received the request.
   * @param tbuf Transaction buffer
   * @param prmDesc Parameter descriptor string.
   * @param dataDesc Data descriptor string.
   * @param tpkt Transaction reply packet
   * @return true if the transaction has been processed, else false.
   */
  protected static final boolean procNetShareEnum(
      SMBSrvSession sess,
      TransactBuffer tbuf,
      String prmDesc,
      String dataDesc,
      SMBSrvTransPacket tpkt)
      throws IOException, SMBSrvException {

    // Validate the parameter string

    if (prmDesc.compareTo("WrLeh") != 0)
      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // Unpack the server get information specific parameters

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    int infoLevel = paramBuf.getShort();
    int bufSize = paramBuf.getShort();

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("NetShareEnum infoLevel=" + infoLevel);

    // Check if the information level requested and data descriptor string match

    if (infoLevel == 1 && dataDesc.compareTo("B13BWz") == 0) {

      // Get the share list from the server

      SharedDeviceList shrList = sess.getSMBServer().getShareList(null, sess);
      int shrCount = 0;
      int strPos = 0;

      if (shrList != null) {

        // Calculate the fixed data length

        shrCount = shrList.numberOfShares();
        strPos = SMBSrvTransPacket.CalculateDataItemSize("B13BWz") * shrCount;
      }

      // Create the transaction reply data buffer

      TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, bufSize);

      // Pack the parameter block

      paramBuf = replyBuf.getParameterBuffer();

      paramBuf.putShort(0); // status code
      paramBuf.putShort(0); // converter for strings
      paramBuf.putShort(shrCount); // number of entries
      paramBuf.putShort(shrCount); // total number of entries

      // Pack the data block

      DataBuffer dataBuf = replyBuf.getDataBuffer();
      Enumeration<SharedDevice> enm = shrList.enumerateShares();

      while (enm.hasMoreElements()) {

        // Get the current share

        SharedDevice shrDev = enm.nextElement();

        // Pack the share name, share type and comment pointer

        dataBuf.putFixedString(shrDev.getName(), 13);
        dataBuf.putByte(0);
        dataBuf.putShort(ShareType.asShareInfoType(shrDev.getType()));
        dataBuf.putStringPointer(strPos);

        if (shrDev.getComment() != null)
          strPos = dataBuf.putStringAt(shrDev.getComment(), strPos, false, true);
        else strPos = dataBuf.putStringAt("", strPos, false, true);
      }

      // Set the data block length

      dataBuf.setLength(strPos);

      // Send the transaction response

      tpkt.doTransactionResponse(sess, replyBuf);
    } else throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // We processed the request

    return true;
  }
  /**
   * Process a NetServerGetInfo transaction request.
   *
   * @param sess Server session that received the request.
   * @param tbuf Transaction buffer
   * @param prmDesc Parameter descriptor string.
   * @param dataDesc Data descriptor string.
   * @param tpkt Transaction reply packet
   * @return true if the transaction has been processed, else false.
   */
  protected static final boolean procNetServerGetInfo(
      SMBSrvSession sess,
      TransactBuffer tbuf,
      String prmDesc,
      String dataDesc,
      SMBSrvTransPacket tpkt)
      throws IOException, SMBSrvException {

    // Validate the parameter string

    if (prmDesc.compareTo("WrLh") != 0)
      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // Unpack the server get information specific parameters

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    int infoLevel = paramBuf.getShort();
    int bufSize = paramBuf.getShort();

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("NetServerGetInfo infoLevel=" + infoLevel);

    // Check if the information level requested and data descriptor string match

    if (infoLevel == 1 && dataDesc.compareTo("B16BBDz") == 0) {

      // Create the transaction reply data buffer

      TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, 1024);

      // Pack the parameter block

      paramBuf = replyBuf.getParameterBuffer();

      paramBuf.putShort(0); // status code
      paramBuf.putShort(0); // converter for strings
      paramBuf.putShort(1); // number of entries

      // Pack the data block, calculate the size of the fixed data block

      DataBuffer dataBuf = replyBuf.getDataBuffer();
      int strPos = SMBSrvTransPacket.CalculateDataItemSize("B16BBDz");

      // Pack the server name pointer and string

      dataBuf.putStringPointer(strPos);
      strPos = dataBuf.putFixedStringAt(sess.getServerName(), 16, strPos);

      // Pack the major/minor version

      dataBuf.putByte(1);
      dataBuf.putByte(0);

      // Pack the server capability flags

      dataBuf.putInt(sess.getSMBServer().getServerType());

      // Pack the server comment string

      String srvComment = sess.getSMBServer().getComment();
      if (srvComment == null) srvComment = "";

      dataBuf.putStringPointer(strPos);
      strPos = dataBuf.putStringAt(srvComment, strPos, false, true);

      // Set the data block length

      dataBuf.setLength(strPos);

      // Send the transaction response

      tpkt.doTransactionResponse(sess, replyBuf);
    } else throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // We processed the request

    return true;
  }
Example #11
0
  /**
   * Process a transact2 query file information (via handle) request.
   *
   * @param sess SMBSrvSession
   * @param vc VirtualCircuit
   * @param tbuf Transaction request details
   * @param smbPkt SMBSrvPacket
   * @exception IOException
   * @exception SMBSrvException
   */
  protected static final void procTrans2QueryFile(
      SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket smbPkt)
      throws IOException, SMBSrvException {

    // Get the tree connection details

    int treeId = tbuf.getTreeId();
    TreeConnection conn = vc.findConnection(treeId);

    if (conn == null) {
      sess.sendErrorResponseSMB(
          smbPkt, 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(
          smbPkt, 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(smbPkt, SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
      return;
    }

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln(
          "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.

      smbPkt.setParameterCount(10);

      // Pack the file information into the data area of the transaction reply

      byte[] buf = smbPkt.getBuffer();
      int prmPos = DataPacker.longwordAlign(smbPkt.getByteOffset());
      int dataPos = prmPos + 4;

      // Pack the return parametes, EA error offset

      smbPkt.setPosition(prmPos);
      smbPkt.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());

      // Set the file allocation size, looks like it is used as the pipe buffer size

      fileInfo.setAllocationSize(4096L);

      // 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(
            smbPkt, SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
        return;
      }

      SMBSrvTransPacket.initTransactReply(smbPkt, 2, prmPos, dataLen, dataPos);
      smbPkt.setByteCount(replyBuf.getPosition() - smbPkt.getByteOffset());

      // Send the transact reply

      sess.sendResponseSMB(smbPkt);
    } catch (FileNotFoundException ex) {

      // Requested file does not exist

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
      return;
    } catch (PathNotFoundException ex) {

      // Requested path does not exist

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
      return;
    } catch (UnsupportedInfoLevelException ex) {

      // Requested information level is not supported

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
      return;
    } catch (DiskOfflineException ex) {

      // Filesystem is offline

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTObjectPathNotFound, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd);
    }
  }
Example #12
0
  /**
   * Process a request made on the IPC$ remote admin named pipe.
   *
   * @param sess SMBSrvSession
   * @param smbPkt SMBSrvPacket
   * @exception IOException
   * @exception SMBSrvException
   */
  public static void processIPCRequest(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.DOSInvalidDrive, SMBStatus.ErrDos);
      return;
    }

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln(
          "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);
        break;

        // Read file request

      case PacketType.ReadFile:
        procIPCFileRead(sess, smbPkt);
        break;

        // Read AndX file request

      case PacketType.ReadAndX:
        procIPCFileReadAndX(sess, smbPkt);
        break;

        // Write file request

      case PacketType.WriteFile:
        procIPCFileWrite(sess, smbPkt);
        break;

        // Write AndX file request

      case PacketType.WriteAndX:
        procIPCFileWriteAndX(sess, smbPkt);
        break;

        // Close file request

      case PacketType.CloseFile:
        procIPCFileClose(sess, smbPkt);
        break;

        // NT create andX request

      case PacketType.NTCreateAndX:
        procNTCreateAndX(sess, smbPkt);
        break;

        // Default, respond with an unsupported function error.

      default:
        sess.sendErrorResponseSMB(smbPkt, SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
        break;
    }
  }
Example #13
0
  /**
   * 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);
  }
Example #14
0
  /**
   * 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);
  }