client

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const SMBProtocolOverhead = 1024

SMBProtocolOverhead is the estimated space needed for SMB protocol headers, parameters, and padding when calculating maximum data transfer sizes.

Breakdown:

  • NetBIOS session header: 4 bytes
  • SMB header: 32 bytes
  • WRITE_ANDX/READ_ANDX parameter block: ~27 bytes
  • Data offset alignment/padding: ~16 bytes
  • Safety margin for extensions: ~945 bytes

Total: 1024 bytes

This constant is used to calculate the maximum payload size that fits within the negotiated MaxBufferSize, ensuring protocol messages don't exceed the server's buffer limits.

Variables

View Source
var ErrConnectionClosed = fmt.Errorf("smb1: connection closed: %w", net.ErrClosed)

ErrConnectionClosed is the error handed to every request still in flight when the connection is torn down — either by an explicit Close or by the Receive goroutine exiting after a socket failure. A dead connection stays dead: this library does not reconnect, so a caller seeing this must dial again.

It wraps net.ErrClosed so that errors.Is and the public IsNetworkError predicate classify it as a network failure rather than leaving callers to match on the message text. It deliberately does not wrap io.EOF: the connection dying mid-frame is not an orderly end of data, and a caller testing for io.EOF would misread it as one.

Functions

func Negotiate

func Negotiate(c *Conn, ctx context.Context) error

Negotiate performs SMB protocol negotiation with the server. It sends a negotiate request with supported dialects and validates the response. After successful negotiation, the connection's capabilities, buffer sizes, and challenge are populated.

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

conn represents a connection to an SMB1 server. It manages the underlying NetBIOS session, request/response correlation, and negotiated protocol parameters.

func NewConn

func NewConn(tcpConn net.Conn) *Conn

NewConn creates a new SMB1 connection wrapping the provided TCP connection. The TCP connection should already be established to the SMB server (typically port 445).

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection and cleans up all resources. It wakes all pending requests with an error and closes the underlying connection.

func (*Conn) GetCapabilities

func (c *Conn) GetCapabilities() (maxMpx uint16, maxBuf uint32, serverName, domainName string)

GetCapabilities returns the negotiated server capabilities. This is a thread-safe way to access capability information.

func (*Conn) Receive

func (c *Conn) Receive()

Receive is the background goroutine that reads responses and dispatches them to waiters. It should be started with go c.Receive() after the connection is created. This is exported for use by the public API layer.

Goroutine cleanup guarantees:

  • When Close() is called, it closes c.done and c.netbiosConn
  • This goroutine checks c.done at the start of each iteration
  • If blocked in ReadPacket(), closing the connection causes it to return an error
  • Any error from ReadPacket() triggers setError() which closes c.done
  • The deferred Close() call ensures cleanup even if the goroutine panics
  • This guarantees the goroutine always exits when the connection is closed

func (*Conn) ServerName

func (c *Conn) ServerName() string

ServerName returns the server's NetBIOS name discovered during negotiation. This method is exported for use by the public API layer.

func (*Conn) ServerTime

func (c *Conn) ServerTime() (systemTime uint64, timeZoneMinutes int16, receivedAt time.Time)

ServerTime returns the server clock values captured from the negotiate response: the server's system time as a Windows FILETIME (100-nanosecond intervals since January 1, 1601 UTC), the server's time zone in minutes from UTC, and the local time at which the negotiate response was received. This method is exported for use by the public API layer.

type File

type File struct {
	// contains filtered or unexported fields
}

File represents an open file on the SMB share.

func (*File) Close

func (f *File) Close(ctx context.Context) error

Close closes the file.

func (*File) GetOffset

func (f *File) GetOffset() int64

GetOffset returns the current file offset. This is thread-safe and can be called concurrently.

func (*File) QueryBasicInfo

func (f *File) QueryBasicInfo(ctx context.Context) (*smb1.FileBasicInfo, error)

QueryBasicInfo queries SMB_QUERY_FILE_BASIC_INFO for the open file. Unlike Stat, it returns the attributes exactly as the server reports them, without merging in the directory flag — callers that read-modify-write the attributes must not echo back bits the server never set.

func (*File) Read

func (f *File) Read(buf []byte, ctx context.Context) (int, error)

Read reads data from the file at the current offset. It advances the file offset by the number of bytes read. For buffers larger than maxDataPerRead, it automatically chunks the read operation. This method uses request pipelining for improved performance on large reads.

func (*File) ReadAt

func (f *File) ReadAt(buf []byte, offset int64, ctx context.Context) (int, error)

ReadAt reads data from the file at the specified offset. It does not change the file offset. Following io.ReaderAt, ReadAt returns a non-nil error whenever it reads fewer than len(buf) bytes: a short read only happens at end of file and carries io.EOF, and reading at or past end of file returns 0, io.EOF.

func (*File) Readdir

func (f *File) Readdir(n int, ctx context.Context) ([]FileStat, error)

Readdir reads the contents of the directory associated with file and returns a slice of up to n FileInfo values, as would be returned by Stat, in directory order. Subsequent calls on the same file will yield further FileInfos.

If n > 0, Readdir returns at most n FileInfo structures. In this case, if Readdir returns an empty slice, it will return a non-nil error explaining why. At the end of a directory, the error is io.EOF.

If n <= 0, Readdir returns all the FileInfo from the directory in a single slice. In this case, if Readdir succeeds (reads all the way to the end of the directory), it returns the slice and a nil error.

This implementation maintains state in the File's offset field to track pagination across multiple calls.

func (*File) Seek

func (f *File) Seek(offset int64, whence int) (int64, error)

Seek sets the file offset for the next Read or Write. It returns the new offset. This method implements the io.Seeker interface.

func (*File) SeekContext

func (f *File) SeekContext(offset int64, whence int, ctx context.Context) (int64, error)

SeekContext sets the file offset for the next Read or Write with context support. It returns the new offset.

func (*File) SetAttributes

func (f *File) SetAttributes(attrs uint32, ctx context.Context) error

SetAttributes sets the extended file attributes of the open file. It first tries TRANS2_SET_FILE_INFORMATION at the SMB_SET_FILE_BASIC_INFO level, with all timestamps zero ("leave unchanged"). Legacy servers that reject attribute changes at that level with STATUS_NOT_SUPPORTED get the core-protocol SMB_COM_SET_INFORMATION fallback instead, which is path-based: it addresses the file by the path it was opened with rather than by handle, and carries the DOS 16-bit attribute subset (see dosAttributes). Any other error is returned as-is, with no fallback attempt.

func (*File) SetBasicInfo

func (f *File) SetBasicInfo(info *smb1.FileBasicInfo, ctx context.Context) error

SetBasicInfo sets SMB_SET_FILE_BASIC_INFO on the open file. Zero-valued timestamps and a zero attributes field mean "leave unchanged" on the wire, so callers set only the fields they intend to change.

func (*File) Stat

func (f *File) Stat(ctx context.Context) (*FileStat, error)

Stat returns file information for the open file. It queries both basic info (timestamps, attributes) and standard info (size).

func (*File) TransactNamedPipe

func (f *File) TransactNamedPipe(data []byte, ctx context.Context) ([]byte, error)

TransactNamedPipe sends a transaction to an already-opened named pipe using its FID. This is used for RPC operations over named pipes. Unlike SendTransaction which uses pipe names for RAP, this method uses the FID from an NT_CREATE_ANDX operation and performs the transaction using the TransactNamedPipe SMB function (0x0026). If the server doesn't support that, it falls back to using Write/Read operations.

func (*File) Tree

func (f *File) Tree() *Tree

Tree returns a Tree helper bound to this file's session and tree ID, for tree-scoped requests (such as TRANS2_QUERY_FS_INFORMATION) that must go to the same tree the file was opened on.

func (*File) Truncate

func (f *File) Truncate(size int64, ctx context.Context) error

Truncate changes the size of the file. It does not change the I/O offset.

func (*File) Write

func (f *File) Write(data []byte, ctx context.Context) (int, error)

Write writes data to the file at the current offset. It advances the file offset by the number of bytes written. For data larger than maxBufferSize, it automatically chunks the write operation. Returns io.ErrShortWrite if not all bytes could be written.

func (*File) WriteAt

func (f *File) WriteAt(data []byte, offset int64, ctx context.Context) (int, error)

WriteAt writes data to the file at the specified offset. It does not change the file offset.

type FileStat

type FileStat struct {
	CreationTime   uint64 // FILETIME format
	LastAccessTime uint64 // FILETIME format
	LastWriteTime  uint64 // FILETIME format
	ChangeTime     uint64 // FILETIME format
	EndOfFile      int64  // File size
	AllocationSize int64  // Allocated size on disk
	FileAttributes uint32 // SMB file attributes
	FileName       string // File name
}

FileStat represents file metadata returned by File.Stat().

type Initiator

type Initiator interface {
	Negotiate() ([]byte, error)
	Authenticate(challengeMsg []byte) ([]byte, error)
	Session() *ntlm.Session
}

Initiator is the interface for NTLM authentication. It's implemented by ntlm.Client in the internal package.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session represents an authenticated SMB1 session. A session is created after successful session setup (authentication). This type is exported for use by the public API layer.

func NewSession

func NewSession(c *Conn, initiator Initiator, ctx context.Context) (*Session, error)

NewSession creates a new SMB1 session by performing session setup. It uses the provided Initiator for NTLM authentication. The session setup process involves two round trips: 1. Send NTLM negotiate message (receive challenge) 2. Send NTLM authenticate message (receive session UID)

func (*Session) Logoff

func (s *Session) Logoff(ctx context.Context) error

Logoff performs SMB_COM_LOGOFF_ANDX to close the session. After logoff, the session should not be used.

func (*Session) TreeConnect

func (s *Session) TreeConnect(path string, ctx context.Context) (*Tree, error)

TreeConnect connects to a share on the server. The path should be in UNC format (e.g., "\\server\share"). Returns a tree handle that can be used for file operations.

func (*Session) TreeDisconnect

func (s *Session) TreeDisconnect(tid uint16, ctx context.Context) error

TreeDisconnect disconnects from a share.

type Tree

type Tree struct {
	Session          *Session // parent session
	TID              uint16   // tree ID
	Path             string   // UNC path (e.g., \\server\share)
	Service          string   // service type (e.g., "A:", "IPC")
	OptionalSupport  uint16   // optional support flags from server
	NativeFileSystem string   // native file system (e.g., "NTFS")
}

Tree represents a connection to a share (tree connect). Multiple trees can be active on a single session. This type is exported for use by the public API layer.

func (*Tree) GetCapabilities

func (t *Tree) GetCapabilities() uint32

GetCapabilities returns the negotiated capabilities for the session.

func (*Tree) OpenFile

func (t *Tree) OpenFile(name string, access, shareAccess, disposition, createOptions uint32, ctx context.Context) (*File, error)

OpenFile opens or creates a file on the share. The access, shareAccess, disposition, and createOptions parameters follow NT semantics. Returns a file handle that can be used for read/write operations.

func (*Tree) OpenNamedPipe

func (t *Tree) OpenNamedPipe(pipeName string, ctx context.Context) (*File, error)

OpenNamedPipe opens a named pipe for RPC communication. The pipeName should be in the format "\pipename" (e.g., "\srvsvc"). Returns a File handle for the opened pipe.

func (*Tree) RPCBind

func (t *Tree) RPCBind(pipe *File, interfaceUUID [16]byte, version uint32, ctx context.Context) (uint16, error)

RPCBind binds to an RPC interface over an open named pipe. Returns the context ID for subsequent RPC requests.

func (*Tree) RPCRequest

func (t *Tree) RPCRequest(pipe *File, contextID uint16, opnum uint16, requestData []byte, callID uint32, ctx context.Context) ([]byte, error)

RPCRequest sends an RPC request over an open named pipe and receives the response. Returns the response data (stub data).

func (*Tree) SendRename

func (t *Tree) SendRename(oldpath, newpath string, ctx context.Context) error

SendRename sends a RENAME command. This is a helper for the public API layer.

func (*Tree) SendSetInformation

func (t *Tree) SendSetInformation(path string, attrs uint16, lastWriteTime uint32, ctx context.Context) error

SendSetInformation sends a core-protocol SMB_COM_SET_INFORMATION request, setting the DOS file attributes (and optionally the UTIME last-write time; 0 leaves it unchanged) of the file at path. This is the legacy set-attributes path for servers that reject the TRANS2 information levels.

func (*Tree) SendTransact2

func (t *Tree) SendTransact2(subcommand uint16, params, data []byte, ctx context.Context) (*smb1.Trans2Response, error)

SendTransact2 sends a TRANS2 request and returns the decoded response. This is a helper for the public API layer to send TRANS2 commands.

func (*Tree) SendTransaction

func (t *Tree) SendTransaction(name string, params, data []byte, ctx context.Context) (*smb1.Trans2Response, error)

SendTransaction sends a TRANSACTION request (for RAP and named pipes). This is a helper for the public API layer to send TRANSACTION commands. The name parameter is typically a pipe name like "\\PIPE\\LANMAN".

func (*Tree) SetPathAttributes

func (t *Tree) SetPathAttributes(path string, attrs uint32, ctx context.Context) error

SetPathAttributes sets the extended file attributes of the file at path. It first tries TRANS2_SET_PATH_INFORMATION at the SMB_SET_FILE_BASIC_INFO level, with all timestamps zero ("leave unchanged"). Legacy servers that reject attribute changes at that level with STATUS_NOT_SUPPORTED get the core-protocol SMB_COM_SET_INFORMATION fallback instead, which carries the DOS 16-bit attribute subset (see dosAttributes). Any other error is returned as-is, with no fallback attempt.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL