nspi

package
v0.0.0-...-f638237 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package nspi implements MS-NSPI (Name Service Provider Interface) protocol for querying Exchange address books via RPC over HTTP v2. This is a modular library that can be used by multiple tools.

Index

Constants

View Source
const (
	NSPI_VERSION_MAJOR = 56
	NSPI_VERSION_MINOR = 0
)

Interface version

View Source
const (
	PtypEmbeddedTable = 0x0000000D
	PtypNull          = 0x00000001
	PtypUnspecified   = 0x00000000
	PtypInteger16     = 0x00000002
	PtypInteger32     = 0x00000003
	PtypFloating32    = 0x00000004
	PtypFloating64    = 0x00000005
	PtypCurrency      = 0x00000006
	PtypFloatingTime  = 0x00000007
	PtypErrorCode     = 0x0000000A
	PtypBoolean       = 0x0000000B
	PtypInteger64     = 0x00000014
	PtypString8       = 0x0000001E
	PtypString        = 0x0000001F
	PtypTime          = 0x00000040
	PtypGuid          = 0x00000048
	PtypBinary        = 0x00000102
	PtypMultipleInt16 = 0x00001002
	PtypMultipleInt32 = 0x00001003
	PtypMultipleStr8  = 0x0000101E
	PtypMultipleStr   = 0x0000101F
	PtypMultipleTime  = 0x00001040
	PtypMultipleGuid  = 0x00001048
	PtypMultipleBin   = 0x00001102
)

Property type values (2.2.1)

View Source
const (
	DT_MAILUSER         = 0x00000000
	DT_DISTLIST         = 0x00000001
	DT_FORUM            = 0x00000002
	DT_AGENT            = 0x00000003
	DT_ORGANIZATION     = 0x00000004
	DT_PRIVATE_DISTLIST = 0x00000005
	DT_REMOTE_MAILUSER  = 0x00000006
	DT_CONTAINER        = 0x00000100
	DT_TEMPLATE         = 0x00000101
	DT_ADDRESS_TEMPLATE = 0x00000102
	DT_SEARCH           = 0x00000200
)

Display Type Values (2.2.3)

View Source
const (
	CP_TELETEX    = 0x00004F25
	CP_WINUNICODE = 0x000004B0
)

Required Codepages (2.2.5)

View Source
const (
	NORM_IGNORECASE     = 1 << 0
	NORM_IGNORENONSPACE = 1 << 1
	NORM_IGNORESYMBOLS  = 1 << 2
	SORT_STRINGSORT     = 1 << 12
	NORM_IGNOREKANATYPE = 1 << 16
	NORM_IGNOREWIDTH    = 1 << 17
)

Comparison Flags (2.2.6.1)

View Source
const (
	MID_BEGINNING_OF_TABLE = 0x00000000
	MID_END_OF_TABLE       = 0x00000002
	MID_CURRENT            = 0x00000001
)

Positioning Minimal Entry IDs (2.2.8)

View Source
const (
	MID_UNRESOLVED = 0x00000000
	MID_AMBIGUOUS  = 0x00000001
	MID_RESOLVED   = 0x00000002
)

Ambiguous Name Resolution Minimal Entry IDs (2.2.9)

View Source
const (
	SortTypeDisplayName         = 0
	SortTypePhoneticDisplayName = 0x00000003
	SortTypeDisplayName_RO      = 0x000003E8
	SortTypeDisplayName_W       = 0x000003E9
)

Table Sort Orders (2.2.10)

View Source
const (
	FSkipObjects = 0x00000001
	FEphID       = 0x00000002
)

Retrieve Property Flags (2.2.12)

View Source
const (
	NspiAddressCreationTemplates = 0x00000002
	NspiUnicodeStrings           = 0x00000004
)

NspiGetSpecialTable Flags (2.2.13)

View Source
const (
	TI_TEMPLATE          = 0x00000001
	TI_SCRIPT            = 0x00000004
	TI_EMT               = 0x00000010
	TI_HELPFILE_NAME     = 0x00000020
	TI_HELPFILE_CONTENTS = 0x00000040
)

NspiGetTemplateInfo Flags (2.2.16)

View Source
const (
	OP_NspiBind            = 0
	OP_NspiUnbind          = 1
	OP_NspiUpdateStat      = 2
	OP_NspiQueryRows       = 3
	OP_NspiSeekEntries     = 4
	OP_NspiGetMatches      = 5
	OP_NspiResortRestrict  = 6
	OP_NspiDNToMId         = 7
	OP_NspiGetPropList     = 8
	OP_NspiGetProps        = 9
	OP_NspiCompareMIds     = 10
	OP_NspiModProps        = 11
	OP_NspiGetSpecialTable = 12
	OP_NspiGetTemplateInfo = 13
	OP_NspiModLinkAtt      = 14
	OP_NspiQueryColumns    = 16
	OP_NspiResolveNames    = 19
	OP_NspiResolveNamesW   = 20
)

NSPI Operation Numbers

View Source
const (
	FAnonymousLogin = 0x00000020
)

NspiBind Flags (2.2.11)

View Source
const (
	FDelete = 0x00000001
)

NspiModLinkAtt Flags (2.2.17)

View Source
const NSPI_DEFAULT_LOCALE = 0x00000409

Default Language Code Identifier (2.2.4)

View Source
const (
	NspiUnicodeProptypes = 0x80000000
)

NspiQueryColumns Flags (2.2.14)

View Source
const (
	NspiVerifyNames = 0x00000002
)

NspiGetIDsFromNames Flags (2.2.15)

Variables

View Source
var GUID_NSPI = uuid.MustParse("C840A7DC-42C0-1A10-B4B9-08002B2FE182")

Permanent Entry ID GUID (2.2.7)

View Source
var MSRPC_UUID_NSPI = uuid.MustParse("F5CC5A18-4264-101A-8C59-08002B2F8426")

NSPI interface UUID

Functions

func FormatFileTime

func FormatFileTime(ft uint64) string

FormatFileTime converts a Windows FILETIME (100-nanosecond intervals since January 1, 1601) to a human-readable string in local time (matching Impacket)

func FormatGUID

func FormatGUID(data []byte) string

FormatGUID formats 16 bytes as a GUID string (little-endian fields)

func FormatSID

func FormatSID(data []byte) string

FormatSID converts a binary SID to string format S-1-5-21-...

func GetDNFromGUID

func GetDNFromGUID(guidStr string) string

GetDNFromGUID creates a minimal DN from a GUID for ResolveNames lookup

func GetGUIDFromDN

func GetGUIDFromDN(entryID []byte) []byte

GetGUIDFromDN extracts GUID from an NSPI PermanentEntryID

func SimplifyPropertyRow

func SimplifyPropertyRow(row *PropertyRow) map[PropertyTag]interface{}

SimplifyPropertyRow converts a PropertyRow to a map for easier access

func UUIDToMSRPC

func UUIDToMSRPC(u uuid.UUID) [16]byte

UUIDToMSRPC converts a google/uuid.UUID (RFC 4122, big-endian) to MS-RPC mixed-endian wire format: Data1(LE), Data2(LE), Data3(LE), Data4(BE)

Types

type AddressBookEntry

type AddressBookEntry struct {
	MId        int32
	Name       string
	GUID       []byte
	Flags      uint32
	Depth      uint32
	IsMaster   bool
	ParentGUID []byte
	Count      uint32
	StartMId   uint32
	Printed    bool
	Properties map[PropertyTag]interface{}
}

AddressBookEntry represents a parsed address book entry

type BinaryObject

type BinaryObject []byte

BinaryObject wraps binary data for proper display

func (BinaryObject) String

func (b BinaryObject) String() string

String returns hex representation

type Client

type Client struct {
	Transport *rpch.AuthTransport
	Handler   ContextHandle
	Stat      *STAT
	CallID    uint32

	// Address book hierarchy (map for lookup, slice for insertion order)
	HTable      map[int32]*AddressBookEntry
	HTableOrder []int32

	// Cached properties list
	Properties []PropertyTag

	// Any existing container ID for queries
	AnyExistingContainerID int32
	// contains filtered or unexported fields
}

Client is an NSPI protocol client

func NewClient

func NewClient(remoteName, rpcHostname string) *Client

NewClient creates a new NSPI client

func (*Client) Connect

func (c *Client) Connect() error

Connect establishes the RPC over HTTP connection and binds to NSPI

func (*Client) Disconnect

func (c *Client) Disconnect() error

Disconnect closes the connection

func (*Client) GetSpecialTable

func (c *Client) GetSpecialTable() error

GetSpecialTable performs NspiGetSpecialTable operation to get address book hierarchy

func (*Client) LoadHTableContainerID

func (c *Client) LoadHTableContainerID() error

LoadHTableContainerID finds an existing container ID for queries

func (*Client) QueryColumns

func (c *Client) QueryColumns() ([]PropertyTag, error)

QueryColumns performs NspiQueryColumns operation to get available properties

func (*Client) QueryRows

func (c *Client) QueryRows(containerID int32, count uint32, propTags []PropertyTag) (*PropertyRowSet, error)

QueryRows performs NspiQueryRows with pagination until MID_END_OF_TABLE

func (*Client) QueryRowsExplicit

func (c *Client) QueryRowsExplicit(containerID int32, count uint32, propTags []PropertyTag, eTable []uint32) (*PropertyRowSet, error)

QueryRowsExplicit performs NspiQueryRows with an explicit table (lpETable)

func (*Client) QueryRowsWithCallback

func (c *Client) QueryRowsWithCallback(containerID int32, count uint32, propTags []PropertyTag, callback func(*PropertyRowSet) error) error

QueryRowsWithCallback performs paginated QueryRows and calls the callback for each batch. This is used for two-phase queries where we first get MIds then fetch full properties.

func (*Client) ResolveNamesW

func (c *Client) ResolveNamesW(names []string, propTags []PropertyTag) (*PropertyRowSet, error)

ResolveNamesW performs NspiResolveNamesW operation for GUID lookups

func (*Client) SetCredentials

func (c *Client) SetCredentials(username, password, domain string, hashes string)

SetCredentials sets authentication credentials

func (*Client) SetKerberosConfig

func (c *Client) SetKerberosConfig(useKerberos bool, creds *session.Credentials)

SetKerberosConfig enables Kerberos authentication for this client

func (*Client) Unbind

func (c *Client) Unbind() error

Unbind performs NspiUnbind operation

func (*Client) UpdateStat

func (c *Client) UpdateStat(containerID int32) error

UpdateStat performs NspiUpdateStat operation

type ContextHandle

type ContextHandle struct {
	Attributes uint32
	UUID       [16]byte
}

ContextHandle represents an NSPI context handle

func (*ContextHandle) IsNull

func (h *ContextHandle) IsNull() bool

IsNull checks if the context handle is null

func (*ContextHandle) Marshal

func (h *ContextHandle) Marshal() []byte

Marshal serializes the context handle

func (*ContextHandle) Unmarshal

func (h *ContextHandle) Unmarshal(data []byte) error

Unmarshal deserializes the context handle

type PropertyRow

type PropertyRow struct {
	Reserved uint32
	Values   []PropertyValue
}

PropertyRow represents a row of property values

type PropertyRowSet

type PropertyRowSet struct {
	Rows []PropertyRow
}

PropertyRowSet represents a set of property rows

func ParsePropertyRowSet

func ParsePropertyRowSet(data []byte, propTags []PropertyTag) (*PropertyRowSet, error)

ParsePropertyRowSet parses a PropertyRowSet_r from NDR response data. The NDR format is:

  • Pointer referent for ppRows (4 bytes)
  • cRows (4 bytes)
  • Conformant array max count (4 bytes)
  • For each row: Reserved(4), cValues(4), lpProps pointer ref(4)
  • Deferred: for each row's lpProps: conformant array of PropertyValue_r
  • Each PropertyValue_r: ulPropTag(4), dwAlignPad(4), union value (8 bytes)
  • Further deferred data for strings, binary, etc.

type PropertyTag

type PropertyTag uint32

PropertyTag represents a MAPI property tag

func (PropertyTag) ID

func (p PropertyTag) ID() uint16

ID returns the property ID (upper 16 bits)

func (PropertyTag) Type

func (p PropertyTag) Type() uint16

Type returns the property type (lower 16 bits)

type PropertyTagArray

type PropertyTagArray struct {
	Values []PropertyTag
}

PropertyTagArray represents an array of property tags

func (*PropertyTagArray) Marshal

func (a *PropertyTagArray) Marshal() []byte

Marshal serializes the property tag array

func (*PropertyTagArray) MarshalNDR

func (a *PropertyTagArray) MarshalNDR() []byte

MarshalNDR serializes the property tag array in NDR format. The IDL defines: [size_is(cValues+1)] DWORD aulPropTag[] This is a conformant-varying array. Wire format:

MaxCount(4) = cValues+1, cValues(4), Offset(4) = 0, ActualCount(4) = cValues, elements

type PropertyValue

type PropertyValue struct {
	Tag   PropertyTag
	Value interface{} // Can be int16, int32, int64, string, []byte, etc.
}

PropertyValue represents a MAPI property value

type STAT

type STAT struct {
	SortType       uint32
	ContainerID    uint32
	CurrentRec     uint32
	Delta          int32
	NumPos         uint32
	TotalRecs      uint32
	CodePage       uint32
	TemplateLocale uint32
	SortLocale     uint32
}

STAT structure (2.3.7)

func NewSTAT

func NewSTAT() *STAT

NewSTAT creates a default STAT structure

func (*STAT) Marshal

func (s *STAT) Marshal() []byte

Marshal serializes the STAT structure

func (*STAT) Unmarshal

func (s *STAT) Unmarshal(data []byte) error

Unmarshal deserializes the STAT structure

Jump to

Keyboard shortcuts

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