auth

package
v0.0.0-...-853189d Latest Latest
Warning

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

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

Documentation

Overview

Package auth checks a user's password with modemmenu's backends (a users file, LDAP, SQL, the system's accounts by PAM), in turn, and changes it in the backend that holds the account.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoUser      = errors.New("no such user")
	ErrBadPassword = errors.New("wrong password")
)

ErrNoUser: the backend does not know the user (the next one is asked); ErrBadPassword: it knows the user, the password is wrong (no other backend is asked)

View Source
var ErrRefused = errors.New("new password refused")

ErrRefused: the backend did not take the new password (its policy)

Functions

func Authenticate

func Authenticate(ctx context.Context, backends []Authenticator, user, password string, logf func(string, ...any)) (string, error)

Authenticate with each backend in turn: the name of the one that accepted the user, or why none did

func Burn

func Burn(password string)

Burn: the time a password check takes, for an unknown user

func CheckPassword

func CheckPassword(stored, password, scheme string) (bool, error)

CheckPassword against a stored password, in the scheme its prefix or scheme (auto: by prefix) names:

$2a$, $2b$, $2y$ ...    bcrypt
{SHA256}hex, {SHA512}hex (or base64), {SSHA256}/{SSHA512}base64(hash+salt)
{PLAIN}text, or text with scheme = plain

func InGroupsNSS

func InGroupsNSS(acct *Account, groups []string) (bool, error)

InGroupsNSS: whether the account is in any of the groups, by the name service (/etc/group, LDAP via NSS...)

Types

type Account

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

Account: a user of the name service

func LookupNSS

func LookupNSS(name string) (*Account, error)

LookupNSS: the account from the name service (getpwnam with cgo)

type Authenticator

type Authenticator interface {
	Name() string
	Authenticate(ctx context.Context, user, password string) error
}

func NewFile

func NewFile(s *config.Section) (Authenticator, error)

NewFile: the [file] backend, its users file checked to exist

func NewLDAP

func NewLDAP(s *config.Section) (Authenticator, error)

NewLDAP: the ldap backend from its section, checked

func NewSQL

func NewSQL(s *config.Section) (Authenticator, error)

NewSQL: the sql backend, its database opened (not yet connected); args names the query's parameters (user, password)

func NewSystem

func NewSystem(s *config.Section) (Authenticator, error)

NewSystem: the [system] backend (PAM and the name service); an error when this modemmenu is built without PAM

type File

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

File: a text file of user:password lines (the password hashed as CheckPassword reads it, ! before it for a locked account; # comments), read at each login so that edits take effect at once

func (*File) Authenticate

func (a *File) Authenticate(_ context.Context, user, password string) error

Authenticate: the user's line in the users file and its hash checked; a locked entry (!) is refused

func (*File) CanChangePassword

func (a *File) CanChangePassword() bool

func (*File) ChangePassword

func (a *File) ChangePassword(_ context.Context, _ Messenger, user, old, new string) error

ChangePassword in the users file: the user's line rewritten in place (other lines as they are) under the lock signups take, the password as bcrypt (as text with hash = plain), a note after it kept

func (*File) Name

func (a *File) Name() string

Name: the backend's Name, for {auth} and the log

type LDAP

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

LDAP: a bind as the user, to bind_dn with {user} in it, or to the DN that search_filter finds under search_base (searched as search_bind_dn, anonymously if none)

func (*LDAP) Authenticate

func (a *LDAP) Authenticate(ctx context.Context, user, password string) error

Authenticate: a bind as the user (found by search, or by bind_dn)

func (*LDAP) CanChangePassword

func (a *LDAP) CanChangePassword() bool

CanChangePassword: always (exop or ad)

func (*LDAP) ChangePassword

func (a *LDAP) ChangePassword(_ context.Context, _ Messenger, user, old, new string) error

ChangePassword bound as the user, so that the server applies its own password policy: by the Password Modify extended operation (RFC 3062), or for Active Directory (password_change = ad, which does not have it) by replacing unicodePwd, the old value deleted and the new one added (which AD takes only over TLS: ldaps:// or starttls)

func (*LDAP) HasGroups

func (a *LDAP) HasGroups() bool

HasGroups: whether groups are looked up here (group_base is set)

func (*LDAP) MemberOf

func (a *LDAP) MemberOf(user, password, group string) (bool, error)

MemberOf: whether user is in group, an entry under group_base that group_filter ({group}, the user's {dn} and {user}) finds; searched as search_bind_dn, else as the user (with their password), else anonymously. ErrNoUser without group_base: LDAP has no groups here.

func (*LDAP) Name

func (a *LDAP) Name() string

Name: the backend's Name, for {auth} and the log

type Messenger

type Messenger interface {
	Write(s string) error
}

Messenger: the caller's line, for what a backend has to tell them

type PasswordChanger

type PasswordChanger interface {
	ChangePassword(ctx context.Context, t Messenger, user, old, new string) error
	// CanChangePassword: whether this backend is set up to (sql: an
	// update_query)
	CanChangePassword() bool
}

PasswordChanger: a backend that can change a user's password; old has been checked already. t is the caller's line, for a backend (PAM) that has something to tell them.

type SQL

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

SQL: query, with the user (and the password, for args = user password) as its arguments, returns the stored password of the user (checked as hash says), or with hash = none any row for a valid login

func (*SQL) Authenticate

func (a *SQL) Authenticate(ctx context.Context, user, password string) error

Authenticate: the query's row for the user, its first column the stored hash checked against the password (hash = none: a row is enough)

func (*SQL) CanChangePassword

func (a *SQL) CanChangePassword() bool

func (*SQL) ChangePassword

func (a *SQL) ChangePassword(ctx context.Context, _ Messenger, user, old, new string) error

ChangePassword in the database: update_query with update_args, the password as update_hash says

func (*SQL) Name

func (a *SQL) Name() string

Name: the backend's Name, for {auth} and the log

type System

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

System: the accounts of the system, by PAM: the auth and account stacks of pam_service, in a build with -tags pam. Only accounts with a uid of at least min_uid (not root, unless allow_root), in one of groups if it is set, may log in.

func (*System) Authenticate

func (a *System) Authenticate(_ context.Context, user, password string) error

Authenticate: the account looked up, min_uid, root and groups checked, then the password by PAM

func (*System) CanChangePassword

func (a *System) CanChangePassword() bool

func (*System) ChangePassword

func (a *System) ChangePassword(_ context.Context, t Messenger, user, old, new string) error

ChangePassword by PAM: the service's password stack

func (*System) Name

func (a *System) Name() string

Name: the backend's Name, for {auth} and the log

Jump to

Keyboard shortcuts

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