Documentation
¶
Overview ¶
Package adcore is the Active Directory vocabulary shared by every backend: the models a directory read returns, the specs a write takes, identities, queries, the normalized error Kind, and the invariant machinery (per-identity write locking, retry, delete verification) that every backend composes rather than reimplements.
It performs no I/O, imports nothing outside the standard library, and knows nothing about PowerShell, LDAP or Terraform.
Index ¶
- Constants
- Variables
- func And(terms ...string) string
- func Backoff(ctx context.Context, cfg RetryConfig, attempt int) error
- func Bool(b bool) *bool
- func CanonicalACEKey(a ACE) string
- func ContainerOf(dn string) (string, error)
- func Equal(attr, value string) string
- func EqualFoldDN(a, b string) (bool, error)
- func EscapeFilter(filter string) string
- func EscapeValue(v string) string
- func IdentityArg(id Identity) string
- func IdentityForm(id Identity) string
- func Int(i int) *int
- func Parent(dn string) (string, error)
- func RevealSecret(s Secret) string
- func SplitDN(dn string) ([]string, error)
- func String(s string) *string
- func ValidateContainer(op, container string) error
- func ValidateName(op, name string) error
- func WithIdentity(err error, op string, id Identity) error
- type ACE
- type ACESpec
- type ACEType
- type ACLDirectory
- type AttributeTypeAndValue
- type Computer
- type ComputerDirectory
- type ComputerSpec
- type DN
- type Delegation
- type DelegationTask
- type DeleteOptions
- type Directory
- type Error
- type GMSA
- type GMSASpec
- type Group
- type GroupCategory
- type GroupDirectory
- type GroupScope
- type GroupSpec
- type Identity
- type Inheritance
- type KeyedMutex
- type Kind
- type Member
- type OU
- type OUDirectory
- type OUSpec
- type OptTime
- type PresenceCheck
- type Query
- type RelativeDN
- type RetryConfig
- type Right
- type SchemaDirectory
- type SchemaRef
- type SchemaRefKind
- type SearchScope
- type Secret
- type ServiceAccountDirectory
- type User
- type UserDirectory
- type UserSpec
Constants ¶
const DefaultSizeLimit = 1000
DefaultSizeLimit caps a search unless the caller sets its own limit. Large enough for a realistic subtree, small enough that a domain-wide accident errors rather than dragging.
Variables ¶
var ( ErrNotFound error = kindSentinel{KindNotFound} ErrAlreadyExists error = kindSentinel{KindAlreadyExists} ErrDenied error = kindSentinel{KindDenied} ErrConstraint error = kindSentinel{KindConstraint} ErrPassword error = kindSentinel{KindPassword} ErrReferral error = kindSentinel{KindReferral} ErrTransient error = kindSentinel{KindTransient} ErrTransport error = kindSentinel{KindTransport} ErrInvalidAttribute error = kindSentinel{KindInvalidAttribute} ErrSchema error = kindSentinel{KindSchema} ErrReplication error = kindSentinel{KindReplication} ErrTooManyResults error = kindSentinel{KindTooManyResults} ErrUnsupported error = kindSentinel{KindUnsupported} )
Kind sentinels for errors.Is.
Functions ¶
func And ¶
And composes a conjunction. Zero terms is the empty filter (the caller decides the default); one term is returned unwrapped; two or more are joined under a single "&".
func Backoff ¶
func Backoff(ctx context.Context, cfg RetryConfig, attempt int) error
Backoff sleeps for the attempt's exponential delay, jittered, and honours cancellation. attempt is 1-based.
A cancelled context yields KindTransport, never KindTransient: the caller gave up, and a Kind that invites a re-issue would turn that into one.
func CanonicalACEKey ¶
CanonicalACEKey is the semantic identity of an ACE: case-insensitive, and order-insensitive over Rights, so two representations of the same grant match. It is what drift detection and revoke-by-identity compare on. Fields join on "\x1f" (US) and rights join on "\x1e" (RS) — control characters that can never appear in a SID, GUID, AD rights name, or enum value — so no field's content can ever be mistaken for a separator.
func ContainerOf ¶
ContainerOf returns the parent DN. It is derived rather than read back, because no directory read returns the parent as its own attribute.
func Equal ¶
Equal builds an equality assertion "(attr=<escaped value>)". The attribute name is a caller-controlled schema identifier and is not escaped; only the value is.
func EqualFoldDN ¶
EqualFoldDN is the string convenience used wherever a spec value meets a value AD echoed back. It is not named EqualFold because at a call site that reads as a string comparison, and comparing two DNs as strings is wrong.
func EscapeFilter ¶
EscapeFilter escapes the RFC 4515 special set `()*\` and every byte outside 0 < c < 0x80 in an assertion value. Every value a backend puts inside a filter goes through here; hand-rolled quoting is the defect class the design exists to retire.
func EscapeValue ¶
EscapeValue is the exported spelling, for a caller that assembles an RDN instead of rendering a parsed DN. Building "OU=" + name + "," + parent by concatenation is correct right up to the first name containing a comma, at which point the name silently reparents the object.
func IdentityForm ¶
IdentityForm returns the identity's form: "guid", "dn", "sid" or "sam".
func Parent ¶
Parent is the string convenience: it returns the container of dn, or "" if dn has no parent.
func RevealSecret ¶
RevealSecret returns the plaintext. It is a function rather than a method so that every site that extracts a password is greppable by name — which is the property Secret exists to provide.
func SplitDN ¶
SplitDN returns the DN's components, most specific first, each in its escaped RFC 4514 form. It parses rather than splitting on commas: an escaped comma is part of a component, not a separator, so a lexical split turns "OU=Sales\, EMEA,DC=corp" into three components and reparents the object.
func String ¶
String is the pointer helper for the tri-state spec fields. Named for how it reads at the call site: Description: adcore.String("x").
func ValidateContainer ¶
ValidateContainer rejects a container that is empty or is not a distinguished name, before any round trip.
func ValidateName ¶
ValidateName rejects an empty name before any round trip.
Types ¶
type ACE ¶
type ACE struct {
Trustee string // SID
Type ACEType
Rights []Right
ObjectType string // GUID; "" = all
InheritedObjectType string // GUID; "" = all child classes
Inheritance Inheritance
Inherited bool // read-only: system-stamped copy; never managed
}
ACE is one explicit access-control entry as the library reads and writes it. Object types are GUIDs at this layer (already resolved from friendly names).
type ACESpec ¶
type ACESpec struct {
Rights []Right
ObjectType string
Scope Inheritance
ObjectClass string
Type ACEType
}
ACESpec is the friendly, unresolved form a delegation template emits and the provider maps to config. ObjectType and ObjectClass are friendly names or GUIDs.
type ACLDirectory ¶
type ACLDirectory interface {
Get(ctx context.Context, id Identity) ([]ACE, error)
Grant(ctx context.Context, id Identity, aces []ACE) error
Revoke(ctx context.Context, id Identity, aces []ACE) error
}
ACL takes resolved ACEs, not the friendly ACESpec a delegation template emits: resolving a name to a schema GUID is a directory read, so it belongs to the caller that already holds a Schema, not to the write.
type AttributeTypeAndValue ¶
AttributeTypeAndValue is one type=value pair inside an RDN.
type Computer ¶
type Computer struct {
GUID string
DN string
Name string
SamAccountName string
Container string
SID string
Enabled bool
DNSHostName string
Description string
DisplayName string
Location string
ManagedBy string // read back as a DN
TrustedForDelegation bool
ServicePrincipalNames []string
AllowedToDelegateTo []string // msDS-AllowedToDelegateTo (SPNs)
PrincipalsAllowed []string // RBCD principals, as objectGUIDs
KerberosEncryptionType []string
AccountExpiration *time.Time
OperatingSystem string
OperatingSystemVersion string
OperatingSystemServicePack string
}
Computer is an Active Directory computer account (objectClass "computer"). OperatingSystem* are read-only: the joined machine owns them.
type ComputerDirectory ¶
type ComputerDirectory interface {
Create(ctx context.Context, spec ComputerSpec) (*Computer, error)
Get(ctx context.Context, id Identity) (*Computer, error)
Search(ctx context.Context, q Query) ([]Computer, error)
Update(ctx context.Context, id Identity, spec ComputerSpec) (*Computer, error)
Delete(ctx context.Context, id Identity) error
}
type ComputerSpec ¶
type ComputerSpec struct {
Name string // CN; required
SamAccountName string // required; "$" is added by AD; length is NOT capped here
Container string // parent DN; required
DNSHostName *string
Description *string
DisplayName *string
Location *string
ManagedBy *string
Enabled *bool
TrustedForDelegation *bool
ServicePrincipalNames *[]string // nil leaves alone, non-nil (incl. empty) replaces
AllowedToDelegateTo *[]string // nil leaves alone, non-nil (incl. empty) replaces
PrincipalsAllowed []Identity // full-replace; nil leaves alone, non-nil (incl. empty) replaces
KerberosEncryptionType *[]string // nil leaves alone, non-nil replaces
AccountExpiration OptTime
}
ComputerSpec is the desired state of a computer account. Pointer fields follow the same tri-state convention as GMSASpec: nil leaves the attribute alone, a pointer to "" clears it, a pointer to a value sets it.
Unlike GMSASpec, SamAccountName has no length cap here: the 15-char NetBIOS limit gMSA enforces is a gMSA-specific constraint (the "$" AD appends must still fit in 20 bytes downlevel-logon-name space), not a general AD rule — AD accepts a computer sAMAccountName well past 15 characters, so validate must not reject one. There are also no create-only fields: DNSHostName, unlike a gMSA's, is settable any time.
type DN ¶
type DN struct {
RDNs []RelativeDN
}
DN is a parsed distinguished name, most specific RDN first.
func ParseDN ¶
ParseDN parses the string form of a distinguished name. Hex-encoded BER attribute values (the "#04024869" form) are rejected rather than decoded: Active Directory never emits them, and decoding would require an ASN.1 parser for no gain.
func (*DN) AncestorOfFold ¶
AncestorOfFold reports whether d is a strict ancestor of other.
func (*DN) EqualFold ¶
EqualFold reports whether two DNs name the same object, comparing attribute types and values case-insensitively. AD's DN syntax is case-insensitive and case-preserving, so this is the only correct comparison.
type Delegation ¶
type Delegation struct{}
Delegation expands a curated delegation task into the concrete ACEs that implement it. It performs no directory I/O: the expansion is pure, so a consumer can compute a plan from it without a round trip. Object types are friendly names; the caller resolves them to GUIDs.
It is named Delegation rather than DelegationClient because it is a stateless struct that never reaches a directory; the Client suffix misled once it stopped being reached through one.
func (*Delegation) Template ¶
func (d *Delegation) Template(task DelegationTask) ([]ACESpec, error)
Template returns the ACE specs a task expands into. These mirror the AD "Delegate Control" wizard's common tasks; the object/attribute names are cross-checked against the schema well-known table and intended to be verified end-to-end on the lab.
type DelegationTask ¶
type DelegationTask string
DelegationTask names a curated bundle of ACEs.
const ( TaskResetUserPasswords DelegationTask = "reset_user_passwords" TaskManageUsers DelegationTask = "manage_users" TaskModifyGroupMembership DelegationTask = "modify_group_membership" TaskManageGroups DelegationTask = "manage_groups" )
type DeleteOptions ¶
type DeleteOptions struct {
// Unprotect lifts ProtectedFromAccidentalDeletion before deleting. Without
// it, deleting an OU created with AD's own default fails.
Unprotect bool
}
DeleteOptions is taken only by OU.Delete. Making the unprotect step an explicit option keeps the destructive part visible at the call site.
type Directory ¶
type Directory struct {
OU OUDirectory
Group GroupDirectory
User UserDirectory
ServiceAccount ServiceAccountDirectory
Computer ComputerDirectory
ACL ACLDirectory
Schema SchemaDirectory
// Server is the pinned domain controller every operation targets.
Server string
// DNC is the domain's default naming context, e.g. "DC=corp,DC=local".
DNC string
Closer io.Closer
}
Directory is what a backend hands a consumer. It is a struct of interfaces rather than an interface of accessors so that a backend whose sub-clients are already struct fields satisfies it without changing its own API.
Every guarantee a consumer relies on — read-back after write, delete verification, a pinned domain controller, serialized writes per identity — is the implementation's to uphold. RunDirectorySuite in adcoretest asserts them behaviourally against any implementation.
type Error ¶
type Error struct {
Kind Kind // the only thing callers switch on
Op string // "User.Create"
Identity string // the identity acted on, in form:value notation
ExceptionType string // verbatim, e.g. …ADIdentityNotFoundException
Code int // Win32 code; decode via MS-ERREF
ServerMessage string // the DC's own words, via IHasServerErrorMessage
FQID string // cmdlet-specific; diagnostics only
Target string
Tombstoned bool // set when an already-exists was traced to a deleted object
Err error
}
Error is the single error type this library returns. AD's raw detail is carried alongside the normalized Kind so a caller can render an exact message without switching on Microsoft's type names.
type GMSA ¶
type GMSA struct {
GUID string
DN string
Name string
SamAccountName string
Container string
SID string
DNSHostName string
Description string
DisplayName string
Enabled bool
TrustedForDelegation bool
PrincipalsAllowed []string // objectGUIDs, resolved from the DNs AD returns
ServicePrincipalNames []string
KerberosEncryptionType []string
ManagedPasswordIntervalInDays int
AccountExpiration *time.Time // nil means never
}
GMSA is a group Managed Service Account as this library reads it back.
type GMSASpec ¶
type GMSASpec struct {
Name string // CN; required
SamAccountName string // required; <= 15 chars, "$" is added by AD
Container string // parent DN; required
DNSHostName *string
Description *string
DisplayName *string
Enabled *bool
TrustedForDelegation *bool
PrincipalsAllowed []Identity // full-replace; nil leaves alone, non-nil (incl. empty) replaces
ServicePrincipalNames *[]string // nil leaves alone, non-nil (incl. empty) replaces
KerberosEncryptionType *[]string // nil leaves alone, non-nil replaces
AccountExpiration OptTime
ManagedPasswordIntervalInDays *int // create-only; ignored on Update
}
GMSASpec is the desired state of a group Managed Service Account. Pointer fields follow the tri-state convention: nil leaves the attribute alone, a pointer to "" clears it, a pointer to a value sets it.
func (GMSASpec) Validate ¶
forCreate follows the same convention GroupSpec.Validate uses: the op string is for error stamping only, never for branching. Branching on it (as an earlier version of this method did, comparing op == "GMSA.Create") silently breaks the moment a caller's op string doesn't match that literal — which is exactly what happened here, since ServiceAccountClient.Create (following the <Resource>.<Verb> convention every other sub-client uses) passes "ServiceAccount.Create", not "GMSA.Create".
type Group ¶
type Group struct {
GUID string
DN string
Name string
SamAccountName string
Container string
Scope GroupScope
Category GroupCategory
Description string
ManagedBy string
SID string
}
Group is a security or distribution group.
type GroupCategory ¶
type GroupCategory string
GroupCategory distinguishes a security principal from a distribution list.
const ( GroupCategorySecurity GroupCategory = "security" GroupCategoryDistribution GroupCategory = "distribution" )
type GroupDirectory ¶
type GroupDirectory interface {
Create(ctx context.Context, spec GroupSpec) (*Group, error)
Get(ctx context.Context, id Identity) (*Group, error)
Search(ctx context.Context, q Query) ([]Group, error)
Update(ctx context.Context, id Identity, spec GroupSpec) (*Group, error)
Delete(ctx context.Context, id Identity) error
Members(ctx context.Context, id Identity) ([]Member, error)
MembersRecursive(ctx context.Context, id Identity) ([]Member, error)
AddMembers(ctx context.Context, id Identity, members []Identity) error
RemoveMembers(ctx context.Context, id Identity, members []Identity) error
IsMember(ctx context.Context, id, member Identity) (bool, error)
}
type GroupScope ¶
type GroupScope string
GroupScope is the group's replication and membership scope.
const ( GroupScopeGlobal GroupScope = "global" GroupScopeDomainLocal GroupScope = "domainlocal" GroupScopeUniversal GroupScope = "universal" )
type GroupSpec ¶
type GroupSpec struct {
Name string // the CN; a change means Rename-ADObject
SamAccountName string // required; changes through Set-ADGroup
Container string // parent DN; a change means Move-ADObject
Scope GroupScope
Category GroupCategory // defaults to security
Description *string
ManagedBy *string
}
GroupSpec is the desired state of a group.
type Identity ¶
type Identity interface {
String() string
// contains filtered or unexported methods
}
Identity is an AD identity argument. The interface is sealed by unexported methods: the only values that satisfy it come from the four constructors below, so no caller can hand a backend an arbitrary string as an identity — which is what keeps a caller's value from becoming PowerShell script text or an unescaped LDAP filter term.
Backends in other modules read the parts through IdentityArg and IdentityForm. Those are functions rather than interface methods precisely so that the seal survives the module boundary: exporting the methods would let any package implement Identity.
func ByGUID ¶
ByGUID identifies an object by objectGUID. This is the canonical form: it survives rename and move, which DN and sAMAccountName do not.
type Inheritance ¶
type Inheritance string
Inheritance is how an ACE propagates. It maps onto System.DirectoryServices.ActiveDirectorySecurityInheritance.
const ( InheritanceThis Inheritance = "this" // this object only InheritanceDescendants Inheritance = "descendants" // all descendants, scoped by InheritedObjectType InheritanceChildren Inheritance = "children" // immediate children only )
type KeyedMutex ¶
type KeyedMutex struct {
// contains filtered or unexported fields
}
KeyedMutex serializes writes to one target. Two writers naming different objects proceed concurrently, which is what keeps Terraform's parallel graph walk useful.
func NewKeyedMutex ¶
func NewKeyedMutex() *KeyedMutex
NewKeyedMutex returns a KeyedMutex ready for use.
func (*KeyedMutex) Lock ¶
func (k *KeyedMutex) Lock(key string) (unlock func())
Lock blocks until key is available and returns the release function.
func (*KeyedMutex) Size ¶
func (k *KeyedMutex) Size() int
Size reports how many keys are currently held or waited on. Test support.
type Kind ¶
type Kind int
Kind is the normalized condition a caller switches on. Adding a condition later adds a Kind, not a type: the public surface does not track Microsoft's exception list.
const ( KindUnknown Kind = iota KindNotFound KindAlreadyExists KindDenied KindConstraint KindPassword KindReferral // KindTransient means the operation provably did not execute: the // failure occurred before the script (or, for a transport, the request // carrying it) was ever sent, so re-issuing the identical request // cannot duplicate a side effect. This is the bar a producer of // KindTransient must clear — not "this looks like it might be worth // retrying," but "nothing happened, by construction, every time." An AD // result code that comes back through the envelope (RPC_S_SERVER_BUSY // and friends in classByCode) clears it: the request reached AD and was // refused before anything was done. A transport-level // failure clears it only when it is raised by a pre-send check (a // semaphore, a circuit breaker, a not-yet-connected guard) that runs // before any bytes carrying the request leave the process. // // Anything that merely *might* not have executed is not transient, and // must map to KindTransport (or another non-retryable Kind) instead. In // particular, a context cancellation or deadline observed while awaiting // a response is not transient: depending on the transport, the script // may already have reached the server before the deadline fired, so the // failure and a completed execution are indistinguishable from here. // This is the exact bug that once made transport/winrm/wrap.go's // mapExecuteError treat context.Canceled/context.DeadlineExceeded as // KindTransient — up to Retry.MaxAttempts re-issues of an operation that // may have already run. See mapExecuteError's doc for the WSMan-specific // mechanics and why a caller-side cancellation loses nothing by staying // non-retryable (core.backoff already aborts on the caller's own // ctx.Done()). KindTransient KindTransport KindInvalidAttribute KindSchema // KindReplication means the write succeeded and the replication wait did // not complete. It is never retried, and the caller must persist the model // it was returned alongside. KindReplication // KindTooManyResults means a search matched more than its size limit. It is // never retried; the caller narrows the filter or raises the limit. KindTooManyResults // KindUnsupported means the operation cannot run against this transport's // endpoint — e.g. an ACL op against a ConstrainedLanguage endpoint, whose // .NET DirectoryServices calls are unavailable. Never retried. KindUnsupported )
func ClassifyCode ¶
ClassifyCode maps a Win32 error code (MS-ERREF) to a Kind. It reports false for an unmapped code, which the caller must treat as KindUnknown: an unrecognized condition is never retried.
Both backends share this table. The PowerShell backend reads the code off the exception the ActiveDirectory module raises; the LDAP backend parses it out of the diagnostic message, which AD prefixes with exactly these codes in hex (for example "0000208D: NameErr:"). Sharing the table is what makes the two produce identical Kinds from identical conditions.
func (Kind) Retryable ¶
Retryable is deliberately narrow, and narrow for two different reasons. Retrying an access-denied or a duplicate-object error only delays a clear message — that failure is final, retrying wastes time. Retrying anything that is not KindTransient risks something worse than wasted time: KindTransient is the only Kind whose contract guarantees the operation provably did not execute (see its doc), so it is the only Kind a backend may safely re-issue. A Kind added later must not be folded into this check unless it can make that same guarantee.
type Member ¶
type Member struct {
GUID string
DN string
Class string // user, group, computer, foreignSecurityPrincipal, …
SID string
}
Member is one entry read back from a group's membership.
type OU ¶
type OU struct {
GUID string
DN string
Name string
Container string // derived from DN; never echoed by the script
Description string
Protected bool
}
OU is an organizational unit as this library reads it back.
type OUDirectory ¶
type OUDirectory interface {
Create(ctx context.Context, spec OUSpec) (*OU, error)
Get(ctx context.Context, id Identity) (*OU, error)
Search(ctx context.Context, q Query) ([]OU, error)
Update(ctx context.Context, id Identity, spec OUSpec) (*OU, error)
Delete(ctx context.Context, id Identity, opts DeleteOptions) error
}
type OUSpec ¶
type OUSpec struct {
Name string // the RDN; required on create, a change means Rename-ADObject
Container string // parent DN; required on create, a change means Move-ADObject
Description *string
Protected *bool // ProtectedFromAccidentalDeletion
}
OUSpec is the desired state of an organizational unit. A nil pointer leaves the attribute alone; a pointer to "" clears it; a pointer to a value sets it.
type OptTime ¶
type OptTime struct {
// contains filtered or unexported fields
}
OptTime is the three-state carrier a *time.Time cannot express: time.Time has no empty sentinel the way string does. The zero value leaves the attribute alone.
func ClearTime ¶
func ClearTime() OptTime
ClearTime clears accountExpires, which in AD means "never expires".
type PresenceCheck ¶
type PresenceCheck struct {
// Present reports whether the object was still resolvable. The JSON tag
// is the name the PowerShell probe writes and must not be renamed with
// the field.
Present bool `json:"found"`
ExceptionType string `json:"type"`
ErrorCode int `json:"errorCode"`
Message string `json:"message"`
Kind Kind `json:"-"`
}
PresenceCheck is the result of re-reading an object after a delete. The probe never decides whether an object is gone: it hands the failure back so the backend's classifier, which fails closed, makes the call.
Kind is the backend's own classification of the probe's failure. It is a field rather than something ConfirmAbsent derives because the two backends classify from different evidence — go-adpwsh from the .NET exception type the ActiveDirectory module raises, go-adldap from an LDAP result code — and neither vocabulary belongs in a backend-neutral module.
func (PresenceCheck) ConfirmAbsent ¶
func (p PresenceCheck) ConfirmAbsent(op string, id Identity, dn string) error
ConfirmAbsent turns a presence probe into the delete verdict. A destroy that silently no-ops is worse than one that fails: Terraform drops the resource from state and the object is then unmanaged and invisible.
type Query ¶
type Query struct {
Filter string // a COMPLETE LDAP filter; "" ⇒ "(objectClass=*)"
SearchBase string // DN; "" ⇒ the pinned domain's defaultNamingContext
Scope SearchScope // "" ⇒ subtree
SizeLimit int // ≤ 0 ⇒ DefaultSizeLimit
}
Query is a directory search. The zero value searches the whole domain subtree for every object of the sub-client's class, capped at the default limit.
func (Query) WithDefaults ¶
WithDefaults resolves the zero-value fields against the pinned domain.
type RelativeDN ¶
type RelativeDN struct {
Attributes []AttributeTypeAndValue
}
RelativeDN is one comma-separated component; it holds more than one attribute only for the multi-valued (plus-joined) form.
type RetryConfig ¶
type RetryConfig struct {
MaxAttempts int
InitialBackoff time.Duration
MaxBackoff time.Duration
Jitter float64 // fraction of the backoff, 0..1
}
RetryConfig is values, not code. It governs re-attempts, and applies only to errors classified transient — see Kind.Retryable for why that set is as narrow as it is.
func (RetryConfig) WithDefaults ¶
func (r RetryConfig) WithDefaults() RetryConfig
WithDefaults fills the zero-value fields.
type Right ¶
type Right string
Right is one System.DirectoryServices.ActiveDirectoryRights value, by name.
type SchemaDirectory ¶
type SchemaDirectory interface {
Resolve(ctx context.Context, refs []SchemaRef) (map[SchemaRef]string, error)
}
Resolve is batched because the round trip is per call, not per name: an ACL grant resolves a dozen names at once and a one-at-a-time signature would make that a dozen searches.
type SchemaRef ¶
type SchemaRef struct {
Kind SchemaRefKind
Name string
}
SchemaRef is a friendly name to resolve to a GUID.
type SchemaRefKind ¶
type SchemaRefKind string
SchemaRefKind is which schema partition a name is resolved against.
const ( RefAttribute SchemaRefKind = "attribute" RefClass SchemaRefKind = "class" RefExtendedRight SchemaRefKind = "extended_right" )
type SearchScope ¶
type SearchScope string
SearchScope is the depth a directory search descends to.
const ( SearchScopeBase SearchScope = "base" SearchScopeOneLevel SearchScope = "onelevel" SearchScopeSubtree SearchScope = "subtree" )
type Secret ¶
type Secret struct {
// contains filtered or unexported fields
}
Secret carries a password without letting it reach a log line, a state file, or a %v verb. Its plaintext is readable only through RevealSecret, which a backend's payload builder calls deliberately at the moment of serialization. The guarantee is on the type, not on each call site.
func (Secret) Format ¶
Format makes every verb safe, not just the string ones. fmt consults a Stringer only for %v, %s, %q, %x and %X; under %d it walks the struct and prints the field, so a Stringer alone leaks the plaintext as "{%!d(string=hunter2)}". Implementing Formatter is what makes "a Secret never reaches a log line" true whatever verb the log line happens to use.
func (Secret) MarshalJSON ¶
MarshalJSON always fails. A Secret must be revealed deliberately; it must never be serialized by a struct walk into a log line or a state file.
type ServiceAccountDirectory ¶
type ServiceAccountDirectory interface {
Create(ctx context.Context, spec GMSASpec) (*GMSA, error)
Get(ctx context.Context, id Identity) (*GMSA, error)
Search(ctx context.Context, q Query) ([]GMSA, error)
Update(ctx context.Context, id Identity, spec GMSASpec) (*GMSA, error)
Delete(ctx context.Context, id Identity) error
}
type User ¶
type User struct {
GUID string
DN string
Name string
SamAccountName string
UserPrincipalName string
DisplayName string
GivenName string
Surname string
Description string
Container string
Enabled bool
SID string
ChangePasswordAtLogon bool
CanChangePassword bool
PasswordExpires bool
AccountExpiration *time.Time // nil means the account never expires
}
User is a user account.
type UserDirectory ¶
type UserDirectory interface {
Create(ctx context.Context, spec UserSpec) (*User, error)
Get(ctx context.Context, id Identity) (*User, error)
Search(ctx context.Context, q Query) ([]User, error)
Update(ctx context.Context, id Identity, spec UserSpec) (*User, error)
Delete(ctx context.Context, id Identity) error
SetPassword(ctx context.Context, id Identity, password Secret) error
}
type UserSpec ¶
type UserSpec struct {
SamAccountName string // required on create
Container string // required on create; a change means Move-ADObject
Name *string // the CN; defaults to SamAccountName on create; a change means Rename-ADObject
UserPrincipalName *string
DisplayName *string
GivenName *string
Surname *string
Description *string
Enabled *bool
Password *Secret
ChangePasswordAtLogon *bool
CanChangePassword *bool
PasswordExpires *bool
AccountExpiration OptTime
}
UserSpec is the desired state of a user account.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package adcorefake is an in-memory adcore.Directory.
|
Package adcorefake is an in-memory adcore.Directory. |
|
Package adcoretest asserts the guarantees an adcore.Directory must uphold, against any implementation.
|
Package adcoretest asserts the guarantees an adcore.Directory must uphold, against any implementation. |
|
Package schema holds the Active Directory schema catalog: every attribute's type and constraints, and every exported class's effective set of allowed attributes.
|
Package schema holds the Active Directory schema catalog: every attribute's type and constraints, and every exported class's effective set of allowed attributes. |