ipa

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 7, 2023 License: BSD-3-Clause Imports: 23 Imported by: 0

README

goipa - FreeIPA client library

===============================================================================

GoDoc

goipa is a FreeIPA client library written in Go. It interfaces with the FreeIPA JSON api over HTTPS.

Usage

Install using go tools:

$ go get github.com/ubccr/goipa

Example calling FreeIPA user-show:

package main

import (
    "fmt"

    "github.com/ubccr/goipa"
)

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

    err := client.LoginWithKeytab("/path/to/user.keytab", "username")
    if err != nil {
        panic(err)
    }

    rec, err := client.UserShow("username")
    if err != nil {
        panic(err)
    }

    fmt.Println("%s - %s", rec.Username, rec.Uid)
}

Hacking

Development and testing goipa uses docker-compose. The scripts to spin up a FreeIPA test server in docker were copied/adopted from this great repository. Most of the scripts in container/ directory are written by Jan Pazdziora and licensed under Apache 2.0 and modified for use with goipa.

NOTE: The containers are NOT meant to be run in production and used solely for development.

To get started hacking on goipa and running the test suite:

$ cp .env.sample .env
[edit to taste. add passwords and ssh key]

$ docker-compose build
$ docker-compose up -d
$ ssh -p 9022 localhost
$ kinit admin
$ cd /app
$ go test

To run a specific test with trace debugging:

$ go test -v -run UserShow

License

goipa is released under a BSD style License. See the LICENSE file.

Documentation

Overview

Package ipa is a Go client library for FreeIPA

Index

Constants

View Source
const (
	DefaultKerbConf   = "/etc/krb5.conf"
	IpaClientVersion  = "2.237"
	IpaDatetimeFormat = "20060102150405Z"
)
View Source
const (
	AlgorithmSHA1   string = "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 (

	// 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")

	// 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
	ErrUserExists = errors.New("unauthorized")
)

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

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) ChangePassword

func (c *Client) ChangePassword(username, old_passwd, new_passwd, otpcode string) error

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

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) EnableOTPToken

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

Enable OTP token.

func (*Client) FetchOTPTokens

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

Fetch OTP tokens by owner.

func (*Client) Host

func (c *Client) Host() string

Returns FreeIPA server hostname

func (*Client) Login

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

Login to FreeIPA using local kerberos login username and password

func (*Client) LoginFromCCache

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

Login to FreeIPA using credentials cache

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) 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.

func (*Client) RemoveOTPToken

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

Remove OTP token

func (*Client) ResetPassword

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

Reset user password and return new random password

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) SetPassword

func (c *Client) SetPassword(username, old_passwd, new_passwd, 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) StickySession

func (c *Client) StickySession(enable bool)

Set stick sessions.

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) 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) 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) UserDisable

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

Disable User Account

func (*Client) UserEnable

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

Enable User Account

func (*Client) UserFind

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

Find users.

func (*Client) UserMod

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

Modify user. Currently only modifies a subset of user attributes: mail, givenname, sn, homedirectory, loginshell, displayname, ipasshpubkey, telephonenumber, and mobile

func (*Client) UserShow

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

Fetch user details by call the FreeIPA user-show method

type IpaError

type IpaError struct {
	Message string
	Code    int
}

FreeIPA error

func (*IpaError) Error

func (e *IpaError) Error() string

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 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"`
}

Result returned from a FreeIPA JSON rpc call

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 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"`
	StorageUrl       string              `json:"storageurl"`
}

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

Jump to

Keyboard shortcuts

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