ldap_pg

package module
v0.12.4 Latest Latest
Warning

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

Go to latest
Published: Jan 2, 2022 License: GPL-2.0 Imports: 37 Imported by: 0

README

ldap-pg

GoDoc

This repository is heavily under development.

ldap-pg is a LDAP server implementation which uses PostgreSQL as the backend database.

Features

  • Basic LDAP operations
    • Bind
      • PLAIN
      • SSHA
      • SSHA256
      • SSHA512
      • ARGON2
      • Pass-through authentication (Support {SASL}foo@domain format)
    • Search
      • base
      • one
      • sub
      • children
    • Add
    • Modify
    • Delete
    • ModifyDN
      • Rename RDN
      • Support deleteoldrdn
      • Support newsuperior
    • Compare
    • Extended
  • LDAP Controls
    • Simple Paged Results Control
    • Sort Control
  • Support association (like OpenLDAP memberOf overlay)
    • Return memberOf attribute as operational attribute
    • Maintain member uniqueMember / memberOf
    • Search filter using memberOf
  • Schema
    • Basic schema processing
    • More schema processing
    • User defined schema
    • Multiple RDNs
  • Password Policy
    • Account lock
    • More policy controls
  • Authorization
    • Simple ACL
  • Last bind
    • Record the timestamp of the last successful bind
  • Network
    • SSL/StartTLS
  • Prometheus metrics
  • Auto create table for PostgreSQL
  • Auto migrate table for PostgreSQL

Requirement

PostgreSQL 12 or later.

Install

From binary

Please download it from release page.

From source

ldap-pg is written by Go. Install Go then build ldap-pg:

make

You can find the binary in ./bin/ directory.

Usage

Start ldap-pg
ldap-pg.

Usage:

  ldap-pg [options]

Options:

  -acl value
        Simple ACL: the format is <DN(User, Group or empty(everyone))>:<Scope(R, W or RW)>:<Invisible Attributes> (e.g. cn=reader,dc=example,dc=com:R:userPassword,telephoneNumber)
  -b string
        Bind address (default "127.0.0.1:8389")
  -d string
        DB Name
  -db-max-idle-conns int
        DB max idle connections (default 2)
  -db-max-open-conns int
        DB max open connections (default 5)
  -default-ppolicy-dn string
        DN of the default password policy entry (e.g. cn=standard-policy,ou=Policies,dc=example,dc=com)
  -gomaxprocs int
        GOMAXPROCS (Use CPU num with default)
  -h string
        DB Hostname (default "localhost")
  -log-level string
        Log level, on of: debug, info, warn, error, alert (default "info")
  -migration
        Enable migration mode which means LDAP server accepts add/modify operational attributes (default false)
  -p int
        DB Port (default 5432)
        If use unix socket set "0"
  -pass-through-ldap-bind-dn string
        Pass-through/LDAP: Bind DN
  -pass-through-ldap-domain string
        Pass-through/LDAP: Domain for pass-through/LDAP
  -pass-through-ldap-filter string
        Pass-through/LDAP: Filter for finding an user (e.g. (cn=%u))
  -pass-through-ldap-password string
        Pass-through/LDAP: Bind password
  -pass-through-ldap-scope string
        Pass-through/LDAP: Search scope, on of: base, one, sub (default "sub")
  -pass-through-ldap-search-base string
        Pass-through/LDAP: Search base
  -pass-through-ldap-server string
        Pass-through/LDAP: Server address and port (e.g. myldap:389)
  -pass-through-ldap-timeout int
        Pass-through/LDAP: Timeout seconds (default 10)
  -pprof string
        Bind address of pprof server (Don't start the server with default)
  -root-dn string
        Root dn for the LDAP
  -root-pw string
        Root password for the LDAP
  -s string
        DB Schema
  -schema value
        Additional/overwriting custom schema
  -suffix string
        Suffix for the LDAP
  -u string
        DB User
  -w string
        DB Password

Example

Start PostgreSQL server.

docker run --rm -d \
  -e POSTGRES_DB=testdb \
  -e POSTGRES_USER=testuser \
  -e POSTGRES_PASSWORD=testpass \
  -p 35432:5432 \
  postgres:13-alpine \
  -c log_destination=stderr \
  -c log_statement=all \
  -c log_connections=on \
  -c log_disconnections=on \
  -c jit=off

Start ldap-pg server.

ldap-pg -h localhost -u testuser -w testpass -d testdb -s public \
 -suffix dc=example,dc=com -root-dn cn=Manager,dc=example,dc=com -root-pw secret \
 -log-level info

[  info ] 2019/10/03 15:13:37 main.go:169: Setup GOMAXPROCS with NumCPU: 8
[  info ] 2019/10/03 15:13:37 main.go:234: Starting ldap-pg on 127.0.0.1:8389

ldap-pg creates required tables and indexes into the PostgreSQL if not exists. You can import your LDIF file by using standard LDAP tools like ldapadd command.

$ cat << EOS > base.ldif

dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Example Inc.
dc: example

dn: ou=Users,dc=example,dc=com
objectClass: organizationalUnit
ou: Users

dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Group

EOS

$ ldapadd -H ldap://localhost:8389 -x -D cn=manager,dc=example,dc=com -w secret -f base.ldif
adding new entry "dc=example,dc=com"

adding new entry "ou=Users,dc=example,dc=com"

adding new entry "ou=Groups,dc=example,dc=com"

Integration Test

Start PostgreSQL server.

docker run --rm -d \
  -e POSTGRES_DB=testdb \
  -e POSTGRES_USER=testuser \
  -e POSTGRES_PASSWORD=testpass \
  -p 35432:5432 \
  postgres:13-alpine \
  -c log_destination=stderr \
  -c log_statement=all \
  -c log_connections=on \
  -c log_disconnections=on \
  -c jit=off

Run test cases.

make it

License

Licensed under the GPL license.

Documentation

Index

Constants

View Source
const TIMESTAMP_FORMAT string = "20060102150405Z"
View Source
const TIMESTAMP_NANO_FORMAT string = "20060102150405.000000Z"

Variables

View Source
var (
	ErrInvalidHash         = errors.New("the encoded hash is not in the correct format")
	ErrIncompatibleVersion = errors.New("incompatible version of argon2")
)
View Source
var BASE_SCHEMA_OPENLDAP24 string = `` /* 165673-byte string literal not displayed */

ldapsearch -o ldif-wrap=no -H ldap://... -x -D "cn=..." -b "cn=Subschema" -v -s base attributeTypes comparators ditContentRules ditStructureRules ldapSyntaxes matchingRules matchingRuleUse nameForms normalizers objectClasses syntaxCheckers

View Source
var LASTBIND_OPERATION_SCHEMA_OPENLDAP24 = `` /* 284-byte string literal not displayed */

https://github.com/winlibs/openldap/blob/2615a35b32b3596a1e8f872f0c244bc4a41a047e/contrib/slapd-modules/lastbind/lastbind.c#L57-L63

View Source
var PPOLICY_OPERATION_SCHEMA_OPENLDAP24 = `` /* 573-byte string literal not displayed */

https://github.com/openldap/openldap/blob/98a0029daeb8aaa7bc58428ad3f94eface7f997b/doc/man/man5/slapo-ppolicy.5

View Source
var SPACE_PATTERN = regexp.MustCompile(`\s+`)

Functions

func NewHandler

func NewHandler(s *Server, handler func(s *Server, w ldap.ResponseWriter, r *ldap.Message)) func(w ldap.ResponseWriter, r *ldap.Message)

func NewInvalidDNError

func NewInvalidDNError(dnNorm string) error

func NewRetryError

func NewRetryError(err error) error

func ParseLanguageTag added in v0.12.2

func ParseLanguageTag(name string) (string, string, error)

func SetSessionContext

func SetSessionContext(parents context.Context, m *ldap.Message) context.Context

Types

type AddEntry

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

func NewAddEntry

func NewAddEntry(schemaMap *SchemaMap, dn *DN) *AddEntry

func (*AddEntry) Add

func (j *AddEntry) Add(attrName string, attrValue []string) error

Append to current value(s).

func (*AddEntry) Attrs

func (j *AddEntry) Attrs() (map[string][]interface{}, map[string][]string)

func (*AddEntry) DN

func (j *AddEntry) DN() *DN

func (*AddEntry) HasAttr

func (j *AddEntry) HasAttr(attrName string) bool

func (*AddEntry) IsDC

func (j *AddEntry) IsDC() bool

func (*AddEntry) IsRoot

func (j *AddEntry) IsRoot() bool

func (*AddEntry) ParentDN

func (j *AddEntry) ParentDN() *DN

func (*AddEntry) SetDN

func (j *AddEntry) SetDN(dn *DN)

func (*AddEntry) Validate

func (j *AddEntry) Validate() error

type ArrayFlags

type ArrayFlags []string
var CustomSchema ArrayFlags

func (*ArrayFlags) Set

func (a *ArrayFlags) Set(s string) error

func (*ArrayFlags) String

func (a *ArrayFlags) String() string

type AttributeType

type AttributeType struct {
	Name               string
	AName              []string
	Oid                string
	Equality           string
	Ordering           string
	Substr             string
	Syntax             string
	Sup                string
	Usage              string
	IndexType          string
	ColumnName         string
	SingleValue        bool
	NoUserModification bool
	LanguageTag        string
	// contains filtered or unexported fields
}

func (*AttributeType) IsAssociationAttribute

func (s *AttributeType) IsAssociationAttribute() bool

func (*AttributeType) IsCaseIgnore

func (s *AttributeType) IsCaseIgnore() bool

func (*AttributeType) IsCaseIgnoreSubstr

func (s *AttributeType) IsCaseIgnoreSubstr() bool

func (*AttributeType) IsNumberOrdering

func (s *AttributeType) IsNumberOrdering() bool

func (*AttributeType) IsOperationalAttribute

func (s *AttributeType) IsOperationalAttribute() bool

func (*AttributeType) IsReverseAssociationAttribute

func (s *AttributeType) IsReverseAssociationAttribute() bool

func (*AttributeType) NewSchemaValueMap

func (s *AttributeType) NewSchemaValueMap(size int) SchemaValueMap

type AttributeTypeAndValue

type AttributeTypeAndValue struct {
	// TypeOrig is the original attribute type
	TypeOrig string
	// TypeNorm is the normalized attribute type
	TypeNorm string
	// Value is the original attribute value
	ValueOrig string
	// Value is the encoded original attribute value
	ValueOrigEncoded string
	// Value is the normalized attribute value
	ValueNorm string
}

type AuthSession

type AuthSession struct {
	DN     *DN
	Groups []*DN
	IsRoot bool
}

func AuthSessionContext

func AuthSessionContext(ctx context.Context) (*AuthSession, error)

type DBRepository

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

type DN

type DN struct {
	RDNs     []*RelativeDN
	RDNIndex map[string]NormString
}

func NormalizeDN

func NormalizeDN(schemaMap *SchemaMap, dn string) (*DN, error)

func ParseDN

func ParseDN(schemaMap *SchemaMap, str string) (*DN, error)

ParseDN returns a distinguishedName or an error. The function respects https://tools.ietf.org/html/rfc4514 This function based on go-ldap/ldap/v3.

func (*DN) DNNormStr

func (d *DN) DNNormStr() string

func (*DN) DNNormStrWithoutSuffix

func (d *DN) DNNormStrWithoutSuffix(suffix *DN) string

func (*DN) DNOrigEncodedStrWithoutSuffix

func (d *DN) DNOrigEncodedStrWithoutSuffix(suffix *DN) string

func (*DN) DNOrigStr

func (d *DN) DNOrigStr() string

func (*DN) Equal

func (d *DN) Equal(o *DN) bool

func (*DN) IsAnonymous

func (d *DN) IsAnonymous() bool

func (*DN) IsDC

func (d *DN) IsDC() bool

func (*DN) IsRoot

func (d *DN) IsRoot() bool

func (*DN) IsSubOf

func (d *DN) IsSubOf(o *DN) bool

IsSubOf checks whether the arg DN is subset of self. Example:

self DN: ou=people,dc=exaple,dc=com
arg DN: dc=example,dc=com

=> true

func (*DN) Level

func (d *DN) Level() int

func (*DN) ModifyRDN

func (d *DN) ModifyRDN(schemaMap *SchemaMap, newRDN string, deleteOld bool) (*DN, *RelativeDN, error)

func (*DN) Move

func (d *DN) Move(newParentDN *DN) (*DN, error)

func (*DN) ParentDN

func (d *DN) ParentDN() *DN

func (*DN) RDN

func (d *DN) RDN() map[string]NormString

func (*DN) RDNNormStr

func (d *DN) RDNNormStr() string

func (*DN) RDNOrigEncodedStr

func (d *DN) RDNOrigEncodedStr() string

type FetchedCredential

type FetchedCredential struct {
	ID int64
	// Credential
	Credential []string
	// DN of the MemberOf
	MemberOf []*DN
	// PPolicy related to this entry
	PPolicy              *PPolicy
	PwdAccountLockedTime *time.Time
	LastPwdFailureTime   *time.Time
	PwdFailureCount      int
}

type FetchedDNOrig

type FetchedDNOrig struct {
	ID     int64  `db:"id"`
	DNOrig string `db:"dn_orig"`
}

type HybridDBEntry

type HybridDBEntry struct {
	ID        int64          `db:"id"`
	RDNNorm   string         `db:"rdn_norm"`
	RDNOrig   string         `db:"rdn_orig"`
	AttrsNorm types.JSONText `db:"attrs_norm"`
	AttrsOrig types.JSONText `db:"attrs_orig"`
	ParentDN  *DN
}

HybridDBEntry is used as insert or update entry.

type HybridDBFilterTranslator

type HybridDBFilterTranslator struct {
}

func (*HybridDBFilterTranslator) AnyMatch

func (t *HybridDBFilterTranslator) AnyMatch(s *AttributeType, sb *strings.Builder, val string, i int)

func (*HybridDBFilterTranslator) ApproxMatch

func (*HybridDBFilterTranslator) EndsMatch

func (t *HybridDBFilterTranslator) EndsMatch(s *AttributeType, sb *strings.Builder, val string, i int)

func (*HybridDBFilterTranslator) EqualityMatch

func (*HybridDBFilterTranslator) GreaterOrEqualMatch

func (t *HybridDBFilterTranslator) GreaterOrEqualMatch(s *AttributeType, q *HybridDBFilterTranslatorResult, val string, isNot bool)

func (*HybridDBFilterTranslator) LessOrEqualMatch

func (t *HybridDBFilterTranslator) LessOrEqualMatch(s *AttributeType, q *HybridDBFilterTranslatorResult, val string, isNot bool)

func (*HybridDBFilterTranslator) PresentMatch

func (*HybridDBFilterTranslator) StartsWithMatch

func (t *HybridDBFilterTranslator) StartsWithMatch(s *AttributeType, sb *strings.Builder, val string, i int)

type HybridDBFilterTranslatorResult

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

type HybridFetchedDBEntry

type HybridFetchedDBEntry struct {
	ID              int64          `db:"id"`
	ParentID        int64          `db:"parent_id"`
	RDNOrig         string         `db:"rdn_orig"`
	RawAttrsOrig    types.JSONText `db:"attrs_orig"`
	RawMember       types.JSONText `db:"member"`       // No real column in the table
	RawUniqueMember types.JSONText `db:"uniquemember"` // No real column in the table
	RawMemberOf     types.JSONText `db:"memberof"`     // No real column in the table
	HasSubordinates *bool          `db:"has_sub"`      // No real column in the table
	DNOrig          string         `db:"dn_orig"`      // No real column in the table
	Count           int32          `db:"count"`        // No real column in the table
}

func (*HybridFetchedDBEntry) AttrsOrig

func (e *HybridFetchedDBEntry) AttrsOrig() map[string][]string

func (*HybridFetchedDBEntry) Clear

func (e *HybridFetchedDBEntry) Clear()

type HybridRepository

type HybridRepository struct {
	*DBRepository
	// contains filtered or unexported fields
}

func (*HybridRepository) AddEntryToDBEntry

func (r *HybridRepository) AddEntryToDBEntry(ctx context.Context, tx *sqlx.Tx, entry *AddEntry) (*HybridDBEntry, map[string][]int64, error)

AddEntryToDBEntry converts LDAP entry object to DB entry object. It handles metadata such as createTimistamp, modifyTimestamp and entryUUID. Also, it handles member and uniqueMember attributes.

func (*HybridRepository) Bind

func (r *HybridRepository) Bind(ctx context.Context, dn *DN, callback func(current *FetchedCredential) error) error

func (HybridRepository) DeleteByDN

func (r HybridRepository) DeleteByDN(ctx context.Context, dn *DN) error

func (*HybridRepository) FindPPolicyByDN

func (r *HybridRepository) FindPPolicyByDN(ctx context.Context, dn *DN) (*PPolicy, error)

func (*HybridRepository) Init

func (r *HybridRepository) Init() error

func (*HybridRepository) Insert

func (r *HybridRepository) Insert(ctx context.Context, entry *AddEntry) (int64, error)

func (*HybridRepository) Search

func (r *HybridRepository) Search(ctx context.Context, baseDN *DN, option *SearchOption, handler func(entry *SearchEntry) error) (int32, int32, error)

func (*HybridRepository) Update

func (r *HybridRepository) Update(ctx context.Context, dn *DN, callback func(current *ModifyEntry) error) error

func (*HybridRepository) UpdateDN

func (r *HybridRepository) UpdateDN(ctx context.Context, oldDN, newDN *DN, oldRDN *RelativeDN) error

oldRDN: set when keeping current entry

type InvalidCredentials

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

func (InvalidCredentials) Error

func (i InvalidCredentials) Error() string

type InvalidDNError

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

func (*InvalidDNError) Error

func (e *InvalidDNError) Error() string

type LDAPAction

type LDAPAction int
const (
	AddOps LDAPAction = iota
	ModifyOps
	ModRDNOps
	DeleteOps
	SearchOps
)

func (LDAPAction) String

func (c LDAPAction) String() string

type LDAPError

type LDAPError struct {
	Code      int
	Msg       string
	MatchedDN string
	Subtype   string
	// contains filtered or unexported fields
}

func NewAccountLocked

func NewAccountLocked() *LDAPError

func NewAccountLocking

func NewAccountLocking() *LDAPError

func NewAlreadyExists

func NewAlreadyExists() *LDAPError

func NewInsufficientAccess

func NewInsufficientAccess() *LDAPError

func NewInvalidCredentials

func NewInvalidCredentials() *LDAPError

func NewInvalidDNSyntax

func NewInvalidDNSyntax() *LDAPError

func NewInvalidPerSyntax

func NewInvalidPerSyntax(attr string, valueidx int) *LDAPError

func NewMoreThanOnceError

func NewMoreThanOnceError(attr string, valueidx int) *LDAPError

func NewMultipleValuesConstraintViolation

func NewMultipleValuesConstraintViolation(attr string) *LDAPError

func NewMultipleValuesProvidedError

func NewMultipleValuesProvidedError(attr string) *LDAPError

func NewNoGlobalSuperiorKnowledge

func NewNoGlobalSuperiorKnowledge() *LDAPError

func NewNoSuchAttribute

func NewNoSuchAttribute(op, attr string) *LDAPError

func NewNoSuchObject

func NewNoSuchObject() *LDAPError

func NewNoSuchObjectWithMatchedDN

func NewNoSuchObjectWithMatchedDN(dn string) *LDAPError

func NewNoUserModificationAllowedConstraintViolation

func NewNoUserModificationAllowedConstraintViolation(attr string) *LDAPError

func NewNotAllowedOnNonLeaf

func NewNotAllowedOnNonLeaf() *LDAPError

func NewObjectClassModsProhibited

func NewObjectClassModsProhibited(from, to string) *LDAPError

func NewObjectClassViolation

func NewObjectClassViolation() *LDAPError

func NewObjectClassViolationInvalidStructualChain

func NewObjectClassViolationInvalidStructualChain(oc1, oc2 string) *LDAPError

func NewObjectClassViolationNoStructural

func NewObjectClassViolationNoStructural() *LDAPError

func NewObjectClassViolationNotAllowed

func NewObjectClassViolationNotAllowed(attrName string) *LDAPError

func NewObjectClassViolationRequiresAttribute

func NewObjectClassViolationRequiresAttribute(objectClass, attrName string) *LDAPError

func NewOperationsError

func NewOperationsError() *LDAPError

func NewSuccess

func NewSuccess() *LDAPError

func NewTypeOrValueExists

func NewTypeOrValueExists(op, attr string, valueidx int) *LDAPError

func NewUnavailable

func NewUnavailable() *LDAPError

func NewUndefinedType

func NewUndefinedType(attr string) *LDAPError

func (*LDAPError) Error

func (e *LDAPError) Error() string

func (*LDAPError) IsAccountLocked

func (e *LDAPError) IsAccountLocked() bool

func (*LDAPError) IsAccountLocking

func (e *LDAPError) IsAccountLocking() bool

func (*LDAPError) IsInvalidCredentials

func (e *LDAPError) IsInvalidCredentials() bool

func (*LDAPError) IsNoSuchObjectError

func (e *LDAPError) IsNoSuchObjectError() bool

func (*LDAPError) Unwrap

func (e *LDAPError) Unwrap() error

type LDAPPassThroughClient

type LDAPPassThroughClient struct {
	Server     string
	SearchBase string
	Timeout    int
	Filter     string
	BindDN     string
	Password   string
	Scope      string
}

func (*LDAPPassThroughClient) Authenticate

func (c *LDAPPassThroughClient) Authenticate(domain, user, password string) (bool, error)

type Mapper

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

func NewMapper

func NewMapper(server *Server) *Mapper

func (*Mapper) LDAPMessageToAddEntry

func (m *Mapper) LDAPMessageToAddEntry(dn *DN, ldapAttrs message.AttributeList) (*AddEntry, error)

type ModifyEntry

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

func NewModifyEntry

func NewModifyEntry(schemaMap *SchemaMap, dn *DN, attrsOrig map[string][]string) (*ModifyEntry, error)

func (*ModifyEntry) Add

func (j *ModifyEntry) Add(attrName string, attrValue []string) error

Append to current value(s).

func (*ModifyEntry) ApplyCurrent

func (j *ModifyEntry) ApplyCurrent(attrName string, attrValue []string) error

func (*ModifyEntry) Attrs

func (j *ModifyEntry) Attrs() (map[string][]interface{}, map[string][]string)

func (*ModifyEntry) Clone

func (e *ModifyEntry) Clone() *ModifyEntry

func (*ModifyEntry) DN

func (j *ModifyEntry) DN() *DN

func (*ModifyEntry) Delete

func (j *ModifyEntry) Delete(attrName string, attrValue []string) error

Delete from current value(s) if the value matchs.

func (*ModifyEntry) GetDNNorm

func (j *ModifyEntry) GetDNNorm() string

func (*ModifyEntry) GetDNOrig

func (j *ModifyEntry) GetDNOrig() string

func (*ModifyEntry) HasAttr

func (j *ModifyEntry) HasAttr(attrName string) bool

func (*ModifyEntry) HasKey

func (j *ModifyEntry) HasKey(s *AttributeType) bool

func (*ModifyEntry) ModifyRDN

func (e *ModifyEntry) ModifyRDN(newDN *DN) *ModifyEntry

func (*ModifyEntry) ObjectClassesNorm

func (j *ModifyEntry) ObjectClassesNorm() ([]string, bool)

func (*ModifyEntry) ObjectClassesOrig

func (j *ModifyEntry) ObjectClassesOrig() ([]string, bool)

func (*ModifyEntry) Put

func (j *ModifyEntry) Put(value *SchemaValue) error

func (*ModifyEntry) Replace

func (j *ModifyEntry) Replace(attrName string, attrValue []string) error

Replace with the value(s).

func (*ModifyEntry) SetDN

func (j *ModifyEntry) SetDN(dn *DN)

func (*ModifyEntry) Validate

func (j *ModifyEntry) Validate() error

type NormString

type NormString struct {
	Orig string
	Norm string
}

type ObjectClass

type ObjectClass struct {
	Name       string
	Oid        string
	Sup        string
	Structural bool
	Abstruct   bool
	Auxiliary  bool
	// contains filtered or unexported fields
}

func (*ObjectClass) Contains

func (o *ObjectClass) Contains(a string) bool

func (*ObjectClass) May

func (o *ObjectClass) May() []string

func (*ObjectClass) Must

func (o *ObjectClass) Must() []string

type PPolicy

type PPolicy struct {
	PwdAttribute       []string `json:"pwdAttribute"`
	PwdLockout         []string `json:"pwdLockout"`
	PwdLockoutDuration []string `json:"pwdLockoutDuration"`
	PwdMaxFailure      []string `json:"pwdMaxFailure"`
}

func (*PPolicy) IsLockoutEnabled

func (p *PPolicy) IsLockoutEnabled() bool

func (*PPolicy) LockoutDuration

func (p *PPolicy) LockoutDuration() int64

func (*PPolicy) MaxFailure

func (p *PPolicy) MaxFailure() int

func (*PPolicy) ShouldLockout

func (p *PPolicy) ShouldLockout(current int) bool

type PassThroughClient

type PassThroughClient interface {
	Authenticate(domain, user, password string) (bool, error)
}

type PassThroughConfig

type PassThroughConfig map[string]PassThroughClient

func (PassThroughConfig) Add

func (p PassThroughConfig) Add(domain string, client PassThroughClient)

func (PassThroughConfig) Get

func (PassThroughConfig) Has

func (p PassThroughConfig) Has(domain string) bool

type RelativeDN

type RelativeDN struct {
	Attributes []*AttributeTypeAndValue
}

func (*RelativeDN) NormStr

func (r *RelativeDN) NormStr() string

func (*RelativeDN) OrigEncodedStr

func (r *RelativeDN) OrigEncodedStr() string

type Repository

type Repository interface {
	// Init is called when initializing repository implementation.
	Init() error

	// Bind fetches the current bind entry by specified DN. Then execute callback with the entry.
	// The callback is expected checking the credential, account lock status and so on.
	// This is used for BIND operation.
	Bind(ctx context.Context, dn *DN, callback func(current *FetchedCredential) error) error

	// FindPPolicyByDN returns the password policy entry by specified DN.
	// This is used for password policy process.
	FindPPolicyByDN(ctx context.Context, dn *DN) (*PPolicy, error)

	// Search handles search request by filter.
	// This is used for SEARCH operation.
	Search(ctx context.Context, baseDN *DN, option *SearchOption, handler func(entry *SearchEntry) error) (int32, int32, error)

	// Update modifies the entry by specified change data.
	// This is used for MOD operation.
	Update(ctx context.Context, dn *DN, callback func(current *ModifyEntry) error) error

	// UpdateDN modifies the entry DN by specified change data.
	// This is used for MODRDN operation.
	UpdateDN(ctx context.Context, oldDN, newDN *DN, oldRDN *RelativeDN) error

	// Insert creates the entry by specified entry data.
	Insert(ctx context.Context, entry *AddEntry) (int64, error)

	// DeleteByDN deletes the entry by specified DN.
	DeleteByDN(ctx context.Context, dn *DN) error
}

func NewRepository

func NewRepository(server *Server) (Repository, error)

type RetryError

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

func (*RetryError) Error

func (e *RetryError) Error() string

func (*RetryError) Unwrap

func (e *RetryError) Unwrap() error

type SchemaMap

type SchemaMap struct {
	ObjectClasses  map[string]*ObjectClass
	AttributeTypes map[string]*AttributeType
	// contains filtered or unexported fields
}

func InitSchemaMap

func InitSchemaMap(server *Server) *SchemaMap

func NewSchema

func NewSchema(server *Server) *SchemaMap

func (*SchemaMap) AttributeType

func (s *SchemaMap) AttributeType(k string) (*AttributeType, bool)

func (*SchemaMap) Dump

func (s *SchemaMap) Dump() string

func (*SchemaMap) ObjectClass

func (s *SchemaMap) ObjectClass(k string) (*ObjectClass, bool)

func (*SchemaMap) PutAttributeType

func (s *SchemaMap) PutAttributeType(k string, attributeType *AttributeType)

func (*SchemaMap) PutObjectClass

func (s *SchemaMap) PutObjectClass(k string, objectClass *ObjectClass)

func (*SchemaMap) ValidateObjectClass

func (s *SchemaMap) ValidateObjectClass(ocs []string, attrs map[string]*SchemaValue) *LDAPError

type SchemaValue

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

func NewSchemaValue

func NewSchemaValue(schemaMap *SchemaMap, attrName string, attrValue []string) (*SchemaValue, error)

func (*SchemaValue) Add

func (s *SchemaValue) Add(value *SchemaValue) error

func (*SchemaValue) Clone

func (s *SchemaValue) Clone() *SchemaValue

func (*SchemaValue) Delete

func (s *SchemaValue) Delete(value *SchemaValue) error

func (*SchemaValue) Equals

func (s *SchemaValue) Equals(value *SchemaValue) bool

func (*SchemaValue) HasDuplicate

func (s *SchemaValue) HasDuplicate(value *SchemaValue) bool

func (*SchemaValue) IsAssociationAttribute

func (s *SchemaValue) IsAssociationAttribute() bool

func (*SchemaValue) IsEmpty

func (s *SchemaValue) IsEmpty() bool

func (*SchemaValue) IsNoUserModification

func (s *SchemaValue) IsNoUserModification() bool

func (*SchemaValue) IsNoUserModificationWithMigrationDisabled

func (s *SchemaValue) IsNoUserModificationWithMigrationDisabled() bool

func (*SchemaValue) IsSingle

func (s *SchemaValue) IsSingle() bool

func (*SchemaValue) LanguageTag added in v0.12.2

func (s *SchemaValue) LanguageTag() string

func (*SchemaValue) Name

func (s *SchemaValue) Name() string

func (*SchemaValue) Norm

func (s *SchemaValue) Norm() []interface{}

func (*SchemaValue) NormStr

func (s *SchemaValue) NormStr() []string

func (*SchemaValue) Orig

func (s *SchemaValue) Orig() []string

type SchemaValueMap

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

func (SchemaValueMap) Has

func (m SchemaValueMap) Has(val string) bool

func (SchemaValueMap) Put

func (m SchemaValueMap) Put(val string)

type SearchEntry

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

func NewSearchEntry

func NewSearchEntry(schemaMap *SchemaMap, dnOrig string, valuesOrig map[string][]string) *SearchEntry

func (*SearchEntry) DNOrig

func (j *SearchEntry) DNOrig() string

func (*SearchEntry) GetAttrOrig

func (j *SearchEntry) GetAttrOrig(attrName string) (string, []string, bool)

func (*SearchEntry) GetAttrsOrig

func (j *SearchEntry) GetAttrsOrig() map[string][]string

func (*SearchEntry) GetAttrsOrigWithoutOperationalAttrs

func (j *SearchEntry) GetAttrsOrigWithoutOperationalAttrs() map[string][]string

func (*SearchEntry) GetOperationalAttrsOrig

func (j *SearchEntry) GetOperationalAttrsOrig() map[string][]string

type SearchOption

type SearchOption struct {
	Scope                      int
	Filter                     message.Filter
	PageSize                   int32
	Offset                     int32
	RequestedAssocation        []string
	IsMemberOfRequested        bool
	IsHasSubordinatesRequested bool
}

type Server

type Server struct {
	Suffix *DN
	// contains filtered or unexported fields
}

func NewServer

func NewServer(c *ServerConfig) *Server

func (*Server) DCRDN

func (s *Server) DCRDN() string

func (*Server) GetRootDN

func (s *Server) GetRootDN() *DN

func (*Server) GetRootPW

func (s *Server) GetRootPW() string

func (*Server) GetSuffix

func (s *Server) GetSuffix() string

func (*Server) LoadSchema

func (s *Server) LoadSchema()

func (*Server) NormalizeDN

func (s *Server) NormalizeDN(dn string) (*DN, error)

func (*Server) Repo

func (s *Server) Repo() Repository

func (*Server) RequiredAuthz

func (s *Server) RequiredAuthz(m *ldap.Message, ops LDAPAction, targetDN *DN) bool

func (*Server) Start

func (s *Server) Start(bindAddress string)

func (*Server) Stop

func (s *Server) Stop()

func (*Server) SuffixNorm

func (s *Server) SuffixNorm() []string

func (*Server) SuffixOrig

func (s *Server) SuffixOrig() []string

func (*Server) SuffixOrigStr

func (s *Server) SuffixOrigStr() string

type ServerConfig

type ServerConfig struct {
	DBHostName        string
	DBPort            int
	DBName            string
	DBSchema          string
	DBUser            string
	DBPassword        string
	DBMaxOpenConns    int
	DBMaxIdleConns    int
	Suffix            string
	RootDN            string
	RootPW            string
	PassThroughConfig *PassThroughConfig
	BindAddress       string
	LogLevel          string
	PProfServer       string
	GoMaxProcs        int
	MigrationEnabled  bool
	QueryTranslator   string
	SimpleACL         []string
	DefaultPPolicyDN  string
}

type SimpleACL

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

func NewSimpleACL

func NewSimpleACL(server *Server) (*SimpleACL, error)

func (*SimpleACL) CanRead

func (s *SimpleACL) CanRead(session *AuthSession) bool

func (*SimpleACL) CanVisible

func (s *SimpleACL) CanVisible(session *AuthSession, attrName string) bool

func (*SimpleACL) CanWrite

func (s *SimpleACL) CanWrite(session *AuthSession) bool

type SimpleACLDef

type SimpleACLDef struct {
	Scope               SimpleACLScopeSet
	InvisibleAttributes StringSet
}

type SimpleACLScope

type SimpleACLScope int
const (
	ReadScope SimpleACLScope = iota
	WriteScope
)

func (SimpleACLScope) String

func (c SimpleACLScope) String() string

type SimpleACLScopeSet

type SimpleACLScopeSet map[SimpleACLScope]struct{}

func (SimpleACLScopeSet) Add

func (s SimpleACLScopeSet) Add(scope SimpleACLScope)

func (SimpleACLScopeSet) Contains

func (s SimpleACLScopeSet) Contains(scope SimpleACLScope) bool

type StmtCache

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

For generic filter

func (*StmtCache) Get

func (m *StmtCache) Get(key string) (*sqlx.NamedStmt, bool)

func (*StmtCache) Put

func (m *StmtCache) Put(key string, value *sqlx.NamedStmt)

type StringSet

type StringSet map[string]struct{}

func NewStringSet

func NewStringSet(str ...string) StringSet

func (StringSet) Add

func (s StringSet) Add(str string)

func (StringSet) Contains

func (s StringSet) Contains(str string) bool

func (StringSet) First

func (s StringSet) First() string

func (StringSet) Size

func (s StringSet) Size() int

func (StringSet) Values

func (s StringSet) Values() []string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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