Documentation
¶
Index ¶
- Constants
- Variables
- func Negotiate(c *Conn, ctx context.Context) error
- type Conn
- type File
- func (f *File) Close(ctx context.Context) error
- func (f *File) GetOffset() int64
- func (f *File) QueryBasicInfo(ctx context.Context) (*smb1.FileBasicInfo, error)
- func (f *File) Read(buf []byte, ctx context.Context) (int, error)
- func (f *File) ReadAt(buf []byte, offset int64, ctx context.Context) (int, error)
- func (f *File) Readdir(n int, ctx context.Context) ([]FileStat, error)
- func (f *File) Seek(offset int64, whence int) (int64, error)
- func (f *File) SeekContext(offset int64, whence int, ctx context.Context) (int64, error)
- func (f *File) SetAttributes(attrs uint32, ctx context.Context) error
- func (f *File) SetBasicInfo(info *smb1.FileBasicInfo, ctx context.Context) error
- func (f *File) Stat(ctx context.Context) (*FileStat, error)
- func (f *File) TransactNamedPipe(data []byte, ctx context.Context) ([]byte, error)
- func (f *File) Tree() *Tree
- func (f *File) Truncate(size int64, ctx context.Context) error
- func (f *File) Write(data []byte, ctx context.Context) (int, error)
- func (f *File) WriteAt(data []byte, offset int64, ctx context.Context) (int, error)
- type FileStat
- type Initiator
- type Session
- type Tree
- func (t *Tree) GetCapabilities() uint32
- func (t *Tree) OpenFile(name string, access, shareAccess, disposition, createOptions uint32, ...) (*File, error)
- func (t *Tree) OpenNamedPipe(pipeName string, ctx context.Context) (*File, error)
- func (t *Tree) RPCBind(pipe *File, interfaceUUID [16]byte, version uint32, ctx context.Context) (uint16, error)
- func (t *Tree) RPCRequest(pipe *File, contextID uint16, opnum uint16, requestData []byte, callID uint32, ...) ([]byte, error)
- func (t *Tree) SendRename(oldpath, newpath string, ctx context.Context) error
- func (t *Tree) SendSetInformation(path string, attrs uint16, lastWriteTime uint32, ctx context.Context) error
- func (t *Tree) SendTransact2(subcommand uint16, params, data []byte, ctx context.Context) (*smb1.Trans2Response, error)
- func (t *Tree) SendTransaction(name string, params, data []byte, ctx context.Context) (*smb1.Trans2Response, error)
- func (t *Tree) SetPathAttributes(path string, attrs uint32, ctx context.Context) error
Constants ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
ServerName returns the server's NetBIOS name discovered during negotiation. This method is exported for use by the public API layer.
func (*Conn) ServerTime ¶
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) GetOffset ¶
GetOffset returns the current file offset. This is thread-safe and can be called concurrently.
func (*File) QueryBasicInfo ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
SeekContext sets the file offset for the next Read or Write with context support. It returns the new offset.
func (*File) SetAttributes ¶
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 ¶
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 ¶
Stat returns file information for the open file. It queries both basic info (timestamps, attributes) and standard info (size).
func (*File) TransactNamedPipe ¶
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 ¶
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.
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 ¶
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 ¶
Logoff performs SMB_COM_LOGOFF_ANDX to close the session. After logoff, the session should not be used.
func (*Session) TreeConnect ¶
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.
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 ¶
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 ¶
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 ¶
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 ¶
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.