Help us shape the future of Go! Take the 2026 Go Developer Survey

sql

package
v2.4.5 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 15 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