ipa

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: BSD-3-Clause Imports: 29 Imported by: 1

README

goipa

Go client library for the FreeIPA / Red Hat IdM JSON-RPC API.

CI Coverage Go Reference Release Go version License

goipa talks to a FreeIPA server over HTTPS using its JSON-RPC API. It logs in with a password, a keytab, a Kerberos credential cache or an existing session, and gives you typed Go calls for users, stage users, groups with their members and member managers, hosts, passwords and lockout, password policy, sub-IDs, HBAC/sudo rules and hbactest, passkeys and OTP tokens.

Note: This is the maintained continuation of ubccr/goipa by Andrew E. Bruno, which has had no release since 2024. It is a drop-in replacement for ubccr/goipa v0.0.7; see Migrating from ubccr/goipa. It is developed alongside mokey, a FreeIPA self-service portal.

Features

  • Login: password (Login, RemoteLogin), keytab (LoginWithKeytab), Kerberos credential cache (LoginFromCCache), or a saved session ID (NewDefaultClientWithSession)
  • Reads the host, realm and CA from /etc/ipa/default.conf and /etc/ipa/ca.crt on enrolled machines, or takes them explicitly (NewClient, NewClientCustomHttp)
  • Users: show, find, add (with random or given password), modify, enable, disable, delete
  • Passwords: set, change (with OTP), reset; typed errors for policy, invalid and expired passwords
  • SSH public keys and user authentication types (password, OTP, ...)
  • OTP tokens: add, list, enable, disable, remove, sync (SyncOTPToken)
  • Stage users: add, show, find, modify, activate, delete (StageUserAdd, StageUserActivate, ...)
  • Groups: show, find, add, modify, delete; members and member managers (GroupAddMember, GroupAddMemberManager, ...), with per-member failures returned as *MemberError
  • Hosts: show, find (HostShow, HostFind)
  • Lockout: per-replica failed logins and unlock (UserStatus, UserUnlock)
  • Password policy: group, global and effective per user (PwPolicyShow, UserPwPolicy)
  • Sub-IDs: find, generate (SubIDFind, SubIDGenerate)
  • HBAC and sudo: rule lookups and access checks (HBACRuleFind, SudoRuleFind, HBACTest)
  • Passkeys: add, remove (UserAddPasskey, UserRemovePasskey)
  • Typed errors: errors.Is(err, ipa.ErrNotFound) and friends; server errors are a bare *IpaError with Code, Name and Data
  • A …Context variant of every call that talks to the server (the Kerberos logins excepted)
  • RPC / RPCContext for any other command, reusing the client's TLS config, session or Kerberos auth and API version
  • ipatest, a fake FreeIPA server for your own tests

See the roadmap for what is next.

Install

go get github.com/neverlless/goipa

Requires Go 1.26 or newer. The package name is ipa.

Usage

On a host enrolled in FreeIPA (with /etc/ipa/default.conf), log in with a keytab and show a user:

package main

import (
	"fmt"
	"log"

	ipa "github.com/neverlless/goipa"
)

func main() {
	client := ipa.NewDefaultClient()

	if err := client.LoginWithKeytab("/etc/myapp/myapp.keytab", "myapp"); err != nil {
		log.Fatal(err)
	}

	user, err := client.UserShow("jdoe")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s <%s> uid=%s groups=%v\n", user.DisplayName, user.Email, user.Uid, user.Groups)
}

Elsewhere, name the server and realm and log in with a password:

client := ipa.NewClient("ipa.example.com", "EXAMPLE.COM")
if err := client.RemoteLogin("jdoe", password); err != nil {
	switch {
	case errors.Is(err, ipa.ErrExpiredPassword):
		// ask for a new password, then client.SetPassword(...)
	case errors.Is(err, ipa.ErrInvalidPassword):
		// wrong password
	}
}
// Keep client.SessionID() and reuse it later with NewDefaultClientWithSession.

Full API reference: pkg.go.dev/github.com/neverlless/goipa.

Migrating from ubccr/goipa

The API is the same as ubccr/goipa v0.0.7. Change the import path:

grep -rl ubccr/goipa --include='*.go' . | xargs sed -i 's#ubccr/goipa#neverlless/goipa#'
go mod tidy

On macOS use sed -i ''. What changed since v0.0.7 is listed in the ChangeLog.

Differences from upstream

  • Security updates: golang.org/x/crypto and friends are current, and Dependabot and govulncheck keep them that way
  • Bug fixes: ErrUserExists no longer has the same message as ErrUnauthorized; Kerberos and request-building errors are returned instead of being ignored
  • go test ./... runs without a FreeIPA server; tests that need one are behind the integration build tag
  • CI with race detector, staticcheck, gosec and govulncheck
  • No logging: upstream's trace logs wrote passwords, random passwords and session cookies into the caller's log
  • A Client is safe for concurrent use
  • include and includedir in krb5.conf are resolved, so Kerberos logins work on ipa-client 4.13 hosts
  • The RPC escape hatch, typed errors and context.Context support
  • ipatest, a fake FreeIPA server, and contract tests that run the same checks nightly against real FreeIPA 4.9, 4.12 and 4.13

Development

go test -race ./...

Consumers can test their own code without a FreeIPA server using the fake in ipatest.

Integration tests run against a real FreeIPA in a container (Linux, Docker, sudo):

scripts/ipa-up.sh && (set -a; . ./.env; set +a; go test -race -tags integration -count=1 ./...) ; scripts/ipa-up.sh down

ipa-up.sh rewrites /etc/krb5.conf (backed up once to /etc/krb5.conf.goipa-bak), /etc/ipa/ and your ccache, and refuses to run on a host whose /etc/ipa/default.conf points at another IPA server unless FORCE=1 is set.

See CONTRIBUTING.md before sending a pull request.

Security

Report vulnerabilities privately; see SECURITY.md.

License

goipa is released under a BSD-style license. See LICENSE and NOTICE. Copyright 2015 Andrew E. Bruno and the goipa authors (AUTHORS.rst).

Documentation

Overview

Package ipa is a Go client for the FreeIPA JSON-RPC API. It is a maintained continuation of github.com/ubccr/goipa.

A Client logs in with a password (Login for Kerberos, RemoteLogin for the web API), a keytab (LoginWithKeytab), a credentials cache (LoginFromCCache), or an existing session (NewDefaultClientWithSession, SetSessionID). A *Client is safe for concurrent use.

A FreeIPA error is returned as a bare *IpaError: match it with errors.Is against ErrNotFound and the other sentinels, or with a type assertion.

Every method that talks to the server has a ...Context twin that bounds the request with a context, except Login, LoginWithKeytab and LoginFromCCache (gokrb5 is not cancellable). RPC calls any command goipa does not wrap.

Example (Login)

The Kerberos logins need a KDC, so this example is compiled but not run.

package main

import (
	"fmt"
	"log"

	ipa "github.com/neverlless/goipa"
)

func main() {
	c := ipa.NewClient("ipa.example.com", "EXAMPLE.COM")
	if err := c.LoginWithKeytab("/etc/app/app.keytab", "svc-app"); err != nil {
		log.Fatal(err)
	}

	u, err := c.UserShow("jesse")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(u.Username, u.Email)
}

Index

Examples

Constants

View Source
const (
	CodeVersion              = 901
	CodeCommand              = 905
	CodeReferer              = 911
	CodeACI                  = 2100
	CodeOption               = 3005
	CodeRequirement          = 3007
	CodeValidation           = 3009
	CodeNotFound             = 4001
	CodeDuplicateEntry       = 4002
	CodeAlreadyActive        = 4009
	CodeAlreadyInactive      = 4010
	CodeNotGroupMember       = 4012
	CodeAlreadyGroupMember   = 4014
	CodeAttrValueNotFound    = 4026
	CodeAlreadyContainsValue = 4038
	CodeEmptyModlist         = 4202
	CodeDatabase             = 4203
)

FreeIPA error codes (ipalib.errors).

View Source
const (
	DefaultKerbConf   = "/etc/krb5.conf"
	IpaClientVersion  = "2.237"
	IpaDatetimeFormat = "20060102150405Z"
)
View Source
const (
	AlgorithmSHA1   = "sha1"
	AlgorithmSHA256 = "sha256"
	AlgorithmSHA384 = "sha384"
	AlgorithmSHA512 = "sha512"
)

OTP Token hash Algorithms supported by FreeIPA

View Source
const (
	TokenTypeTOTP = "totp"
	TokenTypeHOTP = "hotp"
)

OTP Token types supported by FreeIPA

Variables

View Source
var (
	ErrNotFound       = &IpaError{Code: CodeNotFound, Name: "NotFound", Message: "not found"}
	ErrDuplicateEntry = &IpaError{Code: CodeDuplicateEntry, Name: "DuplicateEntry", Message: "entry already exists"}
	ErrACI            = &IpaError{Code: CodeACI, Name: "ACIError", Message: "insufficient access"}
	ErrEmptyModlist   = &IpaError{Code: CodeEmptyModlist, Name: "EmptyModlist", Message: "no modifications to be performed"}
)

Sentinels for common FreeIPA errors. They are matched with errors.Is by code only; any other code is available through errors.As and IpaError.Code.

View Source
var (
	// ErrPasswordPolicy is returned when a password does not conform to the password policy
	ErrPasswordPolicy = errors.New("password does not conform to policy")

	// ErrInvalidPassword is returned when a password is invalid
	ErrInvalidPassword = errors.New("invalid current password")

	// ErrInvalidCredentials is returned by SyncOTPToken when FreeIPA rejects
	// the user, password or codes (X-IPA-TokenSync-Result: invalid-credentials).
	ErrInvalidCredentials = errors.New("invalid user, password or OTP codes")

	// ErrExpiredPassword is returned when a password is expired
	ErrExpiredPassword = errors.New("password expired")

	// ErrUnauthorized is returned when user is not authorized
	ErrUnauthorized = errors.New("unauthorized")

	// ErrUserExists is returned when user account already exists. UserAdd
	// returns it for FreeIPA's DuplicateEntry (4002).
	ErrUserExists = errors.New("user exists")
)

Functions

func ParseDateTime

func ParseDateTime(str string) time.Time

Parse a FreeIPA datetime. Datetimes in FreeIPA are returned using a class-hint system. Values are stored as an array with a single element indicating the type and value, for example, '[{"__datetime__": "YYYY-MM-DDTHH:MM:SSZ"]}'

Types

type Client

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

FreeIPA Client

Methods with a Context suffix bound the HTTP request with the given context. Kerberos login and SPNEGO header generation are not cancellable (gokrb5 has no context support), so Login, LoginWithKeytab and LoginFromCCache have no Context twins.

func NewClient

func NewClient(host, realm string) *Client

New IPA Client with host and realm

func NewClientCustomHttp

func NewClientCustomHttp(host, realm string, httpClient *http.Client) *Client

New IPA Client with host, realm and custom http client

func NewDefaultClient

func NewDefaultClient() *Client

New default IPA Client using host and realm from /etc/ipa/default.conf

func NewDefaultClientWithSession

func NewDefaultClientWithSession(sessionID string) *Client

New default IPA Client with existing sessionID using host and realm from /etc/ipa/default.conf

func (*Client) AddOTPToken

func (c *Client) AddOTPToken(token *OTPToken) (*OTPToken, error)

Add OTP token. Returns new OTPToken

func (*Client) AddOTPTokenContext added in v0.2.0

func (c *Client) AddOTPTokenContext(ctx context.Context, token *OTPToken) (*OTPToken, error)

AddOTPTokenContext is like AddOTPToken but bounds the request with ctx.

func (*Client) ChangePassword

func (c *Client) ChangePassword(username, oldPasswd, newPasswd, otpcode string) error

Change user password. This will run the passwd ipa command. Optionally provide an OTP if required

func (*Client) ChangePasswordContext added in v0.2.0

func (c *Client) ChangePasswordContext(ctx context.Context, username, oldPasswd, newPasswd, otpcode string) error

ChangePasswordContext is like ChangePassword but bounds the request with ctx.

func (*Client) ClearSession

func (c *Client) ClearSession()

Clears out FreeIPA session id

func (*Client) DisableOTPToken

func (c *Client) DisableOTPToken(tokenUUID string) error

Disable OTP token.

func (*Client) DisableOTPTokenContext added in v0.2.0

func (c *Client) DisableOTPTokenContext(ctx context.Context, tokenUUID string) error

DisableOTPTokenContext is like DisableOTPToken but bounds the request with ctx.

func (*Client) EnableOTPToken

func (c *Client) EnableOTPToken(tokenUUID string) error

Enable OTP token.

func (*Client) EnableOTPTokenContext added in v0.2.0

func (c *Client) EnableOTPTokenContext(ctx context.Context, tokenUUID string) error

EnableOTPTokenContext is like EnableOTPToken but bounds the request with ctx.

func (*Client) FetchOTPTokens

func (c *Client) FetchOTPTokens(owner string) ([]*OTPToken, error)

Fetch OTP tokens by owner.

func (*Client) FetchOTPTokensContext added in v0.2.0

func (c *Client) FetchOTPTokensContext(ctx context.Context, owner string) ([]*OTPToken, error)

FetchOTPTokensContext is like FetchOTPTokens but bounds the request with ctx.

func (*Client) GroupAdd added in v0.4.0

func (c *Client) GroupAdd(group *Group) (*Group, error)

GroupAdd creates a group with `group_add` and returns it; it requires the Group Administrators privilege (System: Add Groups). A zero Group creates a POSIX group, as `ipa group-add` does; set NonPOSIX for a group without a GID.

func (*Client) GroupAddContext added in v0.4.0

func (c *Client) GroupAddContext(ctx context.Context, group *Group) (*Group, error)

GroupAddContext is like GroupAdd but bounds the request with ctx.

func (*Client) GroupAddMember added in v0.4.0

func (c *Client) GroupAddMember(group string, users, groups []string) (*Group, error)

GroupAddMember adds users and groups to a group with `group_add_member`. It needs the Group Administrators or Modify Group membership privilege, or the caller is a member manager of the group; per-member problems, including insufficient access, are returned as *MemberError, together with the group as it stands. This is the context-aware API from ubccr/goipa#17, generalised to users and groups.

func (*Client) GroupAddMemberContext added in v0.4.0

func (c *Client) GroupAddMemberContext(ctx context.Context, group string, users, groups []string) (*Group, error)

GroupAddMemberContext is like GroupAddMember but bounds the request with ctx.

func (*Client) GroupAddMemberManager added in v0.4.0

func (c *Client) GroupAddMemberManager(group string, users, groups []string) (*Group, error)

GroupAddMemberManager makes users and groups member managers of a group with `group_add_member_manager`; it requires the Group Administrators privilege (System: Modify Groups). Per-member problems are returned as *MemberError, together with the group as it stands.

func (*Client) GroupAddMemberManagerContext added in v0.4.0

func (c *Client) GroupAddMemberManagerContext(ctx context.Context, group string, users, groups []string) (*Group, error)

GroupAddMemberManagerContext is like GroupAddMemberManager but bounds the request with ctx.

func (*Client) GroupDelete added in v0.4.0

func (c *Client) GroupDelete(names ...string) error

GroupDelete deletes groups with `group_del`; it requires the Group Administrators privilege (System: Remove Groups).

func (*Client) GroupDeleteContext added in v0.4.0

func (c *Client) GroupDeleteContext(ctx context.Context, names ...string) error

GroupDeleteContext is like GroupDelete but bounds the request with ctx.

func (*Client) GroupFind added in v0.4.0

func (c *Client) GroupFind(options Options) ([]*Group, error)

GroupFind finds groups with `group_find`; options are passed through (e.g. `cn`, `user`, `in_group`, `sizelimit`). Any authenticated user may read groups (System: Read Groups).

func (*Client) GroupFindContext added in v0.4.0

func (c *Client) GroupFindContext(ctx context.Context, options Options) ([]*Group, error)

GroupFindContext is like GroupFind but bounds the request with ctx.

func (*Client) GroupMod added in v0.4.0

func (c *Client) GroupMod(group *Group) (*Group, error)

GroupMod changes a group's description (an empty one clears it) and, for a POSIX group, its GID with `group_mod`; it requires the Group Administrators privilege (System: Modify Groups). It returns group itself when nothing changed. Conversion between group types and renames go through RPC.

func (*Client) GroupModContext added in v0.4.0

func (c *Client) GroupModContext(ctx context.Context, group *Group) (*Group, error)

GroupModContext is like GroupMod but bounds the request with ctx.

func (*Client) GroupRemoveMember added in v0.4.0

func (c *Client) GroupRemoveMember(group string, users, groups []string) (*Group, error)

GroupRemoveMember removes users and groups from a group with `group_remove_member`. It needs the Group Administrators or Modify Group membership privilege, or the caller is a member manager of the group; per-member problems, including insufficient access, are returned as *MemberError, together with the group as it stands.

func (*Client) GroupRemoveMemberContext added in v0.4.0

func (c *Client) GroupRemoveMemberContext(ctx context.Context, group string, users, groups []string) (*Group, error)

GroupRemoveMemberContext is like GroupRemoveMember but bounds the request with ctx.

func (*Client) GroupRemoveMemberManager added in v0.4.0

func (c *Client) GroupRemoveMemberManager(group string, users, groups []string) (*Group, error)

GroupRemoveMemberManager removes member managers from a group with `group_remove_member_manager`; it requires the Group Administrators privilege (System: Modify Groups). Per-member problems are returned as *MemberError, together with the group as it stands.

func (*Client) GroupRemoveMemberManagerContext added in v0.4.0

func (c *Client) GroupRemoveMemberManagerContext(ctx context.Context, group string, users, groups []string) (*Group, error)

GroupRemoveMemberManagerContext is like GroupRemoveMemberManager but bounds the request with ctx.

func (*Client) GroupShow added in v0.4.0

func (c *Client) GroupShow(name string) (*Group, error)

GroupShow fetches a group with `group_show`. Any authenticated user may read groups (System: Read Groups).

func (*Client) GroupShowContext added in v0.4.0

func (c *Client) GroupShowContext(ctx context.Context, name string) (*Group, error)

GroupShowContext is like GroupShow but bounds the request with ctx.

func (*Client) HBACRuleFind added in v0.5.0

func (c *Client) HBACRuleFind(options Options) ([]*HBACRule, error)

HBACRuleFind finds HBAC rules with `hbacrule_find`; options are passed through (e.g. `cn`, `ipaenabledflag`, `sizelimit`). Any authenticated user may read rules (System: Read HBAC Rules). FreeIPA returns at most its search limit (100 by default) unless `sizelimit` is set.

func (*Client) HBACRuleFindContext added in v0.5.0

func (c *Client) HBACRuleFindContext(ctx context.Context, options Options) ([]*HBACRule, error)

HBACRuleFindContext is like HBACRuleFind but bounds the request with ctx.

func (*Client) HBACTest added in v0.5.0

func (c *Client) HBACTest(user, host, service string, rules ...string) (*HBACTestResult, error)

HBACTest runs `hbactest`. It evaluates HBAC rules on the server: every enabled rule, or only rules, disabled ones included. Any authenticated user may run it; it reads rules and group membership as the caller. FreeIPA ignores an unknown user, host or service instead of failing, so a typo reads as denied. If a name in rules does not exist, nothing is evaluated: Granted is false and Errors lists the unresolved names.

func (*Client) HBACTestContext added in v0.5.0

func (c *Client) HBACTestContext(ctx context.Context, user, host, service string, rules ...string) (*HBACTestResult, error)

HBACTestContext is like HBACTest but bounds the request with ctx.

func (*Client) Host

func (c *Client) Host() string

Returns FreeIPA server hostname

func (*Client) HostFind added in v0.4.0

func (c *Client) HostFind(options Options) ([]*Host, error)

HostFind finds hosts with `host_find`; options are passed through (e.g. `fqdn`, `in_hostgroup`, `sizelimit`). Any authenticated user may read hosts (System: Read Hosts). ubccr/goipa#11.

func (*Client) HostFindContext added in v0.4.0

func (c *Client) HostFindContext(ctx context.Context, options Options) ([]*Host, error)

HostFindContext is like HostFind but bounds the request with ctx.

func (*Client) HostShow added in v0.4.0

func (c *Client) HostShow(fqdn string) (*Host, error)

HostShow fetches a host with `host_show`. Any authenticated user may read hosts (System: Read Hosts). ubccr/goipa#11.

func (*Client) HostShowContext added in v0.4.0

func (c *Client) HostShowContext(ctx context.Context, fqdn string) (*Host, error)

HostShowContext is like HostShow but bounds the request with ctx.

func (*Client) Login

func (c *Client) Login(username, password string) error

Login to FreeIPA using local kerberos login username and password

Example

Login gets a Kerberos ticket for the password, which later calls authenticate with; it needs /etc/krb5.conf and a KDC, so it is compiled but not run.

package main

import (
	"log"

	ipa "github.com/neverlless/goipa"
)

func main() {
	c := ipa.NewClient("ipa.example.com", "EXAMPLE.COM")
	if err := c.Login("jesse", "secret"); err != nil {
		log.Fatal(err)
	}
}

func (*Client) LoginFromCCache

func (c *Client) LoginFromCCache(cpath string) error

Login to FreeIPA using credentials cache

Example

LoginFromCCache reuses a ticket obtained with kinit; compiled but not run.

package main

import (
	"log"

	ipa "github.com/neverlless/goipa"
)

func main() {
	c := ipa.NewDefaultClient()
	if err := c.LoginFromCCache("/tmp/krb5cc_1000"); err != nil {
		log.Fatal(err)
	}
}

func (*Client) LoginWithKeytab

func (c *Client) LoginWithKeytab(ktab, username string) error

Login to FreeIPA using local kerberos login with keytab and username

func (*Client) Ping

func (c *Client) Ping() (*Response, error)

Ping FreeIPA server to check connection

func (*Client) PingContext added in v0.2.0

func (c *Client) PingContext(ctx context.Context) (*Response, error)

PingContext is like Ping but bounds the request with ctx.

func (*Client) PwPolicyShow added in v0.5.0

func (c *Client) PwPolicyShow(group string) (*PwPolicy, error)

PwPolicyShow fetches the password policy of group with `pwpolicy_show`; "" is the global_policy. It needs the Password Policy Readers or Password Policy Administrator privilege (System: Read Group Password Policy); without it FreeIPA hides the entry and answers ErrNotFound, not ErrACI.

func (*Client) PwPolicyShowContext added in v0.5.0

func (c *Client) PwPolicyShowContext(ctx context.Context, group string) (*PwPolicy, error)

PwPolicyShowContext is like PwPolicyShow but bounds the request with ctx.

func (*Client) RPC added in v0.2.0

func (c *Client) RPC(method string, args []string, options Options) (*Response, error)

RPC calls any FreeIPA command, an escape hatch for commands goipa does not wrap. It uses the client's HTTP client, session or Kerberos credentials and API version. A FreeIPA failure is returned as a bare *IpaError. options is not modified; a "version" in options wins over IpaClientVersion.

Example
package main

import (
	"fmt"
	"log"

	"github.com/neverlless/goipa/ipatest"
)

func main() {
	s := ipatest.New()
	defer s.Close()

	res, err := s.ClientAs("admin").RPC("ping", nil, nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res.Principal, res.Version)
}
Output:
admin@TEST.LOCAL 4.13.4

func (*Client) RPCContext added in v0.2.0

func (c *Client) RPCContext(ctx context.Context, method string, args []string, options Options) (*Response, error)

RPCContext is like RPC but ends the request when ctx is done.

func (*Client) Realm

func (c *Client) Realm() string

Returns FreeIPA realm

func (*Client) RemoteLogin

func (c *Client) RemoteLogin(uid, passwd string) error

Login to FreeIPA using web API with uid/passwd and set the FreeIPA session id on the client for subsequent requests.

Example

RemoteLogin posts the password to /ipa/session/login_password. Its session ID can be stored, for example in a web session, and reused later without logging in again; compiled but not run.

package main

import (
	"fmt"
	"log"

	ipa "github.com/neverlless/goipa"
)

func main() {
	c := ipa.NewDefaultClient()
	if err := c.RemoteLogin("jesse", "secret"); err != nil {
		log.Fatal(err)
	}
	sid := c.SessionID()

	later := ipa.NewDefaultClientWithSession(sid)
	u, err := later.UserShow("jesse")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(u.Username)
}

func (*Client) RemoteLoginContext added in v0.2.0

func (c *Client) RemoteLoginContext(ctx context.Context, uid, passwd string) error

RemoteLoginContext is like RemoteLogin but bounds the request with ctx.

func (*Client) RemoveOTPToken

func (c *Client) RemoveOTPToken(tokenUUID string) error

Remove OTP token

func (*Client) RemoveOTPTokenContext added in v0.2.0

func (c *Client) RemoveOTPTokenContext(ctx context.Context, tokenUUID string) error

RemoveOTPTokenContext is like RemoveOTPToken but bounds the request with ctx.

func (*Client) ResetPassword

func (c *Client) ResetPassword(username string) (string, error)

Reset user password and return new random password

func (*Client) ResetPasswordContext added in v0.2.0

func (c *Client) ResetPasswordContext(ctx context.Context, username string) (string, error)

ResetPasswordContext is like ResetPassword but bounds the request with ctx.

func (*Client) SessionID

func (c *Client) SessionID() string

Return current FreeIPA sessionID

func (*Client) SetAuthTypes

func (c *Client) SetAuthTypes(username string, types []string) error

Update user authentication types.

func (*Client) SetAuthTypesContext added in v0.2.0

func (c *Client) SetAuthTypesContext(ctx context.Context, username string, types []string) error

SetAuthTypesContext is like SetAuthTypes but bounds the request with ctx.

func (*Client) SetPassword

func (c *Client) SetPassword(username, oldPasswd, newPasswd, otpcode string) error

Set user password. In FreeIPA when a password is first set or when a password is later reset it is marked as immediately expired and requires the owner to perform a password change. See here https://www.freeipa.org/page/New_Passwords_Expired for more details. This function exists to circumvent the "new passwords expired" feature of FreeIPA and allow an administrator to set a new password for a user without it being expired. This is acheived, for example, by first calling ResetPassword() then immediately calling this function. *WARNING* See https://www.freeipa.org/page/Self-Service_Password_Reset for security issues and possible weaknesses of this approach.

func (*Client) SetPasswordContext added in v0.2.0

func (c *Client) SetPasswordContext(ctx context.Context, username, oldPasswd, newPasswd, otpcode string) error

SetPasswordContext is like SetPassword but bounds the request with ctx.

func (*Client) SetSessionID added in v0.2.0

func (c *Client) SetSessionID(sessionID string)

SetSessionID restores a session saved from SessionID (for example in a web session store) on any client. An empty string clears it.

func (*Client) StageUserActivate added in v0.5.0

func (c *Client) StageUserActivate(username string) (*User, error)

StageUserActivate activates a stage user with `stageuser_activate` and returns the new active user. It requires the Stage User Administrators and User Administrators privileges. If an active user with that name exists, FreeIPA answers ErrDuplicateEntry and keeps the stage entry.

func (*Client) StageUserActivateContext added in v0.5.0

func (c *Client) StageUserActivateContext(ctx context.Context, username string) (*User, error)

StageUserActivateContext is like StageUserActivate but bounds the request with ctx.

func (*Client) StageUserAdd added in v0.5.0

func (c *Client) StageUserAdd(user *User) (*User, error)

StageUserAdd adds a stage user with `stageuser_add`. Username, First and Last are required; empty fields are not sent. It requires the Stage User Administrators privilege (add also: Stage User Provisioning). A duplicate returns the bare *IpaError (ErrDuplicateEntry), not ErrUserExists.

func (*Client) StageUserAddContext added in v0.5.0

func (c *Client) StageUserAddContext(ctx context.Context, user *User) (*User, error)

StageUserAddContext is like StageUserAdd but bounds the request with ctx.

func (*Client) StageUserDelete added in v0.5.0

func (c *Client) StageUserDelete(usernames ...string) error

StageUserDelete deletes stage users with `stageuser_del`, stopping at the first error. It requires the Stage User Administrators privilege.

func (*Client) StageUserDeleteContext added in v0.5.0

func (c *Client) StageUserDeleteContext(ctx context.Context, usernames ...string) error

StageUserDeleteContext is like StageUserDelete but bounds the request with ctx.

func (*Client) StageUserFind added in v0.5.0

func (c *Client) StageUserFind(options Options) ([]*User, error)

StageUserFind finds stage users with `stageuser_find`; options are passed through (e.g. `uid`, `sizelimit`). It requires the Stage User Administrators privilege.

func (*Client) StageUserFindContext added in v0.5.0

func (c *Client) StageUserFindContext(ctx context.Context, options Options) ([]*User, error)

StageUserFindContext is like StageUserFind but bounds the request with ctx.

func (*Client) StageUserMod added in v0.5.0

func (c *Client) StageUserMod(user *User) (*User, error)

StageUserMod modifies a stage user with `stageuser_mod`, sending the same attributes as UserMod; like UserMod it is read-modify-write, so start from StageUserShow. It returns user itself when nothing changed. It requires the Stage User Administrators privilege.

func (*Client) StageUserModContext added in v0.5.0

func (c *Client) StageUserModContext(ctx context.Context, user *User) (*User, error)

StageUserModContext is like StageUserMod but bounds the request with ctx.

func (*Client) StageUserShow added in v0.5.0

func (c *Client) StageUserShow(username string) (*User, error)

StageUserShow fetches a stage user with `stageuser_show`. It requires the Stage User Administrators privilege.

func (*Client) StageUserShowContext added in v0.5.0

func (c *Client) StageUserShowContext(ctx context.Context, username string) (*User, error)

StageUserShowContext is like StageUserShow but bounds the request with ctx.

func (*Client) StickySession

func (c *Client) StickySession(enable bool)

Set stick sessions.

func (*Client) SubIDFind added in v0.5.0

func (c *Client) SubIDFind(options Options) ([]*SubID, error)

SubIDFind finds sub-ID ranges with `subid_find`; options are passed through (e.g. `ipaowner`). Any authenticated user may read sub-IDs. FreeIPA 4.9.7+.

func (*Client) SubIDFindContext added in v0.5.0

func (c *Client) SubIDFindContext(ctx context.Context, options Options) ([]*SubID, error)

SubIDFindContext is like SubIDFind but bounds the request with ctx.

func (*Client) SubIDGenerate added in v0.5.0

func (c *Client) SubIDGenerate(owner string) (*SubID, error)

SubIDGenerate allocates a range with `subid_generate`; owner "" means the caller. For yourself it needs the Subordinate ID Selfservice User role, for others Subordinate ID Administrators. One range per user: a second call returns ErrDuplicateEntry. A server with sub-IDs disabled returns a 3009 ValidationError.

func (*Client) SubIDGenerateContext added in v0.5.0

func (c *Client) SubIDGenerateContext(ctx context.Context, owner string) (*SubID, error)

SubIDGenerateContext is like SubIDGenerate but bounds the request with ctx.

func (*Client) SudoRuleFind added in v0.5.0

func (c *Client) SudoRuleFind(options Options) ([]*SudoRule, error)

SudoRuleFind finds sudo rules with `sudorule_find`; options are passed through (e.g. `cn`, `ipaenabledflag`, `sizelimit`). Any authenticated user may read rules (System: Read Sudo Rules). FreeIPA returns at most its search limit (100 by default) unless `sizelimit` is set.

func (*Client) SudoRuleFindContext added in v0.5.0

func (c *Client) SudoRuleFindContext(ctx context.Context, options Options) ([]*SudoRule, error)

SudoRuleFindContext is like SudoRuleFind but bounds the request with ctx.

func (*Client) SyncOTPToken added in v0.5.0

func (c *Client) SyncOTPToken(username, password, firstCode, secondCode, tokenID string) error

SyncOTPToken resynchronises an OTP token whose clock or counter drifted, from two consecutive codes, through /ipa/session/sync_token. password is the user's password without an OTP. tokenID selects the token (unique ID or DN); "" lets the server try the user's tokens. No session or Kerberos ticket is needed. Based on ubccr/goipa#2 by @farzandalaee.

func (*Client) SyncOTPTokenContext added in v0.5.0

func (c *Client) SyncOTPTokenContext(ctx context.Context, username, password, firstCode, secondCode, tokenID string) error

SyncOTPTokenContext is like SyncOTPToken but bounds the request with ctx.

func (*Client) UserAdd

func (c *Client) UserAdd(user *User, random bool) (*User, error)

Add new user. If random is true a random password will be created for the user. Note this requires "User Administrators" Privilege in FreeIPA.

func (*Client) UserAddContext added in v0.2.0

func (c *Client) UserAddContext(ctx context.Context, user *User, random bool) (*User, error)

UserAddContext is like UserAdd but bounds the request with ctx.

func (*Client) UserAddPasskey added in v0.5.0

func (c *Client) UserAddPasskey(username, mapping string) error

UserAddPasskey adds a passkey mapping with `user_add_passkey`. The mapping is passkey:<credential id b64>,<public key b64 SPKI>[,<user id>]. Users may manage their own mappings; for others the Passkey Administrators privilege is needed. FreeIPA 4.11+ (older servers return 905 CommandError). A duplicate returns 4038, an invalid mapping 3009. Read mappings with UserShow (User.Passkeys).

func (*Client) UserAddPasskeyContext added in v0.5.0

func (c *Client) UserAddPasskeyContext(ctx context.Context, username, mapping string) error

UserAddPasskeyContext is like UserAddPasskey but bounds the request with ctx.

func (*Client) UserAddWithPassword

func (c *Client) UserAddWithPassword(user *User, password string) (*User, error)

Add new user and set password. Note this requires "User Administrators" Privilege in FreeIPA.

func (*Client) UserAddWithPasswordContext added in v0.2.0

func (c *Client) UserAddWithPasswordContext(ctx context.Context, user *User, password string) (*User, error)

UserAddWithPasswordContext is like UserAddWithPassword but bounds the request with ctx.

func (*Client) UserDelete

func (c *Client) UserDelete(preserve, stopOnError bool, usernames ...string) error

Delete user. If preserve is false the user will be permanetly deleted, if true the users is moved to the Delete container. If stopOnError is false the operation will be in continuous mode otherwise it will stop on errors

func (*Client) UserDeleteContext added in v0.2.0

func (c *Client) UserDeleteContext(ctx context.Context, preserve, stopOnError bool, usernames ...string) error

UserDeleteContext is like UserDelete but bounds the request with ctx.

func (*Client) UserDisable

func (c *Client) UserDisable(username string) error

Disable User Account

func (*Client) UserDisableContext added in v0.2.0

func (c *Client) UserDisableContext(ctx context.Context, username string) error

UserDisableContext is like UserDisable but bounds the request with ctx.

func (*Client) UserEnable

func (c *Client) UserEnable(username string) error

Enable User Account

func (*Client) UserEnableContext added in v0.2.0

func (c *Client) UserEnableContext(ctx context.Context, username string) error

UserEnableContext is like UserEnable but bounds the request with ctx.

func (*Client) UserFind

func (c *Client) UserFind(options Options) ([]*User, error)

Find users.

func (*Client) UserFindContext added in v0.2.0

func (c *Client) UserFindContext(ctx context.Context, options Options) ([]*User, error)

UserFindContext is like UserFind but bounds the request with ctx.

func (*Client) UserMod

func (c *Client) UserMod(user *User) (*User, error)

Modify user. It is read-modify-write: send a User from UserShow with the changes, as every attribute ToOptions sends is set, an empty HomeDir included (FreeIPA rejects that with 4205). Currently only modifies a subset of user attributes: mail (all values, see Emails), givenname, sn, homedirectory, loginshell, displayname, ipasshpubkey, telephonenumber, and mobile

func (*Client) UserModContext added in v0.2.0

func (c *Client) UserModContext(ctx context.Context, user *User) (*User, error)

UserModContext is like UserMod but bounds the request with ctx.

func (*Client) UserPwPolicy added in v0.5.0

func (c *Client) UserPwPolicy(username string) (*PwPolicy, error)

UserPwPolicy fetches the policy that applies to username with `pwpolicy_show` and its `user` option: the group policy with the lowest priority among the user's groups, else the global policy. FreeIPA resolves it as the caller, so the caller must be able to read the user, and, as for PwPolicyShow, a caller without the privilege gets ErrNotFound. Priority is 0 because FreeIPA does not return it here.

func (*Client) UserPwPolicyContext added in v0.5.0

func (c *Client) UserPwPolicyContext(ctx context.Context, username string) (*PwPolicy, error)

UserPwPolicyContext is like UserPwPolicy but bounds the request with ctx.

func (*Client) UserRemovePasskey added in v0.5.0

func (c *Client) UserRemovePasskey(username, mapping string) error

UserRemovePasskey removes a passkey mapping with `user_remove_passkey`; see UserAddPasskey. A mapping that is not present returns 4026.

func (*Client) UserRemovePasskeyContext added in v0.5.0

func (c *Client) UserRemovePasskeyContext(ctx context.Context, username, mapping string) error

UserRemovePasskeyContext is like UserRemovePasskey but bounds the request with ctx.

func (*Client) UserShow

func (c *Client) UserShow(username string) (*User, error)

Fetch user details by call the FreeIPA user-show method

func (*Client) UserShowContext added in v0.2.0

func (c *Client) UserShowContext(ctx context.Context, username string) (*User, error)

UserShowContext is like UserShow but bounds the request with ctx.

func (*Client) UserStatus added in v0.5.0

func (c *Client) UserStatus(username string) ([]*ReplicaStatus, error)

UserStatus reports a user's failed logins with `user_status`; one entry per master, each master is queried live. Without the User Administrators privilege FreeIPA hides the counters (FailedLogins 0, zero times) instead of failing.

func (*Client) UserStatusContext added in v0.5.0

func (c *Client) UserStatusContext(ctx context.Context, username string) ([]*ReplicaStatus, error)

UserStatusContext is like UserStatus but bounds the request with ctx.

func (*Client) UserUnlock added in v0.5.0

func (c *Client) UserUnlock(username string) error

UserUnlock resets a user's failed login counter with `user_unlock`. It requires User Administrators (System: Unlock User). On FreeIPA 4.13 members of admins and trust admins cannot be unlocked through delegation (2100). It writes the local master; replication carries it.

func (*Client) UserUnlockContext added in v0.5.0

func (c *Client) UserUnlockContext(ctx context.Context, username string) error

UserUnlockContext is like UserUnlock but bounds the request with ctx.

type Group added in v0.4.0

type Group struct {
	Name, Description, GID string
	// member_user, member_group, memberindirect_user, memberindirect_group
	Users, Groups, IndirectUsers, IndirectGroups []string
	// memberof_group
	MemberOf []string
	// membermanager_user, membermanager_group
	ManagerUsers, ManagerGroups []string
	// External: objectclass has ipaexternalgroup. NonPOSIX: objectclass lacks
	// posixgroup. The zero value is a POSIX group.
	External, NonPOSIX bool
}

Group is a FreeIPA user group.

type HBACRule added in v0.5.0

type HBACRule struct {
	// cn, description
	Name, Description string
	// ipaenabledflag
	Enabled bool
	// usercategory, hostcategory, servicecategory: "all" or ""
	UserCategory, HostCategory, ServiceCategory string
	// memberuser_user, memberuser_group
	Users, Groups []string
	// memberhost_host, memberhost_hostgroup
	Hosts, HostGroups []string
	// memberservice_hbacsvc, memberservice_hbacsvcgroup
	Services, ServiceGroups []string
}

HBACRule is a host-based access control rule.

type HBACTestResult added in v0.5.0

type HBACTestResult struct {
	// value
	Granted bool
	// matched, notmatched: names of the rules that did and did not match
	Matched, NotMatched []string
	// error, warning
	Errors, Warnings []string
}

HBACTestResult is the outcome of HBACTest.

type HTTPError added in v0.2.0

type HTTPError struct {
	StatusCode int
	Status     string
}

HTTPError is returned when the server answers a JSON-RPC call with a status other than 200. HTTP 401 (for example an expired session) also matches ErrUnauthorized with errors.Is.

func (*HTTPError) Error added in v0.2.0

func (e *HTTPError) Error() string

Error returns the message used before HTTPError existed.

func (*HTTPError) Is added in v0.2.0

func (e *HTTPError) Is(target error) bool

Is reports whether target is ErrUnauthorized and the status is 401.

type Host added in v0.4.0

type Host struct {
	// fqdn, description, l, nshostlocation, nshardwareplatform, nsosversion,
	// krbprincipalname (first value of each)
	FQDN, Description, Locality, Location, Platform, OSVersion, Principal string
	// macaddress, userclass
	MACAddresses, UserClass []string
	// memberof_hostgroup, memberofindirect_hostgroup
	HostGroups, IndirectHostGroups []string
	// managedby_host
	ManagedBy []string
	// has_keytab, has_password
	HasKeytab, HasPassword bool
}

Host is a FreeIPA host.

type IpaError

type IpaError struct {
	Message string
	Code    int
	Name    string `json:"name"`
	// Data is the raw JSON of the exception's keyword arguments, e.g.
	// {"reason":"..."}. A string so IpaError stays comparable.
	Data string `json:"data"`
}

FreeIPA error

func (*IpaError) Error

func (e *IpaError) Error() string

func (*IpaError) Is added in v0.2.0

func (e *IpaError) Is(target error) bool

Is reports whether target is an *IpaError with the same Code.

func (*IpaError) MarshalJSON added in v0.3.0

func (e *IpaError) MarshalJSON() ([]byte, error)

MarshalJSON writes FreeIPA's error shape; an empty or non-JSON Data becomes {}.

func (*IpaError) UnmarshalJSON added in v0.2.0

func (e *IpaError) UnmarshalJSON(b []byte) error

UnmarshalJSON keeps Data as raw JSON text; Message and Code still match the "message" and "code" keys case-insensitively.

type MemberError added in v0.4.0

type MemberError struct {
	Failures []MemberFailure
}

MemberError reports the members a group member call could not change. FreeIPA lists them in the result, with no error, even when the caller lacks the right to change members at all.

func (*MemberError) Error added in v0.4.0

func (e *MemberError) Error() string

type MemberFailure added in v0.4.0

type MemberFailure struct {
	Kind    string // "member" or "membermanager"
	Type    string // "user" or "group"
	Name    string
	Message string
}

MemberFailure is one member FreeIPA refused to add or remove.

type Message added in v0.2.0

type Message struct {
	Type    string          `json:"type"`
	Name    string          `json:"name"`
	Message string          `json:"message"`
	Code    int             `json:"code"`
	Data    json.RawMessage `json:"data"`
}

Message is a server warning attached to a FreeIPA result.

type OTPToken

type OTPToken struct {
	DN          string    `json:"dn"`
	UUID        string    `json:"ipatokenuniqueid"`
	Algorithm   string    `json:"ipatokenotpalgorithm"`
	Digits      int       `json:"ipatokenotpdigits"`
	Owner       string    `json:"ipatokenowner"`
	TimeStep    int       `json:"ipatokentotptimestep"`
	ClockOffest int       `json:"ipatokentotpclockoffset"`
	ManagedBy   string    `json:"managedby_user"`
	Enabled     bool      `json:"-"`
	Type        string    `json:"type"`
	URI         string    `json:"uri"`
	Description string    `json:"description"`
	Vendor      string    `json:"ipatokenvendor"`
	Model       string    `json:"ipatokenmodel"`
	Serial      string    `json:"ipatokenserial"`
	NotBefore   time.Time `json:"ipatokennotbefore"`
	NotAfter    time.Time `json:"ipatokennotafter"`
}

OTPToken encapsulates FreeIPA otptokens

var DefaultTOTPToken *OTPToken = &OTPToken{
	Type:      TokenTypeTOTP,
	Algorithm: AlgorithmSHA1,
	Digits:    6,
	TimeStep:  30,
}

func (*OTPToken) DisplayName

func (t *OTPToken) DisplayName() string

type Options

type Options map[string]interface{}

FreeIPA api options map

type PwPolicy added in v0.5.0

type PwPolicy struct {
	// cn: "global_policy" or the group the policy belongs to
	Name string
	// cospriority; group policies only. 0 from UserPwPolicy: FreeIPA does not
	// return it for the effective policy, use PwPolicyShow(Name).
	Priority int
	// krbmaxpwdlife (days on the wire), krbminpwdlife (hours on the wire)
	MaxLife, MinLife time.Duration
	// krbpwdhistorylength, krbpwdmindiffchars, krbpwdminlength, krbpwdmaxfailure
	HistoryLength, MinClasses, MinLength, MaxFailures int
	// krbpwdfailurecountinterval (seconds), krbpwdlockoutduration (seconds;
	// 0 = locked until an admin unlocks)
	FailureInterval, LockoutDuration time.Duration
	// ipapwdmaxrepeat, ipapwdmaxsequence
	MaxRepeat, MaxSequence int
	// ipapwddictcheck, ipapwdusercheck
	DictCheck, UserCheck bool
	// passwordgracelimit, FreeIPA 4.9.10+; -1 = no grace logins enforced
	GraceLimit int
	// ipapwddcredit, ipapwducredit, ipapwdlcredit, ipapwdocredit; FreeIPA 4.13+
	DigitCredit, UpperCredit, LowerCredit, OtherCredit int
}

PwPolicy is a FreeIPA password policy. Attributes the server does not return (older releases, unset values) are zero.

type ReplicaStatus added in v0.5.0

type ReplicaStatus struct {
	// Server is the master; only the host part when it could not be queried
	// (then Err is set).
	Server string
	// Err is the reason the master could not be queried, "" when it answered.
	Err string
	// FailedLogins is krbloginfailedcount.
	FailedLogins int
	// LastSuccess and LastFailure are krblastsuccessfulauth and
	// krblastfailedauth, read from FreeIPA's {"__datetime__": ...} form or an
	// RFC 3339 string; zero for "N/A".
	LastSuccess, LastFailure time.Time
	// Now is the master's clock.
	Now time.Time
}

ReplicaStatus is one IPA master's view of a user's Kerberos login state (user_status).

type Response

type Response struct {
	Error     *IpaError `json:"error"`
	ID        int       `json:"id"`
	Principal string    `json:"principal"`
	Version   string    `json:"version"`
	Result    *Result   `json:"result"`
}

Response returned from a FreeIPA JSON rpc call

type Result

type Result struct {
	Summary   string          `json:"summary"`
	Value     interface{}     `json:"value"`
	Data      json.RawMessage `json:"result"`
	Count     int             `json:"count"`
	Truncated bool            `json:"truncated"`
	Messages  []Message       `json:"messages"`
	Completed int             `json:"completed"`
	Failed    json.RawMessage `json:"failed"`
	// Raw is the whole FreeIPA result object, for shapes without a "result"
	// key such as hbactest.
	Raw json.RawMessage `json:"-"`
}

Result returned from a FreeIPA JSON rpc call

func (*Result) UnmarshalJSON added in v0.2.0

func (r *Result) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the result and keeps a copy of the raw object in Raw.

type SSHAuthorizedKey

type SSHAuthorizedKey struct {
	Comment     string
	Options     []string
	PublicKey   ssh.PublicKey
	Fingerprint string
}

SSH Public Key

func NewSSHAuthorizedKey

func NewSSHAuthorizedKey(in string) (*SSHAuthorizedKey, error)

func (*SSHAuthorizedKey) MarshalJSON

func (k *SSHAuthorizedKey) MarshalJSON() ([]byte, error)

func (*SSHAuthorizedKey) String

func (k *SSHAuthorizedKey) String() string

type SubID added in v0.5.0

type SubID struct {
	// ipauniqueid, ipaowner, description
	ID, Owner, Description string
	// ipasubuidnumber, ipasubuidcount
	UIDStart, UIDCount int64
	// ipasubgidnumber, ipasubgidcount
	GIDStart, GIDCount int64
}

SubID is a subordinate UID/GID range of a user.

type SudoRule added in v0.5.0

type SudoRule struct {
	// cn, description
	Name, Description string
	// ipaenabledflag
	Enabled bool
	// usercategory, hostcategory, cmdcategory: "all" or ""
	UserCategory, HostCategory, CmdCategory string
	// ipasudorunasusercategory, ipasudorunasgroupcategory
	RunAsUserCategory, RunAsGroupCategory string
	// memberuser_user, memberuser_group, memberhost_host, memberhost_hostgroup
	Users, Groups, Hosts, HostGroups []string
	// memberallowcmd_sudocmd, memberallowcmd_sudocmdgroup,
	// memberdenycmd_sudocmd, memberdenycmd_sudocmdgroup
	AllowCommands, AllowCommandGroups, DenyCommands, DenyCommandGroups []string
	// ipasudorunas_user, ipasudorunasgroup_group
	RunAsUsers, RunAsGroups []string
	// ipasudoopt
	Options []string
	// sudoorder
	Order int
}

SudoRule is a sudo rule.

type User

type User struct {
	UUID             string              `json:"ipauniqueid"`
	DN               string              `json:"dn"`
	First            string              `json:"givenname"`
	Last             string              `json:"sn"`
	DisplayName      string              `json:"displayname"`
	Principal        string              `json:"krbprincipalname"`
	Username         string              `json:"uid"`
	Uid              string              `json:"uidnumber"`
	Gid              string              `json:"gidnumber"`
	Groups           []string            `json:"memberof_group"`
	SSHAuthKeys      []*SSHAuthorizedKey `json:"ipasshpubkey"`
	AuthTypes        []string            `json:"ipauserauthtype"`
	HasKeytab        bool                `json:"has_keytab"`
	HasPassword      bool                `json:"has_password"`
	Locked           bool                `json:"nsaccountlock"`
	Preserved        bool                `json:"preserved"`
	HomeDir          string              `json:"homedirectory"`
	Email            string              `json:"mail"`
	TelephoneNumber  string              `json:"telephonenumber"`
	Mobile           string              `json:"mobile"`
	Shell            string              `json:"loginshell"`
	Category         string              `json:"userclass"`
	SudoRules        []string            `json:"memberofindirect_sudorule"`
	HbacRules        []string            `json:"memberofindirect_hbacrule"`
	LastPasswdChange time.Time           `json:"krblastpwdchange"`
	PasswdExpire     time.Time           `json:"krbpasswordexpiration"`
	PrincipalExpire  time.Time           `json:"krbprincipalexpiration"`
	LastLoginSuccess time.Time           `json:"krblastsuccessfulauth"`
	LastLoginFail    time.Time           `json:"krblastfailedauth"`
	RandomPassword   string              `json:"randompassword"`

	// Emails holds every mail value; Email is the first. UserMod and UserAdd
	// send Email first, then Emails[1:] (see ToOptions), so Emails[0] is
	// ignored on write. To set the whole list, set Email = list[0] and
	// Emails = list.
	Emails []string `json:"emails"`
	// IndirectGroups: nested groups; filled by UserShow only, UserFind puts
	// nested groups in Groups (FreeIPA).
	IndirectGroups []string `json:"memberofindirect_group"`
	// Street, City, State, PostalCode and PreferredLanguage are returned only
	// with all, which UserShow and UserFind send.
	Street            string `json:"street"`
	City              string `json:"l"`
	State             string `json:"st"`
	PostalCode        string `json:"postalcode"`
	PreferredLanguage string `json:"preferredlanguage"`
	Title             string `json:"title"`
	OrgUnit           string `json:"ou"`
	// Passkeys: FreeIPA 4.11+, format passkey:<id>,<key>[,<userid>].
	Passkeys []string `json:"ipapasskey"`
}

User encapsulates user data returned from ipa user commands

func (*User) AddSSHAuthorizedKey

func (u *User) AddSSHAuthorizedKey(key *SSHAuthorizedKey)

Add ssh authorized key

func (*User) FormatSSHAuthorizedKeys

func (u *User) FormatSSHAuthorizedKeys() []string

Format ssh authorized keys

func (*User) HasGroup

func (u *User) HasGroup(group string) bool

Returns true if the User is in group

func (*User) OTPOnly

func (u *User) OTPOnly() bool

Returns true if OTP is the only authentication type enabled

func (*User) RemoveSSHAuthorizedKey

func (u *User) RemoveSSHAuthorizedKey(fingerprint string)

Removes ssh authorized key

func (*User) ToOptions

func (u *User) ToOptions() Options

Directories

Path Synopsis
Package ipatest provides a fake FreeIPA server for tests of code that uses goipa, so they run without a real IPA.
Package ipatest provides a fake FreeIPA server for tests of code that uses goipa, so they run without a real IPA.

Jump to

Keyboard shortcuts

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