Skip to content

Releases: neverlless/goipa

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 20:39
66a0d01

Added

  • Host writes: HostAdd (random one-time password, force),
    HostAddWithPassword, HostMod, HostDelete (updatedns) and
    HostDisable, with …Context twins; Host.RandomPassword
  • StageUserAddWithPassword sets the initial password on stageuser_add
    (#14)
  • WithTruncationErrors(): UserFind, GroupFind, HostFind,
    StageUserFind, SubIDFind, FetchOTPTokens, HBACRuleFind and
    SudoRuleFind return ErrTruncated with the entries they got; the
    default stays silent as in v1.0 (#15)
  • Examples for WithHTTPClient (timing the requests) and HostAdd
  • Kerberos documented: SPNEGO on the first call, then the ipa_session
    cookie; LoginFromCCache takes the path of a file cache (not KCM:; strip
    a FILE: prefix from KRB5CCNAME); after StickySession(false) every call
    negotiates SPNEGO
  • ipatest: Server.GrantPrivilege(uid, privilege) gives a user one FreeIPA
    privilege, for tests of delegated rights (#18)

Changed

  • ipatest: Calls() now redacts passwords (userpassword and the like)
    in the recorded options, so tests that asserted the raw values must
    compare "REDACTED" (the server state keeps the password)
  • ipatest: password changes by the user now enforce the user's effective
    policy (group policies by priority, character classes, history) and the
    minimum lifetime. A second self-change within MinLife (1 h by default)
    is refused; tests that change a password twice should call SetPwPolicy
    with MinLife 0 (users seeded with AddUser are exempt for their first
    change) (#19, Q180 to Q183)
  • ipatest: a malformed krbpasswordexpiration is refused (3008
    ConversionError, as FreeIPA) instead of meaning "never expires" (Q184)
  • ipatest: hbacrule_find, sudorule_find, subid_find and
    otptoken_find honour sizelimit (Q165 to Q167)
  • ipatest: a caller outside admins who holds no granted privilege gets
    2100 ACIError (ErrACI) on user_add, user_mod (other users),
    user_del, stageuser_add, group_add/_mod/_del,
    host_add/_mod/_del, hostgroup_add/_del, service_add/_del,
    hbacrule_add/_enable/_disable/_del, sudorule_add/_del, dnszone_add and
    automember_add, as FreeIPA 4.13.4 does on every release. The message
    follows SetVersion: the API permission text, or the directory's ACI text
    from 4.10 up to 4.13.3. user_mod on the caller's own entry stays allowed
    for self-service attributes. The checks of Q24, Q32, Q95 and Q122 also pass
    with the matching granted privilege. Tests that wrote as a plain user must
    use admin or GrantPrivilege (Q168 to Q174). Not modelled: the 4001 a
    plain user gets from dnsrecord_add (Q171) and 4.13.4 refusing an own
    passkey add (Q172)
  • ipatest: host_add, host_mod, host_disable and host_del with
    updatedns (which removes the host's A and AAAA records, Q158); macaddress
    comes back upper-case (Q156); host_disable follows the real server's
    keytab rules (Q157)
  • ipatest: user_add and stageuser_add with userpassword keep it,
    expired; stageuser_activate carries it over (Q160, #16); user_mod
    accepts setattr krbPasswordExpiration to lift the expiry (#17)

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 25 Oct 01:17
2b7c292

The v1 API freeze: from v1.0.0 no exported identifier of ipa or ipatest
is removed or re-signed (see Stability in the README). This release marks
what newer identifiers supersede, fixes the last client-side bugs found in
the API review and makes ipatest follow FreeIPA more closely.

Deprecated

  • NewDefaultClient, NewDefaultClientWithSession, NewClient and
    NewClientCustomHttp (use New), DefaultTOTPToken (use AddOTPToken
    with nil), ParseDateTime (use Entry.Time) and Response.Error. All
    keep working.

Added

  • ipatest: getters HBACRule, SudoRule, PwPolicy, Role, Privilege
    and Permission, and Service.AuthIndicators

Changed

  • Wire-equivalent shape changes, visible in ipatest.Calls():
    hbacrule_del and dnszone_del send continue: false;
    hostgroup_find and otptoken_find with no criteria send [""] as the
    argument
  • Entry.Strs returns a lone hint object other than __dns_name__ as its
    JSON instead of its inner value, as it already did inside a list
  • A 401 from SetPassword and SyncOTPToken now also matches
    ErrUnauthorized; failures of RemoteLogin, SetPassword and
    SyncOTPToken match *HTTPError with errors.As, message text unchanged
  • With WithValidation, an option key that names a positional argument newer
    than the server gives ErrNotSupported
  • ipatest behaviour (see Q140 to Q155 in the package documentation):
    host_del deletes the host's services; host group cycles are accepted;
    service_mod and krbprincipalauthind; sudoorder must be unique and
    sudo rules reject member lists that conflict with a category; hbactest
    expands the default HBAC service groups; RBAC cn finds match the whole
    name; otptoken_del by a non-admin gives 2100; certificate principals are
    case-sensitive and a second revoke fails; DNS apex and name checks;
    session_logout does not end the session, as on real servers (Q155), and
    a missing session gets FreeIPA's HTML 401 page

Fixed

  • A goroutine waiting for another's password re-login returns ctx.Err()
    when its context ends instead of blocking
  • ClearSession during a re-login is no longer undone by the login that was
    already in flight
  • Command catalogue generator: autofill is read only as a keyword argument,
    a stale allow-list entry and two source files for one version are errors

Security

  • On FreeIPA (seen on 4.9.13, 4.12.2 and 4.13.4) the server keeps accepting a session cookie after
    session_logout. Logout only makes the client forget it, so treat a
    session ID as a credential until it expires. Documented in the README and
    the package documentation.

v0.9.1

Choose a tag to compare

@github-actions github-actions released this 24 Oct 21:34

Fixed

  • ipatest: host group names are matched case-insensitively in rules,
    services, automember rules and nested groups, as in FreeIPA, and are
    reported lower-cased

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 21:03
72c8df1

Typed objects: host groups, services and keytab access, HBAC and sudo rule
management, certificates, DNS zones and records, automember rules, and
roles, privileges and permissions, each with an ipatest model and contract
tests checked against real FreeIPA 4.9, 4.12 and 4.13. ipatest also
answers commands it does not model with responses recorded from those
servers.

Added

  • Host groups: HostGroupShow, HostGroupFind, HostGroupAdd,
    HostGroupDelete, member and member-manager calls
  • Services: ServiceShow, ServiceFind, ServiceAdd, ServiceDelete,
    ServiceDisable, hosts that manage a service, and the keytab access lists
    (ServiceAllowRetrieveKeytab and its three siblings with KeytabAccess)
  • HBAC and sudo rules: show, add, delete, enable, disable and members
    (HBACRuleAddUser, SudoRuleAddAllowCommand, SudoRuleAddRunAsUser,
    SudoRuleAddOption, ...); SudoRule.RunAsUserGroups
  • Certificates: CertRequest, CertShow, CertRevoke
  • DNS: zones (DNSZoneShow, DNSZoneFind, DNSZoneAdd, DNSZoneDelete,
    DNSZoneEnable, DNSZoneDisable) and records (DNSRecordShow,
    DNSRecordFind, DNSRecordAdd, DNSRecordRemove, DNSRecordDelete)
  • Automember rules: show, find, add, delete, conditions, default group,
    rebuild (AutomemberShow, AutomemberAddCondition, AutomemberRebuild, ...)
  • Roles, privileges and permissions, read only: RoleShow/RoleFind,
    PrivilegeShow/PrivilegeFind, PermissionShow/PermissionFind
  • Every new call has a ...Context twin. Attribute changes go through
    Modify (for automember, RPC, since it needs the rule type); member
    calls return the updated object and a *MemberError for members the
    server refused
  • ipatest: models for all of the above, with AddHostGroup, AddService,
    AddRole, AddPrivilege and AddPermission seed helpers (AddHBACRule
    and AddSudoRule exist since v0.5.0)
  • ipatest: NewRecorder records a real server's *_show/*_find
    responses (secrets redacted) and Server.SetReplay answers from them; the
    recordings of FreeIPA 4.9.13, 4.12.2 and 4.13.4 are embedded, so tests of
    commands goipa does not wrap see real response shapes. IPATEST_RECORD=dir
    records during the contract tests

Changed

  • ipatest: host_add and host_del are modelled; host_del and
    hostgroup_del remove the deleted entry from host groups, HBAC and sudo
    rules and services that named it
  • ipatest: sudorule_add_user (and the other sudo member calls) with
    unknown users, groups or hosts now succeeds, keeping them as external
    members as FreeIPA does; a duplicate sudorule_add_option is 4002
  • ipatest: commands that are not modelled are checked against the
    catalogue too, so an unknown option is 3005 before the 905 or replayed
    answer
  • ipatest: a *_show or *_find command that is not modelled and has no
    Handle override is answered from the recordings instead of 905 (a
    built-in or a Handle override still wins); SetReplay(nil) restores 905.
    The recordings add about 3 MB to the ipatest package only
  • The integration CI container installs FreeIPA with integrated DNS

Notes from the real servers

Checked on FreeIPA 4.9.13, 4.12.2 and 4.13.4; ipatest follows them
(quirks Q50 to Q139 in its documentation).

  • Enabling or disabling an HBAC rule, sudo rule or DNS zone twice succeeds
  • The default certificate profile accepts RSA keys only; an ECDSA CSR fails
  • On 4.9 sudorule_add_option takes one option per request, so
    SudoRuleAddOption sends them one at a time
  • A sudo rule's unknown users, groups and hosts become external members

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 18:55
fa48022

Command catalogue: every command, argument and option of FreeIPA 4.9.0 to
4.13.4, with the release that introduced each, generated from FreeIPA's own
API.txt. Clients can opt in to checking every call against it before it
is sent. Checked against real FreeIPA 4.9, 4.12 and 4.13 by the contract
tests, which now run with validation on.

Added

  • Commands, LookupCommand, Command and Param: the FreeIPA command
    catalogue for releases 4.9.0 to 4.13.4 (positional arguments, options,
    types and the release that introduced each), generated from API.txt with
    go generate; a nightly CI job fails when it is out of date
  • WithValidation and ErrInvalidCall: opt-in check of every call against
    the catalogue before it is sent, including each call inside Batch;
    commands and options newer than the server give ErrNotSupported
  • ipatest: built-in commands reject options the command lacks at the
    reported release (OptionError) and commands added after it;
    passkeyconfig_show is modelled

Changed

  • ipatest: built-in commands now reject options they lack and commands
    newer than the SetVersion release (3005 / 905), so consumer tests that
    sent such options may fail on upgrade; SetVersion now affects behaviour,
    not only the reported string. Handle overrides are not checked

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 17:37
6db8d20

Typed escape hatch and core API: any FreeIPA command can be called with
typed decoding, truncated searches are reported, attributes can be changed
one at a time, several commands can run in one round trip, and calls for
features newer than the server fail early. Checked against real FreeIPA
4.9, 4.12 and 4.13 by the contract tests.

Added

  • Call[T], a generic typed call for any FreeIPA command, and Entry, a
    result object with Has, Str, Strs, Bool, Int, Time, Bytes,
    DN and Raw accessors that read FreeIPA's attribute lists,
    __datetime__ and __base64__ values
  • FindEntries(ctx, c, method, args, opts, sizelimit) and ErrTruncated:
    a *_find that reports a result truncated by the server's size limit
    instead of returning it silently
  • ServerVersion and ErrNotSupported: passkey calls (FreeIPA 4.11) and
    SubIDFind/SubIDGenerate (4.9.7) fail before sending when the known
    server is older
  • Modify(command, keys...): setattr/addattr/delattr updates of
    single attributes on any object, nested ones included
  • Batch: several commands in one round trip with per-command results;
    BatchResult.Err is an error holding a bare *IpaError
  • CodeConversion (3008), CodeObjectclassViolation (4205) and CodeOnlyOneValueAllowed (4207)
  • ipatest: SetVersion, sizelimit truncation on user_find,
    group_find and host_find, setattr/addattr/delattr on user_mod
    and stageuser_mod (including OnlyOneValueAllowed), and batch

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 16:32
11544e7

Construction and authentication: an options-based New with no file I/O at
import time, Kerberos login from memory, WhoAmI, and recovery from expired
sessions. The session behaviour is checked against real FreeIPA 4.9, 4.12
and 4.13 by the contract tests.

Added

  • New(opts ...Option) (*Client, error) with WithHost, WithRealm,
    WithCACert, WithHTTPClient, WithKrb5Config, WithKrb5ConfigData and
    WithPasswordRelogin. The old constructors keep their signatures
  • LoginWithKeytabData, LoginFromCCacheData and in-memory Kerberos
    configuration (WithKrb5ConfigData; idea from sitnikovv's fork), for
    containers and secret stores
  • WhoAmI and WhoAmIContext
  • Expired sessions are recovered: Kerberos clients retry once through
    SPNEGO; with WithPasswordRelogin, RemoteLogin clients log in again
    and retry once (a password FreeIPA rejects is forgotten; needs sticky
    sessions; concurrent 401s cost one login). Other clients get
    ErrUnauthorized and the session is cleared
  • ipatest.Server.CACert, and whoami and session_logout in ipatest
  • "Which login to use" guide in the README and package documentation

Changed

  • A 401 on a session request now clears the session (it was kept)
  • Clients with a Kerberos login, old constructors included, retry once
    through SPNEGO after a 401
  • NewDefaultClient*, NewClient and New read /etc/ipa on first use
    instead of at import; NewClientCustomHttp never reads it
  • ClearSession also forgets the credentials kept by WithPasswordRelogin
  • FreeIPA's logout cookie (an ipa_session cookie that deletes the session,
    or MagBearerToken=) clears the session; before, session_logout failed
    with "invalid set-cookie header"

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 15:16
8e638f7

Account lifecycle and access: stage users, lockout status and unlock,
password policy, subordinate IDs, HBAC and sudo rules with hbactest,
passkey mappings and OTP token sync, each with a Context twin and an
ipatest model. Every behaviour is checked against real FreeIPA 4.9,
4.12 and 4.13 by the contract tests.

  • Stage users: StageUserAdd, StageUserShow, StageUserFind,
    StageUserMod, StageUserActivate and StageUserDelete
  • Lockout: UserStatus returns one ReplicaStatus per master (failed
    logins in either of FreeIPA's forms, last success and failure times, an
    unreachable master reported instead of failing the call); UserUnlock
  • Password policy: PwPolicyShow and UserPwPolicy, with durations as
    time.Duration and the FreeIPA 4.13 password-quality credits and grace
    login limit
  • Subordinate IDs: SubIDFind and SubIDGenerate
  • HBAC and sudo: HBACRuleFind, SudoRuleFind and HBACTest, which
    reads hbactest's result correctly and evaluates every rule, not only the
    first 100
  • Passkeys: UserAddPasskey and UserRemovePasskey
  • SyncOTPToken and ErrInvalidCredentials (based on ubccr/goipa#2 by
    @farzandalaee)
  • CodeOption (3005 OptionError: an option the command does not take)
  • ipatest models stage users, user_status and user_unlock, password
    policies, sub-IDs, HBAC and sudo rules (with the default allow_all
    rule), hbactest, passkey mappings and token sync

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 23 Oct 12:57

Users and groups: typed group management with per-member failures as
errors, all of a user's mail addresses, address, language and passkeys,
and host lookups. Every behaviour is checked against real FreeIPA 4.9,
4.12 and 4.13 by the contract tests.

  • Groups: GroupShow, GroupFind, GroupAdd, GroupMod, GroupDelete,
    GroupAddMember, GroupRemoveMember, GroupAddMemberManager and
    GroupRemoveMemberManager, each with a Context twin. Per-member
    failures, including insufficient access, are returned as *MemberError
    (FreeIPA reports them with no error); the updated group is returned with
    it. Based on ubccr/goipa#9 by @earthquakesan, #14 by @ivanovilia96 and
    #17 by @m-vinc
  • User.Emails (all mail values, ubccr/goipa#10), IndirectGroups
    (from user_show; idea from fajo-de), Street, City, State,
    PostalCode, PreferredLanguage, Title, OrgUnit (title/ou as in
    tubby1981's fork) and Passkeys. These are read-only: UserMod does
    not write them
  • HostShow and HostFind (ubccr/goipa#11)
  • ipatest models groups, member managers, nested groups, hosts and the
    new user attributes in FreeIPA's response shapes; contract tests pin
    them against the real server in the nightly run
  • UserMod dropped every mail value but the first. Email is still the
    first address and replaces it; the rest of Emails is kept. A single
    address is sent exactly as before
  • SetPassword no longer posts an empty otp field; randompassword is
    read whether the server returns a string or a list (both found by
    tubby1981)

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 23 Oct 12:32

Test infrastructure: an in-memory FreeIPA server for unit tests, and the
same contract tests run nightly against real FreeIPA 4.9, 4.12 and 4.13.
The first real-server runs found a bug in UserAdd that dates back to
ubccr/goipa v0.0.7; it is fixed here.

  • New package ipatest: a fake FreeIPA server over TLS for tests of code
    that uses goipa. NewServer(t) (or New() outside tests), Client,
    ClientAs, Session, seed and inspect users and OTP tokens, a call
    log (Calls) and Handle to inject errors or serve any command it
    does not model. It models user_show/find/add/mod/del/disable/enable,
    passwd, otptoken_add/del/mod/find, login_password and change_password
    with the lockout, expiry and last-OTP-token behaviour of FreeIPA 4.13;
    each quirk is listed in the package doc and pinned by a test
  • (*IpaError).MarshalJSON writes FreeIPA's error shape
    (code, message, name, data); Data that is not JSON becomes {}
  • Unit tests for the whole API against ipatest, coverage above 80 %
    (gated in CI) and Codecov upload
  • Integration tests run nightly against FreeIPA 4.9.13, 4.12.2 and 4.13.4;
    the same contract tests run against ipatest and the real server. The
    integration tests are now named *_integration_test.go
  • pkg.go.dev examples for the login modes and the RPC escape hatch
  • Removed the CentOS 7 container/, docker-compose.yml and .env.sample;
    scripts/ipa-up.sh starts a FreeIPA container instead
  • Testing with ipatest: it answers /ipa/json (the Kerberos endpoint)
    with 401 unless SetNegotiateUser is set, as a real server does for a
    client without a Kerberos ticket; log in with RemoteLogin or ClientAs
    instead
  • UserAdd and UserAddWithPassword leave empty attributes out of
    user_add, so FreeIPA applies its defaults; an unset HomeDir failed
    with 4205 missing attribute "homeDirectory" (bug since v0.0.7)
  • ipatest: JSON-RPC without a valid Referer gets HTTP 400 text/html like
    FreeIPA, not error 911; a MagBearerToken it did not issue closes the
    connection (goipa returns EOF), as the real server's httpd crashes on it
  • ipatest models user_add with an empty homedirectory (4205, Q19)
  • ipatest.Server.ExpireSession ends a session; calls with it get 401
    (ErrUnauthorized), as for an expired session on FreeIPA
  • scripts/ipa-up.sh sets forwardable = true in krb5.conf; without it
    every Kerberos call fails 2100 "Credential cache is empty"
  • Contract tests expect invalid-password for locked users before FreeIPA
    4.13.1 (FreeIPA issue 9891)