예제 #1
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);
  }
예제 #2
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;
    }
  }
예제 #3
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);
  }