sql

package
v2.4.6 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package sql implements SQL passdb/userdb for yarilo-auth. Supports SQLite, MySQL, PostgreSQL via a unified interface, with customizable queries (password_query / user_query / iterate_query) and %u/%n/%d parameter substitution.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Driver            string // sqlite | mysql | postgres
	DSN               string
	PasswordQuery     string // optional; defaults to built-in yarilo_users schema
	UserQuery         string // optional; if set, userdb lookup uses this query
	IterateQuery      string // optional; for admin tooling (list users)
	DefaultPassScheme string // assumed scheme when stored password has no {SCHEME} prefix (default PLAIN)
	SkipSchema        bool   // do not auto-create yarilo_users
	// UsernameFilter skips this entry for names it does not accept.
	UsernameFilter protocol.UsernameFilter
	// Pool bounds the connection pool. The zero value still yields a
	// bounded, reusing pool.
	Pool sqlpool.Config
}

Config is the open-time configuration for a SQL passdb.

type Passdb

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

Passdb is an SQL-backed passdb (and optional userdb) entry.

func New

func New(c Config) (*Passdb, error)

New opens an SQL passdb.

func (*Passdb) Authenticate

func (p *Passdb) Authenticate(req *protocol.Request) (protocol.Result, error)

Authenticate verifies req.Username / req.Password against the SQL store, writing user fields into req.Fields on success. The Chain owns the bag; the Result drives chain control flow.

Outcomes:

ResultNext       - row not found here; chain falls through
ResultTempFail   - backend / query error (cause in the error return)
ResultFail       - user found but disabled OR password mismatch
ResultOK         - verified; req.Fields populated with user / home / mail

Columns match by name, not position. Only "password" is required; "home", "mail", "enabled" are optional (absent enabled = active). The optional UserQuery runs after the password check to enrich home/mail.

func (*Passdb) Close

func (p *Passdb) Close() error

Close releases the database connection.

func (*Passdb) DriverName

func (p *Passdb) DriverName() string

DriverName satisfies protocol.DriverName so passdb metrics carry the SQL dialect ("mysql" | "postgres" | "sqlite") rather than a generic label.

func (*Passdb) Iterate

func (p *Passdb) Iterate() ([]string, error)

Iterate runs the iterate_query and returns the list of usernames. Returns an error if iterate_query is not configured.

func (*Passdb) LookupCredentials

func (p *Passdb) LookupCredentials(username string) (bool, error)

LookupCredentials reports whether password_query finds the user.

func (*Passdb) LookupCredentialsFor

func (p *Passdb) LookupCredentialsFor(username string, v sqlvars.Vars) (bool, error)

LookupCredentialsFor is LookupCredentials with the request's values bound.

func (*Passdb) LookupSCRAMSha1

func (p *Passdb) LookupSCRAMSha1(username string) (*sasl.ScramCredentials, error)

LookupSCRAMSha1 satisfies protocol.SCRAMSha1Lookup. SHA-1 counterpart of LookupSCRAMSha256; only the verifier-blob scheme prefix differs.

func (*Passdb) LookupSCRAMSha1For

func (p *Passdb) LookupSCRAMSha1For(username string, v sqlvars.Vars) (*sasl.ScramCredentials, error)

LookupSCRAMSha1For is LookupSCRAMSha1 with the request's values bound.

func (*Passdb) LookupSCRAMSha256

func (p *Passdb) LookupSCRAMSha256(username string) (*sasl.ScramCredentials, error)

LookupSCRAMSha256 satisfies protocol.SCRAMSha256Lookup. Runs password_query, recognises the `{SCRAM-SHA-256}` scheme prefix, and returns the parsed ScramCredentials so the SASL mechanism drives challenge-response without a plain password.

Returns (nil, nil) when the user is unknown / disabled / not a SCRAM-SHA-256 verifier. The SCRAM server fabricates a fake verifier on nil so the exchange fails uniformly and users cannot be enumerated.

func (*Passdb) LookupSCRAMSha256For

func (p *Passdb) LookupSCRAMSha256For(username string, v sqlvars.Vars) (*sasl.ScramCredentials, error)

LookupSCRAMSha256For is LookupSCRAMSha256 with the request's values bound.

func (*Passdb) LookupUser

func (p *Passdb) LookupUser(username string) (home, mailLoc string, err error)

LookupUser runs the optional user_query and returns the userdb fields. Returns sql.ErrNoRows when the user does not exist.

func (*Passdb) UsesAddresses

func (p *Passdb) UsesAddresses() bool

UsesAddresses reports whether the password query reads the client's addresses, so an answer cached for one address cannot stand for another.

func (*Passdb) UsesRequest

func (p *Passdb) UsesRequest() bool

UsesRequest reports whether the password query reads anything besides the name; a static userdb checking names against it then does too.

type Userdb

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

Userdb is the SQL-backed implementation of protocol.Userdb. It shares Config + DSN with the existing Passdb (operators typically have one DB serving both roles) but is exposed as a separate type so a deployment can chain heterogeneous backends - e.g. SQL passdb + LDAP userdb.

The default lookup query selects the columns shipped in the built-in yarilo_users schema (home, mail). Operators with richer schemas point Config.UserQuery at their own SELECT that returns the column names listed in [defaultUserdbColumns] - see the rowScanner below for the exact mapping from column name → UserInfo field. Any column the row carries that does not match a known typed field lands in UserInfo.Extra so forward-compatibility is preserved without requiring driver changes for every new field.

func NewUserdb

func NewUserdb(c Config) (*Userdb, error)

NewUserdb opens an SQL userdb. The Config is shared with Passdb's New so callers can construct both from one block; the userdb honours Config.UserQuery and Config.IterateQuery, defaulting to the same yarilo_users columns the Passdb assumes when the operator has not overridden them.

func (*Userdb) Close

func (u *Userdb) Close() error

Close releases the underlying database connection.

func (*Userdb) Iterate

func (u *Userdb) Iterate() ([]string, error)

Iterate implements protocol.UserdbIterator when an iterate_query is configured. Returns an error if no query was set so callers can distinguish "no enumeration support" from "empty result".

func (*Userdb) Lookup

func (u *Userdb) Lookup(username string) (*protocol.UserInfo, error)

Lookup implements protocol.Userdb. Returns (nil, nil) when the query returns no rows so a UserdbChain falls through to the next backend; returns (nil, err) on driver / scan / parse errors so the chain short-circuits with the operator-visible failure.

func (*Userdb) LookupFor

func (u *Userdb) LookupFor(username string, v sqlvars.Vars) (*protocol.UserInfo, error)

LookupFor is Lookup with the request's values bound; a lookup that is not a login or a delivery passes none, and %s binds empty.

func (*Userdb) UsesRequest

func (u *Userdb) UsesRequest() bool

UsesRequest reports whether the user query reads the protocol (#2227).

Jump to

Keyboard shortcuts

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